Ver Fonte

修改bug

yjp há 4 meses atrás
pai
commit
c6da093b7d

+ 0 - 1
client/transaction.go

@@ -8,5 +8,4 @@ type Transaction interface {
 	DeleteTx(request *DeleteRequest) (string, error)
 	DeleteBatchTx(request *DeleteBatchRequest) (string, error)
 	UpdateTx(request *UpdateRequest) (string, error)
-	End() error
 }

+ 26 - 1
dpsv1/client.go

@@ -10,7 +10,9 @@ import (
 	"git.sxidc.com/service-supports/dps-sdk/pb/v1/response"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
+	"io"
 	"reflect"
+	"sync"
 	"time"
 )
 
@@ -20,6 +22,7 @@ type Client struct {
 	commandServiceClient    v1.CommandServiceClient
 	queryServiceClient      v1.QueryServiceClient
 	eventQueryServiceClient v1.EventQueryServiceClient
+	transactionMutex        sync.Mutex
 }
 
 func NewClient(address string, databaseID string) (*Client, error) {
@@ -43,6 +46,9 @@ func DestroyClient(client *Client) error {
 		return nil
 	}
 
+	client.transactionMutex.Lock()
+	defer client.transactionMutex.Unlock()
+
 	err := client.conn.Close()
 	if err != nil {
 		return err
@@ -52,7 +58,6 @@ func DestroyClient(client *Client) error {
 	client.conn = nil
 	client.commandServiceClient = nil
 	client.queryServiceClient = nil
-	client = nil
 
 	return nil
 }
@@ -89,6 +94,13 @@ func (c *Client) Transaction(txFunc client.TransactionFunc) error {
 		return err
 	}
 
+	defer func() {
+		innerErr := stream.CloseSend()
+		if innerErr != nil {
+			panic(innerErr)
+		}
+	}()
+
 	err = stream.Send(&request.TransactionOperation{
 		Request: &request.TransactionOperation_TransactionBeginRequest{
 			TransactionBeginRequest: &request.TransactionBeginRequest{DatabaseID: c.databaseID},
@@ -105,6 +117,19 @@ func (c *Client) Transaction(txFunc client.TransactionFunc) error {
 		return err
 	}
 
+	err = stream.Send(&request.TransactionOperation{
+		Request: &request.TransactionOperation_TransactionEndRequest{
+			TransactionEndRequest: &request.TransactionEndRequest{},
+		}})
+	if err != nil {
+		return err
+	}
+
+	_, err = stream.Recv()
+	if err != nil && err != io.EOF {
+		return err
+	}
+
 	return nil
 }
 

+ 35 - 27
dpsv1/transaction.go

@@ -4,7 +4,6 @@ import (
 	"git.sxidc.com/service-supports/dps-sdk/client"
 	"git.sxidc.com/service-supports/dps-sdk/pb/v1"
 	"git.sxidc.com/service-supports/dps-sdk/pb/v1/request"
-	"io"
 )
 
 type Transaction struct {
@@ -13,6 +12,13 @@ type Transaction struct {
 }
 
 func (tx *Transaction) InsertTx(req *client.InsertRequest) (string, error) {
+	tx.client.transactionMutex.Lock()
+	defer tx.client.transactionMutex.Unlock()
+
+	if tx.client.conn == nil {
+		return "", nil
+	}
+
 	var err error
 
 	defer func() {
@@ -52,6 +58,13 @@ func (tx *Transaction) InsertTx(req *client.InsertRequest) (string, error) {
 }
 
 func (tx *Transaction) InsertBatchTx(req *client.InsertBatchRequest) (string, error) {
+	tx.client.transactionMutex.Lock()
+	defer tx.client.transactionMutex.Unlock()
+
+	if tx.client.conn == nil {
+		return "", nil
+	}
+
 	var err error
 
 	defer func() {
@@ -104,6 +117,13 @@ func (tx *Transaction) InsertBatchTx(req *client.InsertBatchRequest) (string, er
 }
 
 func (tx *Transaction) DeleteTx(req *client.DeleteRequest) (string, error) {
+	tx.client.transactionMutex.Lock()
+	defer tx.client.transactionMutex.Unlock()
+
+	if tx.client.conn == nil {
+		return "", nil
+	}
+
 	var err error
 
 	defer func() {
@@ -137,6 +157,13 @@ func (tx *Transaction) DeleteTx(req *client.DeleteRequest) (string, error) {
 }
 
 func (tx *Transaction) DeleteBatchTx(req *client.DeleteBatchRequest) (string, error) {
+	tx.client.transactionMutex.Lock()
+	defer tx.client.transactionMutex.Unlock()
+
+	if tx.client.conn == nil {
+		return "", nil
+	}
+
 	var err error
 
 	defer func() {
@@ -185,6 +212,13 @@ func (tx *Transaction) DeleteBatchTx(req *client.DeleteBatchRequest) (string, er
 }
 
 func (tx *Transaction) UpdateTx(req *client.UpdateRequest) (string, error) {
+	tx.client.transactionMutex.Lock()
+	defer tx.client.transactionMutex.Unlock()
+
+	if tx.client.conn == nil {
+		return "", nil
+	}
+
 	var err error
 
 	defer func() {
@@ -222,29 +256,3 @@ func (tx *Transaction) UpdateTx(req *client.UpdateRequest) (string, error) {
 
 	return txResponse.Statement, nil
 }
-
-func (tx *Transaction) End() error {
-	var err error
-
-	defer func() {
-		innerErr := tx.stream.CloseSend()
-		if innerErr != nil {
-			panic(innerErr)
-		}
-	}()
-
-	err = tx.stream.Send(&request.TransactionOperation{
-		Request: &request.TransactionOperation_TransactionEndRequest{
-			TransactionEndRequest: &request.TransactionEndRequest{},
-		}})
-	if err != nil {
-		return err
-	}
-
-	_, err = tx.stream.Recv()
-	if err != nil && err != io.EOF {
-		return err
-	}
-
-	return nil
-}

+ 0 - 44
instance.go

@@ -2,21 +2,11 @@ package dps
 
 import (
 	"git.sxidc.com/service-supports/dps-sdk/client"
-	"git.sxidc.com/service-supports/fslog"
-	"sync"
 )
 
-var dpsClientMutex sync.Mutex
 var dpsClient client.Client
 
 func InitInstance(address string, clientVersion string, databaseID string) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	c, err := NewClient(address, clientVersion, databaseID)
 	if err != nil {
 		return err
@@ -28,16 +18,11 @@ func InitInstance(address string, clientVersion string, databaseID string) error
 }
 
 func DestroyInstance(clientVersion string, databaseID string) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
 	err := DestroyClient(clientVersion, databaseID)
 	if err != nil {
 		return err
 	}
 
-	dpsClient = nil
-
 	return nil
 }
 
@@ -46,38 +31,9 @@ func AutoMigrate(items ...client.AutoMigrateItem) error {
 		return nil
 	}
 
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	return dpsClient.AutoMigrate(&client.AutoMigrateRequest{Items: items})
 }
 
 func Transaction(txFunc client.TransactionFunc) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	return dpsClient.Transaction(txFunc)
 }
-
-func EndTransaction(tx client.Transaction) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return
-	}
-
-	err := tx.End()
-	if err != nil {
-		fslog.Error("!!!!!!!!! END TRANSACTION" + err.Error() + "!!!!!!!!!")
-		return
-	}
-}

+ 0 - 42
instance_command.go

@@ -6,13 +6,6 @@ import (
 )
 
 func Insert(req *client.InsertRequest, tx client.Transaction) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	var statement string
 	var err error
 
@@ -31,13 +24,6 @@ func Insert(req *client.InsertRequest, tx client.Transaction) error {
 }
 
 func InsertBatch(req *client.InsertBatchRequest, tx client.Transaction) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	var statement string
 	var err error
 
@@ -56,13 +42,6 @@ func InsertBatch(req *client.InsertBatchRequest, tx client.Transaction) error {
 }
 
 func Delete(req *client.DeleteRequest, tx client.Transaction) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	var statement string
 	var err error
 
@@ -81,13 +60,6 @@ func Delete(req *client.DeleteRequest, tx client.Transaction) error {
 }
 
 func DeleteBatch(req *client.DeleteBatchRequest, tx client.Transaction) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	var statement string
 	var err error
 
@@ -106,13 +78,6 @@ func DeleteBatch(req *client.DeleteBatchRequest, tx client.Transaction) error {
 }
 
 func Update(req *client.UpdateRequest, tx client.Transaction) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	var statement string
 	var err error
 
@@ -131,13 +96,6 @@ func Update(req *client.UpdateRequest, tx client.Transaction) error {
 }
 
 func Replay(req *client.ReplayRequest) error {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return nil
-	}
-
 	var statement string
 	var err error
 

+ 0 - 84
instance_event_query.go

@@ -6,13 +6,6 @@ import (
 )
 
 func EventQueryByKeys(req *client.EventQueryByKeysRequest) ([]client.EventInfo, int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return make([]client.EventInfo, 0), 0, nil
-	}
-
 	statement, infos, totalCount, err := dpsClient.EventQueryByKeys(req)
 	if err != nil {
 		return nil, 0, err
@@ -24,13 +17,6 @@ func EventQueryByKeys(req *client.EventQueryByKeysRequest) ([]client.EventInfo,
 }
 
 func CommonEventQuery(req *client.CommonEventQueryRequest) ([]client.EventInfo, int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return make([]client.EventInfo, 0), 0, nil
-	}
-
 	statement, infos, totalCount, err := dpsClient.CommonEventQuery(req)
 	if err != nil {
 		return nil, 0, err
@@ -42,13 +28,6 @@ func CommonEventQuery(req *client.CommonEventQueryRequest) ([]client.EventInfo,
 }
 
 func CountEventByKeys(req *client.CountEventByKeysRequest) (int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return 0, nil
-	}
-
 	statement, count, err := dpsClient.CountEventByKeys(req)
 	if err != nil {
 		return 0, err
@@ -60,13 +39,6 @@ func CountEventByKeys(req *client.CountEventByKeysRequest) (int64, error) {
 }
 
 func CommonCountEvent(req *client.CommonCountEventRequest) (int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return 0, nil
-	}
-
 	statement, count, err := dpsClient.CommonCountEvent(req)
 	if err != nil {
 		return 0, err
@@ -78,13 +50,6 @@ func CommonCountEvent(req *client.CommonCountEventRequest) (int64, error) {
 }
 
 func CheckEventExistByKeys(req *client.CountEventByKeysRequest) (bool, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return false, nil
-	}
-
 	statement, count, err := dpsClient.CountEventByKeys(req)
 	if err != nil {
 		return false, err
@@ -100,13 +65,6 @@ func CheckEventExistByKeys(req *client.CountEventByKeysRequest) (bool, error) {
 }
 
 func CommonCheckEventExist(req *client.CommonCountEventRequest) (bool, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return false, nil
-	}
-
 	statement, count, err := dpsClient.CommonCountEvent(req)
 	if err != nil {
 		return false, err
@@ -122,13 +80,6 @@ func CommonCheckEventExist(req *client.CommonCountEventRequest) (bool, error) {
 }
 
 func EventHistoryQueryByKeys(req *client.EventQueryByKeysRequest) ([]client.EventInfo, int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return make([]client.EventInfo, 0), 0, nil
-	}
-
 	statement, infos, totalCount, err := dpsClient.EventHistoryQueryByKeys(req)
 	if err != nil {
 		return nil, 0, err
@@ -140,13 +91,6 @@ func EventHistoryQueryByKeys(req *client.EventQueryByKeysRequest) ([]client.Even
 }
 
 func CommonEventHistoryQuery(req *client.CommonEventQueryRequest) ([]client.EventInfo, int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return make([]client.EventInfo, 0), 0, nil
-	}
-
 	statement, infos, totalCount, err := dpsClient.CommonEventHistoryQuery(req)
 	if err != nil {
 		return nil, 0, err
@@ -158,13 +102,6 @@ func CommonEventHistoryQuery(req *client.CommonEventQueryRequest) ([]client.Even
 }
 
 func CountEventHistoryByKeys(req *client.CountEventByKeysRequest) (int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return 0, nil
-	}
-
 	statement, count, err := dpsClient.CountEventHistoryByKeys(req)
 	if err != nil {
 		return 0, err
@@ -176,13 +113,6 @@ func CountEventHistoryByKeys(req *client.CountEventByKeysRequest) (int64, error)
 }
 
 func CommonCountEventHistory(req *client.CommonCountEventRequest) (int64, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return 0, nil
-	}
-
 	statement, count, err := dpsClient.CommonCountEventHistory(req)
 	if err != nil {
 		return 0, err
@@ -194,13 +124,6 @@ func CommonCountEventHistory(req *client.CommonCountEventRequest) (int64, error)
 }
 
 func CheckEventHistoryExistByKeys(req *client.CountEventByKeysRequest) (bool, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return false, nil
-	}
-
 	statement, count, err := dpsClient.CountEventHistoryByKeys(req)
 	if err != nil {
 		return false, err
@@ -216,13 +139,6 @@ func CheckEventHistoryExistByKeys(req *client.CountEventByKeysRequest) (bool, er
 }
 
 func CommonCheckEventHistoryExist(req *client.CommonCountEventRequest) (bool, error) {
-	dpsClientMutex.Lock()
-	defer dpsClientMutex.Unlock()
-
-	if dpsClient == nil {
-		return false, nil
-	}
-
 	statement, count, err := dpsClient.CommonCountEventHistory(req)
 	if err != nil {
 		return false, err

+ 922 - 0
test/instance/instance_test.go

@@ -0,0 +1,922 @@
+package instance
+
+import (
+	"fmt"
+	"git.sxidc.com/service-supports/dps-sdk/client"
+	uuid "github.com/satori/go.uuid"
+	"math/rand"
+	"strings"
+	"testing"
+	"time"
+)
+
+func getUUID() string {
+	return uuid.NewV4().String()
+}
+
+func simpleUUID() string {
+	return strings.ReplaceAll(getUUID(), "-", "")
+}
+
+var tableModelDescribe = map[string]string{
+	"ID":       "gorm:\"primary_key;type:varchar(32);comment:id;\"",
+	"Name":     "gorm:\"not null;type:varchar(128);comment:数据库名称;\"",
+	"Time":     "gorm:\"not null;type:timestamp with time zone;comment:数据库时间;\"",
+	"TableNum": "gorm:\"not null;type:integer;comment:数据库表数量;\"",
+}
+
+func TestAutoMigrate(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: "test." + simpleUUID()[0:8],
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		})
+}
+
+func TestTransaction(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id := simpleUUID()
+	name := simpleUUID()
+	now := time.Now().Local()
+	tableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+	newName := simpleUUID()
+	newNow := time.Now().Local()
+	newTableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+
+	var count int64
+	resultMap := make(map[string]any)
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		transaction(func(tx client.Transaction) error {
+			statement, err := tx.InsertTx(&client.InsertRequest{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				KeyColumns:            []string{"id"},
+				TableRow: map[string]any{
+					"id":        id,
+					"name":      name,
+					"time":      now,
+					"table_num": tableNum,
+				},
+				UserID: "test",
+			})
+			if err != nil {
+				return err
+			}
+
+			fmt.Println(statement)
+
+			return nil
+		}).
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+		}, &resultMap).
+		assertEqual(id, resultMap["id"], "ID不一致").
+		assertEqual(name, resultMap["name"], "名称不一致").
+		assertEqual(now.UnixMilli(), resultMap["time"].(time.Time).UnixMilli(), "时间不一致").
+		assertEqual(tableNum, resultMap["table_num"], "表数量不一致").
+		transaction(func(tx client.Transaction) error {
+			statement, err := tx.UpdateTx(&client.UpdateRequest{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				KeyValues:             map[string]string{"id": id},
+				NewTableRow: map[string]any{
+					"id":        id,
+					"name":      newName,
+					"time":      newNow,
+					"table_num": newTableNum,
+				},
+				UserID: "test",
+			})
+			if err != nil {
+				return err
+			}
+
+			fmt.Println(statement)
+
+			return nil
+		}).
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+		}, &resultMap).
+		assertEqual(id, resultMap["id"], "ID不一致").
+		assertEqual(newName, resultMap["name"], "名称不一致").
+		assertEqual(newNow.UnixMilli(), resultMap["time"].(time.Time).UnixMilli(), "时间不一致").
+		assertEqual(newTableNum, resultMap["table_num"], "表数量不一致").
+		transaction(func(tx client.Transaction) error {
+			statement, err := tx.UpdateTx(&client.UpdateRequest{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				KeyValues:             map[string]string{"id": id},
+				NewTableRow: map[string]any{
+					"id":        id,
+					"name":      name,
+					"time":      now,
+					"table_num": tableNum,
+				},
+				UserID: "test",
+			})
+			if err != nil {
+				return err
+			}
+
+			fmt.Println(statement)
+
+			statement, err = tx.DeleteTx(&client.DeleteRequest{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				KeyValues:             map[string]string{"id": id},
+				UserID:                "test",
+			})
+			if err != nil {
+				return err
+			}
+
+			fmt.Println(statement)
+
+			return nil
+		}).
+		countWhere(&client.CountWhereRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			Where: map[string][]any{
+				"id = ?": {id},
+			},
+		}, &count).
+		assertEqual(int64(0), count, "数量不一致")
+}
+
+func TestTransactionBatch(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id1 := simpleUUID()
+	name1 := simpleUUID()
+	now1 := time.Now().Local()
+	tableNum1 := rand.New(rand.NewSource(now1.Unix())).Intn(10)
+
+	id2 := simpleUUID()
+	name2 := simpleUUID()
+	now2 := time.Now().Local()
+	tableNum2 := rand.New(rand.NewSource(now2.Unix())).Intn(10)
+
+	var count int64
+	resultMap := make(map[string]any)
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		transaction(func(tx client.Transaction) error {
+			statement, err := tx.InsertBatchTx(&client.InsertBatchRequest{
+				Items: []client.InsertTableRowItem{
+					{
+						TablePrefixWithSchema: tablePrefix,
+						Version:               "v1",
+						KeyColumns:            []string{"id"},
+						TableRows: []map[string]any{
+							{
+								"id":        id1,
+								"name":      name1,
+								"time":      now1,
+								"table_num": tableNum1,
+							},
+							{
+								"id":        id2,
+								"name":      name2,
+								"time":      now2,
+								"table_num": tableNum2,
+							},
+						},
+					},
+				},
+			})
+			if err != nil {
+				return err
+			}
+
+			fmt.Println(statement)
+
+			return nil
+		}).
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id1},
+		}, &resultMap).
+		assertEqual(id1, resultMap["id"], "ID不一致").
+		assertEqual(name1, resultMap["name"], "名称不一致").
+		assertEqual(now1.UnixMilli(), resultMap["time"].(time.Time).UnixMilli(), "时间不一致").
+		assertEqual(tableNum1, resultMap["table_num"], "表数量不一致").
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id2},
+		}, &resultMap).
+		assertEqual(id2, resultMap["id"], "ID不一致").
+		assertEqual(name2, resultMap["name"], "名称不一致").
+		assertEqual(now2.UnixMilli(), resultMap["time"].(time.Time).UnixMilli(), "时间不一致").
+		assertEqual(tableNum2, resultMap["table_num"], "表数量不一致").
+		transaction(func(tx client.Transaction) error {
+			statement, err := tx.DeleteBatchTx(&client.DeleteBatchRequest{
+				Items: []client.DeleteTableRowItem{
+					{
+						TablePrefixWithSchema: tablePrefix,
+						Version:               "v1",
+						KeyValues: []map[string]string{
+							{"id": id1},
+							{"id": id2},
+						},
+					},
+				},
+				UserID: "test",
+			})
+			if err != nil {
+				return err
+			}
+
+			fmt.Println(statement)
+
+			return nil
+		}).
+		countWhere(&client.CountWhereRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			Where: map[string][]any{
+				"id = ?": {id1},
+			},
+		}, &count).
+		assertEqual(int64(0), count, "数量不一致").
+		countWhere(&client.CountWhereRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			Where: map[string][]any{
+				"id = ?": {id2},
+			},
+		}, &count).
+		assertEqual(int64(0), count, "数量不一致")
+}
+
+func TestInsert(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id := simpleUUID()
+	name := simpleUUID()
+	now := time.Now().Local()
+	tableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+
+	resultMap := make(map[string]any)
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insert(&client.InsertRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyColumns:            []string{"id"},
+			TableRow: map[string]any{
+				"id":        id,
+				"name":      name,
+				"time":      now,
+				"table_num": tableNum,
+			},
+			UserID: "test",
+		}).
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+		}, &resultMap).
+		assertEqual(id, resultMap["id"], "ID不一致").
+		assertEqual(name, resultMap["name"], "名称不一致").
+		assertEqual(now.UnixMilli(), resultMap["time"].(time.Time).Local().UnixMilli(), "时间不一致").
+		assertEqual(tableNum, resultMap["table_num"], "表数量不一致")
+}
+
+func TestInsertBatch(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id1 := simpleUUID()
+	name1 := simpleUUID()
+	now1 := time.Now().Local()
+	tableNum1 := rand.New(rand.NewSource(now1.Unix())).Intn(10)
+
+	id2 := simpleUUID()
+	name2 := simpleUUID()
+	now2 := time.Now().Local()
+	tableNum2 := rand.New(rand.NewSource(now2.Unix())).Intn(10)
+
+	resultsMap := make([]map[string]any, 0)
+	var totalCount int64
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insertBatch(&client.InsertBatchRequest{
+			Items: []client.InsertTableRowItem{
+				{
+					TablePrefixWithSchema: tablePrefix,
+					Version:               "v1",
+					KeyColumns:            []string{"id"},
+					TableRows: []map[string]any{
+						{
+							"id":        id1,
+							"name":      name1,
+							"time":      now1,
+							"table_num": tableNum1,
+						},
+						{
+							"id":        id2,
+							"name":      name2,
+							"time":      now2,
+							"table_num": tableNum2,
+						},
+					},
+				},
+			},
+		}).
+		queryByWhereAndOrderBy(&client.QueryByWhereAndOrderByRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			Where: map[string][]any{
+				"id = ? AND name = ? AND table_num = ?": {id1, name1, tableNum1},
+			},
+			PageNo:   1,
+			PageSize: 1,
+		}, &resultsMap, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(id1, resultsMap[0]["id"], "ID不一致").
+		assertEqual(name1, resultsMap[0]["name"], "名称不一致").
+		assertEqual(now1.UnixMilli(), resultsMap[0]["time"].(time.Time).Local().UnixMilli(), "时间不一致").
+		assertEqual(tableNum1, resultsMap[0]["table_num"], "表数量不一致").
+		commonQuery(&client.CommonQueryRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			Where: map[string][]any{
+				"id = ? AND name = ? AND table_num = ?": {id2, name2, tableNum2},
+			},
+			PageNo:   1,
+			PageSize: 1,
+		}, &resultsMap, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(id2, resultsMap[0]["id"], "ID不一致").
+		assertEqual(name2, resultsMap[0]["name"], "名称不一致").
+		assertEqual(now2.UnixMilli(), resultsMap[0]["time"].(time.Time).Local().UnixMilli(), "时间不一致").
+		assertEqual(tableNum2, resultsMap[0]["table_num"], "表数量不一致")
+}
+
+func TestUpdate(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id := simpleUUID()
+	name := simpleUUID()
+	now := time.Now().Local()
+	tableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+	newName := simpleUUID()
+	newNow := time.Now().Local()
+	newTableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+
+	resultMap := make(map[string]any)
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insert(&client.InsertRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyColumns:            []string{"id"},
+			TableRow: map[string]any{
+				"id":        id,
+				"name":      name,
+				"time":      now,
+				"table_num": tableNum,
+			},
+			UserID: "test",
+		}).
+		update(&client.UpdateRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+			NewTableRow: map[string]any{
+				"id":        id,
+				"name":      newName,
+				"time":      newNow,
+				"table_num": newTableNum,
+			},
+			UserID: "test",
+		}).
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+		}, &resultMap).
+		assertEqual(id, resultMap["id"], "ID不一致").
+		assertEqual(newName, resultMap["name"], "名称不一致").
+		assertEqual(newNow.UnixMilli(), resultMap["time"].(time.Time).Local().UnixMilli(), "时间不一致").
+		assertEqual(newTableNum, resultMap["table_num"], "表数量不一致")
+}
+
+func TestDelete(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id := simpleUUID()
+	name := simpleUUID()
+	now := time.Now().Local()
+	tableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+
+	var count int64
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insert(&client.InsertRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyColumns:            []string{"id"},
+			TableRow: map[string]any{
+				"id":        id,
+				"name":      name,
+				"time":      now,
+				"table_num": tableNum,
+			},
+			UserID: "test",
+		}).
+		delete(&client.DeleteRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+			UserID:                "test",
+		}).
+		countWhere(&client.CountWhereRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			Where: map[string][]any{
+				"id = ?": {id},
+			},
+		}, &count).
+		assertEqual(int64(0), count, "数量不一致")
+}
+
+func TestDeleteBatch(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id1 := simpleUUID()
+	name1 := simpleUUID()
+	now1 := time.Now().Local()
+	tableNum1 := rand.New(rand.NewSource(now1.Unix())).Intn(10)
+
+	id2 := simpleUUID()
+	name2 := simpleUUID()
+	now2 := time.Now().Local()
+	tableNum2 := rand.New(rand.NewSource(now2.Unix())).Intn(10)
+
+	var count int64
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insertBatch(&client.InsertBatchRequest{
+			Items: []client.InsertTableRowItem{
+				{
+					TablePrefixWithSchema: tablePrefix,
+					Version:               "v1",
+					KeyColumns:            []string{"id"},
+					TableRows: []map[string]any{
+						{
+							"id":        id1,
+							"name":      name1,
+							"time":      now1,
+							"table_num": tableNum1,
+						},
+						{
+							"id":        id2,
+							"name":      name2,
+							"time":      now2,
+							"table_num": tableNum2,
+						},
+					},
+				},
+			},
+		}).
+		deleteBatch(&client.DeleteBatchRequest{
+			Items: []client.DeleteTableRowItem{
+				{
+					TablePrefixWithSchema: tablePrefix,
+					Version:               "v1",
+					KeyValues: []map[string]string{
+						{"id": id1},
+						{"id": id2},
+					},
+				},
+			},
+			UserID: "test",
+		}).
+		commonCount(&client.CommonCountRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+		}, &count).
+		assertEqual(int64(0), count, "数量不一致")
+}
+
+func TestReply(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id := simpleUUID()
+	name := simpleUUID()
+	now := time.Now().Local()
+	tableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+
+	resultMap := make(map[string]any)
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insert(&client.InsertRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyColumns:            []string{"id"},
+			TableRow: map[string]any{
+				"id":        id,
+				"name":      name,
+				"time":      now,
+				"table_num": tableNum,
+			},
+			UserID: "test",
+		}).
+		reply(&client.ReplayRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+			UserID:                "test",
+		}).
+		queryByKeys(&client.QueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+		}, &resultMap).
+		assertEqual(id, resultMap["id"], "ID不一致").
+		assertEqual(name, resultMap["name"], "名称不一致").
+		assertEqual(now.UnixMilli(), resultMap["time"].(time.Time).Local().UnixMilli(), "时间不一致").
+		assertEqual(tableNum, resultMap["table_num"], "表数量不一致")
+}
+
+func TestEventQuery(t *testing.T) {
+	initClient(t, "localhost:30170", "2b78141779ee432295ca371b91c5cac7")
+	defer destroyClient(t, "2b78141779ee432295ca371b91c5cac7")
+
+	tablePrefix := "test." + simpleUUID()[0:8]
+
+	id := simpleUUID()
+	name := simpleUUID()
+	now := time.Now().Local()
+	tableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+	newName := simpleUUID()
+	newNow := time.Now().Local()
+	newTableNum := rand.New(rand.NewSource(now.Unix())).Intn(10)
+
+	var totalCount int64
+	eventInfos := make([]client.EventInfo, 0)
+
+	newToolKit(t).
+		autoMigrate([]client.AutoMigrateItem{
+			{
+				TablePrefixWithSchema: tablePrefix,
+				Version:               "v1",
+				TableModelDescribe:    tableModelDescribe,
+			},
+		}).
+		insert(&client.InsertRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyColumns:            []string{"id"},
+			TableRow: map[string]any{
+				"id":        id,
+				"name":      name,
+				"time":      now,
+				"table_num": tableNum,
+			},
+			UserID: "test",
+		}).
+		update(&client.UpdateRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+			NewTableRow: map[string]any{
+				"id":        id,
+				"name":      newName,
+				"time":      newNow,
+				"table_num": newTableNum,
+			},
+			UserID: "test",
+		}).
+		countEventByKeys(&client.CountEventByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+		}, &totalCount).
+		assertEqual(2, int(totalCount), "总数不一致").
+		commonCountEvent(&client.CommonCountEventRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "create",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+		}, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		commonCountEvent(&client.CommonCountEventRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "update",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+		}, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		eventQueryByKeys(&client.EventQueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(2, int(totalCount), "总数不一致").
+		assertEqual(2, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("create", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		assertEqual(id, eventInfos[1].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[1].Version, "版本不一致").
+		assertEqual("update", eventInfos[1].Operation, "操作不一致").
+		assertEqual("test", eventInfos[1].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[1].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[1].Value, "值为空不一致").
+		eventQueryByKeys(&client.EventQueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			PageNo:                1,
+			PageSize:              1,
+		}, &eventInfos, &totalCount).
+		assertEqual(2, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("create", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		commonEventQuery(&client.CommonEventQueryRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "create",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("create", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		commonEventQuery(&client.CommonEventQueryRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "update",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("update", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		delete(&client.DeleteRequest{
+			TablePrefixWithSchema: tablePrefix,
+			Version:               "v1",
+			KeyValues:             map[string]string{"id": id},
+			UserID:                "test",
+		}).
+		countEventHistoryByKeys(&client.CountEventByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+		}, &totalCount).
+		assertEqual(3, int(totalCount), "总数不一致").
+		commonCountEventHistory(&client.CommonCountEventRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "create",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+		}, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		commonCountEventHistory(&client.CommonCountEventRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "update",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+		}, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		commonCountEventHistory(&client.CommonCountEventRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "delete",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+		}, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		eventHistoryQueryByKeys(&client.EventQueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(3, int(totalCount), "总数不一致").
+		assertEqual(3, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("create", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		assertEqual(id, eventInfos[1].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[1].Version, "版本不一致").
+		assertEqual("update", eventInfos[1].Operation, "操作不一致").
+		assertEqual("test", eventInfos[1].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[1].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[1].Value, "值为空不一致").
+		assertEqual(id, eventInfos[2].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[2].Version, "版本不一致").
+		assertEqual("delete", eventInfos[2].Operation, "操作不一致").
+		assertEqual("test", eventInfos[2].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[2].CreateTime, "创建事件为空").
+		assertEqual("", eventInfos[2].Value, "值为空不一致").
+		eventHistoryQueryByKeys(&client.EventQueryByKeysRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			PageNo:                1,
+			PageSize:              1,
+		}, &eventInfos, &totalCount).
+		assertEqual(3, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("create", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		commonEventHistoryQuery(&client.CommonEventQueryRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "create",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("create", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		commonEventHistoryQuery(&client.CommonEventQueryRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "update",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("update", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertNotEmpty(eventInfos[0].Value, "值为空不一致").
+		commonEventHistoryQuery(&client.CommonEventQueryRequest{
+			TablePrefixWithSchema: tablePrefix,
+			KeyValues:             []string{id},
+			Version:               "v1",
+			Operation:             "delete",
+			CreatorID:             "test",
+			StartCreatedTime:      now.Format(time.DateTime),
+			EndCreatedTime:        now.Add(time.Second).Format(time.DateTime),
+			PageNo:                0,
+			PageSize:              0,
+		}, &eventInfos, &totalCount).
+		assertEqual(1, int(totalCount), "总数不一致").
+		assertEqual(1, len(eventInfos), "事件数量不一致").
+		assertEqual(id, eventInfos[0].Key, "关键字段不一致").
+		assertEqual("v1", eventInfos[0].Version, "版本不一致").
+		assertEqual("delete", eventInfos[0].Operation, "操作不一致").
+		assertEqual("test", eventInfos[0].CreatorID, "创建者ID不一致").
+		assertNotEmpty(eventInfos[0].CreateTime, "创建事件为空").
+		assertEqual("", eventInfos[0].Value, "值为空不一致")
+}

+ 317 - 0
test/instance/sdk.go

@@ -0,0 +1,317 @@
+package instance
+
+import (
+	"git.sxidc.com/service-supports/dps-sdk"
+	"git.sxidc.com/service-supports/dps-sdk/client"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func initClient(t *testing.T, address string, databaseID string) {
+	err := dps.InitInstance(address, "v1", databaseID)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func destroyClient(t *testing.T, databaseID string) {
+	err := dps.DestroyInstance("v1", databaseID)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+type ToolKit struct {
+	t *testing.T
+}
+
+func newToolKit(t *testing.T) *ToolKit {
+	return &ToolKit{t: t}
+}
+
+func (toolKit *ToolKit) autoMigrate(items []client.AutoMigrateItem) *ToolKit {
+	err := dps.AutoMigrate(items...)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) transaction(txFunc client.TransactionFunc) *ToolKit {
+	err := dps.Transaction(txFunc)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) insert(req *client.InsertRequest) *ToolKit {
+	err := dps.Insert(req, nil)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) insertBatch(req *client.InsertBatchRequest) *ToolKit {
+	err := dps.InsertBatch(req, nil)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) delete(req *client.DeleteRequest) *ToolKit {
+	err := dps.Delete(req, nil)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) deleteBatch(req *client.DeleteBatchRequest) *ToolKit {
+	err := dps.DeleteBatch(req, nil)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) update(req *client.UpdateRequest) *ToolKit {
+	err := dps.Update(req, nil)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) reply(req *client.ReplayRequest) *ToolKit {
+	err := dps.Replay(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) queryByWhereAndOrderBy(req *client.QueryByWhereAndOrderByRequest, retInfosMap *[]map[string]any, retTotalCount *int64) *ToolKit {
+	infosMap, totalCount, err := dps.QueryByWhereAndOrderBy(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfosMap != nil {
+		*retInfosMap = make([]map[string]any, 0)
+		*retInfosMap = infosMap
+	}
+
+	if retTotalCount != nil {
+		*retTotalCount = totalCount
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) commonQuery(req *client.CommonQueryRequest, retInfosMap *[]map[string]any, retTotalCount *int64) *ToolKit {
+	infosMap, totalCount, err := dps.CommonQuery(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfosMap != nil {
+		*retInfosMap = make([]map[string]any, 0)
+		*retInfosMap = infosMap
+	}
+
+	if retTotalCount != nil {
+		*retTotalCount = totalCount
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) queryByKeys(req *client.QueryByKeysRequest, retInfoMap *map[string]any) *ToolKit {
+	infoMap, err := dps.QueryByKeys(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfoMap != nil {
+		*retInfoMap = make(map[string]any)
+		*retInfoMap = infoMap
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) countWhere(req *client.CountWhereRequest, retCount *int64) *ToolKit {
+	count, err := dps.CountWhere(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retCount != nil {
+		*retCount = count
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) commonCount(req *client.CommonCountRequest, retCount *int64) *ToolKit {
+	count, err := dps.CommonCount(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retCount != nil {
+		*retCount = count
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) eventQueryByKeys(req *client.EventQueryByKeysRequest, retInfos *[]client.EventInfo, retTotalCount *int64) *ToolKit {
+	infos, totalCount, err := dps.EventQueryByKeys(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfos != nil {
+		*retInfos = make([]client.EventInfo, 0)
+		*retInfos = infos
+	}
+
+	if retTotalCount != nil {
+		*retTotalCount = totalCount
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) commonEventQuery(req *client.CommonEventQueryRequest, retInfos *[]client.EventInfo, retTotalCount *int64) *ToolKit {
+	infos, totalCount, err := dps.CommonEventQuery(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfos != nil {
+		*retInfos = make([]client.EventInfo, 0)
+		*retInfos = infos
+	}
+
+	if retTotalCount != nil {
+		*retTotalCount = totalCount
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) countEventByKeys(req *client.CountEventByKeysRequest, retCount *int64) *ToolKit {
+	count, err := dps.CountEventByKeys(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retCount != nil {
+		*retCount = count
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) commonCountEvent(req *client.CommonCountEventRequest, retCount *int64) *ToolKit {
+	count, err := dps.CommonCountEvent(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retCount != nil {
+		*retCount = count
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) eventHistoryQueryByKeys(req *client.EventQueryByKeysRequest, retInfos *[]client.EventInfo, retTotalCount *int64) *ToolKit {
+	infos, totalCount, err := dps.EventHistoryQueryByKeys(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfos != nil {
+		*retInfos = make([]client.EventInfo, 0)
+		*retInfos = infos
+	}
+
+	if retTotalCount != nil {
+		*retTotalCount = totalCount
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) commonEventHistoryQuery(req *client.CommonEventQueryRequest, retInfos *[]client.EventInfo, retTotalCount *int64) *ToolKit {
+	infos, totalCount, err := dps.CommonEventHistoryQuery(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retInfos != nil {
+		*retInfos = make([]client.EventInfo, 0)
+		*retInfos = infos
+	}
+
+	if retTotalCount != nil {
+		*retTotalCount = totalCount
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) countEventHistoryByKeys(req *client.CountEventByKeysRequest, retCount *int64) *ToolKit {
+	count, err := dps.CountEventHistoryByKeys(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retCount != nil {
+		*retCount = count
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) commonCountEventHistory(req *client.CommonCountEventRequest, retCount *int64) *ToolKit {
+	count, err := dps.CommonCountEventHistory(req)
+	if err != nil {
+		toolKit.t.Fatal(err)
+	}
+
+	if retCount != nil {
+		*retCount = count
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) assertEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.Equal(toolKit.t, expected, actual, msgAndArgs)
+	return toolKit
+}
+
+func (toolKit *ToolKit) assertNotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.NotEqual(toolKit.t, expected, actual, msgAndArgs)
+	return toolKit
+}
+
+func (toolKit *ToolKit) assertNotEmpty(object interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.NotEmpty(toolKit.t, object, msgAndArgs)
+	return toolKit
+}

+ 0 - 14
test/v1/utils.go

@@ -1,14 +0,0 @@
-package v1
-
-import (
-	uuid "github.com/satori/go.uuid"
-	"strings"
-)
-
-func getUUID() string {
-	return uuid.NewV4().String()
-}
-
-func simpleUUID() string {
-	return strings.ReplaceAll(getUUID(), "-", "")
-}

+ 10 - 25
test/v1/v1_test.go

@@ -3,11 +3,21 @@ package v1
 import (
 	"fmt"
 	"git.sxidc.com/service-supports/dps-sdk/client"
+	uuid "github.com/satori/go.uuid"
 	"math/rand"
+	"strings"
 	"testing"
 	"time"
 )
 
+func getUUID() string {
+	return uuid.NewV4().String()
+}
+
+func simpleUUID() string {
+	return strings.ReplaceAll(getUUID(), "-", "")
+}
+
 var tableModelDescribe = map[string]string{
 	"ID":       "gorm:\"primary_key;type:varchar(32);comment:id;\"",
 	"Name":     "gorm:\"not null;type:varchar(128);comment:数据库名称;\"",
@@ -77,11 +87,6 @@ func TestTransaction(t *testing.T) {
 
 			fmt.Println(statement)
 
-			err = tx.End()
-			if err != nil {
-				return err
-			}
-
 			return nil
 		}).
 		queryByKeys(&client.QueryByKeysRequest{
@@ -112,11 +117,6 @@ func TestTransaction(t *testing.T) {
 
 			fmt.Println(statement)
 
-			err = tx.End()
-			if err != nil {
-				return err
-			}
-
 			return nil
 		}).
 		queryByKeys(&client.QueryByKeysRequest{
@@ -159,11 +159,6 @@ func TestTransaction(t *testing.T) {
 
 			fmt.Println(statement)
 
-			err = tx.End()
-			if err != nil {
-				return err
-			}
-
 			return nil
 		}).
 		countWhere(&client.CountWhereRequest{
@@ -235,11 +230,6 @@ func TestTransactionBatch(t *testing.T) {
 
 			fmt.Println(statement)
 
-			err = tx.End()
-			if err != nil {
-				return err
-			}
-
 			return nil
 		}).
 		queryByKeys(&client.QueryByKeysRequest{
@@ -280,11 +270,6 @@ func TestTransactionBatch(t *testing.T) {
 
 			fmt.Println(statement)
 
-			err = tx.End()
-			if err != nil {
-				return err
-			}
-
 			return nil
 		}).
 		countWhere(&client.CountWhereRequest{