From dd50bec39ddc39c15975146c23be6112d22b77af Mon Sep 17 00:00:00 2001 From: "xinfan.wu" <13708123240@163.com> Date: Sat, 7 Dec 2024 19:06:09 +0800 Subject: [PATCH 01/22] optimize: upgrade getty version (#716) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index eb77d6ab1..784cc1945 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( dubbo.apache.org/dubbo-go/v3 v3.0.4 github.com/DATA-DOG/go-sqlmock v1.5.0 - github.com/apache/dubbo-getty v1.4.10 + github.com/apache/dubbo-getty v1.5.0 github.com/arana-db/parser v0.2.5 github.com/bluele/gcache v0.0.2 github.com/dsnet/compress v0.0.1 diff --git a/go.sum b/go.sum index ae805fdea..e4c461f05 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdK github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/dubbo-getty v1.4.9-0.20221022181821-4dc6252ce98c/go.mod h1:6qmrqBSPGs3B35zwEuGhEYNVsx1nfGT/xzV2yOt2amM= -github.com/apache/dubbo-getty v1.4.10 h1:ZmkpHJa/qgS0evX2tTNqNCz6rClI/9Wwp7ctyMml82w= -github.com/apache/dubbo-getty v1.4.10/go.mod h1:V64WqLIxksEgNu5aBJBOxNIvpOZyfUJ7J/DXBlKSUoA= +github.com/apache/dubbo-getty v1.5.0 h1:40RMjEoSfTuoG5EwKbGgfhjd7m6Zc7qBfOFgQv1jHCI= +github.com/apache/dubbo-getty v1.5.0/go.mod h1:V64WqLIxksEgNu5aBJBOxNIvpOZyfUJ7J/DXBlKSUoA= github.com/apache/dubbo-go-hessian2 v1.9.1/go.mod h1:xQUjE7F8PX49nm80kChFvepA/AvqAZ0oh/UaB6+6pBE= github.com/apache/dubbo-go-hessian2 v1.9.3/go.mod h1:xQUjE7F8PX49nm80kChFvepA/AvqAZ0oh/UaB6+6pBE= github.com/apache/dubbo-go-hessian2 v1.11.4 h1:u8spEogpaZ82/k3bmv1PLYnha/wiwsIme15FuZZgkiI= From ccb96999a91020e79ecc001aa4f6c5767ba9086c Mon Sep 17 00:00:00 2001 From: marsevilspirit Date: Sat, 7 Dec 2024 19:43:30 +0800 Subject: [PATCH 02/22] fix: fix undo log parser type jackson not found (#690) * fix undo log parser type jackson not found * update config_test.go --- pkg/datasource/sql/undo/base/undo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/datasource/sql/undo/base/undo.go b/pkg/datasource/sql/undo/base/undo.go index 5861012e2..331930e7e 100644 --- a/pkg/datasource/sql/undo/base/undo.go +++ b/pkg/datasource/sql/undo/base/undo.go @@ -222,7 +222,7 @@ func (m *BaseUndoLogManager) FlushUndoLog(tranCtx *types.TransactionContext, con } parseContext := make(map[string]string, 0) - parseContext[serializerKey] = "json" + parseContext[serializerKey] = undo.UndoConfig.LogSerialization parseContext[compressorTypeKey] = undo.UndoConfig.CompressConfig.Type undoLogContent := m.encodeUndoLogCtx(parseContext) rollbackInfo, err := m.serializeBranchUndoLog(&branchUndoLog, parseContext[serializerKey]) @@ -377,7 +377,7 @@ func (m *BaseUndoLogManager) Undo(ctx context.Context, dbType types.DBType, xid func (m *BaseUndoLogManager) insertUndoLogWithGlobalFinished(ctx context.Context, xid string, branchID uint64, conn *sql.Conn) error { // todo use config to replace parseContext := make(map[string]string, 0) - parseContext[serializerKey] = "json" + parseContext[serializerKey] = undo.UndoConfig.LogSerialization parseContext[compressorTypeKey] = undo.UndoConfig.CompressConfig.Type undoLogContent := m.encodeUndoLogCtx(parseContext) From 0fa027211a175adae2b3902ceaeeaa99074546de Mon Sep 17 00:00:00 2001 From: marsevilspirit Date: Sat, 7 Dec 2024 19:56:11 +0800 Subject: [PATCH 03/22] feature:add undo protobuf parser (#691) * feature:add undo protobuf parser * fix apache header --- .../sql/undo/parser/branch_undo_log.pb.go | 1445 +++++++++++++++++ .../sql/undo/parser/branch_undo_log.proto | 165 ++ .../sql/undo/parser/parser_cache.go | 1 + .../sql/undo/parser/parser_json_test.go | 8 +- .../sql/undo/parser/parser_protobuf.go | 248 +++ .../sql/undo/parser/parser_protobuf_test.go | 91 ++ 6 files changed, 1954 insertions(+), 4 deletions(-) create mode 100644 pkg/datasource/sql/undo/parser/branch_undo_log.pb.go create mode 100644 pkg/datasource/sql/undo/parser/branch_undo_log.proto create mode 100644 pkg/datasource/sql/undo/parser/parser_protobuf.go create mode 100644 pkg/datasource/sql/undo/parser/parser_protobuf_test.go diff --git a/pkg/datasource/sql/undo/parser/branch_undo_log.pb.go b/pkg/datasource/sql/undo/parser/branch_undo_log.pb.go new file mode 100644 index 000000000..4bdce65fa --- /dev/null +++ b/pkg/datasource/sql/undo/parser/branch_undo_log.pb.go @@ -0,0 +1,1445 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.28.3 +// source: branch_undo_log.proto + +package parser + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type IndexType int32 + +const ( + IndexType_IndexTypeNull IndexType = 0 + IndexType_IndexTypePrimaryKey IndexType = 1 +) + +// Enum value maps for IndexType. +var ( + IndexType_name = map[int32]string{ + 0: "IndexTypeNull", + 1: "IndexTypePrimaryKey", + } + IndexType_value = map[string]int32{ + "IndexTypeNull": 0, + "IndexTypePrimaryKey": 1, + } +) + +func (x IndexType) Enum() *IndexType { + p := new(IndexType) + *p = x + return p +} + +func (x IndexType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (IndexType) Descriptor() protoreflect.EnumDescriptor { + return file_branch_undo_log_proto_enumTypes[0].Descriptor() +} + +func (IndexType) Type() protoreflect.EnumType { + return &file_branch_undo_log_proto_enumTypes[0] +} + +func (x IndexType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use IndexType.Descriptor instead. +func (IndexType) EnumDescriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{0} +} + +type JDBCType int32 + +const ( + JDBCType_JDBCTypeNull JDBCType = 0 + JDBCType_JDBCTypeBit JDBCType = -7 + JDBCType_JDBCTypeTinyInt JDBCType = -6 + JDBCType_JDBCTypeSmallInt JDBCType = 5 + JDBCType_JDBCTypeInteger JDBCType = 4 + JDBCType_JDBCTypeBigInt JDBCType = -5 + JDBCType_JDBCTypeFloat JDBCType = 6 + JDBCType_JDBCTypeReal JDBCType = 7 + JDBCType_JDBCTypeDouble JDBCType = 8 + JDBCType_JDBCTypeNumberic JDBCType = 2 + JDBCType_JDBCTypeDecimal JDBCType = 3 + JDBCType_JDBCTypeChar JDBCType = 1 + JDBCType_JDBCTypeVarchar JDBCType = 12 + JDBCType_JDBCTypeLongVarchar JDBCType = -1 + JDBCType_JDBCTypeDate JDBCType = 91 + JDBCType_JDBCTypeTime JDBCType = 92 + JDBCType_JDBCTypeTimestamp JDBCType = 93 + JDBCType_JDBCTypeBinary JDBCType = -2 + JDBCType_JDBCTypeVarBinary JDBCType = -3 + JDBCType_JDBCTypeLongVarBinary JDBCType = -4 + JDBCType_JDBCTypeOther JDBCType = 1111 + JDBCType_JDBCTypeJavaObject JDBCType = 2000 + JDBCType_JDBCTypeDistinct JDBCType = 2001 + JDBCType_JDBCTypeStruct JDBCType = 2002 + JDBCType_JDBCTypeArray JDBCType = 2003 + JDBCType_JDBCTypeBlob JDBCType = 2004 + JDBCType_JDBCTypeClob JDBCType = 2005 + JDBCType_JDBCTypeRef JDBCType = 2006 + JDBCType_JDBCTypeDateLink JDBCType = 70 + JDBCType_JDBCTypeBoolean JDBCType = 16 + JDBCType_JDBCTypeRowID JDBCType = -8 + JDBCType_JDBCTypeNchar JDBCType = -15 + JDBCType_JDBCTypeNvarchar JDBCType = -9 + JDBCType_JDBCTypeLongNvVarchar JDBCType = -16 + JDBCType_JDBCTypeNclob JDBCType = 2011 + JDBCType_JDBCTypeSqlXML JDBCType = 2009 + JDBCType_JDBCTypeRefCursor JDBCType = 2012 + JDBCType_JDBCTypeTimeWithTimeZone JDBCType = 2013 + JDBCType_JDBCTypeTimestampWithTimezone JDBCType = 2014 +) + +// Enum value maps for JDBCType. +var ( + JDBCType_name = map[int32]string{ + 0: "JDBCTypeNull", + -7: "JDBCTypeBit", + -6: "JDBCTypeTinyInt", + 5: "JDBCTypeSmallInt", + 4: "JDBCTypeInteger", + -5: "JDBCTypeBigInt", + 6: "JDBCTypeFloat", + 7: "JDBCTypeReal", + 8: "JDBCTypeDouble", + 2: "JDBCTypeNumberic", + 3: "JDBCTypeDecimal", + 1: "JDBCTypeChar", + 12: "JDBCTypeVarchar", + -1: "JDBCTypeLongVarchar", + 91: "JDBCTypeDate", + 92: "JDBCTypeTime", + 93: "JDBCTypeTimestamp", + -2: "JDBCTypeBinary", + -3: "JDBCTypeVarBinary", + -4: "JDBCTypeLongVarBinary", + 1111: "JDBCTypeOther", + 2000: "JDBCTypeJavaObject", + 2001: "JDBCTypeDistinct", + 2002: "JDBCTypeStruct", + 2003: "JDBCTypeArray", + 2004: "JDBCTypeBlob", + 2005: "JDBCTypeClob", + 2006: "JDBCTypeRef", + 70: "JDBCTypeDateLink", + 16: "JDBCTypeBoolean", + -8: "JDBCTypeRowID", + -15: "JDBCTypeNchar", + -9: "JDBCTypeNvarchar", + -16: "JDBCTypeLongNvVarchar", + 2011: "JDBCTypeNclob", + 2009: "JDBCTypeSqlXML", + 2012: "JDBCTypeRefCursor", + 2013: "JDBCTypeTimeWithTimeZone", + 2014: "JDBCTypeTimestampWithTimezone", + } + JDBCType_value = map[string]int32{ + "JDBCTypeNull": 0, + "JDBCTypeBit": -7, + "JDBCTypeTinyInt": -6, + "JDBCTypeSmallInt": 5, + "JDBCTypeInteger": 4, + "JDBCTypeBigInt": -5, + "JDBCTypeFloat": 6, + "JDBCTypeReal": 7, + "JDBCTypeDouble": 8, + "JDBCTypeNumberic": 2, + "JDBCTypeDecimal": 3, + "JDBCTypeChar": 1, + "JDBCTypeVarchar": 12, + "JDBCTypeLongVarchar": -1, + "JDBCTypeDate": 91, + "JDBCTypeTime": 92, + "JDBCTypeTimestamp": 93, + "JDBCTypeBinary": -2, + "JDBCTypeVarBinary": -3, + "JDBCTypeLongVarBinary": -4, + "JDBCTypeOther": 1111, + "JDBCTypeJavaObject": 2000, + "JDBCTypeDistinct": 2001, + "JDBCTypeStruct": 2002, + "JDBCTypeArray": 2003, + "JDBCTypeBlob": 2004, + "JDBCTypeClob": 2005, + "JDBCTypeRef": 2006, + "JDBCTypeDateLink": 70, + "JDBCTypeBoolean": 16, + "JDBCTypeRowID": -8, + "JDBCTypeNchar": -15, + "JDBCTypeNvarchar": -9, + "JDBCTypeLongNvVarchar": -16, + "JDBCTypeNclob": 2011, + "JDBCTypeSqlXML": 2009, + "JDBCTypeRefCursor": 2012, + "JDBCTypeTimeWithTimeZone": 2013, + "JDBCTypeTimestampWithTimezone": 2014, + } +) + +func (x JDBCType) Enum() *JDBCType { + p := new(JDBCType) + *p = x + return p +} + +func (x JDBCType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (JDBCType) Descriptor() protoreflect.EnumDescriptor { + return file_branch_undo_log_proto_enumTypes[1].Descriptor() +} + +func (JDBCType) Type() protoreflect.EnumType { + return &file_branch_undo_log_proto_enumTypes[1] +} + +func (x JDBCType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use JDBCType.Descriptor instead. +func (JDBCType) EnumDescriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{1} +} + +type SQLType int32 + +const ( + SQLType_SQLTypeSelect SQLType = 0 + SQLType_SQLTypeInsert SQLType = 1 + SQLType_SQLTypeUpdate SQLType = 2 + SQLType_SQLTypeDelete SQLType = 3 + SQLType_SQLTypeSelectForUpdate SQLType = 4 + SQLType_SQLTypeReplace SQLType = 5 + SQLType_SQLTypeTruncate SQLType = 6 + SQLType_SQLTypeCreate SQLType = 7 + SQLType_SQLTypeDrop SQLType = 8 + SQLType_SQLTypeLoad SQLType = 9 + SQLType_SQLTypeMerge SQLType = 10 + SQLType_SQLTypeShow SQLType = 11 + SQLType_SQLTypeAlter SQLType = 12 + SQLType_SQLTypeRename SQLType = 13 + SQLType_SQLTypeDump SQLType = 14 + SQLType_SQLTypeDebug SQLType = 15 + SQLType_SQLTypeExplain SQLType = 16 + SQLType_SQLTypeProcedure SQLType = 17 + SQLType_SQLTypeDesc SQLType = 18 + SQLType_SQLLastInsertID SQLType = 19 + SQLType_SQLSelectWithoutTable SQLType = 20 + SQLType_SQLCreateSequence SQLType = 21 + SQLType_SQLShowSequence SQLType = 22 + SQLType_SQLGetSequence SQLType = 23 + SQLType_SQLAlterSequence SQLType = 24 + SQLType_SQLDropSequence SQLType = 25 + SQLType_SQLTddlShow SQLType = 26 + SQLType_SQLTypeSet SQLType = 27 + SQLType_SQLTypeReload SQLType = 28 + SQLType_SQLTypeSelectUnion SQLType = 29 + SQLType_SQLTypeCreateTable SQLType = 30 + SQLType_SQLTypeDropTable SQLType = 31 + SQLType_SQLTypeAlterTable SQLType = 32 + SQLType_SQLTypeSavePoint SQLType = 33 + SQLType_SQLTypeSelectFromUpdate SQLType = 34 + SQLType_SQLTypeMultiDelete SQLType = 35 + SQLType_SQLTypeMultiUpdate SQLType = 36 + SQLType_SQLTypeCreateIndex SQLType = 37 + SQLType_SQLTypeDropIndex SQLType = 38 + SQLType_SQLTypeKill SQLType = 39 + SQLType_SQLTypeLockTables SQLType = 40 + SQLType_SQLTypeUnLockTables SQLType = 41 + SQLType_SQLTypeCheckTable SQLType = 42 + SQLType_SQLTypeSelectFoundRows SQLType = 43 + SQLType_SQLTypeInsertIgnore SQLType = 101 // Adjusted the value to match Go's logic + SQLType_SQLTypeInsertOnDuplicateUpdate SQLType = 102 + SQLType_SQLTypeMulti SQLType = 1044 // Adjusted the value to match Go's logic + SQLType_SQLTypeUnknown SQLType = 1045 +) + +// Enum value maps for SQLType. +var ( + SQLType_name = map[int32]string{ + 0: "SQLTypeSelect", + 1: "SQLTypeInsert", + 2: "SQLTypeUpdate", + 3: "SQLTypeDelete", + 4: "SQLTypeSelectForUpdate", + 5: "SQLTypeReplace", + 6: "SQLTypeTruncate", + 7: "SQLTypeCreate", + 8: "SQLTypeDrop", + 9: "SQLTypeLoad", + 10: "SQLTypeMerge", + 11: "SQLTypeShow", + 12: "SQLTypeAlter", + 13: "SQLTypeRename", + 14: "SQLTypeDump", + 15: "SQLTypeDebug", + 16: "SQLTypeExplain", + 17: "SQLTypeProcedure", + 18: "SQLTypeDesc", + 19: "SQLLastInsertID", + 20: "SQLSelectWithoutTable", + 21: "SQLCreateSequence", + 22: "SQLShowSequence", + 23: "SQLGetSequence", + 24: "SQLAlterSequence", + 25: "SQLDropSequence", + 26: "SQLTddlShow", + 27: "SQLTypeSet", + 28: "SQLTypeReload", + 29: "SQLTypeSelectUnion", + 30: "SQLTypeCreateTable", + 31: "SQLTypeDropTable", + 32: "SQLTypeAlterTable", + 33: "SQLTypeSavePoint", + 34: "SQLTypeSelectFromUpdate", + 35: "SQLTypeMultiDelete", + 36: "SQLTypeMultiUpdate", + 37: "SQLTypeCreateIndex", + 38: "SQLTypeDropIndex", + 39: "SQLTypeKill", + 40: "SQLTypeLockTables", + 41: "SQLTypeUnLockTables", + 42: "SQLTypeCheckTable", + 43: "SQLTypeSelectFoundRows", + 101: "SQLTypeInsertIgnore", + 102: "SQLTypeInsertOnDuplicateUpdate", + 1044: "SQLTypeMulti", + 1045: "SQLTypeUnknown", + } + SQLType_value = map[string]int32{ + "SQLTypeSelect": 0, + "SQLTypeInsert": 1, + "SQLTypeUpdate": 2, + "SQLTypeDelete": 3, + "SQLTypeSelectForUpdate": 4, + "SQLTypeReplace": 5, + "SQLTypeTruncate": 6, + "SQLTypeCreate": 7, + "SQLTypeDrop": 8, + "SQLTypeLoad": 9, + "SQLTypeMerge": 10, + "SQLTypeShow": 11, + "SQLTypeAlter": 12, + "SQLTypeRename": 13, + "SQLTypeDump": 14, + "SQLTypeDebug": 15, + "SQLTypeExplain": 16, + "SQLTypeProcedure": 17, + "SQLTypeDesc": 18, + "SQLLastInsertID": 19, + "SQLSelectWithoutTable": 20, + "SQLCreateSequence": 21, + "SQLShowSequence": 22, + "SQLGetSequence": 23, + "SQLAlterSequence": 24, + "SQLDropSequence": 25, + "SQLTddlShow": 26, + "SQLTypeSet": 27, + "SQLTypeReload": 28, + "SQLTypeSelectUnion": 29, + "SQLTypeCreateTable": 30, + "SQLTypeDropTable": 31, + "SQLTypeAlterTable": 32, + "SQLTypeSavePoint": 33, + "SQLTypeSelectFromUpdate": 34, + "SQLTypeMultiDelete": 35, + "SQLTypeMultiUpdate": 36, + "SQLTypeCreateIndex": 37, + "SQLTypeDropIndex": 38, + "SQLTypeKill": 39, + "SQLTypeLockTables": 40, + "SQLTypeUnLockTables": 41, + "SQLTypeCheckTable": 42, + "SQLTypeSelectFoundRows": 43, + "SQLTypeInsertIgnore": 101, + "SQLTypeInsertOnDuplicateUpdate": 102, + "SQLTypeMulti": 1044, + "SQLTypeUnknown": 1045, + } +) + +func (x SQLType) Enum() *SQLType { + p := new(SQLType) + *p = x + return p +} + +func (x SQLType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SQLType) Descriptor() protoreflect.EnumDescriptor { + return file_branch_undo_log_proto_enumTypes[2].Descriptor() +} + +func (SQLType) Type() protoreflect.EnumType { + return &file_branch_undo_log_proto_enumTypes[2] +} + +func (x SQLType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SQLType.Descriptor instead. +func (SQLType) EnumDescriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{2} +} + +type BranchUndoLog struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Xid string `protobuf:"bytes,1,opt,name=Xid,proto3" json:"Xid,omitempty"` + BranchID uint64 `protobuf:"varint,2,opt,name=BranchID,proto3" json:"BranchID,omitempty"` + Logs []*SQLUndoLog `protobuf:"bytes,3,rep,name=Logs,proto3" json:"Logs,omitempty"` +} + +func (x *BranchUndoLog) Reset() { + *x = BranchUndoLog{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BranchUndoLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BranchUndoLog) ProtoMessage() {} + +func (x *BranchUndoLog) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BranchUndoLog.ProtoReflect.Descriptor instead. +func (*BranchUndoLog) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{0} +} + +func (x *BranchUndoLog) GetXid() string { + if x != nil { + return x.Xid + } + return "" +} + +func (x *BranchUndoLog) GetBranchID() uint64 { + if x != nil { + return x.BranchID + } + return 0 +} + +func (x *BranchUndoLog) GetLogs() []*SQLUndoLog { + if x != nil { + return x.Logs + } + return nil +} + +type SQLUndoLog struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SQLType SQLType `protobuf:"varint,1,opt,name=SQLType,proto3,enum=parser.SQLType" json:"SQLType,omitempty"` + TableName string `protobuf:"bytes,2,opt,name=TableName,proto3" json:"TableName,omitempty"` + BeforeImage *RecordImage `protobuf:"bytes,3,opt,name=BeforeImage,proto3" json:"BeforeImage,omitempty"` + AfterImage *RecordImage `protobuf:"bytes,4,opt,name=AfterImage,proto3" json:"AfterImage,omitempty"` +} + +func (x *SQLUndoLog) Reset() { + *x = SQLUndoLog{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SQLUndoLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SQLUndoLog) ProtoMessage() {} + +func (x *SQLUndoLog) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SQLUndoLog.ProtoReflect.Descriptor instead. +func (*SQLUndoLog) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{1} +} + +func (x *SQLUndoLog) GetSQLType() SQLType { + if x != nil { + return x.SQLType + } + return SQLType_SQLTypeSelect +} + +func (x *SQLUndoLog) GetTableName() string { + if x != nil { + return x.TableName + } + return "" +} + +func (x *SQLUndoLog) GetBeforeImage() *RecordImage { + if x != nil { + return x.BeforeImage + } + return nil +} + +func (x *SQLUndoLog) GetAfterImage() *RecordImage { + if x != nil { + return x.AfterImage + } + return nil +} + +type RecordImage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + TableName string `protobuf:"bytes,2,opt,name=TableName,proto3" json:"TableName,omitempty"` + SQLType SQLType `protobuf:"varint,3,opt,name=SQLType,proto3,enum=parser.SQLType" json:"SQLType,omitempty"` + Rows []*RowImage `protobuf:"bytes,4,rep,name=Rows,proto3" json:"Rows,omitempty"` + TableMeta *TableMeta `protobuf:"bytes,5,opt,name=TableMeta,proto3" json:"TableMeta,omitempty"` +} + +func (x *RecordImage) Reset() { + *x = RecordImage{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RecordImage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordImage) ProtoMessage() {} + +func (x *RecordImage) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RecordImage.ProtoReflect.Descriptor instead. +func (*RecordImage) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{2} +} + +func (x *RecordImage) GetIndex() int32 { + if x != nil { + return x.Index + } + return 0 +} + +func (x *RecordImage) GetTableName() string { + if x != nil { + return x.TableName + } + return "" +} + +func (x *RecordImage) GetSQLType() SQLType { + if x != nil { + return x.SQLType + } + return SQLType_SQLTypeSelect +} + +func (x *RecordImage) GetRows() []*RowImage { + if x != nil { + return x.Rows + } + return nil +} + +func (x *RecordImage) GetTableMeta() *TableMeta { + if x != nil { + return x.TableMeta + } + return nil +} + +type RowImage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Columns []*ColumnImage `protobuf:"bytes,1,rep,name=Columns,proto3" json:"Columns,omitempty"` +} + +func (x *RowImage) Reset() { + *x = RowImage{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RowImage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RowImage) ProtoMessage() {} + +func (x *RowImage) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RowImage.ProtoReflect.Descriptor instead. +func (*RowImage) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{3} +} + +func (x *RowImage) GetColumns() []*ColumnImage { + if x != nil { + return x.Columns + } + return nil +} + +type ColumnImage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyType IndexType `protobuf:"varint,1,opt,name=KeyType,proto3,enum=parser.IndexType" json:"KeyType,omitempty"` + ColumnName string `protobuf:"bytes,2,opt,name=ColumnName,proto3" json:"ColumnName,omitempty"` + ColumnType JDBCType `protobuf:"varint,3,opt,name=ColumnType,proto3,enum=parser.JDBCType" json:"ColumnType,omitempty"` + Value *anypb.Any `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *ColumnImage) Reset() { + *x = ColumnImage{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ColumnImage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ColumnImage) ProtoMessage() {} + +func (x *ColumnImage) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ColumnImage.ProtoReflect.Descriptor instead. +func (*ColumnImage) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{4} +} + +func (x *ColumnImage) GetKeyType() IndexType { + if x != nil { + return x.KeyType + } + return IndexType_IndexTypeNull +} + +func (x *ColumnImage) GetColumnName() string { + if x != nil { + return x.ColumnName + } + return "" +} + +func (x *ColumnImage) GetColumnType() JDBCType { + if x != nil { + return x.ColumnType + } + return JDBCType_JDBCTypeNull +} + +func (x *ColumnImage) GetValue() *anypb.Any { + if x != nil { + return x.Value + } + return nil +} + +type TableMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TableName string `protobuf:"bytes,1,opt,name=TableName,proto3" json:"TableName,omitempty"` + Columns map[string]*ColumnMeta `protobuf:"bytes,2,rep,name=Columns,proto3" json:"Columns,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Indexs map[string]*IndexMeta `protobuf:"bytes,3,rep,name=Indexs,proto3" json:"Indexs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + ColumnNames []string `protobuf:"bytes,4,rep,name=ColumnNames,proto3" json:"ColumnNames,omitempty"` +} + +func (x *TableMeta) Reset() { + *x = TableMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TableMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TableMeta) ProtoMessage() {} + +func (x *TableMeta) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TableMeta.ProtoReflect.Descriptor instead. +func (*TableMeta) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{5} +} + +func (x *TableMeta) GetTableName() string { + if x != nil { + return x.TableName + } + return "" +} + +func (x *TableMeta) GetColumns() map[string]*ColumnMeta { + if x != nil { + return x.Columns + } + return nil +} + +func (x *TableMeta) GetIndexs() map[string]*IndexMeta { + if x != nil { + return x.Indexs + } + return nil +} + +func (x *TableMeta) GetColumnNames() []string { + if x != nil { + return x.ColumnNames + } + return nil +} + +type ColumnMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Schema string `protobuf:"bytes,1,opt,name=Schema,proto3" json:"Schema,omitempty"` + Table string `protobuf:"bytes,2,opt,name=Table,proto3" json:"Table,omitempty"` + ColumnDef []byte `protobuf:"bytes,3,opt,name=ColumnDef,proto3" json:"ColumnDef,omitempty"` + Autoincrement bool `protobuf:"varint,4,opt,name=Autoincrement,proto3" json:"Autoincrement,omitempty"` + ColumnName string `protobuf:"bytes,5,opt,name=ColumnName,proto3" json:"ColumnName,omitempty"` + ColumnType string `protobuf:"bytes,6,opt,name=ColumnType,proto3" json:"ColumnType,omitempty"` + DatabaseType int32 `protobuf:"varint,7,opt,name=DatabaseType,proto3" json:"DatabaseType,omitempty"` + DatabaseTypeString string `protobuf:"bytes,8,opt,name=DatabaseTypeString,proto3" json:"DatabaseTypeString,omitempty"` + ColumnKey string `protobuf:"bytes,9,opt,name=ColumnKey,proto3" json:"ColumnKey,omitempty"` + IsNullable int32 `protobuf:"varint,10,opt,name=IsNullable,proto3" json:"IsNullable,omitempty"` + Extra string `protobuf:"bytes,11,opt,name=Extra,proto3" json:"Extra,omitempty"` +} + +func (x *ColumnMeta) Reset() { + *x = ColumnMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ColumnMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ColumnMeta) ProtoMessage() {} + +func (x *ColumnMeta) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ColumnMeta.ProtoReflect.Descriptor instead. +func (*ColumnMeta) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{6} +} + +func (x *ColumnMeta) GetSchema() string { + if x != nil { + return x.Schema + } + return "" +} + +func (x *ColumnMeta) GetTable() string { + if x != nil { + return x.Table + } + return "" +} + +func (x *ColumnMeta) GetColumnDef() []byte { + if x != nil { + return x.ColumnDef + } + return nil +} + +func (x *ColumnMeta) GetAutoincrement() bool { + if x != nil { + return x.Autoincrement + } + return false +} + +func (x *ColumnMeta) GetColumnName() string { + if x != nil { + return x.ColumnName + } + return "" +} + +func (x *ColumnMeta) GetColumnType() string { + if x != nil { + return x.ColumnType + } + return "" +} + +func (x *ColumnMeta) GetDatabaseType() int32 { + if x != nil { + return x.DatabaseType + } + return 0 +} + +func (x *ColumnMeta) GetDatabaseTypeString() string { + if x != nil { + return x.DatabaseTypeString + } + return "" +} + +func (x *ColumnMeta) GetColumnKey() string { + if x != nil { + return x.ColumnKey + } + return "" +} + +func (x *ColumnMeta) GetIsNullable() int32 { + if x != nil { + return x.IsNullable + } + return 0 +} + +func (x *ColumnMeta) GetExtra() string { + if x != nil { + return x.Extra + } + return "" +} + +type IndexMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Schema string `protobuf:"bytes,1,opt,name=Schema,proto3" json:"Schema,omitempty"` + Table string `protobuf:"bytes,2,opt,name=Table,proto3" json:"Table,omitempty"` + Name string `protobuf:"bytes,3,opt,name=Name,proto3" json:"Name,omitempty"` + ColumnName string `protobuf:"bytes,4,opt,name=ColumnName,proto3" json:"ColumnName,omitempty"` + IType IndexType `protobuf:"varint,5,opt,name=IType,proto3,enum=parser.IndexType" json:"IType,omitempty"` + Columns []*ColumnMeta `protobuf:"bytes,6,rep,name=Columns,proto3" json:"Columns,omitempty"` +} + +func (x *IndexMeta) Reset() { + *x = IndexMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_branch_undo_log_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IndexMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IndexMeta) ProtoMessage() {} + +func (x *IndexMeta) ProtoReflect() protoreflect.Message { + mi := &file_branch_undo_log_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IndexMeta.ProtoReflect.Descriptor instead. +func (*IndexMeta) Descriptor() ([]byte, []int) { + return file_branch_undo_log_proto_rawDescGZIP(), []int{7} +} + +func (x *IndexMeta) GetSchema() string { + if x != nil { + return x.Schema + } + return "" +} + +func (x *IndexMeta) GetTable() string { + if x != nil { + return x.Table + } + return "" +} + +func (x *IndexMeta) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *IndexMeta) GetColumnName() string { + if x != nil { + return x.ColumnName + } + return "" +} + +func (x *IndexMeta) GetIType() IndexType { + if x != nil { + return x.IType + } + return IndexType_IndexTypeNull +} + +func (x *IndexMeta) GetColumns() []*ColumnMeta { + if x != nil { + return x.Columns + } + return nil +} + +var File_branch_undo_log_proto protoreflect.FileDescriptor + +var file_branch_undo_log_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x75, 0x6e, 0x64, 0x6f, 0x5f, 0x6c, 0x6f, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x1a, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x65, 0x0a, 0x0d, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x55, 0x6e, 0x64, 0x6f, 0x4c, 0x6f, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x58, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x58, 0x69, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x44, 0x12, 0x26, 0x0a, 0x04, 0x4c, 0x6f, 0x67, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x2e, 0x53, 0x51, 0x4c, 0x55, 0x6e, 0x64, 0x6f, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x4c, 0x6f, 0x67, + 0x73, 0x22, 0xc1, 0x01, 0x0a, 0x0a, 0x53, 0x51, 0x4c, 0x55, 0x6e, 0x64, 0x6f, 0x4c, 0x6f, 0x67, + 0x12, 0x29, 0x0a, 0x07, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x53, 0x51, 0x4c, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x07, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x42, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x52, 0x0b, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x12, 0x33, 0x0a, 0x0a, 0x41, 0x66, 0x74, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x41, 0x66, 0x74, 0x65, 0x72, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x53, 0x51, 0x4c, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x2e, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x53, 0x51, 0x4c, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x52, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x77, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x52, 0x04, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x09, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x39, 0x0a, 0x08, 0x52, + 0x6f, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x07, 0x43, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x2e, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0xda, 0x02, 0x0a, 0x09, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, + 0x1c, 0x0a, 0x09, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, + 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x06, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x73, 0x12, 0x20, + 0x0a, 0x0b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x1a, 0x4e, 0x0a, 0x0c, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x4c, 0x0a, 0x0b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, + 0x65, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe6, + 0x02, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, + 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x43, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x12, 0x24, 0x0a, 0x0d, 0x41, 0x75, 0x74, + 0x6f, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x41, 0x75, 0x74, 0x6f, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x22, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x12, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4b, 0x65, 0x79, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4b, 0x65, + 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x49, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x78, 0x74, 0x72, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x45, 0x78, 0x74, 0x72, 0x61, 0x22, 0xc4, 0x01, 0x0a, 0x09, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x14, 0x0a, + 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x43, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x49, 0x54, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x49, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x2c, 0x0a, 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x07, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x2a, 0x37, + 0x0a, 0x09, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x17, + 0x0a, 0x13, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x79, 0x70, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x4b, 0x65, 0x79, 0x10, 0x01, 0x2a, 0xb4, 0x07, 0x0a, 0x08, 0x4a, 0x44, 0x42, 0x43, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, + 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x0b, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, + 0x70, 0x65, 0x42, 0x69, 0x74, 0x10, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x12, 0x1c, 0x0a, 0x0f, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x54, 0x69, 0x6e, 0x79, + 0x49, 0x6e, 0x74, 0x10, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x14, + 0x0a, 0x10, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x49, + 0x6e, 0x74, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, + 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x0e, 0x4a, 0x44, 0x42, + 0x43, 0x54, 0x79, 0x70, 0x65, 0x42, 0x69, 0x67, 0x49, 0x6e, 0x74, 0x10, 0xfb, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, + 0x70, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x44, 0x42, + 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x61, 0x6c, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x4a, + 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x10, 0x08, 0x12, + 0x14, 0x0a, 0x10, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x69, 0x63, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, + 0x65, 0x44, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x44, + 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x43, 0x68, 0x61, 0x72, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, + 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, 0x72, 0x63, 0x68, 0x61, 0x72, 0x10, + 0x0c, 0x12, 0x20, 0x0a, 0x13, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x6f, 0x6e, + 0x67, 0x56, 0x61, 0x72, 0x63, 0x68, 0x61, 0x72, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x44, + 0x61, 0x74, 0x65, 0x10, 0x5b, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x10, 0x5c, 0x12, 0x15, 0x0a, 0x11, 0x4a, 0x44, 0x42, 0x43, 0x54, + 0x79, 0x70, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x10, 0x5d, 0x12, 0x1b, + 0x0a, 0x0e, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x10, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x1e, 0x0a, 0x11, 0x4a, + 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x56, 0x61, 0x72, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x10, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x22, 0x0a, 0x15, 0x4a, + 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x6f, 0x6e, 0x67, 0x56, 0x61, 0x72, 0x42, 0x69, + 0x6e, 0x61, 0x72, 0x79, 0x10, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, + 0x12, 0x0a, 0x0d, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, + 0x10, 0xd7, 0x08, 0x12, 0x17, 0x0a, 0x12, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4a, + 0x61, 0x76, 0x61, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x10, 0xd0, 0x0f, 0x12, 0x15, 0x0a, 0x10, + 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x44, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, + 0x10, 0xd1, 0x0f, 0x12, 0x13, 0x0a, 0x0e, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x10, 0xd2, 0x0f, 0x12, 0x12, 0x0a, 0x0d, 0x4a, 0x44, 0x42, 0x43, + 0x54, 0x79, 0x70, 0x65, 0x41, 0x72, 0x72, 0x61, 0x79, 0x10, 0xd3, 0x0f, 0x12, 0x11, 0x0a, 0x0c, + 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x10, 0xd4, 0x0f, 0x12, + 0x11, 0x0a, 0x0c, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6c, 0x6f, 0x62, 0x10, + 0xd5, 0x0f, 0x12, 0x10, 0x0a, 0x0b, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, + 0x66, 0x10, 0xd6, 0x0f, 0x12, 0x14, 0x0a, 0x10, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, + 0x44, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x46, 0x12, 0x13, 0x0a, 0x0f, 0x4a, 0x44, + 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x10, 0x10, 0x12, + 0x1a, 0x0a, 0x0d, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, 0x6f, 0x77, 0x49, 0x44, + 0x10, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x1a, 0x0a, 0x0d, 0x4a, + 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x63, 0x68, 0x61, 0x72, 0x10, 0xf1, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x1d, 0x0a, 0x10, 0x4a, 0x44, 0x42, 0x43, 0x54, + 0x79, 0x70, 0x65, 0x4e, 0x76, 0x61, 0x72, 0x63, 0x68, 0x61, 0x72, 0x10, 0xf7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x22, 0x0a, 0x15, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, + 0x70, 0x65, 0x4c, 0x6f, 0x6e, 0x67, 0x4e, 0x76, 0x56, 0x61, 0x72, 0x63, 0x68, 0x61, 0x72, 0x10, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x12, 0x12, 0x0a, 0x0d, 0x4a, 0x44, + 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x4e, 0x63, 0x6c, 0x6f, 0x62, 0x10, 0xdb, 0x0f, 0x12, 0x13, + 0x0a, 0x0e, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x53, 0x71, 0x6c, 0x58, 0x4d, 0x4c, + 0x10, 0xd9, 0x0f, 0x12, 0x16, 0x0a, 0x11, 0x4a, 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x65, 0x66, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x10, 0xdc, 0x0f, 0x12, 0x1d, 0x0a, 0x18, 0x4a, + 0x44, 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x57, 0x69, 0x74, 0x68, 0x54, + 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x10, 0xdd, 0x0f, 0x12, 0x22, 0x0a, 0x1d, 0x4a, 0x44, + 0x42, 0x43, 0x54, 0x79, 0x70, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x57, + 0x69, 0x74, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x10, 0xde, 0x0f, 0x2a, 0x8b, + 0x08, 0x0a, 0x07, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x51, + 0x4c, 0x54, 0x79, 0x70, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x10, 0x00, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x01, + 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, + 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, + 0x65, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x53, + 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x10, 0x07, 0x12, 0x0f, + 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x10, 0x08, 0x12, + 0x0f, 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x10, 0x09, + 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x10, 0x0a, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x53, 0x68, 0x6f, + 0x77, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6c, + 0x74, 0x65, 0x72, 0x10, 0x0c, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x10, 0x0d, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, + 0x79, 0x70, 0x65, 0x44, 0x75, 0x6d, 0x70, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x51, 0x4c, + 0x54, 0x79, 0x70, 0x65, 0x44, 0x65, 0x62, 0x75, 0x67, 0x10, 0x0f, 0x12, 0x12, 0x0a, 0x0e, 0x53, + 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x45, 0x78, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x10, 0x12, + 0x14, 0x0a, 0x10, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x64, + 0x75, 0x72, 0x65, 0x10, 0x11, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, + 0x44, 0x65, 0x73, 0x63, 0x10, 0x12, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x51, 0x4c, 0x4c, 0x61, 0x73, + 0x74, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x44, 0x10, 0x13, 0x12, 0x19, 0x0a, 0x15, 0x53, + 0x51, 0x4c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x57, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x10, 0x14, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x51, 0x4c, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x10, 0x15, 0x12, 0x13, 0x0a, + 0x0f, 0x53, 0x51, 0x4c, 0x53, 0x68, 0x6f, 0x77, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, + 0x10, 0x16, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x51, 0x4c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x10, 0x17, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x51, 0x4c, 0x41, 0x6c, 0x74, + 0x65, 0x72, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x10, 0x18, 0x12, 0x13, 0x0a, 0x0f, + 0x53, 0x51, 0x4c, 0x44, 0x72, 0x6f, 0x70, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x10, + 0x19, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, 0x64, 0x64, 0x6c, 0x53, 0x68, 0x6f, 0x77, + 0x10, 0x1a, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x53, 0x65, 0x74, + 0x10, 0x1b, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x10, 0x1c, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x55, 0x6e, 0x69, 0x6f, 0x6e, 0x10, 0x1d, 0x12, 0x16, 0x0a, + 0x12, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x10, 0x1e, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, + 0x44, 0x72, 0x6f, 0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x1f, 0x12, 0x15, 0x0a, 0x11, 0x53, + 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x10, 0x20, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x53, 0x61, 0x76, + 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x10, 0x21, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x51, 0x4c, 0x54, + 0x79, 0x70, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x10, 0x22, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, + 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x23, 0x12, 0x16, 0x0a, + 0x12, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x10, 0x24, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x25, 0x12, 0x14, 0x0a, + 0x10, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x44, 0x72, 0x6f, 0x70, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x10, 0x26, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4b, 0x69, + 0x6c, 0x6c, 0x10, 0x27, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4c, + 0x6f, 0x63, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x10, 0x28, 0x12, 0x17, 0x0a, 0x13, 0x53, + 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x55, 0x6e, 0x4c, 0x6f, 0x63, 0x6b, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x10, 0x29, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x2a, 0x12, 0x1a, 0x0a, 0x16, 0x53, + 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x46, 0x6f, 0x75, 0x6e, + 0x64, 0x52, 0x6f, 0x77, 0x73, 0x10, 0x2b, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x51, 0x4c, 0x54, 0x79, + 0x70, 0x65, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x10, 0x65, + 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x4f, 0x6e, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x10, 0x66, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x51, 0x4c, 0x54, 0x79, 0x70, 0x65, 0x4d, + 0x75, 0x6c, 0x74, 0x69, 0x10, 0x94, 0x08, 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x51, 0x4c, 0x54, 0x79, + 0x70, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x95, 0x08, 0x42, 0x0a, 0x5a, 0x08, + 0x2e, 0x3b, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_branch_undo_log_proto_rawDescOnce sync.Once + file_branch_undo_log_proto_rawDescData = file_branch_undo_log_proto_rawDesc +) + +func file_branch_undo_log_proto_rawDescGZIP() []byte { + file_branch_undo_log_proto_rawDescOnce.Do(func() { + file_branch_undo_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_branch_undo_log_proto_rawDescData) + }) + return file_branch_undo_log_proto_rawDescData +} + +var file_branch_undo_log_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_branch_undo_log_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_branch_undo_log_proto_goTypes = []any{ + (IndexType)(0), // 0: parser.IndexType + (JDBCType)(0), // 1: parser.JDBCType + (SQLType)(0), // 2: parser.SQLType + (*BranchUndoLog)(nil), // 3: parser.BranchUndoLog + (*SQLUndoLog)(nil), // 4: parser.SQLUndoLog + (*RecordImage)(nil), // 5: parser.RecordImage + (*RowImage)(nil), // 6: parser.RowImage + (*ColumnImage)(nil), // 7: parser.ColumnImage + (*TableMeta)(nil), // 8: parser.TableMeta + (*ColumnMeta)(nil), // 9: parser.ColumnMeta + (*IndexMeta)(nil), // 10: parser.IndexMeta + nil, // 11: parser.TableMeta.ColumnsEntry + nil, // 12: parser.TableMeta.IndexsEntry + (*anypb.Any)(nil), // 13: google.protobuf.Any +} +var file_branch_undo_log_proto_depIdxs = []int32{ + 4, // 0: parser.BranchUndoLog.Logs:type_name -> parser.SQLUndoLog + 2, // 1: parser.SQLUndoLog.SQLType:type_name -> parser.SQLType + 5, // 2: parser.SQLUndoLog.BeforeImage:type_name -> parser.RecordImage + 5, // 3: parser.SQLUndoLog.AfterImage:type_name -> parser.RecordImage + 2, // 4: parser.RecordImage.SQLType:type_name -> parser.SQLType + 6, // 5: parser.RecordImage.Rows:type_name -> parser.RowImage + 8, // 6: parser.RecordImage.TableMeta:type_name -> parser.TableMeta + 7, // 7: parser.RowImage.Columns:type_name -> parser.ColumnImage + 0, // 8: parser.ColumnImage.KeyType:type_name -> parser.IndexType + 1, // 9: parser.ColumnImage.ColumnType:type_name -> parser.JDBCType + 13, // 10: parser.ColumnImage.Value:type_name -> google.protobuf.Any + 11, // 11: parser.TableMeta.Columns:type_name -> parser.TableMeta.ColumnsEntry + 12, // 12: parser.TableMeta.Indexs:type_name -> parser.TableMeta.IndexsEntry + 0, // 13: parser.IndexMeta.IType:type_name -> parser.IndexType + 9, // 14: parser.IndexMeta.Columns:type_name -> parser.ColumnMeta + 9, // 15: parser.TableMeta.ColumnsEntry.value:type_name -> parser.ColumnMeta + 10, // 16: parser.TableMeta.IndexsEntry.value:type_name -> parser.IndexMeta + 17, // [17:17] is the sub-list for method output_type + 17, // [17:17] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name +} + +func init() { file_branch_undo_log_proto_init() } +func file_branch_undo_log_proto_init() { + if File_branch_undo_log_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_branch_undo_log_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*BranchUndoLog); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*SQLUndoLog); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*RecordImage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*RowImage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*ColumnImage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*TableMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*ColumnMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_branch_undo_log_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*IndexMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_branch_undo_log_proto_rawDesc, + NumEnums: 3, + NumMessages: 10, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_branch_undo_log_proto_goTypes, + DependencyIndexes: file_branch_undo_log_proto_depIdxs, + EnumInfos: file_branch_undo_log_proto_enumTypes, + MessageInfos: file_branch_undo_log_proto_msgTypes, + }.Build() + File_branch_undo_log_proto = out.File + file_branch_undo_log_proto_rawDesc = nil + file_branch_undo_log_proto_goTypes = nil + file_branch_undo_log_proto_depIdxs = nil +} diff --git a/pkg/datasource/sql/undo/parser/branch_undo_log.proto b/pkg/datasource/sql/undo/parser/branch_undo_log.proto new file mode 100644 index 000000000..9055ea10e --- /dev/null +++ b/pkg/datasource/sql/undo/parser/branch_undo_log.proto @@ -0,0 +1,165 @@ +syntax = "proto3"; +package parser; +import "google/protobuf/any.proto"; + +option go_package=".;parser"; + +message BranchUndoLog { + string Xid = 1; + uint64 BranchID = 2; + repeated SQLUndoLog Logs = 3; +} + +message SQLUndoLog { + SQLType SQLType = 1; + string TableName = 2; + RecordImage BeforeImage = 3; + RecordImage AfterImage = 4; +} + +message RecordImage { + int32 index = 1; + string TableName = 2; + SQLType SQLType = 3; + repeated RowImage Rows = 4; + TableMeta TableMeta = 5; +} + +message RowImage { + repeated ColumnImage Columns = 1; +} + +message ColumnImage { + IndexType KeyType = 1; + string ColumnName = 2; + JDBCType ColumnType = 3; + google.protobuf.Any Value = 4; +} + +message TableMeta { + string TableName = 1; + map Columns = 2; + map Indexs = 3; + repeated string ColumnNames = 4; +} + +message ColumnMeta { + string Schema = 1; + string Table = 2; + bytes ColumnDef = 3; + bool Autoincrement = 4; + string ColumnName = 5; + string ColumnType = 6; + int32 DatabaseType = 7; + string DatabaseTypeString = 8; + string ColumnKey = 9; + int32 IsNullable = 10; + string Extra = 11; +} + +message IndexMeta { + string Schema = 1; + string Table = 2; + string Name = 3; + string ColumnName = 4; + IndexType IType = 5; + repeated ColumnMeta Columns = 6; +} + +enum IndexType { + IndexTypeNull = 0; + IndexTypePrimaryKey = 1; +} + +enum JDBCType { + JDBCTypeNull = 0; + JDBCTypeBit = -7; + JDBCTypeTinyInt = -6; + JDBCTypeSmallInt = 5; + JDBCTypeInteger = 4; + JDBCTypeBigInt = -5; + JDBCTypeFloat = 6; + JDBCTypeReal = 7; + JDBCTypeDouble = 8; + JDBCTypeNumberic = 2; + JDBCTypeDecimal = 3; + JDBCTypeChar = 1; + JDBCTypeVarchar = 12; + JDBCTypeLongVarchar = -1; + JDBCTypeDate = 91; + JDBCTypeTime = 92; + JDBCTypeTimestamp = 93; + JDBCTypeBinary = -2; + JDBCTypeVarBinary = -3; + JDBCTypeLongVarBinary = -4; + JDBCTypeOther = 1111; + JDBCTypeJavaObject = 2000; + JDBCTypeDistinct = 2001; + JDBCTypeStruct = 2002; + JDBCTypeArray = 2003; + JDBCTypeBlob = 2004; + JDBCTypeClob = 2005; + JDBCTypeRef = 2006; + JDBCTypeDateLink = 70; + JDBCTypeBoolean = 16; + JDBCTypeRowID = -8; + JDBCTypeNchar = -15; + JDBCTypeNvarchar = -9; + JDBCTypeLongNvVarchar = -16; + JDBCTypeNclob = 2011; + JDBCTypeSqlXML = 2009; + JDBCTypeRefCursor = 2012; + JDBCTypeTimeWithTimeZone = 2013; + JDBCTypeTimestampWithTimezone = 2014; +} + +enum SQLType { + SQLTypeSelect = 0; + SQLTypeInsert = 1; + SQLTypeUpdate = 2; + SQLTypeDelete = 3; + SQLTypeSelectForUpdate = 4; + SQLTypeReplace = 5; + SQLTypeTruncate = 6; + SQLTypeCreate = 7; + SQLTypeDrop = 8; + SQLTypeLoad = 9; + SQLTypeMerge = 10; + SQLTypeShow = 11; + SQLTypeAlter = 12; + SQLTypeRename = 13; + SQLTypeDump = 14; + SQLTypeDebug = 15; + SQLTypeExplain = 16; + SQLTypeProcedure = 17; + SQLTypeDesc = 18; + SQLLastInsertID = 19; + SQLSelectWithoutTable = 20; + SQLCreateSequence = 21; + SQLShowSequence = 22; + SQLGetSequence = 23; + SQLAlterSequence = 24; + SQLDropSequence = 25; + SQLTddlShow = 26; + SQLTypeSet = 27; + SQLTypeReload = 28; + SQLTypeSelectUnion = 29; + SQLTypeCreateTable = 30; + SQLTypeDropTable = 31; + SQLTypeAlterTable = 32; + SQLTypeSavePoint = 33; + SQLTypeSelectFromUpdate = 34; + SQLTypeMultiDelete = 35; + SQLTypeMultiUpdate = 36; + SQLTypeCreateIndex = 37; + SQLTypeDropIndex = 38; + SQLTypeKill = 39; + SQLTypeLockTables = 40; + SQLTypeUnLockTables = 41; + SQLTypeCheckTable = 42; + SQLTypeSelectFoundRows = 43; + SQLTypeInsertIgnore = 101; // Adjusted the value to match Go's logic + SQLTypeInsertOnDuplicateUpdate = 102; + SQLTypeMulti = 1044; // Adjusted the value to match Go's logic + SQLTypeUnknown = 1045; +} diff --git a/pkg/datasource/sql/undo/parser/parser_cache.go b/pkg/datasource/sql/undo/parser/parser_cache.go index 511fd093a..59c703fd8 100644 --- a/pkg/datasource/sql/undo/parser/parser_cache.go +++ b/pkg/datasource/sql/undo/parser/parser_cache.go @@ -39,6 +39,7 @@ func initCache() { } cache.store(&JsonParser{}) + cache.store(&ProtobufParser{}) } func GetCache() *UndoLogParserCache { diff --git a/pkg/datasource/sql/undo/parser/parser_json_test.go b/pkg/datasource/sql/undo/parser/parser_json_test.go index 4f73c3230..2123f0822 100644 --- a/pkg/datasource/sql/undo/parser/parser_json_test.go +++ b/pkg/datasource/sql/undo/parser/parser_json_test.go @@ -25,15 +25,15 @@ import ( "seata.apache.org/seata-go/pkg/datasource/sql/undo" ) -func TestGetName(t *testing.T) { +func TestJsonGetName(t *testing.T) { assert.Equal(t, "json", (&JsonParser{}).GetName()) } -func TestGetDefaultContext(t *testing.T) { +func TestJsonGetDefaultContext(t *testing.T) { assert.Equal(t, []byte("{}"), (&JsonParser{}).GetDefaultContent()) } -func TestEncode(t *testing.T) { +func TestJsonEncode(t *testing.T) { TestCases := []struct { CaseName string UndoLog *undo.BranchUndoLog @@ -67,7 +67,7 @@ func TestEncode(t *testing.T) { } } -func TestDecode(t *testing.T) { +func TestJsonDecode(t *testing.T) { TestCases := []struct { CaseName string ExpectUndoLog undo.BranchUndoLog diff --git a/pkg/datasource/sql/undo/parser/parser_protobuf.go b/pkg/datasource/sql/undo/parser/parser_protobuf.go new file mode 100644 index 000000000..7fd56082a --- /dev/null +++ b/pkg/datasource/sql/undo/parser/parser_protobuf.go @@ -0,0 +1,248 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package parser + +import ( + "encoding/json" + + "github.com/golang/protobuf/ptypes/any" + "github.com/golang/protobuf/ptypes/wrappers" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" + + "seata.apache.org/seata-go/pkg/datasource/sql/types" + "seata.apache.org/seata-go/pkg/datasource/sql/undo" +) + +type ProtobufParser struct { +} + +// GetName get the name of parser +func (p *ProtobufParser) GetName() string { + return "protobuf" +} + +// GetDefaultContent get default content of this parser +func (p *ProtobufParser) GetDefaultContent() []byte { + return []byte{} +} + +// Encode branch undo log to byte array +func (p *ProtobufParser) Encode(branchUndoLog *undo.BranchUndoLog) ([]byte, error) { + protoLog := ConvertToProto(branchUndoLog) + return proto.Marshal(protoLog) +} + +// Decode byte array to branch undo log +func (p *ProtobufParser) Decode(data []byte) (*undo.BranchUndoLog, error) { + branchUndoLog := &BranchUndoLog{} + err := proto.Unmarshal(data, branchUndoLog) + if err != nil { + return nil, err + } + + return ConvertToIntree(branchUndoLog), nil +} + +func ConvertToProto(intreeLog *undo.BranchUndoLog) *BranchUndoLog { + protoLog := &BranchUndoLog{ + Xid: intreeLog.Xid, + BranchID: intreeLog.BranchID, + Logs: []*SQLUndoLog{}, + } + for _, undolog := range intreeLog.Logs { + protolog := &SQLUndoLog{ + SQLType: SQLType(undolog.SQLType), + TableName: undolog.TableName, + } + + if undolog.BeforeImage != nil { + protolog.BeforeImage = &RecordImage{ + TableName: undolog.BeforeImage.TableName, + SQLType: SQLType(undolog.BeforeImage.SQLType), + Rows: []*RowImage{}, + } + + for _, row := range undolog.BeforeImage.Rows { + protoRow := &RowImage{ + Columns: []*ColumnImage{}, + } + + for _, col := range row.Columns { + anyValue, err := convertInterfaceToAny(col.GetActualValue()) + if err != nil { + continue + } + + protoCol := &ColumnImage{ + KeyType: IndexType(col.KeyType), + ColumnName: col.ColumnName, + ColumnType: JDBCType(col.ColumnType), + Value: anyValue, + } + + protoRow.Columns = append(protoRow.Columns, protoCol) + } + + protolog.BeforeImage.Rows = append(protolog.BeforeImage.Rows, protoRow) + } + } + + if undolog.AfterImage != nil { + protolog.AfterImage = &RecordImage{ + TableName: undolog.AfterImage.TableName, + SQLType: SQLType(undolog.AfterImage.SQLType), + Rows: []*RowImage{}, + } + + for _, row := range undolog.AfterImage.Rows { + protoRow := &RowImage{ + Columns: []*ColumnImage{}, + } + + for _, col := range row.Columns { + anyValue, err := convertInterfaceToAny(col.Value) + if err != nil { + continue + } + + protoCol := &ColumnImage{ + KeyType: IndexType(col.KeyType), + ColumnName: col.ColumnName, + ColumnType: JDBCType(col.ColumnType), + Value: anyValue, + } + + protoRow.Columns = append(protoRow.Columns, protoCol) + } + + protolog.AfterImage.Rows = append(protolog.AfterImage.Rows, protoRow) + } + } + + protoLog.Logs = append(protoLog.Logs, protolog) + } + return protoLog +} + +func ConvertToIntree(protoLog *BranchUndoLog) *undo.BranchUndoLog { + intreeLog := &undo.BranchUndoLog{ + Xid: protoLog.Xid, + BranchID: protoLog.BranchID, + Logs: []undo.SQLUndoLog{}, + } + + for _, pbSqlLog := range protoLog.Logs { + undoSqlLog := undo.SQLUndoLog{ + SQLType: types.SQLType(pbSqlLog.SQLType), + TableName: pbSqlLog.TableName, + } + + if pbSqlLog.BeforeImage != nil { + undoSqlLog.BeforeImage = &types.RecordImage{ + TableName: pbSqlLog.BeforeImage.TableName, + SQLType: types.SQLType(pbSqlLog.BeforeImage.SQLType), + Rows: []types.RowImage{}, + } + + for _, pbRow := range pbSqlLog.BeforeImage.Rows { + undoRow := types.RowImage{ + Columns: []types.ColumnImage{}, + } + + for _, pbCol := range pbRow.Columns { + anyValue, err := convertAnyToInterface(pbCol.Value) + if err != nil { + continue + } + + undoCol := types.ColumnImage{ + KeyType: types.IndexType(pbCol.KeyType), + ColumnName: pbCol.ColumnName, + ColumnType: types.JDBCType(pbCol.ColumnType), + Value: anyValue, + } + + undoRow.Columns = append(undoRow.Columns, undoCol) + } + + undoSqlLog.BeforeImage.Rows = append(undoSqlLog.BeforeImage.Rows, undoRow) + } + } + + if pbSqlLog.AfterImage != nil { + undoSqlLog.AfterImage = &types.RecordImage{ + TableName: pbSqlLog.AfterImage.TableName, + SQLType: types.SQLType(pbSqlLog.AfterImage.SQLType), + Rows: []types.RowImage{}, + } + + for _, pbRow := range pbSqlLog.AfterImage.Rows { + undoRow := types.RowImage{ + Columns: []types.ColumnImage{}, + } + + for _, pbCol := range pbRow.Columns { + anyValue, err := convertAnyToInterface(pbCol.Value) + if err != nil { + continue + } + + undoCol := types.ColumnImage{ + KeyType: types.IndexType(pbCol.KeyType), + ColumnName: pbCol.ColumnName, + ColumnType: types.JDBCType(pbCol.ColumnType), + Value: anyValue, + } + + undoRow.Columns = append(undoRow.Columns, undoCol) + } + + undoSqlLog.AfterImage.Rows = append(undoSqlLog.AfterImage.Rows, undoRow) + } + } + + intreeLog.Logs = append(intreeLog.Logs, undoSqlLog) + } + + return intreeLog +} + +func convertAnyToInterface(anyValue *any.Any) (interface{}, error) { + var value interface{} + bytesValue := &wrappers.BytesValue{} + err := anypb.UnmarshalTo(anyValue, bytesValue, proto.UnmarshalOptions{}) + if err != nil { + return value, err + } + uErr := json.Unmarshal(bytesValue.Value, &value) + if uErr != nil { + return value, uErr + } + return value, nil +} + +func convertInterfaceToAny(v interface{}) (*any.Any, error) { + anyValue := &any.Any{} + bytes, _ := json.Marshal(v) + bytesValue := &wrappers.BytesValue{ + Value: bytes, + } + err := anypb.MarshalFrom(anyValue, bytesValue, proto.MarshalOptions{}) + return anyValue, err +} diff --git a/pkg/datasource/sql/undo/parser/parser_protobuf_test.go b/pkg/datasource/sql/undo/parser/parser_protobuf_test.go new file mode 100644 index 000000000..e8cb0d52a --- /dev/null +++ b/pkg/datasource/sql/undo/parser/parser_protobuf_test.go @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package parser + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "seata.apache.org/seata-go/pkg/datasource/sql/undo" +) + +func TestProtobufGetName(t *testing.T) { + assert.Equal(t, "protobuf", (&ProtobufParser{}).GetName()) +} + +func TestProtobufDefaultContext(t *testing.T) { + assert.Equal(t, []byte{}, (&ProtobufParser{}).GetDefaultContent()) +} + +func TestProtobufEncodeDecode(t *testing.T) { + TestCases := []struct { + CaseName string + UndoLog *undo.BranchUndoLog + ExpectErr bool + }{ + { + CaseName: "pass", + UndoLog: &undo.BranchUndoLog{ + Xid: "123456", + BranchID: 123456, + Logs: []undo.SQLUndoLog{}, + }, + ExpectErr: false, + }, + } + + for _, Case := range TestCases { + t.Run(Case.CaseName, func(t *testing.T) { + parser := &ProtobufParser{} + + encodedBytes, err := parser.Encode(Case.UndoLog) + if Case.ExpectErr { + assert.NotNil(t, err) + return + } + assert.Nil(t, err) + + decodedUndoLog, err := parser.Decode(encodedBytes) + if Case.ExpectErr { + assert.NotNil(t, err) + return + } + assert.Nil(t, err) + + assert.Equal(t, Case.UndoLog.Xid, decodedUndoLog.Xid) + assert.Equal(t, Case.UndoLog.BranchID, decodedUndoLog.BranchID) + assert.Equal(t, len(Case.UndoLog.Logs), len(decodedUndoLog.Logs)) + }) + } +} + +func TestConvertInterfaceToAnyAndBack(t *testing.T) { + originalValue := map[string]interface{}{ + "key1": "value1", + "key2": float64(123), // Use float64 to match JSON default behavior + "key3": true, + } + + anyValue, err := convertInterfaceToAny(originalValue) + assert.NoError(t, err, "convertInterfaceToAny should not return an error") + + convertedValue, err := convertAnyToInterface(anyValue) + assert.NoError(t, err, "convertAnyToInterface should not return an error") + + assert.Equal(t, originalValue, convertedValue, "The converted value should match the original") +} From 406b8bac9cd6c81e46e1414a2bed792e8ac38b88 Mon Sep 17 00:00:00 2001 From: FinnTew Date: Sat, 7 Dec 2024 20:06:45 +0800 Subject: [PATCH 04/22] fix: undo log sql (#724) * fix the problem of mock replacing mysql.GetTableMeta in TestBuildSelectSQLByUpdate * fix the problem of MySQLUpdateUndoLogBuilder failing to generate undo log sql --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- .../sql/undo/builder/basic_undo_log_builder.go | 4 ++++ .../builder/mysql_update_undo_log_builder_test.go | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go b/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go index a619c15e4..043e7eb44 100644 --- a/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go @@ -121,6 +121,10 @@ func (b *BasicUndoLogBuilder) traversalArgs(node ast.Node, argsIndex *[]int32) { b.traversalArgs(exprs[i], argsIndex) } break + case *ast.ParenthesesExpr: + expr := node.(*ast.ParenthesesExpr) + b.traversalArgs(expr.Expr, argsIndex) + break case *test_driver.ParamMarkerExpr: *argsIndex = append(*argsIndex, int32(node.(*test_driver.ParamMarkerExpr).Order)) break diff --git a/pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder_test.go b/pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder_test.go index f5b07a450..f65a2e94a 100644 --- a/pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder_test.go +++ b/pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder_test.go @@ -39,12 +39,14 @@ import ( ) func TestBuildSelectSQLByUpdate(t *testing.T) { - t.SkipNow() + //t.SkipNow() var ( builder = MySQLUpdateUndoLogBuilder{} ) - stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string, conn driver.Conn) (*types.TableMeta, error) { + datasource.RegisterTableCache(types.DBTypeMySQL, &mysql.TableMetaCache{}) + + stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string) (*types.TableMeta, error) { return &types.TableMeta{ Indexs: map[string]types.IndexMeta{ "id": { @@ -77,6 +79,12 @@ func TestBuildSelectSQLByUpdate(t *testing.T) { expectQuery: "SELECT SQL_NO_CACHE name,age,id FROM t_user WHERE id=? AND name=_UTF8MB4Jack AND age BETWEEN ? AND ? FOR UPDATE", expectQueryArgs: []driver.Value{100, 18, 28}, }, + { + sourceQuery: "update t_user set name = ?, age = ? where (id = ? or name = 'Jack') and age between ? and ?", + sourceQueryArgs: []driver.Value{"Jack", 1, 100, 18, 28}, + expectQuery: "SELECT SQL_NO_CACHE name,age,id FROM t_user WHERE (id=? OR name=_UTF8MB4Jack) AND age BETWEEN ? AND ? FOR UPDATE", + expectQueryArgs: []driver.Value{100, 18, 28}, + }, { sourceQuery: "update t_user set name = ?, age = ? where id = ? and name = 'Jack' and age in (?,?)", sourceQueryArgs: []driver.Value{"Jack", 1, 100, 18, 28}, From 3188ecf883b7585afe2c609d635e3a717d449533 Mon Sep 17 00:00:00 2001 From: "xinfan.wu" <13708123240@163.com> Date: Thu, 12 Dec 2024 23:59:46 +0800 Subject: [PATCH 05/22] feat:add more linter in configuration file (#686) * feat:add more linter * feat:change golangclilint version to 1.57.x to support more linter * feat:adjust lint conf and adjust the code to pass the check --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- .golangci.yml | 25 +++++++++++++++---- go.mod | 1 - go.sum | 2 -- .../sql/datasource/mysql/trigger.go | 8 ++++-- pkg/datasource/sql/undo/base/undo.go | 7 ++++-- pkg/datasource/sql/undo/executor/executor.go | 4 ++- pkg/rm/rm_remoting.go | 2 +- pkg/rm/tcc/fence/fennce_driver_test.go | 2 +- pkg/rm/tcc/tcc_service.go | 4 +-- 9 files changed, 38 insertions(+), 17 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 1180b7084..bb7d6eda5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,7 +17,7 @@ linters-settings: govet: - check-shadowing: false + shadow: true golint: min-confidence: 0 gocyclo: @@ -56,13 +56,22 @@ linters: - staticcheck - ineffassign - misspell + # - errcheck + - asciicheck + - bodyclose + - rowserrcheck + #- makezero + - durationcheck + # - prealloc + # - predeclared + run: - skip-dirs: - - test/testdata_etc - - pkg/golinters/goanalysis/(checker|passes) issues: + exclude-dirs: + - test/testdata_etc + - pkg/golinters/goanalysis/(checker|passes) exclude-rules: - text: "weak cryptographic primitive" linters: @@ -70,11 +79,17 @@ issues: - linters: - staticcheck text: "SA1019:" + - path: _test\.go + linters: + - errcheck + - gosec + - rowserrcheck + - govet # golangci.com configuration # https://github.com/golangci/golangci/wiki/Configuration service: - golangci-lint-version: 1.49.x # use the fixed version to not introduce new linters unexpectedly + golangci-lint-version: 1.57.x # use the fixed version to not introduce new linters unexpectedly prepare: - echo "here I can run custom commands, but no preparation needed for this repo" diff --git a/go.mod b/go.mod index 784cc1945..e35e9966d 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,6 @@ require ( ) require ( - github.com/agiledragon/gomonkey v2.0.2+incompatible github.com/agiledragon/gomonkey/v2 v2.9.0 go.etcd.io/etcd/api/v3 v3.5.6 go.etcd.io/etcd/client/v3 v3.5.6 diff --git a/go.sum b/go.sum index e4c461f05..461c515b4 100644 --- a/go.sum +++ b/go.sum @@ -54,8 +54,6 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= -github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/agiledragon/gomonkey/v2 v2.9.0 h1:PDiKKybR596O6FHW+RVSG0Z7uGCBNbmbUXh3uCNQ7Hc= github.com/agiledragon/gomonkey/v2 v2.9.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= diff --git a/pkg/datasource/sql/datasource/mysql/trigger.go b/pkg/datasource/sql/datasource/mysql/trigger.go index 5512a416c..d9339a6d1 100644 --- a/pkg/datasource/sql/datasource/mysql/trigger.go +++ b/pkg/datasource/sql/datasource/mysql/trigger.go @@ -144,7 +144,9 @@ func (m *mysqlTrigger) getColumnMetas(ctx context.Context, dbName string, table columnMeta.Autoincrement = strings.Contains(strings.ToLower(extra), "auto_increment") columnMetas = append(columnMetas, columnMeta) } - + if err := rows.Err(); err != nil { + return nil, err + } if len(columnMetas) == 0 { return nil, fmt.Errorf("can't find column") } @@ -204,6 +206,8 @@ func (m *mysqlTrigger) getIndexes(ctx context.Context, dbName string, tableName result = append(result, index) } - + if err := rows.Err(); err != nil { + return nil, err + } return result, nil } diff --git a/pkg/datasource/sql/undo/base/undo.go b/pkg/datasource/sql/undo/base/undo.go index 331930e7e..394cacbd6 100644 --- a/pkg/datasource/sql/undo/base/undo.go +++ b/pkg/datasource/sql/undo/base/undo.go @@ -297,7 +297,10 @@ func (m *BaseUndoLogManager) Undo(ctx context.Context, dbType types.DBType, xid } undoLogRecords = append(undoLogRecords, record) } - + if err := rows.Err(); err != nil { + log.Errorf("read rows next fail, xid: %s, branchID:%s err:%v", xid, branchID, err) + return err + } var exists bool for _, record := range undoLogRecords { exists = true @@ -410,7 +413,7 @@ func (m *BaseUndoLogManager) DBType() types.DBType { // HasUndoLogTable check undo log table if exist func (m *BaseUndoLogManager) HasUndoLogTable(ctx context.Context, conn *sql.Conn) (res bool, err error) { - if _, err = conn.QueryContext(ctx, getCheckUndoLogTableExistSql()); err != nil { + if _, err = conn.QueryContext(ctx, getCheckUndoLogTableExistSql()); err != nil { //nolint:rowserrcheck // 1146 mysql table not exist fault code if e, ok := err.(*mysql.SQLError); ok && e.Code == mysql.ErrNoSuchTable { return false, nil diff --git a/pkg/datasource/sql/undo/executor/executor.go b/pkg/datasource/sql/undo/executor/executor.go index f4d9a8bba..f4c9aed46 100644 --- a/pkg/datasource/sql/undo/executor/executor.go +++ b/pkg/datasource/sql/undo/executor/executor.go @@ -159,7 +159,9 @@ func (b *BaseExecutor) queryCurrentRecords(ctx context.Context, conn *sql.Conn) } rowImages = append(rowImages, types.RowImage{Columns: columns}) } - + if err := rows.Err(); err != nil { + return nil, err + } image.Rows = rowImages return &image, nil } diff --git a/pkg/rm/rm_remoting.go b/pkg/rm/rm_remoting.go index 675225012..563ebc8b1 100644 --- a/pkg/rm/rm_remoting.go +++ b/pkg/rm/rm_remoting.go @@ -156,7 +156,7 @@ func isRegisterSuccess(response interface{}) bool { func isReportSuccess(response interface{}) error { if res, ok := response.(message.BranchReportResponse); ok { if res.ResultCode == message.ResultCodeFailed { - return fmt.Errorf(res.Msg) + return errors.New(res.Msg) } } else { return ErrBranchReportResponseFault diff --git a/pkg/rm/tcc/fence/fennce_driver_test.go b/pkg/rm/tcc/fence/fennce_driver_test.go index cfaddd2a1..c0e804e8b 100644 --- a/pkg/rm/tcc/fence/fennce_driver_test.go +++ b/pkg/rm/tcc/fence/fennce_driver_test.go @@ -24,7 +24,7 @@ import ( "reflect" "testing" - "github.com/agiledragon/gomonkey" + gomonkey "github.com/agiledragon/gomonkey/v2" "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" ) diff --git a/pkg/rm/tcc/tcc_service.go b/pkg/rm/tcc/tcc_service.go index ffedff1e6..87335c65e 100644 --- a/pkg/rm/tcc/tcc_service.go +++ b/pkg/rm/tcc/tcc_service.go @@ -20,7 +20,7 @@ package tcc import ( "context" "encoding/json" - "fmt" + "errors" "reflect" "sync" "time" @@ -94,7 +94,7 @@ func (t *TCCServiceProxy) registeBranch(ctx context.Context, params interface{}) if !tm.IsGlobalTx(ctx) { errStr := "BranchRegister error, transaction should be opened" log.Errorf(errStr) - return fmt.Errorf(errStr) + return errors.New(errStr) } tccContext := t.initBusinessActionContext(ctx, params) From 9b5b080e27a5a52ce4223aa99dfb319aea239bc9 Mon Sep 17 00:00:00 2001 From: "xinfan.wu" Date: Sat, 14 Dec 2024 16:24:29 +0800 Subject: [PATCH 06/22] fix:sql statement was not closed (#736) * feat:add more linter * feat:change golangclilint version to 1.57.x to support more linter * feat:adjust lint conf and adjust the code to pass the check * style: format some code; fix: some sql statement or rows was not been closed --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- .golangci.yml | 7 ++----- pkg/datasource/sql/datasource/mysql/trigger.go | 3 ++- pkg/datasource/sql/exec/at/escape.go | 2 +- pkg/datasource/sql/tx.go | 2 +- pkg/datasource/sql/types/image.go | 4 ++-- pkg/datasource/sql/undo/base/undo.go | 7 +++++-- pkg/datasource/sql/undo/executor/executor.go | 2 +- .../sql/undo/executor/mysql_undo_delete_executor.go | 4 ++-- .../sql/undo/executor/mysql_undo_insert_executor.go | 4 ++-- .../sql/undo/executor/mysql_undo_update_executor.go | 5 +++-- pkg/datasource/sql/undo/executor/sql.go | 2 +- pkg/remoting/getty/readwriter.go | 6 +++--- pkg/remoting/loadbalance/loadbalance.go | 2 +- 13 files changed, 26 insertions(+), 24 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index bb7d6eda5..e558827c0 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -56,15 +56,12 @@ linters: - staticcheck - ineffassign - misspell - # - errcheck - asciicheck - bodyclose - rowserrcheck - #- makezero + - gofmt - durationcheck - # - prealloc - # - predeclared - + - sqlclosecheck run: diff --git a/pkg/datasource/sql/datasource/mysql/trigger.go b/pkg/datasource/sql/datasource/mysql/trigger.go index d9339a6d1..689ad2c73 100644 --- a/pkg/datasource/sql/datasource/mysql/trigger.go +++ b/pkg/datasource/sql/datasource/mysql/trigger.go @@ -93,6 +93,7 @@ func (m *mysqlTrigger) getColumnMetas(ctx context.Context, dbName string, table if err != nil { return nil, err } + defer stmt.Close() rows, err := stmt.Query(dbName, table) if err != nil { @@ -164,7 +165,7 @@ func (m *mysqlTrigger) getIndexes(ctx context.Context, dbName string, tableName if err != nil { return nil, err } - + defer stmt.Close() rows, err := stmt.Query(dbName, tableName) if err != nil { return nil, err diff --git a/pkg/datasource/sql/exec/at/escape.go b/pkg/datasource/sql/exec/at/escape.go index 3133b40d6..bd8d1c6ab 100644 --- a/pkg/datasource/sql/exec/at/escape.go +++ b/pkg/datasource/sql/exec/at/escape.go @@ -142,7 +142,7 @@ func addEscape(colName string, dbType types.DBType, escape string) string { buf := make([]byte, len(colName)+2) buf[0], buf[len(buf)-1] = escape[0], escape[0] - for key, _ := range colName { + for key := range colName { buf[key+1] = colName[key] } diff --git a/pkg/datasource/sql/tx.go b/pkg/datasource/sql/tx.go index a6c5f70ff..db55e97d1 100644 --- a/pkg/datasource/sql/tx.go +++ b/pkg/datasource/sql/tx.go @@ -166,7 +166,7 @@ func (tx *Tx) register(ctx *types.TransactionContext) error { if !ctx.HasUndoLog() || !ctx.HasLockKey() { return nil } - for k, _ := range ctx.LockKeys { + for k := range ctx.LockKeys { lockKey += k + ";" } request.LockKeys = lockKey diff --git a/pkg/datasource/sql/types/image.go b/pkg/datasource/sql/types/image.go index f755d9c91..0290b3660 100644 --- a/pkg/datasource/sql/types/image.go +++ b/pkg/datasource/sql/types/image.go @@ -146,7 +146,7 @@ func (r *RowImage) GetColumnMap() map[string]*ColumnImage { // PrimaryKeys Primary keys list. func (r *RowImage) PrimaryKeys(cols []ColumnImage) []ColumnImage { var pkFields []ColumnImage - for key, _ := range cols { + for key := range cols { if cols[key].KeyType == PrimaryKey.Number() { pkFields = append(pkFields, cols[key]) } @@ -158,7 +158,7 @@ func (r *RowImage) PrimaryKeys(cols []ColumnImage) []ColumnImage { // NonPrimaryKeys get non-primary keys func (r *RowImage) NonPrimaryKeys(cols []ColumnImage) []ColumnImage { var nonPkFields []ColumnImage - for key, _ := range cols { + for key := range cols { if cols[key].KeyType != PrimaryKey.Number() { nonPkFields = append(nonPkFields, cols[key]) } diff --git a/pkg/datasource/sql/undo/base/undo.go b/pkg/datasource/sql/undo/base/undo.go index 394cacbd6..752597fbf 100644 --- a/pkg/datasource/sql/undo/base/undo.go +++ b/pkg/datasource/sql/undo/base/undo.go @@ -106,6 +106,8 @@ func (m *BaseUndoLogManager) InsertUndoLogWithSqlConn(ctx context.Context, recor if err != nil { return err } + defer stmt.Close() + _, err = stmt.Exec(record.BranchID, record.XID, record.Context, record.RollbackInfo, int64(record.LogStatus)) if err != nil { return err @@ -120,7 +122,7 @@ func (m *BaseUndoLogManager) DeleteUndoLog(ctx context.Context, xid string, bran log.Errorf("[DeleteUndoLog] prepare sql fail, err: %v", err) return err } - + defer stmt.Close() if _, err = stmt.Exec(branchID, xid); err != nil { log.Errorf("[DeleteUndoLog] exec delete undo log fail, err: %v", err) return err @@ -146,6 +148,7 @@ func (m *BaseUndoLogManager) BatchDeleteUndoLog(xid []string, branchID []int64, log.Errorf("prepare sql fail, err: %v", err) return err } + defer stmt.Close() branchIDStr, err := Int64Slice2Str(branchID, ",") if err != nil { @@ -413,7 +416,7 @@ func (m *BaseUndoLogManager) DBType() types.DBType { // HasUndoLogTable check undo log table if exist func (m *BaseUndoLogManager) HasUndoLogTable(ctx context.Context, conn *sql.Conn) (res bool, err error) { - if _, err = conn.QueryContext(ctx, getCheckUndoLogTableExistSql()); err != nil { //nolint:rowserrcheck + if _, err = conn.QueryContext(ctx, getCheckUndoLogTableExistSql()); err != nil { //nolint:rowserrcheck,sqlclosecheck // 1146 mysql table not exist fault code if e, ok := err.(*mysql.SQLError); ok && e.Code == mysql.ErrNoSuchTable { return false, nil diff --git a/pkg/datasource/sql/undo/executor/executor.go b/pkg/datasource/sql/undo/executor/executor.go index f4c9aed46..f5b573a6a 100644 --- a/pkg/datasource/sql/undo/executor/executor.go +++ b/pkg/datasource/sql/undo/executor/executor.go @@ -124,7 +124,7 @@ func (b *BaseExecutor) queryCurrentRecords(ctx context.Context, conn *sql.Conn) if err != nil { return nil, err } - + defer rows.Close() image := types.RecordImage{ TableName: b.undoImage.TableName, TableMeta: tableMeta, diff --git a/pkg/datasource/sql/undo/executor/mysql_undo_delete_executor.go b/pkg/datasource/sql/undo/executor/mysql_undo_delete_executor.go index 7a392fc98..02045c3df 100644 --- a/pkg/datasource/sql/undo/executor/mysql_undo_delete_executor.go +++ b/pkg/datasource/sql/undo/executor/mysql_undo_delete_executor.go @@ -48,7 +48,7 @@ func (m *mySQLUndoDeleteExecutor) ExecuteOn(ctx context.Context, dbType types.DB if err != nil { return err } - + defer stmt.Close() beforeImage := m.sqlUndoLog.BeforeImage for _, row := range beforeImage.Rows { @@ -97,7 +97,7 @@ func (m *mySQLUndoDeleteExecutor) buildUndoSQL(dbType types.DBType) (string, err insertColumnSlice, insertValueSlice []string ) - for key, _ := range fields { + for key := range fields { insertColumnSlice = append(insertColumnSlice, AddEscape(fields[key].ColumnName, dbType)) insertValueSlice = append(insertValueSlice, "?") } diff --git a/pkg/datasource/sql/undo/executor/mysql_undo_insert_executor.go b/pkg/datasource/sql/undo/executor/mysql_undo_insert_executor.go index 108a62e64..bd80804d5 100644 --- a/pkg/datasource/sql/undo/executor/mysql_undo_insert_executor.go +++ b/pkg/datasource/sql/undo/executor/mysql_undo_insert_executor.go @@ -50,7 +50,7 @@ func (m *mySQLUndoInsertExecutor) ExecuteOn(ctx context.Context, dbType types.DB if err != nil { return err } - + defer stmt.Close() afterImage := m.sqlUndoLog.AfterImage for _, row := range afterImage.Rows { pkValueList := make([]interface{}, 0) @@ -96,7 +96,7 @@ func (m *mySQLUndoInsertExecutor) generateDeleteSql( } var pkList []string - for key, _ := range colImages { + for key := range colImages { pkList = append(pkList, colImages[key].ColumnName) } diff --git a/pkg/datasource/sql/undo/executor/mysql_undo_update_executor.go b/pkg/datasource/sql/undo/executor/mysql_undo_update_executor.go index d3561c449..65e132188 100644 --- a/pkg/datasource/sql/undo/executor/mysql_undo_update_executor.go +++ b/pkg/datasource/sql/undo/executor/mysql_undo_update_executor.go @@ -54,6 +54,7 @@ func (m *mySQLUndoUpdateExecutor) ExecuteOn(ctx context.Context, dbType types.DB if err != nil { return err } + defer stmt.Close() beforeImage := m.sqlUndoLog.BeforeImage for _, row := range beforeImage.Rows { @@ -93,7 +94,7 @@ func (m *mySQLUndoUpdateExecutor) buildUndoSQL(dbType types.DBType) (string, err ) nonPkFields := row.NonPrimaryKeys(row.Columns) - for key, _ := range nonPkFields { + for key := range nonPkFields { updateColumnSlice = append(updateColumnSlice, AddEscape(nonPkFields[key].ColumnName, dbType)+" = ? ") } @@ -103,7 +104,7 @@ func (m *mySQLUndoUpdateExecutor) buildUndoSQL(dbType types.DBType) (string, err return "", err } - for key, _ := range pkList { + for key := range pkList { pkNameList = append(pkNameList, pkList[key].ColumnName) } diff --git a/pkg/datasource/sql/undo/executor/sql.go b/pkg/datasource/sql/undo/executor/sql.go index 104baced0..5594a4436 100644 --- a/pkg/datasource/sql/undo/executor/sql.go +++ b/pkg/datasource/sql/undo/executor/sql.go @@ -142,7 +142,7 @@ func addEscape(colName string, dbType types.DBType, escape string) string { buf := make([]byte, len(colName)+2) buf[0], buf[len(buf)-1] = escape[0], escape[0] - for key, _ := range colName { + for key := range colName { buf[key+1] = colName[key] } diff --git a/pkg/remoting/getty/readwriter.go b/pkg/remoting/getty/readwriter.go index 5232315f8..321648969 100644 --- a/pkg/remoting/getty/readwriter.go +++ b/pkg/remoting/getty/readwriter.go @@ -58,9 +58,9 @@ var ( var ( ErrNotEnoughStream = errors.New("packet stream is not enough") - ErrTooLargePackage = errors.New("package length is exceed the getty package's legal maximum length.") + ErrTooLargePackage = errors.New("package length is exceed the getty package's legal maximum length") ErrInvalidPackage = errors.New("invalid rpc package") - ErrIllegalMagic = errors.New("package magic is not right.") + ErrIllegalMagic = errors.New("package magic is not right") ) type RpcPackageHandler struct{} @@ -141,7 +141,7 @@ func (p *RpcPackageHandler) Write(ss getty.Session, pkg interface{}) ([]byte, er headLength := message.V1HeadLength var headMapBytes []byte - if msg.HeadMap != nil && len(msg.HeadMap) > 0 { + if len(msg.HeadMap) > 0 { hb, headMapLength := encodeHeapMap(msg.HeadMap) headMapBytes = hb headLength += headMapLength diff --git a/pkg/remoting/loadbalance/loadbalance.go b/pkg/remoting/loadbalance/loadbalance.go index 5704eb39a..abfb6b6f7 100644 --- a/pkg/remoting/loadbalance/loadbalance.go +++ b/pkg/remoting/loadbalance/loadbalance.go @@ -40,7 +40,7 @@ func Select(loadBalanceType string, sessions *sync.Map, xid string) getty.Sessio case consistentHashLoadBalance: return ConsistentHashLoadBalance(sessions, xid) case leastActiveLoadBalance: - return LeastActiveLoadBalance(sessions, xid) + return LeastActiveLoadBalance(sessions, xid) case roundRobinLoadBalance: return RoundRobinLoadBalance(sessions, xid) default: From 1d1214deb192a3d65d626180b71cded19ffceca8 Mon Sep 17 00:00:00 2001 From: "xinfan.wu" Date: Sat, 14 Dec 2024 16:27:03 +0800 Subject: [PATCH 07/22] feat: remove session when send heart beat message failed (#738) * feat:add more linter * feat:change golangclilint version to 1.57.x to support more linter * feat:adjust lint conf and adjust the code to pass the check * feat:close session when send heart beat message failed --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- pkg/remoting/getty/listener.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pkg/remoting/getty/listener.go b/pkg/remoting/getty/listener.go index f5ba96ff2..2f2e97489 100644 --- a/pkg/remoting/getty/listener.go +++ b/pkg/remoting/getty/listener.go @@ -115,10 +115,14 @@ func (g *gettyClientHandler) OnMessage(session getty.Session, pkg interface{}) { func (g *gettyClientHandler) OnCron(session getty.Session) { log.Debug("session{%s} Oncron executing", session.Stat()) - g.transferBeatHeart(session, message.HeartBeatMessagePing) + err := g.transferHeartBeat(session, message.HeartBeatMessagePing) + if err != nil { + log.Errorf("failed to send heart beat: {%#v}", err.Error()) + g.sessionManager.releaseSession(session) + } } -func (g *gettyClientHandler) transferBeatHeart(session getty.Session, msg message.HeartBeatMessage) { +func (g *gettyClientHandler) transferHeartBeat(session getty.Session, msg message.HeartBeatMessage) error { rpcMessage := message.RpcMessage{ ID: int32(g.idGenerator.Inc()), Type: message.GettyRequestTypeHeartbeatRequest, @@ -126,7 +130,7 @@ func (g *gettyClientHandler) transferBeatHeart(session getty.Session, msg messag Compressor: 0, Body: msg, } - GetGettyRemotingInstance().SendASync(rpcMessage, session, nil) + return GetGettyRemotingInstance().SendASync(rpcMessage, session, nil) } func (g *gettyClientHandler) RegisterProcessor(msgType message.MessageType, processor processor.RemotingProcessor) { From e251741f05a4449759d12e974dd146eeeaedfcfe Mon Sep 17 00:00:00 2001 From: FinnTew Date: Sat, 14 Dec 2024 16:31:51 +0800 Subject: [PATCH 08/22] doc: update readme (#737) * update README.md and README_ZH.md * update readme --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- README.md | 6 +++--- README_ZH.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e95785ee6..e2f2bd070 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The principle of seata-go is consistent with that of Seata-java, which is compos ## TODO list - [x] TCC -- [ ] XA +- [x] XA - [x] AT - [x] Insert SQL - [x] Delete SQL @@ -33,9 +33,9 @@ The principle of seata-go is consistent with that of Seata-java, which is compos - [x] Manually way - [x] Proxy datasource way - [x] Null compensation -- [ ] Configuration center +- [x] Configuration center - [x] Configuration file -- [ ] Registration Center +- [x] Registration Center - [ ] Metric monitoring - [x] Compressor algorithm - [x] Examples diff --git a/README_ZH.md b/README_ZH.md index cea4ec1aa..3cc58144b 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -17,7 +17,7 @@ Seata-go 的原理和 Seata-java 保持一致,都是由 TM、RM 和 TC 组成 ## 待办事项 - [x] TCC -- [ ] XA +- [x] XA - [x] AT - [x] Insert SQL - [x] Delete SQL @@ -35,9 +35,9 @@ Seata-go 的原理和 Seata-java 保持一致,都是由 TM、RM 和 TC 组成 - [x] 空补偿 - [x] 手动方式 - [x] 代理数据源方式 -- [ ] 配置中心 +- [x] 配置中心 - [x] 配置文件 -- [ ] 注册中心 +- [x] 注册中心 - [ ] Metric 监控 - [x] 压缩算法 - [x] Sample 例子 From 6bf7b943886ca15bad1869049b2b9aa871f91d55 Mon Sep 17 00:00:00 2001 From: FinnTew Date: Sat, 14 Dec 2024 16:51:50 +0800 Subject: [PATCH 09/22] fix: bypassing modifying the primary key (#727) * adjust unit tests to verify the issue of "bypassing modifying the primary key" * fix: bypass modify the primary key --- .../mysql_insertonduplicate_update_undo_log_builder.go | 10 +++++----- ...l_insertonduplicate_update_undo_log_builder_test.go | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder.go b/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder.go index 4a23dedda..6b82d5370 100644 --- a/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder.go @@ -128,7 +128,7 @@ func (u *MySQLInsertOnDuplicateUndoLogBuilder) buildBeforeImageSQL(insertStmt *a columnIsNull := true uniqueList := make([]string, 0) for _, columnMeta := range index.Columns { - columnName := columnMeta.ColumnName + columnName := strings.ToLower(columnMeta.ColumnName) imageParameters, ok := paramMap[columnName] if !ok && columnMeta.ColumnDef != nil { if strings.EqualFold("PRIMARY", index.Name) { @@ -222,7 +222,7 @@ func (u *MySQLInsertOnDuplicateUndoLogBuilder) buildAfterImageSQL(ctx context.Co func checkDuplicateKeyUpdate(insert *ast.InsertStmt, metaData types.TableMeta) error { duplicateColsMap := make(map[string]bool) for _, v := range insert.OnDuplicate { - duplicateColsMap[v.Column.Name.L] = true + duplicateColsMap[strings.ToLower(v.Column.Name.L)] = true } if len(duplicateColsMap) == 0 { return nil @@ -254,7 +254,7 @@ func (u *MySQLInsertOnDuplicateUndoLogBuilder) buildImageParameters(insert *ast. return nil, fmt.Errorf("insert row's column size not equal to insert column size") } for i, col := range insertColumns { - columnName := executor.DelEscape(col, types.DBTypeMySQL) + columnName := strings.ToLower(executor.DelEscape(col, types.DBTypeMySQL)) val := row[i] rStr, ok := val.(string) if ok && strings.EqualFold(rStr, SqlPlaceholder) { @@ -279,14 +279,14 @@ func getInsertColumns(insertStmt *ast.InsertStmt) []string { } var list []string for _, col := range colList { - list = append(list, col.Name.L) + list = append(list, strings.ToLower(col.Name.L)) } return list } func isIndexValueNotNull(indexMeta types.IndexMeta, imageParameterMap map[string][]driver.Value, rowIndex int) bool { for _, colMeta := range indexMeta.Columns { - columnName := colMeta.ColumnName + columnName := strings.ToLower(colMeta.ColumnName) imageParameters := imageParameterMap[columnName] if imageParameters == nil && colMeta.ColumnDef == nil { return false diff --git a/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder_test.go b/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder_test.go index 03e028fe3..59e673f7d 100644 --- a/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder_test.go +++ b/pkg/datasource/sql/undo/builder/mysql_insertonduplicate_update_undo_log_builder_test.go @@ -46,7 +46,7 @@ func TestInsertOnDuplicateBuildBeforeImageSQL(t *testing.T) { ) columnId := types.ColumnMeta{ ColumnDef: nil, - ColumnName: "id", + ColumnName: "ID", } columnName := types.ColumnMeta{ ColumnDef: nil, @@ -56,12 +56,12 @@ func TestInsertOnDuplicateBuildBeforeImageSQL(t *testing.T) { ColumnDef: nil, ColumnName: "age", } - columns["id"] = columnId + columns["ID"] = columnId columns["name"] = columnName columns["age"] = columnAge columnMeta1 = append(columnMeta1, columnId) columnMeta2 = append(columnMeta2, columnName, columnAge) - index["id"] = types.IndexMeta{ + index["ID"] = types.IndexMeta{ Name: "PRIMARY", IType: types.IndexTypePrimaryKey, Columns: columnMeta1, @@ -72,7 +72,7 @@ func TestInsertOnDuplicateBuildBeforeImageSQL(t *testing.T) { Columns: columnMeta2, } - ColumnNames = []string{"id", "name", "age"} + ColumnNames = []string{"ID", "name", "age"} tableMeta1 = types.TableMeta{ TableName: "t_user", Columns: columns, From d7b6a4c8a37c5efc44dec32c07e4af8ed2b3fb92 Mon Sep 17 00:00:00 2001 From: lxfeng1997 <33981743+lxfeng1997@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:03:47 +0800 Subject: [PATCH 10/22] optimize: only inserted fields (#719) * only inserted fields * It is suspected that it is not used, so restore the previous code --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- pkg/datasource/sql/exec/at/base_executor.go | 43 +++++++++++++++++++ pkg/datasource/sql/exec/at/insert_executor.go | 14 ++++-- .../sql/exec/at/insert_executor_test.go | 4 +- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/pkg/datasource/sql/exec/at/base_executor.go b/pkg/datasource/sql/exec/at/base_executor.go index 75f0cab56..05f440577 100644 --- a/pkg/datasource/sql/exec/at/base_executor.go +++ b/pkg/datasource/sql/exec/at/base_executor.go @@ -23,6 +23,7 @@ import ( "database/sql" "database/sql/driver" "fmt" + "seata.apache.org/seata-go/pkg/datasource/sql/undo" "strings" "github.com/arana-db/parser/ast" @@ -187,6 +188,48 @@ func (b *baseExecutor) buildRecordImages(rowsi driver.Rows, tableMetaData *types return &types.RecordImage{TableName: tableMetaData.TableName, Rows: rowImages, SQLType: sqlType}, nil } +func (b *baseExecutor) getNeedColumns(meta *types.TableMeta, columns []string, dbType types.DBType) []string { + var needUpdateColumns []string + if undo.UndoConfig.OnlyCareUpdateColumns && columns != nil && len(columns) > 0 { + needUpdateColumns = columns + if !b.containsPKByName(meta, columns) { + pkNames := meta.GetPrimaryKeyOnlyName() + if pkNames != nil && len(pkNames) > 0 { + for _, name := range pkNames { + needUpdateColumns = append(needUpdateColumns, name) + } + } + } + // todo If it contains onUpdate columns, add onUpdate columns + } else { + needUpdateColumns = meta.ColumnNames + } + + for i := range needUpdateColumns { + needUpdateColumns[i] = AddEscape(needUpdateColumns[i], dbType) + } + return needUpdateColumns +} + +func (b *baseExecutor) containsPKByName(meta *types.TableMeta, columns []string) bool { + pkColumnNameList := meta.GetPrimaryKeyOnlyName() + if len(pkColumnNameList) == 0 { + return false + } + + matchCounter := 0 + for _, column := range columns { + for _, pkName := range pkColumnNameList { + if strings.EqualFold(pkName, column) || + strings.EqualFold(pkName, strings.ToLower(column)) { + matchCounter++ + } + } + } + + return matchCounter == len(pkColumnNameList) +} + func getSqlNullValue(value interface{}) interface{} { if value == nil { return nil diff --git a/pkg/datasource/sql/exec/at/insert_executor.go b/pkg/datasource/sql/exec/at/insert_executor.go index a05da5062..ae7bac71d 100644 --- a/pkg/datasource/sql/exec/at/insert_executor.go +++ b/pkg/datasource/sql/exec/at/insert_executor.go @@ -184,9 +184,17 @@ func (i *insertExecutor) buildAfterImageSQL(ctx context.Context) (string, []driv } // build check sql sb := strings.Builder{} - sb.WriteString("SELECT * FROM " + tableName) - whereSQL := i.buildWhereConditionByPKs(pkColumnNameList, len(pkValuesMap[pkColumnNameList[0]]), "mysql", maxInSize) - sb.WriteString(" WHERE " + whereSQL + " ") + suffix := strings.Builder{} + var insertColumns []string + + for _, column := range i.parserCtx.InsertStmt.Columns { + insertColumns = append(insertColumns, column.Name.O) + } + sb.WriteString("SELECT " + strings.Join(i.getNeedColumns(meta, insertColumns, types.DBTypeMySQL), ", ")) + suffix.WriteString(" FROM " + tableName) + whereSQL := i.buildWhereConditionByPKs(pkColumnNameList, rowSize, "mysql", maxInSize) + suffix.WriteString(" WHERE " + whereSQL + " ") + sb.WriteString(suffix.String()) return sb.String(), i.buildPKParams(pkRowImages, pkColumnNameList), nil } diff --git a/pkg/datasource/sql/exec/at/insert_executor_test.go b/pkg/datasource/sql/exec/at/insert_executor_test.go index fa899df11..742249bc4 100644 --- a/pkg/datasource/sql/exec/at/insert_executor_test.go +++ b/pkg/datasource/sql/exec/at/insert_executor_test.go @@ -78,7 +78,7 @@ func TestBuildSelectSQLByInsert(t *testing.T) { }, }, - expectQuery: "SELECT * FROM user WHERE (`id`) IN ((?),(?)) ", + expectQuery: "SELECT id, name FROM user WHERE (`id`) IN ((?),(?)) ", expectQueryArgs: []driver.Value{int64(19), int64(21)}, }, { @@ -107,7 +107,7 @@ func TestBuildSelectSQLByInsert(t *testing.T) { }, }, }, - expectQuery: "SELECT * FROM user WHERE (`user_id`) IN ((?)) ", + expectQuery: "SELECT user_id, name FROM user WHERE (`user_id`) IN ((?)) ", expectQueryArgs: []driver.Value{int64(20)}, }, } From 8ce100621fedcc7ce3bdb4222fe11049e54bbdd4 Mon Sep 17 00:00:00 2001 From: "xinfan.wu" Date: Sat, 21 Dec 2024 15:32:32 +0800 Subject: [PATCH 11/22] refactor: refact getty module (#746) * feat:add more linter * feat:change golangclilint version to 1.57.x to support more linter * feat:adjust lint conf and adjust the code to pass the check * style: format some code; fix: some sql statement or rows was not been closed * feat:close session when send heart beat message failed * refactor: change GettyRemoting from singleton to GettyRemotingClient member * remove rpc client * refactor: complete GettyRemoting refactoring * refactor: change getter name, improve variable naming and remove unused fields * update something * feat:add heart-beat failed retry times * Refactor getty. > > Co-authored-by: marsevilspirit Co-authored-by: solisamicus Co-authored-by: No-SilverBullet * Refactor getty. Co-authored-by: marsevilspirit Co-authored-by: solisamicus Co-authored-by: No-SilverBullet --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> Co-authored-by: SolisAmicus Co-authored-by: marsevilspirit --- pkg/client/client.go | 8 +- pkg/remoting/config/config.go | 2 +- pkg/remoting/getty/getty_client.go | 34 ++++- pkg/remoting/getty/getty_client_test.go | 6 +- pkg/remoting/getty/getty_init.go | 29 ++++ pkg/remoting/getty/getty_remoting.go | 20 +-- pkg/remoting/getty/getty_remoting_test.go | 36 +++-- pkg/remoting/getty/listener.go | 39 ++--- pkg/remoting/getty/rpc_client.go | 138 ------------------ pkg/remoting/getty/session_manager.go | 120 ++++++++++++++- .../client/client_on_response_processor.go | 15 +- 11 files changed, 233 insertions(+), 214 deletions(-) create mode 100644 pkg/remoting/getty/getty_init.go delete mode 100644 pkg/remoting/getty/rpc_client.go diff --git a/pkg/client/client.go b/pkg/client/client.go index 5c1191872..2b3cd38a7 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -62,15 +62,17 @@ func initTmClient(cfg *Config) { }) } -// initRemoting init rpc client +// initRemoting init remoting func initRemoting(cfg *Config) { - getty.InitRpcClient(&cfg.GettyConfig, &remoteConfig.SeataConfig{ + seataConfig := remoteConfig.SeataConfig{ ApplicationID: cfg.ApplicationID, TxServiceGroup: cfg.TxServiceGroup, ServiceVgroupMapping: cfg.ServiceConfig.VgroupMapping, ServiceGrouplist: cfg.ServiceConfig.Grouplist, LoadBalanceType: cfg.GettyConfig.LoadBalanceType, - }) + } + + getty.InitGetty(&cfg.GettyConfig, &seataConfig) } // InitRmClient init client rm client diff --git a/pkg/remoting/config/config.go b/pkg/remoting/config/config.go index 5bb126677..823440c7b 100644 --- a/pkg/remoting/config/config.go +++ b/pkg/remoting/config/config.go @@ -84,7 +84,7 @@ type SeataConfig struct { LoadBalanceType string } -func IniConfig(seataConf *SeataConfig) { +func InitConfig(seataConf *SeataConfig) { seataConfig = seataConf } diff --git a/pkg/remoting/getty/getty_client.go b/pkg/remoting/getty/getty_client.go index 72874b0f9..470f2a4f4 100644 --- a/pkg/remoting/getty/getty_client.go +++ b/pkg/remoting/getty/getty_client.go @@ -35,14 +35,16 @@ var ( ) type GettyRemotingClient struct { - idGenerator *atomic.Uint32 + idGenerator *atomic.Uint32 + gettyRemoting *GettyRemoting } func GetGettyRemotingClient() *GettyRemotingClient { if gettyRemotingClient == nil { onceGettyRemotingClient.Do(func() { gettyRemotingClient = &GettyRemotingClient{ - idGenerator: &atomic.Uint32{}, + idGenerator: &atomic.Uint32{}, + gettyRemoting: newGettyRemoting(), } }) } @@ -63,7 +65,7 @@ func (client *GettyRemotingClient) SendAsyncRequest(msg interface{}) error { Compressor: 0, Body: msg, } - return GetGettyRemotingInstance().SendASync(rpcMessage, nil, client.asyncCallback) + return client.gettyRemoting.SendAsync(rpcMessage, nil, client.asyncCallback) } func (client *GettyRemotingClient) SendAsyncResponse(msgID int32, msg interface{}) error { @@ -74,7 +76,7 @@ func (client *GettyRemotingClient) SendAsyncResponse(msgID int32, msg interface{ Compressor: 0, Body: msg, } - return GetGettyRemotingInstance().SendASync(rpcMessage, nil, nil) + return client.gettyRemoting.SendAsync(rpcMessage, nil, nil) } func (client *GettyRemotingClient) SendSyncRequest(msg interface{}) (interface{}, error) { @@ -85,7 +87,7 @@ func (client *GettyRemotingClient) SendSyncRequest(msg interface{}) (interface{} Compressor: 0, Body: msg, } - return GetGettyRemotingInstance().SendSync(rpcMessage, nil, client.syncCallback) + return client.gettyRemoting.SendSync(rpcMessage, nil, client.syncCallback) } func (g *GettyRemotingClient) asyncCallback(reqMsg message.RpcMessage, respMsg *message.MessageFuture) (interface{}, error) { @@ -96,10 +98,30 @@ func (g *GettyRemotingClient) asyncCallback(reqMsg message.RpcMessage, respMsg * func (g *GettyRemotingClient) syncCallback(reqMsg message.RpcMessage, respMsg *message.MessageFuture) (interface{}, error) { select { case <-gxtime.GetDefaultTimerWheel().After(RpcRequestTimeout): - GetGettyRemotingInstance().RemoveMergedMessageFuture(reqMsg.ID) + g.gettyRemoting.RemoveMergedMessageFuture(reqMsg.ID) log.Errorf("wait resp timeout: %#v", reqMsg) return nil, fmt.Errorf("wait response timeout, request: %#v", reqMsg) case <-respMsg.Done: return respMsg.Response, respMsg.Err } } + +func (client *GettyRemotingClient) GetMergedMessage(msgID int32) *message.MergedWarpMessage { + return client.gettyRemoting.GetMergedMessage(msgID) +} + +func (client *GettyRemotingClient) GetMessageFuture(msgID int32) *message.MessageFuture { + return client.gettyRemoting.GetMessageFuture(msgID) +} + +func (client *GettyRemotingClient) RemoveMessageFuture(msgID int32) { + client.gettyRemoting.RemoveMessageFuture(msgID) +} + +func (client *GettyRemotingClient) RemoveMergedMessageFuture(msgID int32) { + client.gettyRemoting.RemoveMergedMessageFuture(msgID) +} + +func (client *GettyRemotingClient) NotifyRpcMessageResponse(msg message.RpcMessage) { + client.gettyRemoting.NotifyRpcMessageResponse(msg) +} diff --git a/pkg/remoting/getty/getty_client_test.go b/pkg/remoting/getty/getty_client_test.go index a5737283f..e3e5e48d5 100644 --- a/pkg/remoting/getty/getty_client_test.go +++ b/pkg/remoting/getty/getty_client_test.go @@ -40,7 +40,7 @@ func TestGettyRemotingClient_SendSyncRequest(t *testing.T) { }, }, } - gomonkey.ApplyMethod(reflect.TypeOf(GetGettyRemotingInstance()), "SendSync", + gomonkey.ApplyMethod(reflect.TypeOf(GetGettyRemotingClient().gettyRemoting), "SendSync", func(_ *GettyRemoting, msg message.RpcMessage, s getty.Session, callback callbackMethod) (interface{}, error) { return respMsg, nil @@ -52,7 +52,7 @@ func TestGettyRemotingClient_SendSyncRequest(t *testing.T) { // TestGettyRemotingClient_SendAsyncResponse unit test for SendAsyncResponse function func TestGettyRemotingClient_SendAsyncResponse(t *testing.T) { - gomonkey.ApplyMethod(reflect.TypeOf(GetGettyRemotingInstance()), "SendASync", + gomonkey.ApplyMethod(reflect.TypeOf(GetGettyRemotingClient().gettyRemoting), "SendAsync", func(_ *GettyRemoting, msg message.RpcMessage, s getty.Session, callback callbackMethod) error { return nil }) @@ -77,7 +77,7 @@ func TestGettyRemotingClient_SendAsyncRequest(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - gomonkey.ApplyMethod(reflect.TypeOf(GetGettyRemotingInstance()), "SendASync", + gomonkey.ApplyMethod(reflect.TypeOf(GetGettyRemotingClient().gettyRemoting), "SendAsync", func(_ *GettyRemoting, msg message.RpcMessage, s getty.Session, callback callbackMethod) error { return nil }) diff --git a/pkg/remoting/getty/getty_init.go b/pkg/remoting/getty/getty_init.go new file mode 100644 index 000000000..37f716010 --- /dev/null +++ b/pkg/remoting/getty/getty_init.go @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package getty + +import ( + "seata.apache.org/seata-go/pkg/protocol/codec" + "seata.apache.org/seata-go/pkg/remoting/config" +) + +func InitGetty(gettyConfig *config.Config, seataConfig *config.SeataConfig) { + config.InitConfig(seataConfig) + codec.Init() + initSessionManager(gettyConfig) +} diff --git a/pkg/remoting/getty/getty_remoting.go b/pkg/remoting/getty/getty_remoting.go index bd378f64d..3dec63c12 100644 --- a/pkg/remoting/getty/getty_remoting.go +++ b/pkg/remoting/getty/getty_remoting.go @@ -33,11 +33,6 @@ const ( RpcRequestTimeout = 20 * time.Second ) -var ( - gettyRemoting *GettyRemoting - onceGettyRemoting = &sync.Once{} -) - type ( callbackMethod func(reqMsg message.RpcMessage, respMsg *message.MessageFuture) (interface{}, error) GettyRemoting struct { @@ -46,16 +41,11 @@ type ( } ) -func GetGettyRemotingInstance() *GettyRemoting { - if gettyRemoting == nil { - onceGettyRemoting.Do(func() { - gettyRemoting = &GettyRemoting{ - futures: &sync.Map{}, - mergeMsgMap: &sync.Map{}, - } - }) +func newGettyRemoting() *GettyRemoting { + return &GettyRemoting{ + futures: &sync.Map{}, + mergeMsgMap: &sync.Map{}, } - return gettyRemoting } func (g *GettyRemoting) SendSync(msg message.RpcMessage, s getty.Session, callback callbackMethod) (interface{}, error) { @@ -72,7 +62,7 @@ func (g *GettyRemoting) SendSync(msg message.RpcMessage, s getty.Session, callba return result, err } -func (g *GettyRemoting) SendASync(msg message.RpcMessage, s getty.Session, callback callbackMethod) error { +func (g *GettyRemoting) SendAsync(msg message.RpcMessage, s getty.Session, callback callbackMethod) error { if s == nil { s = sessionManager.selectSession(msg) } diff --git a/pkg/remoting/getty/getty_remoting_test.go b/pkg/remoting/getty/getty_remoting_test.go index 8a3e9116e..ef18719f3 100644 --- a/pkg/remoting/getty/getty_remoting_test.go +++ b/pkg/remoting/getty/getty_remoting_test.go @@ -47,14 +47,15 @@ func TestGettyRemoting_GetMessageFuture(t *testing.T) { }, }, } + gettyRemotingClient := GetGettyRemotingClient() for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.messageFuture != nil { - GetGettyRemotingInstance().futures.Store(test.msgID, test.messageFuture) - messageFuture := GetGettyRemotingInstance().GetMessageFuture(test.msgID) + gettyRemotingClient.gettyRemoting.futures.Store(test.msgID, test.messageFuture) + messageFuture := gettyRemotingClient.gettyRemoting.GetMessageFuture(test.msgID) assert.Equal(t, *test.messageFuture, *messageFuture) } else { - messageFuture := GetGettyRemotingInstance().GetMessageFuture(test.msgID) + messageFuture := gettyRemotingClient.gettyRemoting.GetMessageFuture(test.msgID) assert.Empty(t, messageFuture) } }) @@ -78,13 +79,14 @@ func TestGettyRemoting_RemoveMessageFuture(t *testing.T) { }, }, } + gettyRemotingClient := GetGettyRemotingClient() for _, test := range tests { t.Run(test.name, func(t *testing.T) { - GetGettyRemotingInstance().futures.Store(test.msgID, test.messageFuture) - messageFuture := GetGettyRemotingInstance().GetMessageFuture(test.msgID) + gettyRemotingClient.gettyRemoting.futures.Store(test.msgID, test.messageFuture) + messageFuture := gettyRemotingClient.gettyRemoting.GetMessageFuture(test.msgID) assert.Equal(t, messageFuture, test.messageFuture) - GetGettyRemotingInstance().RemoveMessageFuture(test.msgID) - messageFuture = GetGettyRemotingInstance().GetMessageFuture(test.msgID) + gettyRemotingClient.gettyRemoting.RemoveMessageFuture(test.msgID) + messageFuture = gettyRemotingClient.gettyRemoting.GetMessageFuture(test.msgID) assert.Empty(t, messageFuture) }) } @@ -110,14 +112,15 @@ func TestGettyRemoting_GetMergedMessage(t *testing.T) { }, }, } + gettyRemotingClient := GetGettyRemotingClient() for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.mergedWarpMessage != nil { - GetGettyRemotingInstance().mergeMsgMap.Store(test.msgID, test.mergedWarpMessage) - mergedWarpMessage := GetGettyRemotingInstance().GetMergedMessage(test.msgID) + gettyRemotingClient.gettyRemoting.mergeMsgMap.Store(test.msgID, test.mergedWarpMessage) + mergedWarpMessage := gettyRemotingClient.gettyRemoting.GetMergedMessage(test.msgID) assert.Equal(t, *test.mergedWarpMessage, *mergedWarpMessage) } else { - mergedWarpMessage := GetGettyRemotingInstance().GetMessageFuture(test.msgID) + mergedWarpMessage := gettyRemotingClient.gettyRemoting.GetMessageFuture(test.msgID) assert.Empty(t, mergedWarpMessage) } }) @@ -144,18 +147,19 @@ func TestGettyRemoting_RemoveMergedMessageFuture(t *testing.T) { }, }, } + gettyRemotingClient := GetGettyRemotingClient() for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.mergedWarpMessage != nil { - GetGettyRemotingInstance().mergeMsgMap.Store(test.msgID, test.mergedWarpMessage) - mergedWarpMessage := GetGettyRemotingInstance().GetMergedMessage(test.msgID) + gettyRemotingClient.gettyRemoting.mergeMsgMap.Store(test.msgID, test.mergedWarpMessage) + mergedWarpMessage := gettyRemotingClient.gettyRemoting.GetMergedMessage(test.msgID) assert.NotEmpty(t, mergedWarpMessage) - GetGettyRemotingInstance().RemoveMergedMessageFuture(test.msgID) - mergedWarpMessage = GetGettyRemotingInstance().GetMergedMessage(test.msgID) + gettyRemotingClient.gettyRemoting.RemoveMergedMessageFuture(test.msgID) + mergedWarpMessage = gettyRemotingClient.gettyRemoting.GetMergedMessage(test.msgID) assert.Empty(t, mergedWarpMessage) } else { - GetGettyRemotingInstance().RemoveMergedMessageFuture(test.msgID) - mergedWarpMessage := GetGettyRemotingInstance().GetMergedMessage(test.msgID) + gettyRemotingClient.gettyRemoting.RemoveMergedMessageFuture(test.msgID) + mergedWarpMessage := gettyRemotingClient.gettyRemoting.GetMergedMessage(test.msgID) assert.Empty(t, mergedWarpMessage) } }) diff --git a/pkg/remoting/getty/listener.go b/pkg/remoting/getty/listener.go index 2f2e97489..09886c3a7 100644 --- a/pkg/remoting/getty/listener.go +++ b/pkg/remoting/getty/listener.go @@ -38,22 +38,16 @@ var ( ) type gettyClientHandler struct { - idGenerator *atomic.Uint32 - msgFutures *sync.Map - mergeMsgMap *sync.Map - sessionManager *SessionManager - processorMap map[message.MessageType]processor.RemotingProcessor + idGenerator *atomic.Uint32 + processorMap map[message.MessageType]processor.RemotingProcessor } func GetGettyClientHandlerInstance() *gettyClientHandler { if clientHandler == nil { onceClientHandler.Do(func() { clientHandler = &gettyClientHandler{ - idGenerator: &atomic.Uint32{}, - msgFutures: &sync.Map{}, - mergeMsgMap: &sync.Map{}, - sessionManager: sessionManager, - processorMap: make(map[message.MessageType]processor.RemotingProcessor, 0), + idGenerator: &atomic.Uint32{}, + processorMap: make(map[message.MessageType]processor.RemotingProcessor, 0), } }) } @@ -62,7 +56,7 @@ func GetGettyClientHandlerInstance() *gettyClientHandler { func (g *gettyClientHandler) OnOpen(session getty.Session) error { log.Infof("Open new getty session ") - g.sessionManager.registerSession(session) + sessionManager.registerSession(session) conf := config.GetSeataConfig() go func() { request := message.RegisterTMRequest{AbstractIdentifyRequest: message.AbstractIdentifyRequest{ @@ -73,7 +67,7 @@ func (g *gettyClientHandler) OnOpen(session getty.Session) error { err := GetGettyRemotingClient().SendAsyncRequest(request) if err != nil { log.Errorf("OnOpen error: {%#v}", err.Error()) - g.sessionManager.releaseSession(session) + sessionManager.releaseSession(session) return } }() @@ -83,12 +77,12 @@ func (g *gettyClientHandler) OnOpen(session getty.Session) error { func (g *gettyClientHandler) OnError(session getty.Session, err error) { log.Infof("session{%s} got error{%v}, will be closed.", session.Stat(), err) - g.sessionManager.releaseSession(session) + sessionManager.releaseSession(session) } func (g *gettyClientHandler) OnClose(session getty.Session) { log.Infof("session{%s} is closing......", session.Stat()) - g.sessionManager.releaseSession(session) + sessionManager.releaseSession(session) } func (g *gettyClientHandler) OnMessage(session getty.Session, pkg interface{}) { @@ -117,8 +111,19 @@ func (g *gettyClientHandler) OnCron(session getty.Session) { log.Debug("session{%s} Oncron executing", session.Stat()) err := g.transferHeartBeat(session, message.HeartBeatMessagePing) if err != nil { - log.Errorf("failed to send heart beat: {%#v}", err.Error()) - g.sessionManager.releaseSession(session) + log.Warnf("failed to send heart beat: {%#v}", err.Error()) + if session.GetAttribute(heartBeatRetryTimesKey) != nil { + retryTimes := session.GetAttribute(heartBeatRetryTimesKey).(int) + if retryTimes >= maxHeartBeatRetryTimes { + log.Warnf("heartbeat retry times exceed default max retry times{%d}, close the session{%s}", + maxHeartBeatRetryTimes, session.Stat()) + sessionManager.releaseSession(session) + return + } + session.SetAttribute(heartBeatRetryTimesKey, retryTimes+1) + } else { + session.SetAttribute(heartBeatRetryTimesKey, 1) + } } } @@ -130,7 +135,7 @@ func (g *gettyClientHandler) transferHeartBeat(session getty.Session, msg messag Compressor: 0, Body: msg, } - return GetGettyRemotingInstance().SendASync(rpcMessage, session, nil) + return GetGettyRemotingClient().gettyRemoting.SendAsync(rpcMessage, session, nil) } func (g *gettyClientHandler) RegisterProcessor(msgType message.MessageType, processor processor.RemotingProcessor) { diff --git a/pkg/remoting/getty/rpc_client.go b/pkg/remoting/getty/rpc_client.go deleted file mode 100644 index 17b6cec3e..000000000 --- a/pkg/remoting/getty/rpc_client.go +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package getty - -import ( - "crypto/tls" - "fmt" - "net" - "sync" - - getty "github.com/apache/dubbo-getty" - gxsync "github.com/dubbogo/gost/sync" - - "seata.apache.org/seata-go/pkg/discovery" - "seata.apache.org/seata-go/pkg/protocol/codec" - "seata.apache.org/seata-go/pkg/remoting/config" - "seata.apache.org/seata-go/pkg/util/log" -) - -type RpcClient struct { - gettyConf *config.Config - seataConf *config.SeataConfig - gettyClients []getty.Client - futures *sync.Map -} - -func InitRpcClient(gettyConfig *config.Config, seataConfig *config.SeataConfig) { - config.IniConfig(seataConfig) - rpcClient := &RpcClient{ - gettyConf: gettyConfig, - seataConf: seataConfig, - gettyClients: make([]getty.Client, 0), - } - codec.Init() - rpcClient.init() -} - -func (c *RpcClient) init() { - addressList := c.getAvailServerList() - if len(addressList) == 0 { - log.Warn("no have valid seata server list") - } - for _, address := range addressList { - gettyClient := getty.NewTCPClient( - getty.WithServerAddress(fmt.Sprintf("%s:%d", address.Addr, address.Port)), - // todo if read c.gettyConf.ConnectionNum, will cause the connect to fail - getty.WithConnectionNumber(1), - getty.WithReconnectInterval(c.gettyConf.ReconnectInterval), - getty.WithClientTaskPool(gxsync.NewTaskPoolSimple(0)), - ) - go gettyClient.RunEventLoop(c.newSession) - // c.gettyClients = append(c.gettyClients, gettyClient) - } -} - -func (c *RpcClient) getAvailServerList() []*discovery.ServiceInstance { - registryService := discovery.GetRegistry() - instances, err := registryService.Lookup(c.seataConf.TxServiceGroup) - if err != nil { - return nil - } - return instances -} - -func (c *RpcClient) newSession(session getty.Session) error { - var ( - ok bool - tcpConn *net.TCPConn - err error - ) - - if c.gettyConf.SessionConfig.CompressEncoding { - session.SetCompressType(getty.CompressZip) - } - if _, ok = session.Conn().(*tls.Conn); ok { - c.setSessionConfig(session) - log.Debugf("server accepts new tls session:%s\n", session.Stat()) - return nil - } - if _, ok = session.Conn().(*net.TCPConn); !ok { - panic(fmt.Sprintf("%s, session.conn{%#v} is not a tcp connection\n", session.Stat(), session.Conn())) - } - - if _, ok = session.Conn().(*tls.Conn); !ok { - if tcpConn, ok = session.Conn().(*net.TCPConn); !ok { - return fmt.Errorf("%s, session.conn{%#v} is not tcp connection", session.Stat(), session.Conn()) - } - - if err = tcpConn.SetNoDelay(c.gettyConf.SessionConfig.TCPNoDelay); err != nil { - return err - } - if err = tcpConn.SetKeepAlive(c.gettyConf.SessionConfig.TCPKeepAlive); err != nil { - return err - } - if c.gettyConf.SessionConfig.TCPKeepAlive { - if err = tcpConn.SetKeepAlivePeriod(c.gettyConf.SessionConfig.KeepAlivePeriod); err != nil { - return err - } - } - if err = tcpConn.SetReadBuffer(c.gettyConf.SessionConfig.TCPRBufSize); err != nil { - return err - } - if err = tcpConn.SetWriteBuffer(c.gettyConf.SessionConfig.TCPWBufSize); err != nil { - return err - } - } - - c.setSessionConfig(session) - log.Debugf("rpc_client new session:%s\n", session.Stat()) - - return nil -} - -func (c *RpcClient) setSessionConfig(session getty.Session) { - session.SetName(c.gettyConf.SessionConfig.SessionName) - session.SetMaxMsgLen(c.gettyConf.SessionConfig.MaxMsgLen) - session.SetPkgHandler(rpcPkgHandler) - session.SetEventListener(GetGettyClientHandlerInstance()) - session.SetReadTimeout(c.gettyConf.SessionConfig.TCPReadTimeout) - session.SetWriteTimeout(c.gettyConf.SessionConfig.TCPWriteTimeout) - session.SetCronPeriod((int)(c.gettyConf.SessionConfig.CronPeriod.Milliseconds())) - session.SetWaitTime(c.gettyConf.SessionConfig.WaitTimeout) -} diff --git a/pkg/remoting/getty/session_manager.go b/pkg/remoting/getty/session_manager.go index 6a68cf1b1..602fffed0 100644 --- a/pkg/remoting/getty/session_manager.go +++ b/pkg/remoting/getty/session_manager.go @@ -18,38 +18,142 @@ package getty import ( + "crypto/tls" + "fmt" + "net" "reflect" "sync" "sync/atomic" "time" getty "github.com/apache/dubbo-getty" + gxsync "github.com/dubbogo/gost/sync" + "seata.apache.org/seata-go/pkg/discovery" "seata.apache.org/seata-go/pkg/protocol/message" "seata.apache.org/seata-go/pkg/remoting/config" "seata.apache.org/seata-go/pkg/remoting/loadbalance" + "seata.apache.org/seata-go/pkg/util/log" ) const ( - maxCheckAliveRetry = 600 - checkAliveInternal = 100 + maxCheckAliveRetry = 600 + checkAliveInternal = 100 + heartBeatRetryTimesKey = "heartbeat-retry-times" + maxHeartBeatRetryTimes = 3 ) -var sessionManager = newSessionManager() +var ( + sessionManager *SessionManager + onceSessionManager = &sync.Once{} +) type SessionManager struct { // serverAddress -> rpc_client.Session -> bool serverSessions sync.Map allSessions sync.Map sessionSize int32 + gettyConf *config.Config +} + +func initSessionManager(gettyConfig *config.Config) { + if sessionManager == nil { + onceSessionManager.Do(func() { + sessionManager = &SessionManager{ + allSessions: sync.Map{}, + serverSessions: sync.Map{}, + gettyConf: gettyConfig, + } + sessionManager.init() + }) + } } -func newSessionManager() *SessionManager { - return &SessionManager{ - allSessions: sync.Map{}, - // serverAddress -> rpc_client.Session -> bool - serverSessions: sync.Map{}, +func (g *SessionManager) init() { + addressList := g.getAvailServerList() + if len(addressList) == 0 { + log.Warn("no have valid seata server list") + } + for _, address := range addressList { + gettyClient := getty.NewTCPClient( + getty.WithServerAddress(fmt.Sprintf("%s:%d", address.Addr, address.Port)), + // todo if read c.gettyConf.ConnectionNum, will cause the connect to fail + getty.WithConnectionNumber(1), + getty.WithReconnectInterval(g.gettyConf.ReconnectInterval), + getty.WithClientTaskPool(gxsync.NewTaskPoolSimple(0)), + ) + go gettyClient.RunEventLoop(g.newSession) + } +} + +func (g *SessionManager) getAvailServerList() []*discovery.ServiceInstance { + registryService := discovery.GetRegistry() + instances, err := registryService.Lookup(config.GetSeataConfig().TxServiceGroup) + if err != nil { + return nil + } + return instances +} + +func (g *SessionManager) setSessionConfig(session getty.Session) { + session.SetName(g.gettyConf.SessionConfig.SessionName) + session.SetMaxMsgLen(g.gettyConf.SessionConfig.MaxMsgLen) + session.SetPkgHandler(rpcPkgHandler) + session.SetEventListener(GetGettyClientHandlerInstance()) + session.SetReadTimeout(g.gettyConf.SessionConfig.TCPReadTimeout) + session.SetWriteTimeout(g.gettyConf.SessionConfig.TCPWriteTimeout) + session.SetCronPeriod((int)(g.gettyConf.SessionConfig.CronPeriod.Milliseconds())) + session.SetWaitTime(g.gettyConf.SessionConfig.WaitTimeout) + session.SetAttribute(heartBeatRetryTimesKey, 0) +} + +func (g *SessionManager) newSession(session getty.Session) error { + var ( + ok bool + tcpConn *net.TCPConn + err error + ) + + if g.gettyConf.SessionConfig.CompressEncoding { + session.SetCompressType(getty.CompressZip) } + if _, ok = session.Conn().(*tls.Conn); ok { + g.setSessionConfig(session) + log.Debugf("server accepts new tls session:%s\n", session.Stat()) + return nil + } + if _, ok = session.Conn().(*net.TCPConn); !ok { + panic(fmt.Sprintf("%s, session.conn{%#v} is not a tcp connection\n", session.Stat(), session.Conn())) + } + + if _, ok = session.Conn().(*tls.Conn); !ok { + if tcpConn, ok = session.Conn().(*net.TCPConn); !ok { + return fmt.Errorf("%s, session.conn{%#v} is not tcp connection", session.Stat(), session.Conn()) + } + + if err = tcpConn.SetNoDelay(g.gettyConf.SessionConfig.TCPNoDelay); err != nil { + return err + } + if err = tcpConn.SetKeepAlive(g.gettyConf.SessionConfig.TCPKeepAlive); err != nil { + return err + } + if g.gettyConf.SessionConfig.TCPKeepAlive { + if err = tcpConn.SetKeepAlivePeriod(g.gettyConf.SessionConfig.KeepAlivePeriod); err != nil { + return err + } + } + if err = tcpConn.SetReadBuffer(g.gettyConf.SessionConfig.TCPRBufSize); err != nil { + return err + } + if err = tcpConn.SetWriteBuffer(g.gettyConf.SessionConfig.TCPWBufSize); err != nil { + return err + } + } + + g.setSessionConfig(session) + log.Debugf("rpc_client new session:%s\n", session.Stat()) + + return nil } func (g *SessionManager) selectSession(msg interface{}) getty.Session { diff --git a/pkg/remoting/processor/client/client_on_response_processor.go b/pkg/remoting/processor/client/client_on_response_processor.go index 55644b770..ada449614 100644 --- a/pkg/remoting/processor/client/client_on_response_processor.go +++ b/pkg/remoting/processor/client/client_on_response_processor.go @@ -46,27 +46,28 @@ type clientOnResponseProcessor struct{} func (f *clientOnResponseProcessor) Process(ctx context.Context, rpcMessage message.RpcMessage) error { log.Infof("the rm client received clientOnResponse msg %#v from tc server.", rpcMessage) + gettyRemotingClient := getty.GetGettyRemotingClient() if mergedResult, ok := rpcMessage.Body.(message.MergeResultMessage); ok { - mergedMessage := getty.GetGettyRemotingInstance().GetMergedMessage(rpcMessage.ID) + mergedMessage := gettyRemotingClient.GetMergedMessage(rpcMessage.ID) if mergedMessage != nil { for i := 0; i < len(mergedMessage.Msgs); i++ { msgID := mergedMessage.MsgIds[i] - response := getty.GetGettyRemotingInstance().GetMessageFuture(msgID) + response := gettyRemotingClient.GetMessageFuture(msgID) if response != nil { response.Response = mergedResult.Msgs[i] response.Done <- struct{}{} - getty.GetGettyRemotingInstance().RemoveMessageFuture(msgID) + gettyRemotingClient.RemoveMessageFuture(msgID) } } - getty.GetGettyRemotingInstance().RemoveMergedMessageFuture(rpcMessage.ID) + gettyRemotingClient.RemoveMergedMessageFuture(rpcMessage.ID) } return nil } else { // 如果是请求消息,做处理逻辑 - msgFuture := getty.GetGettyRemotingInstance().GetMessageFuture(rpcMessage.ID) + msgFuture := gettyRemotingClient.GetMessageFuture(rpcMessage.ID) if msgFuture != nil { - getty.GetGettyRemotingInstance().NotifyRpcMessageResponse(rpcMessage) - getty.GetGettyRemotingInstance().RemoveMessageFuture(rpcMessage.ID) + gettyRemotingClient.NotifyRpcMessageResponse(rpcMessage) + gettyRemotingClient.RemoveMessageFuture(rpcMessage.ID) } else { if _, ok := rpcMessage.Body.(message.AbstractResultMessage); ok { log.Infof("the rm client received response msg [{}] from tc server.", msgFuture) From cd8588e0909fd6b0f458fb0c3d47ab676e01d672 Mon Sep 17 00:00:00 2001 From: JayLiu <38887641+luky116@users.noreply.github.com> Date: Sat, 21 Dec 2024 17:28:02 +0800 Subject: [PATCH 12/22] fix:Reclaim the heartbeat response message to avoid memory leakage of GettyRemoting.futures (#665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix:回收心跳response消息,以避免GettyRemoting.futures内存泄露 * remove chinese comment --------- Co-authored-by: tanzegen <39859116+tanzegen@users.noreply.github.com> Co-authored-by: Xin Wang --- pkg/remoting/processor/client/client_heart_beat_processon.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/remoting/processor/client/client_heart_beat_processon.go b/pkg/remoting/processor/client/client_heart_beat_processon.go index 0ba2f58cf..c3822c54a 100644 --- a/pkg/remoting/processor/client/client_heart_beat_processon.go +++ b/pkg/remoting/processor/client/client_heart_beat_processon.go @@ -38,5 +38,9 @@ func (f *clientHeartBeatProcessor) Process(ctx context.Context, rpcMessage messa log.Debug("received PONG from {}", ctx) } } + msgFuture := getty.GetGettyRemotingInstance().GetMessageFuture(rpcMessage.ID) + if msgFuture != nil { + getty.GetGettyRemotingInstance().RemoveMessageFuture(rpcMessage.ID) + } return nil } From 14341750a781bccde3ab8f8f27bee7c40ea9a94c Mon Sep 17 00:00:00 2001 From: JayLiu <38887641+luky116@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:40:52 +0800 Subject: [PATCH 13/22] fix: fix heart beat bug (#749) --- pkg/remoting/processor/client/client_heart_beat_processon.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/remoting/processor/client/client_heart_beat_processon.go b/pkg/remoting/processor/client/client_heart_beat_processon.go index c3822c54a..b0ca35187 100644 --- a/pkg/remoting/processor/client/client_heart_beat_processon.go +++ b/pkg/remoting/processor/client/client_heart_beat_processon.go @@ -38,9 +38,9 @@ func (f *clientHeartBeatProcessor) Process(ctx context.Context, rpcMessage messa log.Debug("received PONG from {}", ctx) } } - msgFuture := getty.GetGettyRemotingInstance().GetMessageFuture(rpcMessage.ID) + msgFuture := getty.GetGettyRemotingClient().GetMessageFuture(rpcMessage.ID) if msgFuture != nil { - getty.GetGettyRemotingInstance().RemoveMessageFuture(rpcMessage.ID) + getty.GetGettyRemotingClient().RemoveMessageFuture(rpcMessage.ID) } return nil } From 0b45672c8ac811040a0fce286969cb46ab6a7fc0 Mon Sep 17 00:00:00 2001 From: JayLiu <38887641+luky116@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:49:44 +0800 Subject: [PATCH 14/22] fix: fix gomonkey bug (#743) fix gomonkey bug Co-authored-by: funkye <364176773@qq.com> --- go.mod | 6 +++--- go.sum | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index e35e9966d..457a0fa09 100644 --- a/go.mod +++ b/go.mod @@ -31,9 +31,11 @@ require ( ) require ( - github.com/agiledragon/gomonkey/v2 v2.9.0 + github.com/agiledragon/gomonkey/v2 v2.12.0 + github.com/golang/protobuf v1.5.3 go.etcd.io/etcd/api/v3 v3.5.6 go.etcd.io/etcd/client/v3 v3.5.6 + google.golang.org/protobuf v1.30.0 ) require ( @@ -56,7 +58,6 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/jinzhu/copier v0.3.5 // indirect @@ -90,7 +91,6 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 461c515b4..6deb6be94 100644 --- a/go.sum +++ b/go.sum @@ -54,8 +54,10 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agiledragon/gomonkey/v2 v2.9.0 h1:PDiKKybR596O6FHW+RVSG0Z7uGCBNbmbUXh3uCNQ7Hc= -github.com/agiledragon/gomonkey/v2 v2.9.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= +github.com/agiledragon/gomonkey/v2 v2.11.0 h1:5oxSgA+tC1xuGsrIorR+sYiziYltmJyEZ9qA25b6l5U= +github.com/agiledragon/gomonkey/v2 v2.11.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= +github.com/agiledragon/gomonkey/v2 v2.12.0 h1:ek0dYu9K1rSV+TgkW5LvNNPRWyDZVIxGMCFI6Pz9o38= +github.com/agiledragon/gomonkey/v2 v2.12.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= From af53317c6c49e344d01b57e77ce3700ded24ea63 Mon Sep 17 00:00:00 2001 From: FengZhang Date: Sat, 21 Dec 2024 20:01:03 +0800 Subject: [PATCH 15/22] feat: Implement automatic refresh functionality for TableMetaCache (#739) * support auto refresh table mate cache * fix test * Refactor the code to address the issue of duplicate definitions * Refactor the code to address the issue of duplicate definitions * Refactor the code to address the issue of duplicate definitions * Refactor the code to address the issue of duplicate definitions --------- Co-authored-by: root Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- .../sql/datasource/base/meta_cache.go | 26 ++- .../sql/datasource/base/meta_cache_test.go | 126 ++++++++++++ .../sql/datasource/mysql/meta_cache.go | 6 +- .../sql/datasource/mysql/trigger.go | 12 +- .../sql/datasource/mysql/trigger_test.go | 190 ++++++++++++++++++ pkg/datasource/sql/driver.go | 2 +- .../sql/exec/at/insert_executor_test.go | 8 +- .../sql/exec/at/multi_update_excutor_test.go | 4 +- .../sql/exec/at/update_executor_test.go | 2 +- testdata/meta_cache.go | 53 +++++ 10 files changed, 413 insertions(+), 16 deletions(-) create mode 100644 pkg/datasource/sql/datasource/base/meta_cache_test.go create mode 100644 pkg/datasource/sql/datasource/mysql/trigger_test.go create mode 100644 testdata/meta_cache.go diff --git a/pkg/datasource/sql/datasource/base/meta_cache.go b/pkg/datasource/sql/datasource/base/meta_cache.go index 859157e2b..c4694d8b7 100644 --- a/pkg/datasource/sql/datasource/base/meta_cache.go +++ b/pkg/datasource/sql/datasource/base/meta_cache.go @@ -24,6 +24,8 @@ import ( "sync" "time" + "github.com/go-sql-driver/mysql" + "seata.apache.org/seata-go/pkg/datasource/sql/types" ) @@ -32,7 +34,7 @@ type ( trigger interface { LoadOne(ctx context.Context, dbName string, table string, conn *sql.Conn) (*types.TableMeta, error) - LoadAll() ([]types.TableMeta, error) + LoadAll(ctx context.Context, dbName string, conn *sql.Conn, tables ...string) ([]types.TableMeta, error) } entry struct { @@ -50,10 +52,12 @@ type BaseTableMetaCache struct { cache map[string]*entry cancel context.CancelFunc trigger trigger + db *sql.DB + cfg *mysql.Config } // NewBaseCache -func NewBaseCache(capity int32, expireDuration time.Duration, trigger trigger) *BaseTableMetaCache { +func NewBaseCache(capity int32, expireDuration time.Duration, trigger trigger, db *sql.DB, cfg *mysql.Config) *BaseTableMetaCache { ctx, cancel := context.WithCancel(context.Background()) c := &BaseTableMetaCache{ @@ -64,6 +68,8 @@ func NewBaseCache(capity int32, expireDuration time.Duration, trigger trigger) * cache: map[string]*entry{}, cancel: cancel, trigger: trigger, + cfg: cfg, + db: db, } c.Init(ctx) @@ -82,7 +88,19 @@ func (c *BaseTableMetaCache) Init(ctx context.Context) error { // refresh func (c *BaseTableMetaCache) refresh(ctx context.Context) { f := func() { - v, err := c.trigger.LoadAll() + if c.db == nil || c.cfg == nil || c.cache == nil || len(c.cache) == 0 { + return + } + + tables := make([]string, 0, len(c.cache)) + for table := range c.cache { + tables = append(tables, table) + } + conn, err := c.db.Conn(ctx) + if err != nil { + return + } + v, err := c.trigger.LoadAll(ctx, c.cfg.DBName, conn, tables...) if err != nil { return } @@ -92,7 +110,7 @@ func (c *BaseTableMetaCache) refresh(ctx context.Context) { for i := range v { tm := v[i] - if _, ok := c.cache[tm.TableName]; !ok { + if _, ok := c.cache[tm.TableName]; ok { c.cache[tm.TableName] = &entry{ value: tm, } diff --git a/pkg/datasource/sql/datasource/base/meta_cache_test.go b/pkg/datasource/sql/datasource/base/meta_cache_test.go new file mode 100644 index 000000000..570674e1a --- /dev/null +++ b/pkg/datasource/sql/datasource/base/meta_cache_test.go @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package base + +import ( + "context" + "database/sql" + "sync" + "testing" + "time" + + "github.com/agiledragon/gomonkey/v2" + "github.com/go-sql-driver/mysql" + "github.com/stretchr/testify/assert" + "seata.apache.org/seata-go/pkg/datasource/sql/types" + "seata.apache.org/seata-go/testdata" +) + +var ( + capacity int32 = 1024 + EexpireTime = 15 * time.Minute + tableMetaOnce sync.Once +) + +type mockTrigger struct { +} + +func (m *mockTrigger) LoadOne(ctx context.Context, dbName string, table string, conn *sql.Conn) (*types.TableMeta, error) { + return nil, nil +} + +func (m *mockTrigger) LoadAll(ctx context.Context, dbName string, conn *sql.Conn, tables ...string) ([]types.TableMeta, error) { + return nil, nil +} + +func TestBaseTableMetaCache_refresh(t *testing.T) { + type fields struct { + lock sync.RWMutex + expireDuration time.Duration + capity int32 + size int32 + cache map[string]*entry + cancel context.CancelFunc + trigger trigger + db *sql.DB + cfg *mysql.Config + } + type args struct { + ctx context.Context + } + ctx, cancel := context.WithCancel(context.Background()) + tests := []struct { + name string + fields fields + args args + want types.TableMeta + }{ + {name: "test-1", + 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")}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + connStub := gomonkey.ApplyMethodFunc(tt.fields.db, "Conn", + func(_ context.Context) (*sql.Conn, error) { + return &sql.Conn{}, nil + }) + + defer connStub.Reset() + + loadAllStub := gomonkey.ApplyMethodFunc(tt.fields.trigger, "LoadAll", + func(_ context.Context, _ string, _ *sql.Conn, _ ...string) ([]types.TableMeta, error) { + return []types.TableMeta{tt.want}, nil + }) + + defer loadAllStub.Reset() + + c := &BaseTableMetaCache{ + lock: tt.fields.lock, + expireDuration: tt.fields.expireDuration, + capity: tt.fields.capity, + size: tt.fields.size, + cache: tt.fields.cache, + cancel: tt.fields.cancel, + trigger: tt.fields.trigger, + db: tt.fields.db, + cfg: tt.fields.cfg, + } + go c.refresh(tt.args.ctx) + time.Sleep(time.Second * 3) + + assert.Equal(t, c.cache["test"].value, tt.want) + }) + } +} diff --git a/pkg/datasource/sql/datasource/mysql/meta_cache.go b/pkg/datasource/sql/datasource/mysql/meta_cache.go index 82ac0fbc7..2b0a45ea3 100644 --- a/pkg/datasource/sql/datasource/mysql/meta_cache.go +++ b/pkg/datasource/sql/datasource/mysql/meta_cache.go @@ -24,6 +24,8 @@ import ( "sync" "time" + "github.com/go-sql-driver/mysql" + "seata.apache.org/seata-go/pkg/datasource/sql/datasource/base" "seata.apache.org/seata-go/pkg/datasource/sql/types" ) @@ -39,9 +41,9 @@ type TableMetaCache struct { db *sql.DB } -func NewTableMetaInstance(db *sql.DB) *TableMetaCache { +func NewTableMetaInstance(db *sql.DB, cfg *mysql.Config) *TableMetaCache { tableMetaInstance := &TableMetaCache{ - tableMetaCache: base.NewBaseCache(capacity, EexpireTime, NewMysqlTrigger()), + tableMetaCache: base.NewBaseCache(capacity, EexpireTime, NewMysqlTrigger(), db, cfg), db: db, } return tableMetaInstance diff --git a/pkg/datasource/sql/datasource/mysql/trigger.go b/pkg/datasource/sql/datasource/mysql/trigger.go index 689ad2c73..adbbb2f79 100644 --- a/pkg/datasource/sql/datasource/mysql/trigger.go +++ b/pkg/datasource/sql/datasource/mysql/trigger.go @@ -79,8 +79,16 @@ func (m *mysqlTrigger) LoadOne(ctx context.Context, dbName string, tableName str } // LoadAll -func (m *mysqlTrigger) LoadAll() ([]types.TableMeta, error) { - return []types.TableMeta{}, nil +func (m *mysqlTrigger) LoadAll(ctx context.Context, dbName string, conn *sql.Conn, tables ...string) ([]types.TableMeta, error) { + var tableMetas []types.TableMeta + for _, tableName := range tables { + tableMeta, err := m.LoadOne(ctx, dbName, tableName, conn) + if err != nil { + continue + } + tableMetas = append(tableMetas, *tableMeta) + } + return tableMetas, nil } // getColumnMetas get tableMeta column diff --git a/pkg/datasource/sql/datasource/mysql/trigger_test.go b/pkg/datasource/sql/datasource/mysql/trigger_test.go new file mode 100644 index 000000000..4c8bc8bc9 --- /dev/null +++ b/pkg/datasource/sql/datasource/mysql/trigger_test.go @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package mysql + +import ( + "context" + "database/sql" + "testing" + + "github.com/agiledragon/gomonkey/v2" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "seata.apache.org/seata-go/testdata" + + "seata.apache.org/seata-go/pkg/datasource/sql/mock" + "seata.apache.org/seata-go/pkg/datasource/sql/types" + "seata.apache.org/seata-go/pkg/protocol/branch" + "seata.apache.org/seata-go/pkg/rm" +) + +func initMockIndexMeta() []types.IndexMeta { + return []types.IndexMeta{ + { + IType: types.IndexTypePrimaryKey, + ColumnName: "id", + Columns: []types.ColumnMeta{ + { + ColumnName: "id", + DatabaseType: types.GetSqlDataType("BIGINT"), + }, + }, + }, + } +} + +func initMockColumnMeta() []types.ColumnMeta { + return []types.ColumnMeta{ + { + ColumnName: "id", + }, + { + ColumnName: "name", + }, + } +} + +func initGetIndexesStub(m *mysqlTrigger, indexMeta []types.IndexMeta) *gomonkey.Patches { + getIndexesStub := gomonkey.ApplyPrivateMethod(m, "getIndexes", + func(_ *mysqlTrigger, ctx context.Context, dbName string, tableName string, conn *sql.Conn) ([]types.IndexMeta, error) { + return indexMeta, nil + }) + return getIndexesStub +} + +func initGetColumnMetasStub(m *mysqlTrigger, columnMeta []types.ColumnMeta) *gomonkey.Patches { + getColumnMetasStub := gomonkey.ApplyPrivateMethod(m, "getColumnMetas", + func(_ *mysqlTrigger, ctx context.Context, dbName string, table string, conn *sql.Conn) ([]types.ColumnMeta, error) { + return columnMeta, nil + }) + return getColumnMetasStub +} + +func Test_mysqlTrigger_LoadOne(t *testing.T) { + wantTableMeta := testdata.MockWantTypesMeta("test") + type args struct { + ctx context.Context + dbName string + tableName string + conn *sql.Conn + } + tests := []struct { + name string + args args + columnMeta []types.ColumnMeta + indexMeta []types.IndexMeta + wantTableMeta *types.TableMeta + }{ + { + name: "1", + args: args{ctx: context.Background(), dbName: "dbName", tableName: "test", conn: nil}, + indexMeta: initMockIndexMeta(), + columnMeta: initMockColumnMeta(), + wantTableMeta: &wantTableMeta, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &mysqlTrigger{} + + getColumnMetasStub := initGetColumnMetasStub(m, tt.columnMeta) + defer getColumnMetasStub.Reset() + + getIndexesStub := initGetIndexesStub(m, tt.indexMeta) + defer getIndexesStub.Reset() + + got, err := m.LoadOne(tt.args.ctx, tt.args.dbName, tt.args.tableName, tt.args.conn) + if err != nil { + t.Errorf("LoadOne() error = %v", err) + return + } + + assert.Equal(t, tt.wantTableMeta, got) + }) + } +} + +func initMockResourceManager(branchType branch.BranchType, ctrl *gomock.Controller) *mock.MockDataSourceManager { + mockResourceMgr := mock.NewMockDataSourceManager(ctrl) + mockResourceMgr.SetBranchType(branchType) + mockResourceMgr.EXPECT().BranchRegister(gomock.Any(), gomock.Any()).AnyTimes().Return(int64(0), nil) + rm.GetRmCacheInstance().RegisterResourceManager(mockResourceMgr) + mockResourceMgr.EXPECT().RegisterResource(gomock.Any()).AnyTimes().Return(nil) + mockResourceMgr.EXPECT().CreateTableMetaCache(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(nil, nil) + return mockResourceMgr +} + +func Test_mysqlTrigger_LoadAll(t *testing.T) { + sql.Register("seata-at-mysql", &mock.MockTestDriver{}) + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockMgr := initMockResourceManager(branch.BranchTypeAT, ctrl) + _ = mockMgr + + conn := sql.Conn{} + type args struct { + ctx context.Context + dbName string + conn *sql.Conn + tables []string + } + tests := []struct { + name string + args args + columnMeta []types.ColumnMeta + indexMeta []types.IndexMeta + want []types.TableMeta + }{ + { + name: "test-01", + args: args{ + ctx: nil, + dbName: "dbName", + conn: &conn, + tables: []string{ + "test_01", + "test_02", + }, + }, + indexMeta: initMockIndexMeta(), + columnMeta: initMockColumnMeta(), + want: []types.TableMeta{testdata.MockWantTypesMeta("test_01"), testdata.MockWantTypesMeta("test_02")}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &mysqlTrigger{} + + getColumnMetasStub := initGetColumnMetasStub(m, tt.columnMeta) + defer getColumnMetasStub.Reset() + + getIndexesStub := initGetIndexesStub(m, tt.indexMeta) + defer getIndexesStub.Reset() + + got, err := m.LoadAll(tt.args.ctx, tt.args.dbName, tt.args.conn, tt.args.tables...) + if err != nil { + t.Errorf("LoadAll() error = %v", err) + return + } + + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/datasource/sql/driver.go b/pkg/datasource/sql/driver.go index a4b511100..905d81d39 100644 --- a/pkg/datasource/sql/driver.go +++ b/pkg/datasource/sql/driver.go @@ -155,7 +155,7 @@ func (d *seataDriver) getOpenConnectorProxy(connector driver.Connector, dbType t log.Errorf("create new resource: %w", err) return nil, err } - datasource.RegisterTableCache(types.DBTypeMySQL, mysql2.NewTableMetaInstance(db)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql2.NewTableMetaInstance(db, cfg)) if err = datasource.GetDataSourceManager(d.branchType).RegisterResource(res); err != nil { log.Errorf("regisiter resource: %w", err) return nil, err diff --git a/pkg/datasource/sql/exec/at/insert_executor_test.go b/pkg/datasource/sql/exec/at/insert_executor_test.go index 742249bc4..ecf37392c 100644 --- a/pkg/datasource/sql/exec/at/insert_executor_test.go +++ b/pkg/datasource/sql/exec/at/insert_executor_test.go @@ -114,7 +114,7 @@ func TestBuildSelectSQLByInsert(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string) (*types.TableMeta, error) { return &test.metaData, nil @@ -629,7 +629,7 @@ func TestMySQLInsertUndoLogBuilder_getPkValuesByColumn(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string) (*types.TableMeta, error) { return &tt.args.meta, nil @@ -731,7 +731,7 @@ func TestMySQLInsertUndoLogBuilder_getPkValuesByAuto(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string) (*types.TableMeta, error) { return &tt.args.meta, nil @@ -824,7 +824,7 @@ func TestMySQLInsertUndoLogBuilder_autoGeneratePks(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string) (*types.TableMeta, error) { return &tt.args.meta, nil diff --git a/pkg/datasource/sql/exec/at/multi_update_excutor_test.go b/pkg/datasource/sql/exec/at/multi_update_excutor_test.go index 9207346dd..21ef2e309 100644 --- a/pkg/datasource/sql/exec/at/multi_update_excutor_test.go +++ b/pkg/datasource/sql/exec/at/multi_update_excutor_test.go @@ -34,7 +34,7 @@ import ( func TestBuildSelectSQLByMultiUpdate(t *testing.T) { undo.InitUndoConfig(undo.Config{OnlyCareUpdateColumns: true}) - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) tests := []struct { name string @@ -101,7 +101,7 @@ func TestBuildSelectSQLByMultiUpdate(t *testing.T) { func TestBuildSelectSQLByMultiUpdateAllColumns(t *testing.T) { undo.InitUndoConfig(undo.Config{OnlyCareUpdateColumns: false}) - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) tests := []struct { name string diff --git a/pkg/datasource/sql/exec/at/update_executor_test.go b/pkg/datasource/sql/exec/at/update_executor_test.go index 770f21688..a6ffc9bef 100644 --- a/pkg/datasource/sql/exec/at/update_executor_test.go +++ b/pkg/datasource/sql/exec/at/update_executor_test.go @@ -38,7 +38,7 @@ import ( func TestBuildSelectSQLByUpdate(t *testing.T) { undo.InitUndoConfig(undo.Config{OnlyCareUpdateColumns: true}) - datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil)) + datasource.RegisterTableCache(types.DBTypeMySQL, mysql.NewTableMetaInstance(nil, nil)) stub := gomonkey.ApplyMethod(reflect.TypeOf(datasource.GetTableCache(types.DBTypeMySQL)), "GetTableMeta", func(_ *mysql.TableMetaCache, ctx context.Context, dbName, tableName string) (*types.TableMeta, error) { return &types.TableMeta{ diff --git a/testdata/meta_cache.go b/testdata/meta_cache.go new file mode 100644 index 000000000..38c2e6433 --- /dev/null +++ b/testdata/meta_cache.go @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package testdata + +import "seata.apache.org/seata-go/pkg/datasource/sql/types" + +func MockWantTypesMeta(tableName string) types.TableMeta { + return types.TableMeta{ + TableName: tableName, + Columns: map[string]types.ColumnMeta{ + "id": { + ColumnName: "id", + }, + "name": { + ColumnName: "name", + }, + }, + Indexs: map[string]types.IndexMeta{ + "": { + ColumnName: "id", + IType: types.IndexTypePrimaryKey, + Columns: []types.ColumnMeta{ + { + ColumnName: "id", + DatabaseType: types.GetSqlDataType("BIGINT"), + }, + { + ColumnName: "id", + }, + }, + }, + }, + ColumnNames: []string{ + "id", + "name", + }, + } +} From 1b72cb8cb8bb5c5019d478558515d6dc5d168073 Mon Sep 17 00:00:00 2001 From: FinnTew Date: Fri, 27 Dec 2024 23:46:57 +0800 Subject: [PATCH 16/22] optimize: optimize the speed of buildLockKey (#714) * optimize: optimize the speed of buildLockKey * improve unit testing of buildLockKey * fix the situation where primaryKeyValues contains nil value * update the unit test of buildLockKey --------- Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- .../undo/builder/basic_undo_log_builder.go | 46 +++--- .../builder/basic_undo_log_builder_test.go | 139 ++++++++++++++++-- 2 files changed, 152 insertions(+), 33 deletions(-) diff --git a/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go b/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go index 043e7eb44..775cb6199 100644 --- a/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go +++ b/pkg/datasource/sql/undo/builder/basic_undo_log_builder.go @@ -276,35 +276,41 @@ func (b *BasicUndoLogBuilder) buildLockKey(rows driver.Rows, meta types.TableMet // the string as local key. the local key example(multi pk): "t_user:1_a,2_b" func (b *BasicUndoLogBuilder) buildLockKey2(records *types.RecordImage, meta types.TableMeta) string { - var ( - lockKeys bytes.Buffer - filedSequence int - ) + var lockKeys bytes.Buffer lockKeys.WriteString(meta.TableName) lockKeys.WriteString(":") keys := meta.GetPrimaryKeyOnlyName() + keyIndexMap := make(map[string]int, len(keys)) - for _, row := range records.Rows { - if filedSequence > 0 { + for idx, columnName := range keys { + keyIndexMap[columnName] = idx + } + + primaryKeyRows := make([][]interface{}, len(records.Rows)) + + for i, row := range records.Rows { + primaryKeyValues := make([]interface{}, len(keys)) + for _, column := range row.Columns { + if idx, exist := keyIndexMap[column.ColumnName]; exist { + primaryKeyValues[idx] = column.Value + } + } + primaryKeyRows[i] = primaryKeyValues + } + + for i, primaryKeyValues := range primaryKeyRows { + if i > 0 { lockKeys.WriteString(",") } - pkSplitIndex := 0 - for _, column := range row.Columns { - var hasKeyColumn bool - for _, key := range keys { - if column.ColumnName == key { - hasKeyColumn = true - if pkSplitIndex > 0 { - lockKeys.WriteString("_") - } - lockKeys.WriteString(fmt.Sprintf("%v", column.Value)) - pkSplitIndex++ - } + for j, pkVal := range primaryKeyValues { + if j > 0 { + lockKeys.WriteString("_") } - if hasKeyColumn { - filedSequence++ + if pkVal == nil { + continue } + lockKeys.WriteString(fmt.Sprintf("%v", pkVal)) } } diff --git a/pkg/datasource/sql/undo/builder/basic_undo_log_builder_test.go b/pkg/datasource/sql/undo/builder/basic_undo_log_builder_test.go index 152c0a47d..465bf5164 100644 --- a/pkg/datasource/sql/undo/builder/basic_undo_log_builder_test.go +++ b/pkg/datasource/sql/undo/builder/basic_undo_log_builder_test.go @@ -50,22 +50,135 @@ func TestBuildWhereConditionByPKs(t *testing.T) { } func TestBuildLockKey(t *testing.T) { - metaData := types.TableMeta{ - TableName: "test_name", - Indexs: map[string]types.IndexMeta{ - "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{{ColumnName: "id"}, {ColumnName: "userId"}}}, - }, + var builder BasicUndoLogBuilder + + columnID := types.ColumnMeta{ + ColumnName: "id", + } + columnUserId := types.ColumnMeta{ + ColumnName: "userId", + } + columnName := types.ColumnMeta{ + ColumnName: "name", + } + columnAge := types.ColumnMeta{ + ColumnName: "age", } + columnNonExistent := types.ColumnMeta{ + ColumnName: "non_existent", + } + + columnsTwoPk := []types.ColumnMeta{columnID, columnUserId} + columnsMixPk := []types.ColumnMeta{columnName, columnAge} - records := types.RecordImage{ - TableName: "test_name", - Rows: []types.RowImage{ - {Columns: []types.ColumnImage{{KeyType: types.IndexTypePrimaryKey, ColumnName: "id", Value: 1}, {KeyType: types.IndexTypePrimaryKey, ColumnName: "userId", Value: "one"}}}, - {Columns: []types.ColumnImage{{KeyType: types.IndexTypePrimaryKey, ColumnName: "id", Value: 2}, {KeyType: types.IndexTypePrimaryKey, ColumnName: "userId", Value: "two"}}}, + getColumnImage := func(columnName string, value interface{}) types.ColumnImage { + return types.ColumnImage{KeyType: types.IndexTypePrimaryKey, ColumnName: columnName, Value: value} + } + + tests := []struct { + name string + metaData types.TableMeta + records types.RecordImage + expected string + }{ + { + "Two Primary Keys", + types.TableMeta{ + TableName: "test_name", + Indexs: map[string]types.IndexMeta{ + "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: columnsTwoPk}, + }, + }, + types.RecordImage{ + TableName: "test_name", + Rows: []types.RowImage{ + {[]types.ColumnImage{getColumnImage("id", 1), getColumnImage("userId", "one")}}, + {[]types.ColumnImage{getColumnImage("id", 2), getColumnImage("userId", "two")}}, + }, + }, + "test_name:1_one,2_two", + }, + { + name: "Single Primary Key", + metaData: types.TableMeta{ + TableName: "single_key", + Indexs: map[string]types.IndexMeta{ + "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}}, + }, + }, + records: types.RecordImage{ + TableName: "single_key", + Rows: []types.RowImage{ + {Columns: []types.ColumnImage{getColumnImage("id", 100)}}, + }, + }, + expected: "single_key:100", + }, + { + name: "Mixed Type Keys", + metaData: types.TableMeta{ + TableName: "mixed_key", + Indexs: map[string]types.IndexMeta{ + "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: columnsMixPk}, + }, + }, + records: types.RecordImage{ + TableName: "mixed_key", + Rows: []types.RowImage{ + {Columns: []types.ColumnImage{getColumnImage("name", "Alice"), getColumnImage("age", 25)}}, + }, + }, + expected: "mixed_key:Alice_25", + }, + { + name: "Empty Records", + metaData: types.TableMeta{ + TableName: "empty", + Indexs: map[string]types.IndexMeta{ + "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}}, + }, + }, + records: types.RecordImage{TableName: "empty"}, + expected: "empty:", + }, + { + name: "Special Characters", + metaData: types.TableMeta{ + TableName: "special", + Indexs: map[string]types.IndexMeta{ + "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnID}}, + }, + }, + records: types.RecordImage{ + TableName: "special", + Rows: []types.RowImage{ + {Columns: []types.ColumnImage{getColumnImage("id", "a,b_c")}}, + }, + }, + expected: "special:a,b_c", + }, + { + name: "Non-existent Key Name", + metaData: types.TableMeta{ + TableName: "error_key", + Indexs: map[string]types.IndexMeta{ + "PRIMARY_KEY": {IType: types.IndexTypePrimaryKey, Columns: []types.ColumnMeta{columnNonExistent}}, + }, + }, + records: types.RecordImage{ + TableName: "error_key", + Rows: []types.RowImage{ + {Columns: []types.ColumnImage{getColumnImage("id", 1)}}, + }, + }, + expected: "error_key:", }, } - builder := BasicUndoLogBuilder{} - lockKeys := builder.buildLockKey2(&records, metaData) - assert.Equal(t, "test_name:1_one,2_two", lockKeys) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + lockKeys := builder.buildLockKey2(&tt.records, tt.metaData) + assert.Equal(t, tt.expected, lockKeys) + }) + } } From 9aead3033cfbc617de030794ddea9cc97bb0c47c Mon Sep 17 00:00:00 2001 From: FengZhang Date: Fri, 27 Dec 2024 23:47:37 +0800 Subject: [PATCH 17/22] =?UTF-8?q?=E3=80=90WIP=E3=80=91fix:=20xa=20report?= =?UTF-8?q?=20state=20to=20TC=20(#717)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix xa report state to tc Co-authored-by: JayLiu <38887641+luky116@users.noreply.github.com> --- pkg/datasource/sql/conn_xa.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/datasource/sql/conn_xa.go b/pkg/datasource/sql/conn_xa.go index b370845c0..65f42ce97 100644 --- a/pkg/datasource/sql/conn_xa.go +++ b/pkg/datasource/sql/conn_xa.go @@ -181,13 +181,6 @@ func (c *XAConn) createNewTxOnExecIfNeed(ctx context.Context, f func() (types.Ex err error ) - currentAutoCommit := c.autoCommit - if c.txCtx.TransactionMode != types.Local && tm.IsGlobalTx(ctx) && c.autoCommit { - tx, err = c.BeginTx(ctx, driver.TxOptions{Isolation: driver.IsolationLevel(gosql.LevelDefault)}) - if err != nil { - return nil, err - } - } defer func() { recoverErr := recover() if err != nil || recoverErr != nil { @@ -201,6 +194,14 @@ func (c *XAConn) createNewTxOnExecIfNeed(ctx context.Context, f func() (types.Ex } }() + currentAutoCommit := c.autoCommit + if c.txCtx.TransactionMode != types.Local && tm.IsGlobalTx(ctx) && c.autoCommit { + tx, err = c.BeginTx(ctx, driver.TxOptions{Isolation: driver.IsolationLevel(gosql.LevelDefault)}) + if err != nil { + return nil, err + } + } + // execute SQL ret, err := f() if err != nil { @@ -212,7 +213,7 @@ func (c *XAConn) createNewTxOnExecIfNeed(ctx context.Context, f func() (types.Ex } if tx != nil && currentAutoCommit { - if err := c.Commit(ctx); err != nil { + if err = c.Commit(ctx); err != nil { log.Errorf("xa connection proxy commit failure xid:%s, err:%v", c.txCtx.XID, err) // XA End & Rollback if err := c.Rollback(ctx); err != nil { From f2587d29548bec856368224bdb968fe3daa971f5 Mon Sep 17 00:00:00 2001 From: JayLiu <38887641+luky116@users.noreply.github.com> Date: Sat, 4 Jan 2025 14:21:48 +0800 Subject: [PATCH 18/22] doc: add release 2.0.0 note (#752) * add release 2.0.0 note --- CHANGELOG.md | 38 ------------- changes/2.0.0.md | 132 ++++++++++++++++++++++++++++++++++++++++++++ changes/2.0.0_zh.md | 131 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+), 38 deletions(-) delete mode 100644 CHANGELOG.md create mode 100644 changes/2.0.0.md create mode 100644 changes/2.0.0_zh.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index c2ddf8446..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,38 +0,0 @@ -# Release Notes ---- - -## 0.1.0-rc1 - -### feature: - -- [[#1](https://github.com/apache/incubator-seata-go/commit/06b9969bb3fd24071adc271dc543c3eb684070c9)] initialize project structure and support tcc local -- [[#2](https://github.com/apache/incubator-seata-go/commit/80913fa73e38fd3c159dcd28804344b9a87f718c)] add github Actions -- [[#122](https://github.com/apache/incubator-seata-go/pull/122)] feat: add two phase and tcc dubbo -- [[#127](https://github.com/apache/incubator-seata-go/pull/127)] feat: transaction at datasource - -### bugfix: - -- [[#5](https://github.com/apache/incubator-seata-go/commit/48f1b6bf6c8890d649ceac3d048f61695dce2f7a)] fix cli bug -- [[#15](https://github.com/apache/incubator-seata-go/commit/de615531e9d17af66067c54452ee5bce2d670008)] fix branch commit bug -- [[#34](https://github.com/apache/incubator-seata-go/commit/846a3b336194f9d188f07bf6af65f617b0baf489)] style:change bool to struct{} -- [[#130](https://github.com/apache/incubator-seata-go/pull/130)] fix: getty session auto close bug -- [[#155](https://github.com/apache/incubator-seata-go/pull/155)] bugfix: fix rollback response status bug - -### optimize: - -- [[#3](https://github.com/apache/incubator-seata-go/commit/65c2e1ed676a2306eb10f7d43e3bf5b37271ee3e)] adjust the structure of the project -- [[#18](https://github.com/apache/incubator-seata-go/commit/de615531e9d17af66067c54452ee5bce2d670008)] remove goetty -- [[#19](https://github.com/apache/incubator-seata-go/commit/de615531e9d17af66067c54452ee5bce2d670008)] optimize codec code -- [[#125](https://github.com/apache/incubator-seata-go/pull/125)] optimize named for the resource manager api -- [[#165](https://github.com/apache/incubator-seata-go/pull/165)] test: add unit test and labeler workflow - -### test: - -- [[#9f4d8](https://github.com/apache/incubator-seata-go/commit/9f4d8cc0b6f1e26860cded5ab05b504ad6a6d6ff)] add unit test for codec - -### doc: - -- [[#0](https://github.com/apache/incubator-seata-go/commit/fcda132629032321a7cc733a7a2ed02e05c2151b)] hello world -- [[#146](https://github.com/apache/incubator-seata-go/pull/146)] doc: add license -- [[#153](https://github.com/apache/incubator-seata-go/pull/153)] docs: add readme ,contributing and pr template doc -- [[#167](https://github.com/apache/incubator-seata-go/pull/167)] fix typo in reademe diff --git a/changes/2.0.0.md b/changes/2.0.0.md new file mode 100644 index 000000000..5bd3270f3 --- /dev/null +++ b/changes/2.0.0.md @@ -0,0 +1,132 @@ + + +### 2.0.0 + +
+ Release notes + +### Seata-go 2.0.0 + +Seata-go 2.0.0 Released. + +Seata-go is an easy-to-use, high-performance, open source distributed transaction solution. + +The version is updated as follows: + +### feature: + +- [[#659](https://github.com/apache/incubator-seata-go/pull/659)] support compress for AT undo log +- [[#574](https://github.com/apache/incubator-seata-go/pull/574)] support file and nacos service registry +- [[#584](https://github.com/apache/incubator-seata-go/pull/584)] support the ConsistentHash load balancing strategy in the remoting module +- [[#585](https://github.com/apache/incubator-seata-go/pull/585)] support the LeastActive load balancing strategy in the remoting module +- [[#605](https://github.com/apache/incubator-seata-go/pull/605)] support the discovery service of Etcd +- [[#622](https://github.com/apache/incubator-seata-go/pull/622)] add round robin strategy of remote call +- [[#691](https://github.com/apache/incubator-seata-go/pull/691)] support protobuf undo log parser +- [[#738](https://github.com/apache/incubator-seata-go/pull/738)] remove session when send heart beat message failed +- [[#739](https://github.com/apache/incubator-seata-go/pull/739)] support automatic refresh functionality for table meta cache + +### bugfix: + +- [[#540](https://github.com/apache/incubator-seata-go/pull/540)] fix init XA panic bug +- [[#590](https://github.com/apache/incubator-seata-go/pull/590)] fix some repo error +- [[#595](https://github.com/apache/incubator-seata-go/pull/595)] check the response error is nil for commit or rollback +- [[#607](https://github.com/apache/incubator-seata-go/pull/607)] fix the bug of jackson serialize +- [[#665](https://github.com/apache/incubator-seata-go/pull/665)] reclaim the heartbeat response message to avoid memory leakage of GettyRemoting.future +- [[#672](https://github.com/apache/incubator-seata-go/pull/672)] fix AT rollback bug +- [[#674](https://github.com/apache/incubator-seata-go/pull/674)] fix XA rollback bug +- [[#690](https://github.com/apache/incubator-seata-go/pull/690)] fix AT undo log jackson parser not found bug +- [[#701](https://github.com/apache/incubator-seata-go/pull/701)] fix the InsertOnDuplicateUpdate is an issue with bypassing modifying the primary key +- [[#717](https://github.com/apache/incubator-seata-go/pull/717)] support XA report state to TC +- [[#724](https://github.com/apache/incubator-seata-go/pull/724)] support ParenthesesExpr for SQL parser +- [[#736](https://github.com/apache/incubator-seata-go/pull/736)] fix SQL statement not closed's bug +- [[#743](https://github.com/apache/incubator-seata-go/pull/743)] fix bug of gomonkey +- [[#749](https://github.com/apache/incubator-seata-go/pull/749)] fix bug of heart beat + + +### optimize: + +- [[#576](https://github.com/apache/incubator-seata-go/pull/576)] use mirromutth/mysql-action instead of icomponent/mysql-action +- [[#594](https://github.com/apache/incubator-seata-go/pull/594)] optimize the log of branch commit procesor +- [[#621](https://github.com/apache/incubator-seata-go/pull/621)] add codeql for ci +- [[#631](https://github.com/apache/incubator-seata-go/pull/631)] upgrade crypto version from 0.9.0 to 0.17.0 +- [[#652](https://github.com/apache/incubator-seata-go/pull/652)] upgrade gRPC version from 1.51.0 ro 1.56.3 +- [[#667](https://github.com/apache/incubator-seata-go/pull/667)] change mailbox of issues and pull requests from dev to notifications +- [[#678](https://github.com/apache/incubator-seata-go/pull/678)] rename module name to seata.apache.org/seata-go +- [[#679](https://github.com/apache/incubator-seata-go/pull/679)] upgrade getty version from 1.4.9 to 1.4.10 +- [[#714](https://github.com/apache/incubator-seata-go/pull/714)] optimize the speed of build lock key +- [[#719](https://github.com/apache/incubator-seata-go/pull/719)] only save insertd filed when execute insert SQL in AT +- [[#721](https://github.com/apache/incubator-seata-go/pull/721)] fix the issue where the translation bot is not working + +### test: + +- [[#570](https://github.com/apache/incubator-seata-go/pull/570)] add collection unit test +- [[#571](https://github.com/apache/incubator-seata-go/pull/571)] add convert unit test +- [[#572](https://github.com/apache/incubator-seata-go/pull/572)] add reflectx unit test +- [[#5835f0](https://github.com/apache/incubator-seata-go/commit/5835f09ecfd6edeb04c2961163bc4460f578e942)] add random loadbalance unit test +- [[#599](https://github.com/apache/incubator-seata-go/pull/599)] add xid loadbalance unit test + + +### doc: +- [[#614](https://github.com/apache/incubator-seata-go/pull/614)] upgrade the unknown license dependency +- [[#632](https://github.com/apache/incubator-seata-go/pull/632)] add ASF basic config +- [[#633](https://github.com/apache/incubator-seata-go/pull/633)] optimize ASF basic config to remove th context check +- [[#644](https://github.com/apache/incubator-seata-go/pull/644)] optimize readme file +- [[#686](https://github.com/apache/incubator-seata-go/pull/686)] add more linter in ci +- [[#737](https://github.com/apache/incubator-seata-go/pull/737)] modify the readme file and update the currently completed work + + +### contributors: + +Thanks to these contributors for their code commits. Please report an unintended omission. + +- [luky116](https://github.com/luky116) +- [Code-Fight](https://github.com/Code-Fight) +- [wt-better](https://github.com/wt-better) +- [luweiqianyi](https://github.com/luweiqianyi) +- [wang1309](https://github.com/wang1309) +- [576470954](https://github.com/576470954) +- [No-SilverBullet](https://github.com/No-SilverBullet) +- [solisamicus](https://github.com/solisamicus) +- [marsevilspirit](https://github.com/marsevilspirit) +- [lxfeng1997](https://github.com/lxfeng1997) +- [AlexStocks](https://github.com/AlexStocks) +- [smiletrl](https://github.com/smiletrl) +- [ptyin](https://github.com/ptyin) +- [yizhibian](https://github.com/yizhibian) +- [oldmee](https://github.com/oldmee) +- [air-3](https://github.com/air-3) +- [slievrly](https://github.com/slievrly) +- [xjlgod](https://github.com/xjlgod) +- [baerwang](https://github.com/baerwang) +- [xyombo](https://github.com/xyombo) +- [testwill](https://github.com/testwill) +- [jasondeng1997](https://github.com/jasondeng1997) +- [jsbxyyx](https://github.com/jsbxyyx) +- [iSuperCoder](https://github.com/iSuperCoder) +- [georgehao](https://github.com/georgehao) +- [liuyuecai](https://github.com/liuyuecai) +- [106umao](https://github.com/106umao) +- [FinnTew](https://github.com/FinnTew) +- [funky-eyes](https://github.com/funky-eyes) +- [tanzegen](https://github.com/tanzegen) +- [lovepoem](https://github.com/lovepoem) + + +Also, we receive many valuable issues, questions and advices from our community. Thanks all. + + \ No newline at end of file diff --git a/changes/2.0.0_zh.md b/changes/2.0.0_zh.md new file mode 100644 index 000000000..dffbdfd81 --- /dev/null +++ b/changes/2.0.0_zh.md @@ -0,0 +1,131 @@ + + +### 2.0.0 + +
+ 版本变更 + +### Seata-go 2.0.0 + +Seata-go 2.0.0 发布。 + +Seata-go 是一款开源的分布式事务解决方案,提供高性能和简单易用的分布式事务服务。 + +此版本更新如下: + +### feature: + +- [[#574](https://github.com/apache/incubator-seata-go/pull/574)] 支持本地文件类型和 Nacos 类型的注册中心 +- [[#584](https://github.com/apache/incubator-seata-go/pull/584)] 远程调用模块支持 ConsistentHash 负载均衡策略 +- [[#585](https://github.com/apache/incubator-seata-go/pull/585)] 远程调用模块支持 LeastActive 负载均衡策略 +- [[#605](https://github.com/apache/incubator-seata-go/pull/605)] 支持 Etcd 的服务发现 +- [[#622](https://github.com/apache/incubator-seata-go/pull/622)] 远程调用模块增加轮询策略 +- [[#659](https://github.com/apache/incubator-seata-go/pull/659)] 支持 AT undo log 的压缩 +- [[#691](https://github.com/apache/incubator-seata-go/pull/691)] 支持 protobuf 类型的 undo log 解析 +- [[#738](https://github.com/apache/incubator-seata-go/pull/738)] 发送心跳消息失败时移除会话 +- [[#739](https://github.com/apache/incubator-seata-go/pull/739)] 支持表元数据缓存的自动刷新功能 + +### bugfix: + +- [[#540](https://github.com/apache/incubator-seata-go/pull/540)] 修复初始化 XA 时的 bug +- [[#590](https://github.com/apache/incubator-seata-go/pull/590)] 修复一些类型的错误 +- [[#595](https://github.com/apache/incubator-seata-go/pull/595)] 提交或回滚时检查响应错误是否为 nil +- [[#607](https://github.com/apache/incubator-seata-go/pull/607)] 修复 Jackson 序列化的 bug +- [[#665](https://github.com/apache/incubator-seata-go/pull/665)] 回收心跳响应消息,避免 GettyRemoting.future 的内存泄漏 +- [[#672](https://github.com/apache/incubator-seata-go/pull/672)] 修复 AT 回滚的 bug +- [[#674](https://github.com/apache/incubator-seata-go/pull/674)] 修复 XA 回滚的 bug +- [[#690](https://github.com/apache/incubator-seata-go/pull/690)] 修复 AT undo log Jackson 解析器未找到的 bug +- [[#701](https://github.com/apache/incubator-seata-go/pull/701)] 修复 InsertOnDuplicateUpdate 问题,绕过修改主键 +- [[#717](https://github.com/apache/incubator-seata-go/pull/717)] 支持 XA 向 TC 报告状态 +- [[#724](https://github.com/apache/incubator-seata-go/pull/724)] SQL 解析器支持 ParenthesesExpr +- [[#736](https://github.com/apache/incubator-seata-go/pull/736)] 修复 SQL 语句未关闭的 bug +- [[#743](https://github.com/apache/incubator-seata-go/pull/743)] 修复 gomonkey 的 bug +- [[#749](https://github.com/apache/incubator-seata-go/pull/749)] 修复心跳的 bug + + +### optimize: + +- [[#576](https://github.com/apache/incubator-seata-go/pull/576)] 使用 mirromutth/mysql-action 替代 icomponent/mysql-action +- [[#594](https://github.com/apache/incubator-seata-go/pull/594)] 优化 branch commit procesor 的日志 +- [[#621](https://github.com/apache/incubator-seata-go/pull/621)] 为 ci 添加 codeql +- [[#631](https://github.com/apache/incubator-seata-go/pull/631)] 将 crypto 版本从 0.9.0 升级到 0.17.0 +- [[#652](https://github.com/apache/incubator-seata-go/pull/652)] 将 gRPC 版本从 1.51.0 升级到 1.56.3 +- [[#667](https://github.com/apache/incubator-seata-go/pull/667)] 将通知邮箱从 dev 更新为 notifications +- [[#679](https://github.com/apache/incubator-seata-go/pull/679)] 将 getty 版本从 1.4.9 升级到 1.4.10 +- [[#678](https://github.com/apache/incubator-seata-go/pull/678)] 将 module 命名为 seata.apache.org/seata-go +- [[#721](https://github.com/apache/incubator-seata-go/pull/721)] 修复翻译机器人无法工作的问题 +- [[#719](https://github.com/apache/incubator-seata-go/pull/719)] Insert SQL 的 undo log 只保留插入的字段 +- [[#714](https://github.com/apache/incubator-seata-go/pull/714)] 优化构建锁键的速度 + +### test: + +- [[#570](https://github.com/apache/incubator-seata-go/pull/570)] 添加 collecion 的单元测试 +- [[#571](https://github.com/apache/incubator-seata-go/pull/571)] 添加 convert 的单元测试 +- [[#572](https://github.com/apache/incubator-seata-go/pull/572)] 添加 reflectx 的单元测试 +- [[#5835f0](https://github.com/apache/incubator-seata-go/commit/5835f09ecfd6edeb04c2961163bc4460f578e942)] 添加 random loadbalance 的单元测试 +- [[#599](https://github.com/apache/incubator-seata-go/pull/599)] 添加 xid loadbalance 的单元测试 + + +### doc: +- [[#614](https://github.com/apache/incubator-seata-go/pull/614)] 升级未知许可证依赖 +- [[#632](https://github.com/apache/incubator-seata-go/pull/632)] 添加 ASF 配置 +- [[#633](https://github.com/apache/incubator-seata-go/pull/633)] 优化 ASF 配置,移除上下文检查 +- [[#644](https://github.com/apache/incubator-seata-go/pull/644)] 优化 readme 文件 +- [[#686](https://github.com/apache/incubator-seata-go/pull/686)] 在 ci 中添加更多的 linter +- [[#737](https://github.com/apache/incubator-seata-go/pull/737)] 更新 readme 文件中已完成的工作 + + +### contributors: + +非常感谢以下 contributors 的代码贡献。若有无意遗漏,请报告。 + +- [luky116](https://github.com/luky116) +- [Code-Fight](https://github.com/Code-Fight) +- [wt-better](https://github.com/wt-better) +- [luweiqianyi](https://github.com/luweiqianyi) +- [wang1309](https://github.com/wang1309) +- [576470954](https://github.com/576470954) +- [No-SilverBullet](https://github.com/No-SilverBullet) +- [solisamicus](https://github.com/solisamicus) +- [marsevilspirit](https://github.com/marsevilspirit) +- [lxfeng1997](https://github.com/lxfeng1997) +- [AlexStocks](https://github.com/AlexStocks) +- [smiletrl](https://github.com/smiletrl) +- [ptyin](https://github.com/ptyin) +- [yizhibian](https://github.com/yizhibian) +- [oldmee](https://github.com/oldmee) +- [air-3](https://github.com/air-3) +- [slievrly](https://github.com/slievrly) +- [xjlgod](https://github.com/xjlgod) +- [baerwang](https://github.com/baerwang) +- [xyombo](https://github.com/xyombo) +- [testwill](https://github.com/testwill) +- [jasondeng1997](https://github.com/jasondeng1997) +- [jsbxyyx](https://github.com/jsbxyyx) +- [iSuperCoder](https://github.com/iSuperCoder) +- [georgehao](https://github.com/georgehao) +- [liuyuecai](https://github.com/liuyuecai) +- [106umao](https://github.com/106umao) +- [FinnTew](https://github.com/FinnTew) +- [funky-eyes](https://github.com/funky-eyes) +- [tanzegen](https://github.com/tanzegen) +- [lovepoem](https://github.com/lovepoem) + +同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。 + + \ No newline at end of file From 86b8d920d77c9352ed8f232253116c4927e465c3 Mon Sep 17 00:00:00 2001 From: jimin Date: Mon, 6 Jan 2025 23:23:20 +0800 Subject: [PATCH 19/22] optimize: update license checker (#756) * optimize: update license checker --- .github/workflows/license.yml | 21 ++++++---- .licenserc.yaml | 22 ++--------- VERSION | 2 +- go.sum | 2 - licenses/LICENSE.tpl | 9 +++++ .../sql/undo/parser/branch_undo_log.proto | 17 +++++++++ pkg/discovery/etcd3_test.go | 17 +++++++++ pkg/discovery/mock/test_etcd_client.go | 17 +++++++++ testdata/dockercompose/mysql/mysqld.cnf | 38 +++++++------------ testdata/sql/all_in_one.sql | 30 +++++++-------- testdata/sql/undo_log.sql | 15 ++++++++ 11 files changed, 120 insertions(+), 70 deletions(-) create mode 100644 licenses/LICENSE.tpl diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml index 68e83a647..4f3195dd2 100644 --- a/.github/workflows/license.yml +++ b/.github/workflows/license.yml @@ -15,10 +15,11 @@ # limitations under the License. # -name: CI +name: License checker on: pull_request: + branches: [ master ] schedule: - cron: "0 18 * * *" # TimeZone: UTC 0 @@ -33,10 +34,13 @@ jobs: submodules: true - name: Check license header uses: apache/skywalking-eyes@985866ce7e324454f61e22eb2db2e998db09d6f3 + with: + log: info + config: .licenserc.yaml + mode: check dependency-license: name: Dependency licenses - needs: [changes] runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -46,15 +50,16 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: "1.18" + go-version: "1.20" - name: Check Dependencies Licenses run: | + mkdir -p ./dist-material/ + cp ./licenses/LICENSE.tpl ./dist-material/LICENSE.tpl go install github.com/apache/skywalking-eyes/cmd/license-eye@47febf5 - license-eye dependency resolve --summary ./dist-material/release-docs/LICENSE.tpl || exit 1 - if [ ! -z "$(git diff -U0 ./dist-material/release-docs/LICENSE)" ]; then - echo "LICENSE file is not updated correctly" - git diff -U0 ./dist-material/release-docs/LICENSE - exit 1 + license-eye dependency resolve --summary ./dist-material/LICENSE.tpl || exit 1 + if [ -f "./dist-material/LICENSE)" ]; then + echo "echo LICENSE check" + cat ./dist-material/LICENSE fi - name: Check Dependencies Licenses Invalid run: | diff --git a/.licenserc.yaml b/.licenserc.yaml index 23e969673..0bab631fb 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -54,34 +54,20 @@ header: # `header` section is configurations for source codes license header. - '**' paths-ignore: # `paths-ignore` are the path list that will be ignored by license-eye. - - 'dist' + - 'dist-material/**' - 'licenses' - '**/*.md' - - '**/testdata/**' - '**/go.mod' - '**/go.sum' - 'LICENSE' - 'NOTICE' - - '**/assets/header-templates/**' - - '**/assets/lcs-templates/**' - - '**/assets/languages.yaml' - - '**/assets/assets.gen.go' - - 'docs/**.svg' - - '.travis.yml' - '.gitignore' - - '.gitmodules' - 'makefile' - - 'justfile' - - 'docker' - - 'pkg/resolver/mysql/constants.go' # with two license: apache and Vitess - - 'pkg/resolver/mysql/encoding.go' - - 'pkg/resolver/mysql/sql_error.go' - - 'pkg/resolver/mysql/type.go' - 'VERSION' - - ".errcheck-exclude" - - ".golangci.yml" - - '.pre-commit-config.yaml' - '.github' + - 'DISCLAIMER' + - 'pkg/discovery/mock/mock_etcd_client.go' + - 'pkg/datasource/sql/undo/parser/branch_undo_log.pb.go' comment: on-failure # on what condition license-eye will comment on the pull request, `on-failure`, `always`, `never`. language: diff --git a/VERSION b/VERSION index 8a9ecc2ea..359a5b952 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1 \ No newline at end of file +2.0.0 \ No newline at end of file diff --git a/go.sum b/go.sum index 6deb6be94..cd6b4f5b0 100644 --- a/go.sum +++ b/go.sum @@ -54,8 +54,6 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agiledragon/gomonkey/v2 v2.11.0 h1:5oxSgA+tC1xuGsrIorR+sYiziYltmJyEZ9qA25b6l5U= -github.com/agiledragon/gomonkey/v2 v2.11.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/agiledragon/gomonkey/v2 v2.12.0 h1:ek0dYu9K1rSV+TgkW5LvNNPRWyDZVIxGMCFI6Pz9o38= github.com/agiledragon/gomonkey/v2 v2.12.0/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= diff --git a/licenses/LICENSE.tpl b/licenses/LICENSE.tpl new file mode 100644 index 000000000..7ff3ca711 --- /dev/null +++ b/licenses/LICENSE.tpl @@ -0,0 +1,9 @@ +{{.LicenseContent }} +{{ range .Groups }} +======================================================================== +{{.LicenseID}} licenses +======================================================================== +{{range .Deps}} +{{.Name}} {{.Version}} {{.LicenseID}} +{{- end }} +{{ end }} \ No newline at end of file diff --git a/pkg/datasource/sql/undo/parser/branch_undo_log.proto b/pkg/datasource/sql/undo/parser/branch_undo_log.proto index 9055ea10e..56cd39e9b 100644 --- a/pkg/datasource/sql/undo/parser/branch_undo_log.proto +++ b/pkg/datasource/sql/undo/parser/branch_undo_log.proto @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + syntax = "proto3"; package parser; import "google/protobuf/any.proto"; diff --git a/pkg/discovery/etcd3_test.go b/pkg/discovery/etcd3_test.go index 131cd0bb8..7c9c59fbc 100644 --- a/pkg/discovery/etcd3_test.go +++ b/pkg/discovery/etcd3_test.go @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package discovery import ( diff --git a/pkg/discovery/mock/test_etcd_client.go b/pkg/discovery/mock/test_etcd_client.go index d780e0ea8..e7cc5fc08 100644 --- a/pkg/discovery/mock/test_etcd_client.go +++ b/pkg/discovery/mock/test_etcd_client.go @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package mock import "go.etcd.io/etcd/client/v3" diff --git a/testdata/dockercompose/mysql/mysqld.cnf b/testdata/dockercompose/mysql/mysqld.cnf index ba7b3bcb7..b2f2584d4 100644 --- a/testdata/dockercompose/mysql/mysqld.cnf +++ b/testdata/dockercompose/mysql/mysqld.cnf @@ -1,36 +1,24 @@ -# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. +# http://www.apache.org/licenses/LICENSE-2.0 # -# This program is also distributed with certain software (including -# but not limited to OpenSSL) that is licensed under separate terms, -# as designated in a particular file or component or in included license -# documentation. The authors of MySQL hereby grant you an additional -# permission to link the program and your derivative works with the -# separately licensed software that they have included with MySQL. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -# -# The MySQL Server configuration file. -# -# For explanations see -# http://dev.mysql.com/doc/mysql/en/server-system-variables.html [mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql -#log-error = /var/log/mysql/error.log +log-error = /var/log/mysql/error.log # By default we only accept connections from localhost bind-address = 0.0.0.0 # Disabling symbolic-links is recommended to prevent assorted security risks diff --git a/testdata/sql/all_in_one.sql b/testdata/sql/all_in_one.sql index b9a4e30ac..a8374aab3 100644 --- a/testdata/sql/all_in_one.sql +++ b/testdata/sql/all_in_one.sql @@ -1,19 +1,17 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. DROP TABLE IF EXISTS `stock_tbl`; CREATE TABLE `stock_tbl` diff --git a/testdata/sql/undo_log.sql b/testdata/sql/undo_log.sql index 7a00b709d..d975d1da7 100644 --- a/testdata/sql/undo_log.sql +++ b/testdata/sql/undo_log.sql @@ -1,3 +1,18 @@ +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + DROP TABLE IF EXISTS `undo_log`; CREATE TABLE `undo_log` ( From b68f5a4471040d039f40a2c9564722f4bb8b3ce6 Mon Sep 17 00:00:00 2001 From: JayLiu <38887641+luky116@users.noreply.github.com> Date: Mon, 6 Jan 2025 23:29:39 +0800 Subject: [PATCH 20/22] optimize: remove unsed files (#758) remove unsed files --- VERSION | 1 - testdata/dockercompose/docker-compose.yml | 45 ---------- testdata/dockercompose/docker-health-check.sh | 30 ------- testdata/dockercompose/mysql/mysqld.cnf | 25 ------ testdata/dockercompose/mysql/order.sql | 83 ------------------- 5 files changed, 184 deletions(-) delete mode 100644 VERSION delete mode 100644 testdata/dockercompose/docker-compose.yml delete mode 100755 testdata/dockercompose/docker-health-check.sh delete mode 100644 testdata/dockercompose/mysql/mysqld.cnf delete mode 100644 testdata/dockercompose/mysql/order.sql diff --git a/VERSION b/VERSION deleted file mode 100644 index 359a5b952..000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.0.0 \ No newline at end of file diff --git a/testdata/dockercompose/docker-compose.yml b/testdata/dockercompose/docker-compose.yml deleted file mode 100644 index 417f84a07..000000000 --- a/testdata/dockercompose/docker-compose.yml +++ /dev/null @@ -1,45 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -version: '3' -services: - seata-server: - image: seataio/seata-server:1.5.2 - ports: - - "8091:8091" - - "7091:7091" - environment: - - SEATA_PORT=8091 - - STORE_MODE=file - - zookeeper: - image: zookeeper - ports: - - "2181:2181" - restart: on-failure - - mysql: - image: mysql:5.7 - container_name: mysql - environment: - - MYSQL_ROOT_PASSWORD=12345678 - command: --default-authentication-plugin=mysql_native_password --default-time-zone='+08:00' - volumes: - - ./mysql:/docker-entrypoint-initdb.d - - ./mysql/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf - ports: - - "3306:3306" diff --git a/testdata/dockercompose/docker-health-check.sh b/testdata/dockercompose/docker-health-check.sh deleted file mode 100755 index ca7363a74..000000000 --- a/testdata/dockercompose/docker-health-check.sh +++ /dev/null @@ -1,30 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -curl 127.0.0.1:7091 -res=$? -passCode=52 -while [ "$res" != "$passCode" ];do - sleep 5 - curl 127.0.0.1:7091 - res=$? -done - -sleep 5 -curl http://127.0.0.1:7091 -sleep 10 - diff --git a/testdata/dockercompose/mysql/mysqld.cnf b/testdata/dockercompose/mysql/mysqld.cnf deleted file mode 100644 index b2f2584d4..000000000 --- a/testdata/dockercompose/mysql/mysqld.cnf +++ /dev/null @@ -1,25 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -[mysqld] -pid-file = /var/run/mysqld/mysqld.pid -socket = /var/run/mysqld/mysqld.sock -datadir = /var/lib/mysql -log-error = /var/log/mysql/error.log -# By default we only accept connections from localhost -bind-address = 0.0.0.0 -# Disabling symbolic-links is recommended to prevent assorted security risks -symbolic-links=0 diff --git a/testdata/dockercompose/mysql/order.sql b/testdata/dockercompose/mysql/order.sql deleted file mode 100644 index 58464e532..000000000 --- a/testdata/dockercompose/mysql/order.sql +++ /dev/null @@ -1,83 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one or more --- contributor license agreements. See the NOTICE file distributed with --- this work for additional information regarding copyright ownership. --- The ASF licenses this file to You under the Apache License, Version 2.0 --- (the "License"); you may not use this file except in compliance with --- the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. - -CREATE database if NOT EXISTS `seata_client` default character set utf8mb4 collate utf8mb4_unicode_ci; -USE `seata_client`; - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - -CREATE TABLE IF NOT EXISTS `order_tbl` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` varchar(255) DEFAULT NULL, - `commodity_code` varchar(255) DEFAULT NULL, - `count` int(11) DEFAULT '0', - `money` int(11) DEFAULT '0', - `descs` varchar(255) DEFAULT '', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `seata_client`.`order_tbl` (`id`, `user_id`, `commodity_code`, `count`, `money`, `descs`) VALUES (1, 'NO-100001', 'C100000', 100, 10, 'init desc'); - -DROP TABLE IF EXISTS `undo_log`; - -CREATE TABLE `undo_log` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `branch_id` bigint NOT NULL, - `xid` varchar(100) NOT NULL, - `context` varchar(128) NOT NULL, - `rollback_info` longblob NOT NULL, - `log_status` int NOT NULL, - `log_created` datetime NOT NULL, - `log_modified` datetime NOT NULL, - `ext` varchar(100) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `idx_unionkey` (`xid`,`branch_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE database if NOT EXISTS `seata_client1` default character set utf8mb4 collate utf8mb4_unicode_ci; -USE `seata_client1`; - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - -CREATE TABLE IF NOT EXISTS `order_tbl` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user_id` varchar(255) DEFAULT NULL, - `commodity_code` varchar(255) DEFAULT NULL, - `count` int(11) DEFAULT '0', - `money` int(11) DEFAULT '0', - `descs` varchar(255) DEFAULT '', - PRIMARY KEY (`id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -INSERT INTO `seata_client1`.`order_tbl` (`id`, `user_id`, `commodity_code`, `count`, `money`, `descs`) VALUES (1, 'NO-100001', 'C100000', 100, 10, 'init desc'); - -DROP TABLE IF EXISTS `undo_log`; - -CREATE TABLE `undo_log` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `branch_id` bigint NOT NULL, - `xid` varchar(100) NOT NULL, - `context` varchar(128) NOT NULL, - `rollback_info` longblob NOT NULL, - `log_status` int NOT NULL, - `log_created` datetime NOT NULL, - `log_modified` datetime NOT NULL, - `ext` varchar(100) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `idx_unionkey` (`xid`,`branch_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file From cf2212a41550649b5b32dc029a608d3746f5de3a Mon Sep 17 00:00:00 2001 From: JayLiu <38887641+luky116@users.noreply.github.com> Date: Sun, 12 Jan 2025 16:05:29 +0800 Subject: [PATCH 21/22] doc: V2.0.2 release updater (#760) update 2.0.0 change log --- changes/2.0.0.md | 2 ++ changes/2.0.0_zh.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/changes/2.0.0.md b/changes/2.0.0.md index 5bd3270f3..e051682aa 100644 --- a/changes/2.0.0.md +++ b/changes/2.0.0.md @@ -71,6 +71,7 @@ The version is updated as follows: - [[#714](https://github.com/apache/incubator-seata-go/pull/714)] optimize the speed of build lock key - [[#719](https://github.com/apache/incubator-seata-go/pull/719)] only save insertd filed when execute insert SQL in AT - [[#721](https://github.com/apache/incubator-seata-go/pull/721)] fix the issue where the translation bot is not working +- [[#758](https://github.com/apache/incubator-seata-go/pull/758)] remove unusen files ### test: @@ -88,6 +89,7 @@ The version is updated as follows: - [[#644](https://github.com/apache/incubator-seata-go/pull/644)] optimize readme file - [[#686](https://github.com/apache/incubator-seata-go/pull/686)] add more linter in ci - [[#737](https://github.com/apache/incubator-seata-go/pull/737)] modify the readme file and update the currently completed work +- [[#756](https://github.com/apache/incubator-seata-go/pull/756)] update license checker ### contributors: diff --git a/changes/2.0.0_zh.md b/changes/2.0.0_zh.md index dffbdfd81..977e910ec 100644 --- a/changes/2.0.0_zh.md +++ b/changes/2.0.0_zh.md @@ -71,6 +71,7 @@ Seata-go 是一款开源的分布式事务解决方案,提供高性能和简 - [[#721](https://github.com/apache/incubator-seata-go/pull/721)] 修复翻译机器人无法工作的问题 - [[#719](https://github.com/apache/incubator-seata-go/pull/719)] Insert SQL 的 undo log 只保留插入的字段 - [[#714](https://github.com/apache/incubator-seata-go/pull/714)] 优化构建锁键的速度 +- [[#758](https://github.com/apache/incubator-seata-go/pull/758)] 移除无用的文件 ### test: @@ -88,6 +89,7 @@ Seata-go 是一款开源的分布式事务解决方案,提供高性能和简 - [[#644](https://github.com/apache/incubator-seata-go/pull/644)] 优化 readme 文件 - [[#686](https://github.com/apache/incubator-seata-go/pull/686)] 在 ci 中添加更多的 linter - [[#737](https://github.com/apache/incubator-seata-go/pull/737)] 更新 readme 文件中已完成的工作 +- [[#756](https://github.com/apache/incubator-seata-go/pull/756)] 添加 license 检查逻辑 ### contributors: From 2878b9f03b885acc5dc04dd52b8f4bc6e8751d49 Mon Sep 17 00:00:00 2001 From: zhangym <40376181+zhangymPerson@users.noreply.github.com> Date: Fri, 24 Jan 2025 11:23:02 +0800 Subject: [PATCH 22/22] optimize: update parser to v0.2.17 (#768) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 457a0fa09..77aca2ac2 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( dubbo.apache.org/dubbo-go/v3 v3.0.4 github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/apache/dubbo-getty v1.5.0 - github.com/arana-db/parser v0.2.5 + github.com/arana-db/parser v0.2.17 github.com/bluele/gcache v0.0.2 github.com/dsnet/compress v0.0.1 github.com/dubbogo/gost v1.13.2 diff --git a/go.sum b/go.sum index cd6b4f5b0..12c2b5334 100644 --- a/go.sum +++ b/go.sum @@ -74,8 +74,8 @@ github.com/apache/dubbo-go-hessian2 v1.11.4 h1:u8spEogpaZ82/k3bmv1PLYnha/wiwsIme github.com/apache/dubbo-go-hessian2 v1.11.4/go.mod h1:QP9Tc0w/B/mDopjusebo/c7GgEfl6Lz8jeuFg8JA6yw= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/arana-db/parser v0.2.5 h1:X7SZUjs52nNkX+PL3wrJVd7+BL4VALIXahX+Bx+pmOQ= -github.com/arana-db/parser v0.2.5/go.mod h1:/XA29bplweWSEAjgoM557ZCzhBilSawUlHcZFjOeDAc= +github.com/arana-db/parser v0.2.17 h1:4wNfSgza2N3pjpwR5jmWLvu4L6Sme6EtoLuZOgwWlsU= +github.com/arana-db/parser v0.2.17/go.mod h1:/XA29bplweWSEAjgoM557ZCzhBilSawUlHcZFjOeDAc= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=