You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

base_executor_test.go 6.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package at
  18. import (
  19. "github.com/stretchr/testify/assert"
  20. "seata.apache.org/seata-go/pkg/datasource/sql/types"
  21. "testing"
  22. )
  23. func TestBaseExecBuildLockKey(t *testing.T) {
  24. var exec baseExecutor
  25. columnID := types.ColumnMeta{
  26. ColumnName: "id",
  27. }
  28. columnUserId := types.ColumnMeta{
  29. ColumnName: "userId",
  30. }
  31. columnName := types.ColumnMeta{
  32. ColumnName: "name",
  33. }
  34. columnAge := types.ColumnMeta{
  35. ColumnName: "age",
  36. }
  37. columnNonExistent := types.ColumnMeta{
  38. ColumnName: "non_existent",
  39. }
  40. columnsTwoPk := []types.ColumnMeta{columnID, columnUserId}
  41. columnsThreePk := []types.ColumnMeta{columnID, columnUserId, columnAge}
  42. columnsMixPk := []types.ColumnMeta{columnName, columnAge}
  43. getColumnImage := func(columnName string, value interface{}) types.ColumnImage {
  44. return types.ColumnImage{KeyType: types.IndexTypePrimaryKey, ColumnName: columnName, Value: value}
  45. }
  46. tests := []struct {
  47. name string
  48. metaData types.TableMeta
  49. records types.RecordImage
  50. expected string
  51. }{
  52. {
  53. "Two Primary Keys",
  54. types.TableMeta{
  55. TableName: "test_name",
  56. Indexs: map[string]types.IndexMeta{
  57. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: columnsTwoPk},
  58. },
  59. },
  60. types.RecordImage{
  61. TableName: "test_name",
  62. Rows: []types.RowImage{
  63. {[]types.ColumnImage{getColumnImage("id", 1), getColumnImage("userId", "user1")}},
  64. {[]types.ColumnImage{getColumnImage("id", 2), getColumnImage("userId", "user2")}},
  65. },
  66. },
  67. "TEST_NAME:1_user1,2_user2",
  68. },
  69. {
  70. "Three Primary Keys",
  71. types.TableMeta{
  72. TableName: "test2_name",
  73. Indexs: map[string]types.IndexMeta{
  74. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: columnsThreePk},
  75. },
  76. },
  77. types.RecordImage{
  78. TableName: "test2_name",
  79. Rows: []types.RowImage{
  80. {[]types.ColumnImage{getColumnImage("id", 1), getColumnImage("userId", "one"), getColumnImage("age", "11")}},
  81. {[]types.ColumnImage{getColumnImage("id", 2), getColumnImage("userId", "two"), getColumnImage("age", "22")}},
  82. {[]types.ColumnImage{getColumnImage("id", 3), getColumnImage("userId", "three"), getColumnImage("age", "33")}},
  83. },
  84. },
  85. "TEST2_NAME:1_one_11,2_two_22,3_three_33",
  86. },
  87. {
  88. name: "Single Primary Key",
  89. metaData: types.TableMeta{
  90. TableName: "single_key",
  91. Indexs: map[string]types.IndexMeta{
  92. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}},
  93. },
  94. },
  95. records: types.RecordImage{
  96. TableName: "single_key",
  97. Rows: []types.RowImage{
  98. {Columns: []types.ColumnImage{getColumnImage("id", 100)}},
  99. },
  100. },
  101. expected: "SINGLE_KEY:100",
  102. },
  103. {
  104. name: "Mixed Type Keys",
  105. metaData: types.TableMeta{
  106. TableName: "mixed_key",
  107. Indexs: map[string]types.IndexMeta{
  108. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: columnsMixPk},
  109. },
  110. },
  111. records: types.RecordImage{
  112. TableName: "mixed_key",
  113. Rows: []types.RowImage{
  114. {Columns: []types.ColumnImage{getColumnImage("name", "mike"), getColumnImage("age", 25)}},
  115. },
  116. },
  117. expected: "MIXED_KEY:mike_25",
  118. },
  119. {
  120. name: "Empty Records",
  121. metaData: types.TableMeta{
  122. TableName: "empty",
  123. Indexs: map[string]types.IndexMeta{
  124. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}},
  125. },
  126. },
  127. records: types.RecordImage{TableName: "empty"},
  128. expected: "EMPTY:",
  129. },
  130. {
  131. name: "Special Characters",
  132. metaData: types.TableMeta{
  133. TableName: "special",
  134. Indexs: map[string]types.IndexMeta{
  135. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}},
  136. },
  137. },
  138. records: types.RecordImage{
  139. TableName: "special",
  140. Rows: []types.RowImage{
  141. {Columns: []types.ColumnImage{getColumnImage("id", "A,b_c")}},
  142. },
  143. },
  144. expected: "SPECIAL:A,b_c",
  145. },
  146. {
  147. name: "Non-existent Key Name",
  148. metaData: types.TableMeta{
  149. TableName: "error_key",
  150. Indexs: map[string]types.IndexMeta{
  151. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnNonExistent}},
  152. },
  153. },
  154. records: types.RecordImage{
  155. TableName: "error_key",
  156. Rows: []types.RowImage{
  157. {Columns: []types.ColumnImage{getColumnImage("id", 1)}},
  158. },
  159. },
  160. expected: "ERROR_KEY:",
  161. },
  162. {
  163. name: "Multiple Rows With Nil PK Value",
  164. metaData: types.TableMeta{
  165. TableName: "nil_pk",
  166. Indexs: map[string]types.IndexMeta{
  167. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}},
  168. },
  169. },
  170. records: types.RecordImage{
  171. TableName: "nil_pk",
  172. Rows: []types.RowImage{
  173. {Columns: []types.ColumnImage{getColumnImage("id", nil)}},
  174. {Columns: []types.ColumnImage{getColumnImage("id", 123)}},
  175. {Columns: []types.ColumnImage{getColumnImage("id", nil)}},
  176. },
  177. },
  178. expected: "NIL_PK:,123,",
  179. },
  180. {
  181. name: "PK As Bool And Float",
  182. metaData: types.TableMeta{
  183. TableName: "type_pk",
  184. Indexs: map[string]types.IndexMeta{
  185. "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnName, columnAge}},
  186. },
  187. },
  188. records: types.RecordImage{
  189. TableName: "type_pk",
  190. Rows: []types.RowImage{
  191. {Columns: []types.ColumnImage{getColumnImage("name", true), getColumnImage("age", 3.14)}},
  192. {Columns: []types.ColumnImage{getColumnImage("name", false), getColumnImage("age", 0.0)}},
  193. },
  194. },
  195. expected: "TYPE_PK:true_3.14,false_0",
  196. },
  197. }
  198. for _, tt := range tests {
  199. t.Run(tt.name, func(t *testing.T) {
  200. lockKeys := exec.buildLockKey(&tt.records, tt.metaData)
  201. assert.Equal(t, tt.expected, lockKeys)
  202. })
  203. }
  204. }