package main import ( "fmt" "git.sxidc.com/go-tools/utils/strutils" "git.sxidc.com/service-supports/ds-sdk/sdk" "git.sxidc.com/service-supports/ds-sdk/sdk/raw_sql_tpl" "git.sxidc.com/service-supports/ds-sdk/sdk/tag" "github.com/iancoleman/strcase" "math/rand" "strconv" "sync" "testing" "time" ) type Class struct { ID string `sqlmapping:"key;"` Name string `sqlmapping:"updateClear;notQuery;insertCallback;updateCallback;"` StudentNum int `sqlmapping:"column:student_num;notUpdate;queryCallback;" sqlresult:"column:student_num_alias;"` GraduatedTime time.Time `sqlresult:"callback"` CreatedTime *time.Time LastUpdatedTime time.Time Ignored string `sqlmapping:"-" sqlresult:"-"` } const ( token = "IpTTwAQweh/BP51fz5CzWKQFaXHvZe6ewvk6yOcAOkU=" address = "localhost" httpPort = "10000" grpcPort = "10001" namespace = "ns-sdk-demo" dataSource = "ds-sdk-demo" deleteSql = "delete-sdk-demo" goRoutineCount = 100 tableName = "test.classes" ) var ( sqlSpec = sdk.SqlSpec{ Clauses: "- DELETE FROM {{ .table_name }} WHERE id = '{{ .id }}'", } ) func TestBasic(t *testing.T) { classID := strutils.SimpleUUID() className := strutils.SimpleUUID() studentNum := rand.Int31n(100) now := time.Now() nowStr := now.Format(time.DateTime + ".000000 +08:00") insertExecuteParams, err := raw_sql_tpl.InsertExecuteParams{ TableName: tableName, TableRows: []raw_sql_tpl.TableRow{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + className + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(studentNum), 10), }, { Column: "graduated_time", Value: "'" + nowStr + "'", }, { Column: "created_time", Value: "'" + nowStr + "'", }, { Column: "last_updated_time", Value: "'" + nowStr + "'", }, }, }.Map() if err != nil { t.Fatal(err) } deleteExecuteParams := map[string]any{ "table_name": tableName, "id": classID, } err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource) if err != nil { t.Fatal(err) } defer func() { err := sdk.DestroyInstance() if err != nil { t.Fatal(err) } }() err = sdk.GetInstance().CreateSQL(deleteSql, sqlSpec.ToMap()) if err != nil { t.Fatal(err) } defer func() { err = sdk.GetInstance().DeleteSQL(deleteSql) if err != nil { t.Fatal(err) } }() _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.InsertTpl, insertExecuteParams) if err != nil { t.Fatal(err) } _, err = sdk.GetInstance().ExecuteSql(deleteSql, deleteExecuteParams) if err != nil { t.Fatal(err) } wg := sync.WaitGroup{} wg.Add(goRoutineCount) start := time.Now() for i := 0; i < goRoutineCount; i++ { go func() { defer wg.Done() err = sdk.GetInstance().Transaction(func(tx *sdk.Transaction) error { _, err := tx.ExecuteRawSql(raw_sql_tpl.InsertTpl, insertExecuteParams) if err != nil { return err } _, err = tx.ExecuteSql(deleteSql, deleteExecuteParams) if err != nil { return err } return nil }) if err != nil { panic(err) } }() } wg.Wait() end := time.Now() fmt.Println(end.Sub(start).Milliseconds()) } func TestRawSqlTemplate(t *testing.T) { classID := strutils.SimpleUUID() className := strutils.SimpleUUID() studentNum := rand.Int31n(100) newClassName := strutils.SimpleUUID() newStudentNum := rand.Int31n(100) now := time.Now() nowStr := now.Format(time.DateTime + ".000000 +08:00") exceptedNowStr := now.Format("2006-01-02T15:04:05.000000+08:00") insertExecuteParams, err := raw_sql_tpl.InsertExecuteParams{ TableName: tableName, TableRows: []raw_sql_tpl.TableRow{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + className + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(studentNum), 10), }, { Column: "graduated_time", Value: "'" + nowStr + "'", }, { Column: "created_time", Value: "'" + nowStr + "'", }, { Column: "last_updated_time", Value: "'" + nowStr + "'", }, }, }.Map() if err != nil { t.Fatal(err) } deleteExecuteParams, err := raw_sql_tpl.DeleteExecuteParams{ TableName: tableName, Conditions: []raw_sql_tpl.Condition{ { Column: "id", Value: "'" + classID + "'", }, }, }.Map() if err != nil { t.Fatal(err) } updateExecuteParams, err := raw_sql_tpl.UpdateExecuteParams{ TableName: tableName, TableRows: []raw_sql_tpl.TableRow{ { Column: "name", Value: "'" + newClassName + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(newStudentNum), 10), }, }, Conditions: []raw_sql_tpl.Condition{ { Column: "id", Value: "'" + classID + "'", }, }, }.Map() if err != nil { t.Fatal(err) } queryExecuteParams, err := raw_sql_tpl.QueryExecuteParams{ TableName: tableName, SelectColumns: []string{"id", "name", "student_num as student_num_alias", "graduated_time", "created_time", "last_updated_time"}, Conditions: []raw_sql_tpl.Condition{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + className + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(studentNum), 10), }, }, Limit: 1, Offset: 0, }.Map() if err != nil { t.Fatal(err) } newQueryExecuteParams, err := raw_sql_tpl.QueryExecuteParams{ TableName: tableName, SelectColumns: []string{"id", "name", "student_num as student_num_alias", "graduated_time", "created_time", "last_updated_time"}, Conditions: []raw_sql_tpl.Condition{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + newClassName + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(newStudentNum), 10), }, }, Limit: 0, Offset: 0, }.Map() if err != nil { t.Fatal(err) } countExecuteParams, err := raw_sql_tpl.CountExecuteParams{ TableName: tableName, Conditions: []raw_sql_tpl.Condition{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + className + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(studentNum), 10), }, }, }.Map() if err != nil { t.Fatal(err) } newCountExecuteParams, err := raw_sql_tpl.CountExecuteParams{ TableName: tableName, Conditions: []raw_sql_tpl.Condition{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + newClassName + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(newStudentNum), 10), }, }, }.Map() if err != nil { t.Fatal(err) } err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource) if err != nil { t.Fatal(err) } defer func() { err := sdk.DestroyInstance() if err != nil { t.Fatal(err) } }() _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.InsertTpl, insertExecuteParams) if err != nil { t.Fatal(err) } queryResults, err := sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.QueryTpl, queryExecuteParams) if err != nil { t.Fatal(err) } countResults, err := sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.CountTpl, countExecuteParams) if err != nil { t.Fatal(err) } if float64(len(queryResults)) != countResults[0]["count"].(float64) { t.Fatal("总数不正确") } if queryResults[0]["id"].(string) != classID || queryResults[0]["name"].(string) != className || queryResults[0]["student_num_alias"].(float64) != float64(studentNum) || queryResults[0]["graduated_time"].(string) != exceptedNowStr || queryResults[0]["created_time"].(string) != exceptedNowStr || queryResults[0]["last_updated_time"].(string) != exceptedNowStr { t.Fatal("查询数据不正确") } _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.UpdateTpl, updateExecuteParams) if err != nil { t.Fatal(err) } queryResults, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.QueryTpl, newQueryExecuteParams) if err != nil { t.Fatal(err) } countResults, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.CountTpl, newCountExecuteParams) if err != nil { t.Fatal(err) } if float64(len(queryResults)) != countResults[0]["count"].(float64) { t.Fatal("总数不正确") } if queryResults[0]["id"].(string) != classID || queryResults[0]["name"].(string) != newClassName || queryResults[0]["student_num_alias"].(float64) != float64(newStudentNum) || queryResults[0]["graduated_time"].(string) != exceptedNowStr || queryResults[0]["created_time"].(string) != exceptedNowStr || queryResults[0]["last_updated_time"].(string) != exceptedNowStr { t.Fatal("查询数据不正确") } _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.DeleteTpl, deleteExecuteParams) if err != nil { t.Fatal(err) } } func TestSqlMapping(t *testing.T) { sqlMapping, err := tag.ParseSqlMapping(&Class{}) if err != nil { t.Fatal(err) } for fieldName, sqlColumn := range sqlMapping.ColumnMap { if fieldName != "ID" && fieldName != "Name" && fieldName != "StudentNum" && fieldName != "GraduatedTime" && fieldName != "CreatedTime" && fieldName != "LastUpdatedTime" { t.Fatal("字段名不正确") } if sqlColumn.Name != "id" && sqlColumn.Name != "name" && sqlColumn.Name != "student_num" && sqlColumn.Name != "graduated_time" && sqlColumn.Name != "created_time" && sqlColumn.Name != "last_updated_time" { t.Fatal("列名不正确") } if sqlColumn.Name != strcase.ToSnake(fieldName) { t.Fatal("列名不正确") } if sqlColumn.IsKey && sqlColumn.Name != "id" { t.Fatal("键字段不正确") } if !sqlColumn.CanUpdate && (sqlColumn.Name != "id" && sqlColumn.Name != "student_num") { t.Fatal("不可更新字段不正确") } if sqlColumn.CanUpdateClear && sqlColumn.Name != "name" { t.Fatal("可清除字段不正确") } if !sqlColumn.CanQuery && sqlColumn.Name != "name" { t.Fatal("可清除字段不正确") } if sqlColumn.InsertCallback && sqlColumn.Name != "name" { t.Fatal("插入回调不正确") } if sqlColumn.UpdateCallback && sqlColumn.Name != "name" { t.Fatal("更新回调不正确") } if sqlColumn.QueryCallback && sqlColumn.Name != "student_num" { t.Fatal("查询回调不正确") } } } func TestSqlResult(t *testing.T) { sqlResult, err := tag.ParseSqlResult(&Class{}) if err != nil { t.Fatal(err) } for fieldName, sqlColumn := range sqlResult.ColumnMap { if fieldName != "ID" && fieldName != "Name" && fieldName != "StudentNum" && fieldName != "GraduatedTime" && fieldName != "CreatedTime" && fieldName != "LastUpdatedTime" { t.Fatal("字段名不正确") } if sqlColumn.Name != "id" && sqlColumn.Name != "name" && sqlColumn.Name != "student_num" && sqlColumn.Name != "graduated_time" && sqlColumn.Name != "created_time" && sqlColumn.Name != "last_updated_time" { t.Fatal("列名不正确") } if sqlColumn.Name != strcase.ToSnake(fieldName) { t.Fatal("列名不正确") } if sqlColumn.Name == "student_num" { if sqlColumn.ResultColumnName != "student_num_alias" { t.Fatal("结果列名不正确") } } if sqlColumn.Callback && sqlColumn.Name != "graduated_time" { t.Fatal("回调不正确") } } } func TestSql(t *testing.T) { classID := strutils.SimpleUUID() className := strutils.SimpleUUID() studentNum := rand.Int31n(100) newClassName := strutils.SimpleUUID() newStudentNum := rand.Int31n(100) now := time.Now() nowStr := now.Format(time.DateTime + ".000000 +08:00") insertExecuteParams, err := raw_sql_tpl.InsertExecuteParams{ TableName: tableName, TableRows: []raw_sql_tpl.TableRow{ { Column: "id", Value: "'" + classID + "'", }, { Column: "name", Value: "'" + className + "'", }, { Column: "student_num", Value: strconv.FormatInt(int64(studentNum), 10), }, { Column: "graduated_time", Value: "'" + nowStr + "'", }, { Column: "created_time", Value: "'" + nowStr + "'", }, { Column: "last_updated_time", Value: "'" + nowStr + "'", }, }, }.Map() if err != nil { t.Fatal(err) } deleteExecuteParams := map[string]any{ "table_name": tableName, "id": classID, } class := &Class{ ID: classID, Name: className, StudentNum: int(studentNum), GraduatedTime: time.Now(), Ignored: "", } newClass := &Class{ ID: classID, Name: newClassName, StudentNum: int(newStudentNum), GraduatedTime: time.Now(), Ignored: "", } err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource) if err != nil { t.Fatal(err) } defer func() { err := sdk.DestroyInstance() if err != nil { t.Fatal(err) } }() err = sdk.GetInstance().CreateSQL(deleteSql, sqlSpec.ToMap()) if err != nil { t.Fatal(err) } defer func() { err = sdk.GetInstance().DeleteSQL(deleteSql) if err != nil { t.Fatal(err) } }() err = sdk.Insert(sdk.GetInstance(), tableName, class, func(e *Class, fieldName string, value any) (retValue any, err error) { return value, nil }) if err != nil { t.Fatal(err) } err = sdk.Update(sdk.GetInstance(), tableName, newClass, func(e *Class, fieldName string, value any) (retValue any, err error) { return value, nil }) if err != nil { t.Fatal(err) } err = sdk.Delete(sdk.GetInstance(), tableName, class) if err != nil { t.Fatal(err) } _, err = sdk.ExecuteRawSql(sdk.GetInstance(), raw_sql_tpl.InsertTpl, insertExecuteParams) if err != nil { t.Fatal(err) } _, err = sdk.ExecuteSql(sdk.GetInstance(), deleteSql, deleteExecuteParams) if err != nil { t.Fatal(err) } err = sdk.GetInstance().Transaction(func(tx *sdk.Transaction) error { err = sdk.Insert(tx, tableName, class, func(e *Class, fieldName string, value any) (retValue any, err error) { return value, nil }) if err != nil { t.Fatal(err) } err = sdk.Update(tx, tableName, newClass, func(e *Class, fieldName string, value any) (retValue any, err error) { return value, nil }) if err != nil { t.Fatal(err) } err = sdk.Delete(tx, tableName, class) if err != nil { t.Fatal(err) } _, err = sdk.ExecuteRawSql(tx, raw_sql_tpl.InsertTpl, insertExecuteParams) if err != nil { t.Fatal(err) } _, err = sdk.ExecuteSql(tx, deleteSql, deleteExecuteParams) if err != nil { t.Fatal(err) } return nil }) if err != nil { t.Fatal(err) } }