* fix: uppertable metacache todo:Fix lockkey case difference #846 * increase uppertablename and Fix lockkey case difference #846 * Fix test case difference #846 * Fix test case difference #846 * reduce uppertablename col #846 * reduce uppertablename #846 * fix test #846 --------- Co-authored-by: FengZhang <zfcode@qq.com>tags/v2.0.0-rc01^0
| @@ -21,7 +21,6 @@ import ( | |||
| "context" | |||
| "database/sql" | |||
| "fmt" | |||
| "strings" | |||
| "sync" | |||
| "time" | |||
| @@ -111,9 +110,8 @@ func (c *BaseTableMetaCache) refresh(ctx context.Context) { | |||
| for i := range v { | |||
| tm := v[i] | |||
| upperTableName := strings.ToUpper(tm.TableName) | |||
| if _, ok := c.cache[upperTableName]; ok { | |||
| c.cache[upperTableName] = &entry{ | |||
| if _, ok := c.cache[tm.TableName]; ok { | |||
| c.cache[tm.TableName] = &entry{ | |||
| value: tm, | |||
| } | |||
| } | |||
| @@ -159,16 +157,15 @@ func (c *BaseTableMetaCache) GetTableMeta(ctx context.Context, dbName, tableName | |||
| defer c.lock.Unlock() | |||
| defer conn.Close() | |||
| upperTableName := strings.ToUpper(tableName) | |||
| v, ok := c.cache[upperTableName] | |||
| v, ok := c.cache[tableName] | |||
| if !ok { | |||
| meta, err := c.trigger.LoadOne(ctx, dbName, upperTableName, conn) | |||
| meta, err := c.trigger.LoadOne(ctx, dbName, tableName, conn) | |||
| if err != nil { | |||
| return types.TableMeta{}, err | |||
| } | |||
| if meta != nil && !meta.IsEmpty() { | |||
| c.cache[upperTableName] = &entry{ | |||
| c.cache[tableName] = &entry{ | |||
| value: *meta, | |||
| lastAccess: time.Now(), | |||
| } | |||
| @@ -180,7 +177,7 @@ func (c *BaseTableMetaCache) GetTableMeta(ctx context.Context, dbName, tableName | |||
| } | |||
| v.lastAccess = time.Now() | |||
| c.cache[upperTableName] = v | |||
| c.cache[tableName] = v | |||
| return v.value, nil | |||
| } | |||
| @@ -93,7 +93,29 @@ func TestBaseTableMetaCache_refresh(t *testing.T) { | |||
| args args | |||
| want types.TableMeta | |||
| }{ | |||
| {name: "test-1", | |||
| { | |||
| name: "test1", | |||
| fields: fields{ | |||
| lock: sync.RWMutex{}, | |||
| capity: capacity, | |||
| size: 0, | |||
| expireDuration: EexpireTime, | |||
| cache: map[string]*entry{ | |||
| "test": { | |||
| value: types.TableMeta{}, | |||
| lastAccess: time.Now(), | |||
| }, | |||
| }, | |||
| cancel: cancel, | |||
| trigger: &mockTrigger{}, | |||
| cfg: &mysql.Config{}, | |||
| db: &sql.DB{}, | |||
| }, | |||
| args: args{ctx: ctx}, | |||
| want: testdata.MockWantTypesMeta("test"), | |||
| }, | |||
| { | |||
| name: "test2", | |||
| fields: fields{ | |||
| lock: sync.RWMutex{}, | |||
| capity: capacity, | |||
| @@ -109,8 +131,10 @@ func TestBaseTableMetaCache_refresh(t *testing.T) { | |||
| trigger: &mockTrigger{}, | |||
| cfg: &mysql.Config{}, | |||
| db: &sql.DB{}, | |||
| }, args: args{ctx: ctx}, | |||
| want: testdata.MockWantTypesMeta("test")}, | |||
| }, | |||
| args: args{ctx: ctx}, | |||
| want: testdata.MockWantTypesMeta("TEST"), | |||
| }, | |||
| } | |||
| for _, tt := range tests { | |||
| t.Run(tt.name, func(t *testing.T) { | |||
| @@ -144,7 +168,12 @@ func TestBaseTableMetaCache_refresh(t *testing.T) { | |||
| time.Sleep(time.Second * 3) | |||
| c.lock.RLock() | |||
| defer c.lock.RUnlock() | |||
| assert.Equal(t, c.cache["TEST"].value, tt.want) | |||
| assert.Equal(t, c.cache[func() string { | |||
| if tt.name == "test2" { | |||
| return "TEST" | |||
| } | |||
| return "test" | |||
| }()].value, tt.want) | |||
| }) | |||
| } | |||
| } | |||
| @@ -190,7 +219,7 @@ func TestBaseTableMetaCache_GetTableMeta(t *testing.T) { | |||
| ColumnNames = []string{"id", "name", "age"} | |||
| tableMeta1 = types.TableMeta{ | |||
| TableName: "T_USER1", | |||
| TableName: "t_user1", | |||
| Columns: columns, | |||
| Indexs: index, | |||
| ColumnNames: ColumnNames, | |||
| @@ -229,12 +258,12 @@ func TestBaseTableMetaCache_GetTableMeta(t *testing.T) { | |||
| cache := &BaseTableMetaCache{ | |||
| trigger: mockTrigger, | |||
| cache: map[string]*entry{ | |||
| "T_USER": { | |||
| value: tableMeta2, | |||
| "t_user1": { | |||
| value: tableMeta1, | |||
| lastAccess: time.Now(), | |||
| }, | |||
| "T_USER1": { | |||
| value: tableMeta1, | |||
| "T_USER2": { | |||
| value: tableMeta2, | |||
| lastAccess: time.Now(), | |||
| }, | |||
| }, | |||
| @@ -71,7 +71,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {[]types.ColumnImage{getColumnImage("id", 2), getColumnImage("userId", "user2")}}, | |||
| }, | |||
| }, | |||
| "test_name:1_user1,2_user2", | |||
| "TEST_NAME:1_user1,2_user2", | |||
| }, | |||
| { | |||
| "Three Primary Keys", | |||
| @@ -89,7 +89,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {[]types.ColumnImage{getColumnImage("id", 3), getColumnImage("userId", "three"), getColumnImage("age", "33")}}, | |||
| }, | |||
| }, | |||
| "test2_name:1_one_11,2_two_22,3_three_33", | |||
| "TEST2_NAME:1_one_11,2_two_22,3_three_33", | |||
| }, | |||
| { | |||
| name: "Single Primary Key", | |||
| @@ -105,7 +105,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", 100)}}, | |||
| }, | |||
| }, | |||
| expected: "single_key:100", | |||
| expected: "SINGLE_KEY:100", | |||
| }, | |||
| { | |||
| name: "Mixed Type Keys", | |||
| @@ -121,7 +121,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("name", "mike"), getColumnImage("age", 25)}}, | |||
| }, | |||
| }, | |||
| expected: "mixed_key:mike_25", | |||
| expected: "MIXED_KEY:mike_25", | |||
| }, | |||
| { | |||
| name: "Empty Records", | |||
| @@ -132,7 +132,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| }, | |||
| }, | |||
| records: types.RecordImage{TableName: "empty"}, | |||
| expected: "empty:", | |||
| expected: "EMPTY:", | |||
| }, | |||
| { | |||
| name: "Special Characters", | |||
| @@ -148,7 +148,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", "A,b_c")}}, | |||
| }, | |||
| }, | |||
| expected: "special:A,b_c", | |||
| expected: "SPECIAL:A,b_c", | |||
| }, | |||
| { | |||
| name: "Non-existent Key Name", | |||
| @@ -164,7 +164,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", 1)}}, | |||
| }, | |||
| }, | |||
| expected: "error_key:", | |||
| expected: "ERROR_KEY:", | |||
| }, | |||
| { | |||
| name: "Multiple Rows With Nil PK Value", | |||
| @@ -182,7 +182,7 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", nil)}}, | |||
| }, | |||
| }, | |||
| expected: "nil_pk:,123,", | |||
| expected: "NIL_PK:,123,", | |||
| }, | |||
| { | |||
| name: "PK As Bool And Float", | |||
| @@ -199,10 +199,9 @@ func TestBaseExecBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("name", false), getColumnImage("age", 0.0)}}, | |||
| }, | |||
| }, | |||
| expected: "type_pk:true_3.14,false_0", | |||
| expected: "TYPE_PK:true_3.14,false_0", | |||
| }, | |||
| } | |||
| for _, tt := range tests { | |||
| t.Run(tt.name, func(t *testing.T) { | |||
| lockKeys := exec.buildLockKey(&tt.records, tt.metaData) | |||
| @@ -247,7 +247,7 @@ func (b *BasicUndoLogBuilder) buildLockKey(rows driver.Rows, meta types.TableMet | |||
| lockKeys bytes.Buffer | |||
| filedSequence int | |||
| ) | |||
| lockKeys.WriteString(meta.TableName) | |||
| lockKeys.WriteString(strings.ToUpper(meta.TableName)) | |||
| lockKeys.WriteString(":") | |||
| pks := b.GetScanSlice(meta.GetPrimaryKeyOnlyName(), &meta) | |||
| @@ -97,7 +97,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| {[]types.ColumnImage{getColumnImage("id", 2), getColumnImage("userId", "two")}}, | |||
| }, | |||
| }, | |||
| "test_name:1_one,2_two", | |||
| "TEST_NAME:1_one,2_two", | |||
| }, | |||
| { | |||
| "Three Primary Keys", | |||
| @@ -115,7 +115,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| {[]types.ColumnImage{getColumnImage("id", 3), getColumnImage("userId", "three"), getColumnImage("age", "33")}}, | |||
| }, | |||
| }, | |||
| "test2_name:1_one_11,2_two_22,3_three_33", | |||
| "TEST2_NAME:1_one_11,2_two_22,3_three_33", | |||
| }, | |||
| { | |||
| name: "Single Primary Key", | |||
| @@ -131,7 +131,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", 100)}}, | |||
| }, | |||
| }, | |||
| expected: "single_key:100", | |||
| expected: "SINGLE_KEY:100", | |||
| }, | |||
| { | |||
| name: "Mixed Type Keys", | |||
| @@ -147,7 +147,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("name", "Alice"), getColumnImage("age", 25)}}, | |||
| }, | |||
| }, | |||
| expected: "mixed_key:Alice_25", | |||
| expected: "MIXED_KEY:Alice_25", | |||
| }, | |||
| { | |||
| name: "Empty Records", | |||
| @@ -158,7 +158,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| }, | |||
| }, | |||
| records: types.RecordImage{TableName: "empty"}, | |||
| expected: "empty:", | |||
| expected: "EMPTY:", | |||
| }, | |||
| { | |||
| name: "Special Characters", | |||
| @@ -174,7 +174,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", "a,b_c")}}, | |||
| }, | |||
| }, | |||
| expected: "special:a,b_c", | |||
| expected: "SPECIAL:a,b_c", | |||
| }, | |||
| { | |||
| name: "Non-existent Key Name", | |||
| @@ -190,7 +190,7 @@ func TestBuildLockKey(t *testing.T) { | |||
| {Columns: []types.ColumnImage{getColumnImage("id", 1)}}, | |||
| }, | |||
| }, | |||
| expected: "error_key:", | |||
| expected: "ERROR_KEY:", | |||
| }, | |||
| } | |||
| @@ -34,7 +34,7 @@ func BuildLockKey(records *types.RecordImage, meta types.TableMeta) string { | |||
| colIndex int | |||
| } | |||
| lockKeys.WriteString(meta.TableName) | |||
| lockKeys.WriteString(strings.ToUpper(meta.TableName)) | |||
| lockKeys.WriteString(":") | |||
| keys := meta.GetPrimaryKeyOnlyName() | |||
| @@ -17,7 +17,9 @@ | |||
| package testdata | |||
| import "seata.apache.org/seata-go/pkg/datasource/sql/types" | |||
| import ( | |||
| "seata.apache.org/seata-go/pkg/datasource/sql/types" | |||
| ) | |||
| func MockWantTypesMeta(tableName string) types.TableMeta { | |||
| return types.TableMeta{ | |||