database.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. package database
  2. import (
  3. "reflect"
  4. "strings"
  5. "time"
  6. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/operations"
  7. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql"
  8. "git.sxidc.com/go-framework/baize/framework/core/tag/sql/sql_mapping"
  9. "git.sxidc.com/go-tools/utils/reflectutils"
  10. "git.sxidc.com/go-tools/utils/strutils"
  11. "github.com/pkg/errors"
  12. )
  13. // Executor 数据库基础设施接口
  14. type Executor interface {
  15. // ExecuteRawSql SQL执行接口
  16. // 参数:
  17. // - sql: SQL语句,可以使用预编译,需要填充的值用?占位
  18. // - values: 预编译填充值
  19. // 返回值:
  20. // - SQL执行结果
  21. // - 错误
  22. ExecuteRawSql(sql string, args ...any) ([]sql.Result, error)
  23. // ExecuteRawSqlTemplate SQL模板执行接口
  24. // 参数:
  25. // - sql: SQL语句模板,可以使用预编译,需要填充的值用?占位,可以使用Go模板构造SQL语句
  26. // - template: 渲染SQL语句模板的模板参数
  27. // - values: 预编译填充值
  28. // 返回值:
  29. // - SQL执行结果
  30. // - 错误
  31. ExecuteRawSqlTemplate(sql string, template map[string]any, args ...any) ([]sql.Result, error)
  32. // ExecuteRawSqlWithRowsAffected SQL执行接口,返回影响行数
  33. // 参数:
  34. // - sql: SQL语句,可以使用预编译,需要填充的值用?占位
  35. // - values: 预编译填充值
  36. // 返回值:
  37. // - SQL执行结果
  38. // - 影响行数
  39. // - 错误
  40. ExecuteRawSqlWithRowsAffected(sql string, args ...any) ([]sql.Result, int64, error)
  41. // ExecuteRawSqlTemplateWithRowsAffected SQL模板执行接口,返回影响行数
  42. // 参数:
  43. // - sql: SQL语句模板,可以使用预编译,需要填充的值用?占位,可以使用Go模板构造SQL语句
  44. // - template: 渲染SQL语句模板的模板参数
  45. // - values: 预编译填充值
  46. // 返回值:
  47. // - SQL执行结果
  48. // - 影响行数
  49. // - 错误
  50. ExecuteRawSqlTemplateWithRowsAffected(sql string, template map[string]any, args ...any) ([]sql.Result, int64, error)
  51. }
  52. const (
  53. createdTimeFieldName = "CreatedTime"
  54. lastUpdatedTimeFieldName = "LastUpdatedTime"
  55. )
  56. // Transaction 执行事务
  57. // 参数:
  58. // - executor: 数据库基础设施接口
  59. // - txFunc: 事务函数
  60. // 返回值:
  61. // - 错误
  62. func Transaction(executor Executor, txFunc func(tx Executor) error) (err error) {
  63. if executor == nil {
  64. return nil
  65. }
  66. if txFunc == nil {
  67. return nil
  68. }
  69. switch e := executor.(type) {
  70. case *operations.Operations:
  71. tx := e.BeginTransaction()
  72. defer func() {
  73. if r := recover(); r != nil {
  74. tx.RollbackTransaction()
  75. err = errors.Errorf("panic: %v", r)
  76. }
  77. }()
  78. err = txFunc(tx)
  79. if err != nil {
  80. tx.RollbackTransaction()
  81. return err
  82. }
  83. tx.CommitTransaction()
  84. default:
  85. return nil
  86. }
  87. return nil
  88. }
  89. // InsertEntity 通过结构插入数据
  90. // 参数:
  91. // - executor: 数据库基础设施接口
  92. // - tableName: 表名
  93. // - es: 结构或结构slice(批量插入),结构字段需要使用sqlmapping标注
  94. // 返回值:
  95. // - 错误
  96. func InsertEntity(executor Executor, tableName string, es any) error {
  97. if executor == nil {
  98. return errors.New("没有传递执行器")
  99. }
  100. if strutils.IsStringEmpty(tableName) {
  101. return errors.New("没有传递表名")
  102. }
  103. if es == nil {
  104. return nil
  105. }
  106. entityType := reflect.TypeOf(es)
  107. entityElemType := reflectutils.PointerTypeElem(entityType)
  108. if entityElemType.Kind() == reflect.Struct {
  109. return insertEntitySingle(executor, tableName, es)
  110. } else if entityElemType.Kind() == reflect.Slice {
  111. return insertEntityBatch(executor, tableName, es)
  112. } else {
  113. return errors.New("实体可以是结构,结构指针,结构Slice,结构指针的Slice或Slice的指针")
  114. }
  115. }
  116. func insertEntitySingle(executor Executor, tableName string, e any) error {
  117. fields, err := sql_mapping.DefaultUsage(e)
  118. if err != nil {
  119. return err
  120. }
  121. executeParams := sql.InsertExecuteParams{
  122. TableName: tableName,
  123. TableRow: formInsertTableRow(fields, time.Now().Local()),
  124. }
  125. executeParamsMap, err := executeParams.Map()
  126. if err != nil {
  127. return err
  128. }
  129. _, err = executor.ExecuteRawSqlTemplate(sql.InsertTpl, executeParamsMap, executeParams.TableRow.Values()...)
  130. if err != nil {
  131. if strings.Contains(err.Error(), "SQLSTATE 23505") {
  132. return ErrDBRecordHasExist
  133. }
  134. return err
  135. }
  136. return nil
  137. }
  138. func insertEntityBatch(executor Executor, tableName string, es any) error {
  139. now := time.Now().Local()
  140. tableRowBatch := make([]sql.TableRow, 0)
  141. entitiesValue := reflectutils.PointerValueElem(reflect.ValueOf(es))
  142. for i := 0; i < entitiesValue.Len(); i++ {
  143. entityValue := entitiesValue.Index(i)
  144. if !entityValue.IsValid() || entityValue.IsZero() {
  145. continue
  146. }
  147. e := entityValue.Interface()
  148. entityType := reflect.TypeOf(e)
  149. if !reflectutils.IsTypeStructOrStructPointer(entityType) {
  150. return errors.New("实体参数不是结构或结构指针")
  151. }
  152. fields, err := sql_mapping.DefaultUsage(e)
  153. if err != nil {
  154. return err
  155. }
  156. tableRowBatch = append(tableRowBatch, *formInsertTableRow(fields, now))
  157. }
  158. executeParams := sql.InsertBatchExecuteParams{
  159. TableName: tableName,
  160. TableRowBatch: tableRowBatch,
  161. }
  162. executeParamsMap, err := executeParams.Map()
  163. if err != nil {
  164. return err
  165. }
  166. values := make([]any, 0)
  167. for _, tableRow := range executeParams.TableRowBatch {
  168. values = append(values, tableRow.Values()...)
  169. }
  170. _, err = executor.ExecuteRawSqlTemplate(sql.InsertTpl, executeParamsMap, values...)
  171. if err != nil {
  172. if strings.Contains(err.Error(), "SQLSTATE 23505") {
  173. return ErrDBRecordHasExist
  174. }
  175. return err
  176. }
  177. return nil
  178. }
  179. func formInsertTableRow(fields []sql_mapping.Field, createTime time.Time) *sql.TableRow {
  180. tableRow := sql.NewTableRow()
  181. for _, field := range fields {
  182. fieldValue := reflect.ValueOf(field.Value)
  183. if (field.FieldName == createdTimeFieldName || field.FieldName == lastUpdatedTimeFieldName) &&
  184. reflectutils.IsValueTime(fieldValue) && fieldValue.IsZero() {
  185. field.Value = createTime
  186. }
  187. if field.FieldName != createdTimeFieldName && field.FieldName != lastUpdatedTimeFieldName &&
  188. reflectutils.IsValueTime(fieldValue) && fieldValue.IsZero() {
  189. field.Value = nil
  190. }
  191. tableRow.Add(field.ColumnName, field.Value)
  192. }
  193. return tableRow
  194. }
  195. // DeleteEntity 通过结构删除数据
  196. // 参数:
  197. // - executor: 数据库基础设施接口
  198. // - tableName: 表名
  199. // - e: 结构,结构字段需要使用sqlmapping标注
  200. // 返回值:
  201. // - 错误
  202. func DeleteEntity(executor Executor, tableName string, e any) error {
  203. return deleteEntityCommon(executor, tableName, e)
  204. }
  205. // DeleteEntityWithScope 通过结构删除数据,可以添加范围条件,如租户ID
  206. // 参数:
  207. // - executor: 数据库基础设施接口
  208. // - tableName: 表名
  209. // - e: 结构,结构字段需要使用sqlmapping标注
  210. // - scopeFields: 范围字段名
  211. // 返回值:
  212. // - 错误
  213. func DeleteEntityWithScope(executor Executor, tableName string, e any, scopeFields ...string) error {
  214. return deleteEntityCommon(executor, tableName, e, scopeFields...)
  215. }
  216. func deleteEntityCommon(executor Executor, tableName string, e any, scopeFields ...string) error {
  217. if executor == nil {
  218. return errors.New("没有传递执行器")
  219. }
  220. if strutils.IsStringEmpty(tableName) {
  221. return errors.New("没有传递表名")
  222. }
  223. if e == nil {
  224. return nil
  225. }
  226. entityType := reflect.TypeOf(e)
  227. if !reflectutils.IsTypeStructOrStructPointer(entityType) {
  228. return errors.New("实体参数不是结构或结构指针")
  229. }
  230. fields, err := sql_mapping.DefaultUsage(e)
  231. if err != nil {
  232. return err
  233. }
  234. conditions := sql.NewConditions()
  235. for _, field := range fields {
  236. if scopeFields != nil && len(scopeFields) != 0 {
  237. for _, scopeField := range scopeFields {
  238. if scopeField != field.FieldName {
  239. continue
  240. }
  241. conditions.Equal(field.ColumnName, field.Value)
  242. }
  243. }
  244. if field.IsKey {
  245. conditions.Equal(field.ColumnName, field.Value)
  246. }
  247. }
  248. executeParams := sql.DeleteExecuteParams{
  249. TableName: tableName,
  250. Conditions: conditions,
  251. }
  252. executeParamsMap, err := executeParams.Map()
  253. if err != nil {
  254. return err
  255. }
  256. _, err = executor.ExecuteRawSqlTemplate(sql.DeleteTpl, executeParamsMap, executeParams.Conditions.Args()...)
  257. if err != nil {
  258. return err
  259. }
  260. return nil
  261. }
  262. // UpdateEntity 通过结构更新数据
  263. // 参数:
  264. // - executor: 数据库基础设施接口
  265. // - tableName: 表名
  266. // - e: 结构,结构字段需要使用sqlmapping标注
  267. // 返回值:
  268. // - 错误
  269. func UpdateEntity(executor Executor, tableName string, e any) error {
  270. _, err := updateEntityCommon(executor, tableName, e)
  271. if err != nil {
  272. return err
  273. }
  274. return nil
  275. }
  276. // UpdateEntityWithScope 通过结构更新数据,可以添加范围条件,如租户ID
  277. // 参数:
  278. // - executor: 数据库基础设施接口
  279. // - tableName: 表名
  280. // - e: 结构,结构字段需要使用sqlmapping标注
  281. // - scopeFields: 范围字段名
  282. // 返回值:
  283. // - 错误
  284. func UpdateEntityWithScope(executor Executor, tableName string, e any, scopeFields ...string) error {
  285. _, err := updateEntityCommon(executor, tableName, e, scopeFields...)
  286. if err != nil {
  287. return err
  288. }
  289. return nil
  290. }
  291. // UpdateEntityWithRowsAffected 通过结构更新数据,返回影响行数
  292. // 参数:
  293. // - executor: 数据库基础设施接口
  294. // - tableName: 表名
  295. // - e: 结构,结构字段需要使用sqlmapping标注
  296. // 返回值:
  297. // - 影响行数
  298. // - 错误
  299. func UpdateEntityWithRowsAffected(executor Executor, tableName string, e any) (int64, error) {
  300. return updateEntityCommon(executor, tableName, e)
  301. }
  302. // UpdateEntityWithRowsAffectedAndScope 通过结构更新数据,可以添加范围条件,如租户ID,返回影响行数
  303. // 参数:
  304. // - executor: 数据库基础设施接口
  305. // - tableName: 表名
  306. // - e: 结构,结构字段需要使用sqlmapping标注
  307. // - scopeFields: 范围字段名
  308. // 返回值:
  309. // - 影响行数
  310. // - 错误
  311. func UpdateEntityWithRowsAffectedAndScope(executor Executor, tableName string, e any, scopeFields ...string) (int64, error) {
  312. return updateEntityCommon(executor, tableName, e, scopeFields...)
  313. }
  314. func updateEntityCommon(executor Executor, tableName string, e any, scopeFields ...string) (int64, error) {
  315. if executor == nil {
  316. return 0, errors.New("没有传递执行器")
  317. }
  318. if strutils.IsStringEmpty(tableName) {
  319. return 0, errors.New("没有传递表名")
  320. }
  321. if e == nil {
  322. return 0, nil
  323. }
  324. entityType := reflect.TypeOf(e)
  325. if !reflectutils.IsTypeStructOrStructPointer(entityType) {
  326. return 0, errors.New("实体参数不是结构或结构指针")
  327. }
  328. fields, err := sql_mapping.DefaultUsage(e)
  329. if err != nil {
  330. return 0, err
  331. }
  332. now := time.Now().Local()
  333. tableRow := sql.NewTableRow()
  334. conditions := sql.NewConditions()
  335. for _, field := range fields {
  336. if scopeFields != nil && len(scopeFields) != 0 {
  337. for _, scopeField := range scopeFields {
  338. if scopeField != field.FieldName {
  339. continue
  340. }
  341. conditions.Equal(field.ColumnName, field.Value)
  342. }
  343. }
  344. // 不是键字段
  345. // 不是更新时间字段
  346. // 不更新的字段或者字段为零值且不能清空,跳过
  347. if !field.IsKey && field.FieldName != lastUpdatedTimeFieldName &&
  348. (!field.CanUpdate || (reflect.ValueOf(field.Value).IsZero() && !field.CanUpdateClear)) {
  349. continue
  350. }
  351. fieldValue := reflect.ValueOf(field.Value)
  352. if field.FieldName == lastUpdatedTimeFieldName &&
  353. reflectutils.IsValueTime(fieldValue) && fieldValue.IsZero() {
  354. field.Value = now
  355. }
  356. if field.FieldName != lastUpdatedTimeFieldName &&
  357. reflectutils.IsValueTime(fieldValue) && fieldValue.IsZero() {
  358. field.Value = nil
  359. }
  360. if field.IsKey {
  361. conditions.Equal(field.ColumnName, field.Value)
  362. } else {
  363. if (field.Value == nil || reflect.ValueOf(field.Value).IsZero()) && !field.CanUpdateClear {
  364. continue
  365. }
  366. tableRow.Add(field.ColumnName, field.Value)
  367. }
  368. }
  369. executeParams := sql.UpdateExecuteParams{
  370. TableName: tableName,
  371. TableRow: tableRow,
  372. Conditions: conditions,
  373. }
  374. executeParamsMap, err := executeParams.Map()
  375. if err != nil {
  376. return 0, err
  377. }
  378. args := make([]any, 0)
  379. args = append(args, executeParams.TableRow.Values()...)
  380. args = append(args, executeParams.Conditions.Args()...)
  381. _, rowsAffected, err := executor.ExecuteRawSqlTemplateWithRowsAffected(sql.UpdateTpl, executeParamsMap, args...)
  382. if err != nil {
  383. return 0, err
  384. }
  385. return rowsAffected, nil
  386. }
  387. // Insert 插入数据
  388. // 参数:
  389. // - executor: 数据库基础设施接口
  390. // - executeParams: 插入数据参数
  391. // 返回值:
  392. // - 错误
  393. func Insert(executor Executor, executeParams *sql.InsertExecuteParams) error {
  394. if executor == nil {
  395. return errors.New("没有传递执行器")
  396. }
  397. if executeParams == nil {
  398. return errors.New("没有传递执行参数")
  399. }
  400. executeParamsMap, err := executeParams.Map()
  401. if err != nil {
  402. return err
  403. }
  404. _, err = executor.ExecuteRawSqlTemplate(sql.InsertTpl, executeParamsMap, executeParams.TableRow.Values()...)
  405. if err != nil {
  406. return err
  407. }
  408. return nil
  409. }
  410. // InsertBatch 批量插入数据
  411. // 参数:
  412. // - executor: 数据库基础设施接口
  413. // - executeParams: 批量插入数据参数
  414. // 返回值:
  415. // - 错误
  416. func InsertBatch(executor Executor, executeParams *sql.InsertBatchExecuteParams) error {
  417. if executor == nil {
  418. return errors.New("没有传递执行器")
  419. }
  420. if executeParams == nil {
  421. return errors.New("没有传递执行参数")
  422. }
  423. executeParamsMap, err := executeParams.Map()
  424. if err != nil {
  425. return err
  426. }
  427. values := make([]any, 0)
  428. for _, tableRow := range executeParams.TableRowBatch {
  429. values = append(values, tableRow.Values()...)
  430. }
  431. _, err = executor.ExecuteRawSqlTemplate(sql.InsertTpl, executeParamsMap, values...)
  432. if err != nil {
  433. return err
  434. }
  435. return nil
  436. }
  437. // Delete 删除数据
  438. // 参数:
  439. // - executor: 数据库基础设施接口
  440. // - executeParams: 删除数据参数
  441. // 返回值:
  442. // - 错误
  443. func Delete(executor Executor, executeParams *sql.DeleteExecuteParams) error {
  444. if executor == nil {
  445. return errors.New("没有传递执行器")
  446. }
  447. if executeParams == nil {
  448. return errors.New("没有传递执行参数")
  449. }
  450. executeParamsMap, err := executeParams.Map()
  451. if err != nil {
  452. return err
  453. }
  454. _, err = executor.ExecuteRawSqlTemplate(sql.DeleteTpl, executeParamsMap, executeParams.Conditions.Args()...)
  455. if err != nil {
  456. return err
  457. }
  458. return nil
  459. }
  460. // Update 更新数据
  461. // 参数:
  462. // - executor: 数据库基础设施接口
  463. // - executeParams: 更新数据参数
  464. // 返回值:
  465. // - 错误
  466. func Update(executor Executor, executeParams *sql.UpdateExecuteParams) error {
  467. _, err := UpdateWithRowsAffected(executor, executeParams)
  468. if err != nil {
  469. return err
  470. }
  471. return nil
  472. }
  473. // UpdateWithRowsAffected 更新数据,返回影响行数
  474. // 参数:
  475. // - executor: 数据库基础设施接口
  476. // - executeParams: 更新数据参数
  477. // 返回值:
  478. // - 影响行数
  479. // - 错误
  480. func UpdateWithRowsAffected(executor Executor, executeParams *sql.UpdateExecuteParams) (int64, error) {
  481. if executor == nil {
  482. return 0, errors.New("没有传递执行器")
  483. }
  484. if executeParams == nil {
  485. return 0, errors.New("没有传递执行参数")
  486. }
  487. if executeParams.Conditions == nil {
  488. executeParams.Conditions = sql.NewConditions()
  489. }
  490. executeParamsMap, err := executeParams.Map()
  491. if err != nil {
  492. return 0, err
  493. }
  494. args := make([]any, 0)
  495. args = append(args, executeParams.TableRow.Values()...)
  496. args = append(args, executeParams.Conditions.Args()...)
  497. _, rowsAffected, err := executor.ExecuteRawSqlTemplateWithRowsAffected(sql.UpdateTpl, executeParamsMap, args...)
  498. if err != nil {
  499. return 0, err
  500. }
  501. return rowsAffected, nil
  502. }
  503. // Query 查询数据
  504. // 参数:
  505. // - executor: 数据库基础设施接口
  506. // - executeParams: 查询数据参数
  507. // 返回值:
  508. // - 查询结果
  509. // - 总数
  510. // - 错误
  511. func Query(executor Executor, executeParams *sql.QueryExecuteParams) ([]sql.Result, int64, error) {
  512. if executor == nil {
  513. return nil, 0, errors.New("没有传递执行器")
  514. }
  515. if executeParams == nil {
  516. return nil, 0, errors.New("没有传递执行参数")
  517. }
  518. if executeParams.Conditions == nil {
  519. executeParams.Conditions = sql.NewConditions()
  520. }
  521. queryExecuteParamsMap, err := executeParams.Map()
  522. if err != nil {
  523. return nil, 0, err
  524. }
  525. countExecuteParams := sql.CountExecuteParams{
  526. TableName: executeParams.TableName,
  527. Conditions: executeParams.Conditions,
  528. }
  529. countExecuteParamsMap, err := countExecuteParams.Map()
  530. if err != nil {
  531. return nil, 0, err
  532. }
  533. tableRows, err := executor.ExecuteRawSqlTemplate(sql.QueryTpl, queryExecuteParamsMap, executeParams.Conditions.Args()...)
  534. if err != nil {
  535. return nil, 0, err
  536. }
  537. countTableRow, err := executor.ExecuteRawSqlTemplate(sql.CountTpl, countExecuteParamsMap, countExecuteParams.Conditions.Args()...)
  538. if err != nil {
  539. return nil, 0, err
  540. }
  541. results := make([]sql.Result, len(tableRows))
  542. for i, row := range tableRows {
  543. results[i] = row
  544. }
  545. totalCount, err := reflectutils.ToInt64(countTableRow[0]["count"])
  546. if err != nil {
  547. return nil, 0, err
  548. }
  549. return results, totalCount, nil
  550. }
  551. // QueryOne 查询单条数据
  552. // 参数:
  553. // - executor: 数据库基础设施接口
  554. // - executeParams: 查询单条数据参数
  555. // 返回值:
  556. // - 查询结果
  557. // - 错误
  558. func QueryOne(executor Executor, executeParams *sql.QueryOneExecuteParams) (sql.Result, error) {
  559. if executor == nil {
  560. return nil, errors.New("没有传递执行器")
  561. }
  562. if executeParams == nil {
  563. return nil, errors.New("没有传递执行参数")
  564. }
  565. if executeParams.Conditions == nil {
  566. executeParams.Conditions = sql.NewConditions()
  567. }
  568. executeParamsMap, err := executeParams.Map()
  569. if err != nil {
  570. return nil, err
  571. }
  572. tableRows, err := executor.ExecuteRawSqlTemplate(sql.QueryTpl, executeParamsMap, executeParams.Conditions.Args()...)
  573. if err != nil {
  574. return nil, err
  575. }
  576. if tableRows == nil || len(tableRows) == 0 {
  577. return nil, ErrDBRecordNotExist
  578. }
  579. return tableRows[0], nil
  580. }
  581. // Count 数据计数
  582. // 参数:
  583. // - executor: 数据库基础设施接口
  584. // - executeParams: 数据计数参数
  585. // 返回值:
  586. // - 数量
  587. // - 错误
  588. func Count(executor Executor, executeParams *sql.CountExecuteParams) (int64, error) {
  589. if executor == nil {
  590. return 0, errors.New("没有传递执行器")
  591. }
  592. if executeParams == nil {
  593. return 0, errors.New("没有传递执行参数")
  594. }
  595. if executeParams.Conditions == nil {
  596. executeParams.Conditions = sql.NewConditions()
  597. }
  598. executeParamsMap, err := executeParams.Map()
  599. if err != nil {
  600. return 0, err
  601. }
  602. tableRows, err := executor.ExecuteRawSqlTemplate(sql.CountTpl, executeParamsMap, executeParams.Conditions.Args()...)
  603. if err != nil {
  604. return 0, err
  605. }
  606. count, err := reflectutils.ToInt64(tableRows[0]["count"])
  607. if err != nil {
  608. return 0, err
  609. }
  610. return count, nil
  611. }
  612. // CheckExist 数据存在性检查
  613. // 参数:
  614. // - executor: 数据库基础设施接口
  615. // - executeParams: 数据存在性检查参数
  616. // 返回值:
  617. // - 是否存在
  618. // - 错误
  619. func CheckExist(executor Executor, executeParams *sql.CheckExistExecuteParams) (bool, error) {
  620. if executor == nil {
  621. return false, errors.New("没有传递执行器")
  622. }
  623. if executeParams == nil {
  624. return false, errors.New("没有传递执行参数")
  625. }
  626. if executeParams.Conditions == nil {
  627. executeParams.Conditions = sql.NewConditions()
  628. }
  629. executeParamsMap, err := executeParams.Map()
  630. if err != nil {
  631. return false, err
  632. }
  633. tableRows, err := executor.ExecuteRawSqlTemplate(sql.CountTpl, executeParamsMap, executeParams.Conditions.Args()...)
  634. if err != nil {
  635. return false, err
  636. }
  637. count, err := reflectutils.ToInt64(tableRows[0]["count"])
  638. if err != nil {
  639. return false, err
  640. }
  641. return count > 0, nil
  642. }
  643. // CheckHasOnlyOne 数据唯一性检查
  644. // 参数:
  645. // - executor: 数据库基础设施接口
  646. // - executeParams: 数据唯一性检查参数
  647. // 返回值:
  648. // - 是否唯一
  649. // - 错误
  650. func CheckHasOnlyOne(executor Executor, executeParams *sql.CheckHasOnlyOneExecuteParams) (bool, error) {
  651. if executor == nil {
  652. return false, errors.New("没有传递执行器")
  653. }
  654. if executeParams == nil {
  655. return false, errors.New("没有传递执行参数")
  656. }
  657. if executeParams.Conditions == nil {
  658. executeParams.Conditions = sql.NewConditions()
  659. }
  660. executeParamsMap, err := executeParams.Map()
  661. if err != nil {
  662. return false, err
  663. }
  664. tableRows, err := executor.ExecuteRawSqlTemplate(sql.CountTpl, executeParamsMap, executeParams.Conditions.Args()...)
  665. if err != nil {
  666. return false, err
  667. }
  668. count, err := reflectutils.ToInt64(tableRows[0]["count"])
  669. if err != nil {
  670. return false, err
  671. }
  672. return count == 1, nil
  673. }
  674. // ExecuteRawSql SQL执行接口
  675. // 参数:
  676. // - executor: 数据库基础设施接口
  677. // - sql: SQL语句,可以使用预编译,需要填充的值用?占位
  678. // - args: 预编译填充值
  679. // 返回值:
  680. // - SQL执行结果
  681. // - 错误
  682. func ExecuteRawSql(executor Executor, sql string, args ...any) ([]sql.Result, error) {
  683. return ExecuteRawSqlTemplate(executor, sql, nil, args...)
  684. }
  685. // ExecuteRawSqlTemplate SQL模板执行接口
  686. // 参数:
  687. // - executor: 数据库基础设施接口
  688. // - sql: SQL语句模板,可以使用预编译,需要填充的值用?占位,可以使用Go模板构造SQL语句
  689. // - template: 渲染SQL语句模板的模板参数
  690. // - args: 预编译填充值
  691. // 返回值:
  692. // - SQL执行结果
  693. // - 错误
  694. func ExecuteRawSqlTemplate(executor Executor, sql string, executeParams map[string]any, args ...any) ([]sql.Result, error) {
  695. if executor == nil {
  696. return nil, errors.New("没有传递执行器")
  697. }
  698. if strutils.IsStringEmpty(sql) {
  699. return nil, errors.New("没有sql")
  700. }
  701. tableRows, err := executor.ExecuteRawSqlTemplate(sql, executeParams, args...)
  702. if err != nil {
  703. return nil, err
  704. }
  705. return tableRows, nil
  706. }