package database import ( "git.sxidc.com/go-framework/baize/framwork/infrastructure/database/data_service" "git.sxidc.com/go-framework/baize/framwork/infrastructure/database/operations" "git.sxidc.com/go-framework/baize/framwork/infrastructure/database/sql" "git.sxidc.com/go-framework/baize/framwork/tag/sql/sql_mapping" "git.sxidc.com/go-tools/utils/reflectutils" "git.sxidc.com/go-tools/utils/strutils" "git.sxidc.com/service-supports/fserr" "reflect" "strings" "time" ) type Executor interface { ExecuteRawSql(sql string, executeParams map[string]any) ([]sql.Result, error) ExecuteSql(name string, executeParams map[string]any) ([]sql.Result, error) } const ( createdTimeFieldName = "CreatedTime" lastUpdatedTimeFieldName = "LastUpdatedTime" ) func Transaction(executor Executor, txFunc func(tx Executor) error) error { if executor == nil { return nil } if txFunc == nil { return nil } switch e := executor.(type) { case *operations.Operations: tx := e.BeginTransaction() err := txFunc(tx) if err != nil { tx.RollbackTransaction() return err } tx.CommitTransaction() case *data_service.DataService: return e.Transaction(func(tx *data_service.Transaction) error { return txFunc(tx) }) default: return nil } return nil } func InsertEntity(executor Executor, tableName string, e any) error { if executor == nil { return fserr.New("没有传递执行器") } if strutils.IsStringEmpty(tableName) { return fserr.New("没有传递表名") } if e == nil { return nil } entityType := reflect.TypeOf(e) if !reflectutils.IsTypeStructOrStructPointer(entityType) { return fserr.New("实体参数不是结构或结构指针") } fields, err := sql_mapping.DefaultUsage(e) if err != nil { return err } executeParamsMap, err := sql.InsertExecuteParams{ TableName: tableName, TableRow: formInsertTableRow(fields), }.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.InsertTpl, executeParamsMap) if err != nil { if strings.Contains(err.Error(), "SQLSTATE 23505") { return ErrDBRecordHasExist } return err } return nil } func InsertEntityBatch(executor Executor, tableName string, es []any) error { if executor == nil { return fserr.New("没有传递执行器") } if strutils.IsStringEmpty(tableName) { return fserr.New("没有传递表名") } tableRowBatch := make([]sql.TableRow, 0) for _, e := range es { if e == nil { return nil } entityType := reflect.TypeOf(e) if !reflectutils.IsTypeStructOrStructPointer(entityType) { return fserr.New("实体参数不是结构或结构指针") } fields, err := sql_mapping.DefaultUsage(e) if err != nil { return err } tableRowBatch = append(tableRowBatch, *formInsertTableRow(fields)) } executeParamsMap, err := sql.InsertBatchExecuteParams{ TableName: tableName, TableRowBatch: tableRowBatch, }.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.InsertTpl, executeParamsMap) if err != nil { if strings.Contains(err.Error(), "SQLSTATE 23505") { return ErrDBRecordHasExist } return err } return nil } func formInsertTableRow(fields []sql_mapping.Field) *sql.TableRow { now := time.Now().Local() tableRow := sql.NewTableRow() for _, field := range fields { fieldValue := reflect.ValueOf(field.Value) if (field.FieldName == createdTimeFieldName || field.FieldName == lastUpdatedTimeFieldName) && reflectutils.IsValueTime(fieldValue) && fieldValue.IsZero() { field.Value = now } tableRow.Add(field.ColumnName, field.Value) } return tableRow } func DeleteEntity(executor Executor, tableName string, e any) error { if executor == nil { return fserr.New("没有传递执行器") } if strutils.IsStringEmpty(tableName) { return fserr.New("没有传递表名") } if e == nil { return nil } entityType := reflect.TypeOf(e) if !reflectutils.IsTypeStructOrStructPointer(entityType) { return fserr.New("实体参数不是结构或结构指针") } fields, err := sql_mapping.DefaultUsage(e) if err != nil { return err } conditions := sql.NewConditions() for _, field := range fields { // 不是键,字段跳过 if !field.IsKey { continue } conditions.Equal(field.ColumnName, field.Value) } executeParamsMap, err := sql.DeleteExecuteParams{ TableName: tableName, Conditions: conditions, }.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.DeleteTpl, executeParamsMap) if err != nil { return err } return nil } func UpdateEntity(executor Executor, tableName string, e any) error { if executor == nil { return fserr.New("没有传递执行器") } if strutils.IsStringEmpty(tableName) { return fserr.New("没有传递表名") } if e == nil { return nil } entityType := reflect.TypeOf(e) if !reflectutils.IsTypeStructOrStructPointer(entityType) { return fserr.New("实体参数不是结构或结构指针") } fields, err := sql_mapping.DefaultUsage(e) if err != nil { return err } now := time.Now().Local() tableRow := sql.NewTableRow() conditions := sql.NewConditions() for _, field := range fields { // 不是键字段 // 不是更新时间字段 // 不更新的字段或者字段为零值且不能清空,跳过 if !field.IsKey && field.FieldName != lastUpdatedTimeFieldName && (!field.CanUpdate || (reflect.ValueOf(field.Value).IsZero() && !field.CanUpdateClear)) { continue } fieldValue := reflect.ValueOf(field.Value) if field.FieldName == lastUpdatedTimeFieldName && reflectutils.IsValueTime(fieldValue) && fieldValue.IsZero() { field.Value = now } if field.IsKey { conditions.Equal(field.ColumnName, field.Value) } else { if reflect.ValueOf(field.Value).IsZero() && !field.CanUpdateClear { continue } tableRow.Add(field.ColumnName, field.Value) } } executeParamsMap, err := sql.UpdateExecuteParams{ TableName: tableName, TableRow: tableRow, Conditions: conditions, }.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.UpdateTpl, executeParamsMap) if err != nil { return err } return nil } func Insert(executor Executor, executeParams *sql.InsertExecuteParams) error { if executor == nil { return fserr.New("没有传递执行器") } if executeParams == nil { return fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.InsertTpl, executeParamsMap) if err != nil { return err } return nil } func InsertBatch(executor Executor, executeParams *sql.InsertBatchExecuteParams) error { if executor == nil { return fserr.New("没有传递执行器") } if executeParams == nil { return fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.InsertTpl, executeParamsMap) if err != nil { return err } return nil } func Delete(executor Executor, executeParams *sql.DeleteExecuteParams) error { if executor == nil { return fserr.New("没有传递执行器") } if executeParams == nil { return fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.DeleteTpl, executeParamsMap) if err != nil { return err } return nil } func Update(executor Executor, executeParams *sql.UpdateExecuteParams) error { if executor == nil { return fserr.New("没有传递执行器") } if executeParams == nil { return fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return err } _, err = executor.ExecuteRawSql(sql.UpdateTpl, executeParamsMap) if err != nil { return err } return nil } func Query(executor Executor, executeParams *sql.QueryExecuteParams) ([]sql.Result, int64, error) { if executor == nil { return nil, 0, fserr.New("没有传递执行器") } if executeParams == nil { return nil, 0, fserr.New("没有传递执行参数") } queryExecuteParamsMap, err := executeParams.Map() if err != nil { return nil, 0, err } countExecuteParamsMap, err := sql.CountExecuteParams{ TableName: executeParams.TableName, Conditions: executeParams.Conditions, }.Map() if err != nil { return nil, 0, err } tableRows, err := executor.ExecuteRawSql(sql.QueryTpl, queryExecuteParamsMap) if err != nil { return nil, 0, err } countTableRow, err := executor.ExecuteRawSql(sql.CountTpl, countExecuteParamsMap) if err != nil { return nil, 0, err } results := make([]sql.Result, len(tableRows)) for i, row := range tableRows { results[i] = row } return results, int64(countTableRow[0]["count"].(float64)), nil } func QueryOne(executor Executor, executeParams *sql.QueryOneExecuteParams) (sql.Result, error) { if executor == nil { return nil, fserr.New("没有传递执行器") } if executeParams == nil { return nil, fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return nil, err } tableRows, err := executor.ExecuteRawSql(sql.QueryTpl, executeParamsMap) if err != nil { return nil, err } if tableRows == nil || len(tableRows) == 0 { return nil, ErrDBRecordNotExist } return tableRows[0], nil } func Count(executor Executor, executeParams *sql.CountExecuteParams) (int64, error) { if executor == nil { return 0, fserr.New("没有传递执行器") } if executeParams == nil { return 0, fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return 0, err } tableRows, err := executor.ExecuteRawSql(sql.CountTpl, executeParamsMap) if err != nil { return 0, err } return int64(tableRows[0]["count"].(float64)), nil } func CheckExist(executor Executor, executeParams *sql.CheckExistExecuteParams) (bool, error) { if executor == nil { return false, fserr.New("没有传递执行器") } if executeParams == nil { return false, fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return false, err } tableRows, err := executor.ExecuteRawSql(sql.CountTpl, executeParamsMap) if err != nil { return false, err } return int64(tableRows[0]["count"].(float64)) > 0, nil } func CheckHasOnlyOne(executor Executor, executeParams *sql.CheckHasOnlyOneExecuteParams) (bool, error) { if executor == nil { return false, fserr.New("没有传递执行器") } if executeParams == nil { return false, fserr.New("没有传递执行参数") } executeParamsMap, err := executeParams.Map() if err != nil { return false, err } tableRows, err := executor.ExecuteRawSql(sql.CountTpl, executeParamsMap) if err != nil { return false, err } return int64(tableRows[0]["count"].(float64)) == 1, nil } func ExecuteRawSql(executor Executor, sql string, executeParams map[string]any) ([]sql.Result, error) { if executor == nil { return nil, fserr.New("没有传递执行器") } if strutils.IsStringEmpty(sql) { return nil, fserr.New("没有sql") } tableRows, err := executor.ExecuteRawSql(sql, executeParams) if err != nil { return nil, err } return tableRows, nil } func ExecuteSql(executor Executor, name string, executeParams map[string]any) ([]sql.Result, error) { if executor == nil { return nil, fserr.New("没有传递执行器") } if strutils.IsStringEmpty(name) { return nil, fserr.New("没有sql资源名称") } tableRows, err := executor.ExecuteSql(name, executeParams) if err != nil { return nil, err } return tableRows, nil }