sql.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. package sql
  2. import (
  3. "errors"
  4. "git.sxidc.com/go-tools/utils/strutils"
  5. "git.sxidc.com/service-supports/ds-sdk/sdk"
  6. "git.sxidc.com/service-supports/ds-sdk/sql/sql_tpl"
  7. "reflect"
  8. "strings"
  9. "time"
  10. )
  11. type Executor interface {
  12. ExecuteRawSql(sql string, executeParams map[string]any) ([]map[string]any, error)
  13. ExecuteSql(name string, executeParams map[string]any) ([]map[string]any, error)
  14. }
  15. const (
  16. createdTimeFieldName = "CreatedTime"
  17. lastUpdatedTimeFieldName = "LastUpdatedTime"
  18. )
  19. func InsertEntity[T any](executor Executor, tableName string, e T) error {
  20. if executor == nil {
  21. return errors.New("没有传递执行器")
  22. }
  23. if strutils.IsStringEmpty(tableName) {
  24. return errors.New("没有传递表名")
  25. }
  26. if reflect.TypeOf(e) == nil {
  27. return errors.New("没有传递实体")
  28. }
  29. tableRows := sql_tpl.NewTableRows()
  30. err := formInsertTableRow(e, tableRows)
  31. if err != nil {
  32. return err
  33. }
  34. executeParamsMap, err := sql_tpl.InsertExecuteParams{
  35. TableName: tableName,
  36. TableRows: tableRows,
  37. }.Map()
  38. if err != nil {
  39. return err
  40. }
  41. _, err = executor.ExecuteRawSql(sql_tpl.InsertTpl, executeParamsMap)
  42. if err != nil {
  43. if strings.Contains(err.Error(), "SQLSTATE 23505") {
  44. return sdk.ErrDBRecordHasExist
  45. }
  46. return err
  47. }
  48. return nil
  49. }
  50. func formInsertTableRow(e any, tableRows *sql_tpl.TableRows) error {
  51. sqlMapping, err := ParseSqlMapping(e)
  52. if err != nil {
  53. return err
  54. }
  55. now := time.Now()
  56. for fieldName, mappingElement := range sqlMapping.MappingElement {
  57. switch element := mappingElement.(type) {
  58. case *MappingStruct:
  59. err := formInsertTableRow(element.FieldValueElem.Addr().Interface(), tableRows)
  60. if err != nil {
  61. return err
  62. }
  63. case *MappingColumn:
  64. if element.IsKey && element.FieldValueElem.IsZero() {
  65. return errors.New("键字段没有传值")
  66. }
  67. fieldType := element.FieldTypeElem
  68. // 有值取值,没有值构造零值
  69. value := reflect.Zero(fieldType).Interface()
  70. if !element.FieldValueElem.IsZero() {
  71. value = element.FieldValueElem.Interface()
  72. }
  73. // 自动添加创建时间和更新时间
  74. if (fieldName == createdTimeFieldName || fieldName == lastUpdatedTimeFieldName) &&
  75. fieldType.String() == "time.Time" && value.(time.Time).IsZero() {
  76. value = now
  77. }
  78. var opts []sql_tpl.AfterParsedStrValueOption
  79. if strutils.IsStringNotEmpty(element.AESKey) {
  80. opts = append(opts, sql_tpl.WithAESKey(element.AESKey))
  81. }
  82. tableRows.Add(element.Name, value, opts...)
  83. default:
  84. return errors.New("不支持的元素类型")
  85. }
  86. }
  87. return nil
  88. }
  89. func DeleteEntity[T any](executor Executor, tableName string, e T) error {
  90. if executor == nil {
  91. return errors.New("没有传递执行器")
  92. }
  93. if strutils.IsStringEmpty(tableName) {
  94. return errors.New("没有传递表名")
  95. }
  96. if reflect.TypeOf(e) == nil {
  97. return errors.New("没有传递实体")
  98. }
  99. conditions := sql_tpl.NewConditions()
  100. err := formDeleteConditions(e, conditions)
  101. if err != nil {
  102. return err
  103. }
  104. executeParamsMap, err := sql_tpl.DeleteExecuteParams{
  105. TableName: tableName,
  106. Conditions: conditions,
  107. }.Map()
  108. if err != nil {
  109. return err
  110. }
  111. _, err = executor.ExecuteRawSql(sql_tpl.DeleteTpl, executeParamsMap)
  112. if err != nil {
  113. return err
  114. }
  115. return nil
  116. }
  117. func formDeleteConditions(e any, conditions *sql_tpl.Conditions) error {
  118. sqlMapping, err := ParseSqlMapping(e)
  119. if err != nil {
  120. return err
  121. }
  122. for _, mappingElement := range sqlMapping.MappingElement {
  123. switch element := mappingElement.(type) {
  124. case *MappingStruct:
  125. err := formDeleteConditions(element.FieldValueElem.Addr().Interface(), conditions)
  126. if err != nil {
  127. return err
  128. }
  129. case *MappingColumn:
  130. // 不是键,字段跳过
  131. if !element.IsKey {
  132. continue
  133. }
  134. // 键字段没有赋值
  135. if element.FieldValueElem.IsZero() {
  136. return errors.New("键字段没有传值")
  137. }
  138. var opts []sql_tpl.AfterParsedStrValueOption
  139. if strutils.IsStringNotEmpty(element.AESKey) {
  140. opts = append(opts, sql_tpl.WithAESKey(element.AESKey))
  141. }
  142. conditions.Equal(element.Name, element.FieldValueElem.Interface(), opts...)
  143. default:
  144. return errors.New("不支持的元素类型")
  145. }
  146. }
  147. return nil
  148. }
  149. func UpdateEntity[T any](executor Executor, tableName string, e T) error {
  150. if executor == nil {
  151. return errors.New("没有传递执行器")
  152. }
  153. if strutils.IsStringEmpty(tableName) {
  154. return errors.New("没有传递表名")
  155. }
  156. if reflect.TypeOf(e) == nil {
  157. return errors.New("没有传递实体")
  158. }
  159. tableRows := sql_tpl.NewTableRows()
  160. conditions := sql_tpl.NewConditions()
  161. err := formUpdateTableRowsAndConditions(e, tableRows, conditions)
  162. if err != nil {
  163. return err
  164. }
  165. executeParamsMap, err := sql_tpl.UpdateExecuteParams{
  166. TableName: tableName,
  167. TableRows: tableRows,
  168. Conditions: conditions,
  169. }.Map()
  170. if err != nil {
  171. return err
  172. }
  173. _, err = executor.ExecuteRawSql(sql_tpl.UpdateTpl, executeParamsMap)
  174. if err != nil {
  175. return err
  176. }
  177. return nil
  178. }
  179. func formUpdateTableRowsAndConditions(e any, tableRows *sql_tpl.TableRows, conditions *sql_tpl.Conditions) error {
  180. sqlMapping, err := ParseSqlMapping(e)
  181. if err != nil {
  182. return err
  183. }
  184. now := time.Now()
  185. for fieldName, mappingElement := range sqlMapping.MappingElement {
  186. switch element := mappingElement.(type) {
  187. case *MappingStruct:
  188. err := formUpdateTableRowsAndConditions(element.FieldValueElem.Addr().Interface(), tableRows, conditions)
  189. if err != nil {
  190. return err
  191. }
  192. case *MappingColumn:
  193. if element.IsKey {
  194. // 键字段但是没有赋值
  195. if element.FieldValueElem.IsZero() {
  196. return errors.New("键字段没有传值")
  197. }
  198. } else {
  199. // 不是更新时间字段
  200. // 不是键字段
  201. // 不更新的字段或者字段为空且不能清空,跳过
  202. if fieldName != lastUpdatedTimeFieldName &&
  203. (!element.CanUpdate || (element.FieldValueElem.IsZero() && !element.CanUpdateClear)) {
  204. continue
  205. }
  206. }
  207. fieldType := element.FieldTypeElem
  208. value := reflect.Zero(fieldType).Interface()
  209. if !element.FieldValueElem.IsZero() {
  210. value = element.FieldValueElem.Interface()
  211. }
  212. if fieldName == lastUpdatedTimeFieldName &&
  213. fieldType.String() == "time.Time" && value.(time.Time).IsZero() {
  214. value = now
  215. }
  216. var opts []sql_tpl.AfterParsedStrValueOption
  217. if strutils.IsStringNotEmpty(element.AESKey) {
  218. opts = append(opts, sql_tpl.WithAESKey(element.AESKey))
  219. }
  220. if element.IsKey {
  221. conditions.Equal(element.Name, value, opts...)
  222. } else {
  223. tableRows.Add(element.Name, value, opts...)
  224. }
  225. default:
  226. return errors.New("不支持的元素类型")
  227. }
  228. }
  229. return nil
  230. }
  231. func Insert(executor Executor, executeParams *sql_tpl.InsertExecuteParams) error {
  232. if executor == nil {
  233. return errors.New("没有传递执行器")
  234. }
  235. if executeParams == nil {
  236. return errors.New("没有传递执行参数")
  237. }
  238. executeParamsMap, err := executeParams.Map()
  239. if err != nil {
  240. return err
  241. }
  242. _, err = executor.ExecuteRawSql(sql_tpl.InsertTpl, executeParamsMap)
  243. if err != nil {
  244. return err
  245. }
  246. return nil
  247. }
  248. func Delete(executor Executor, executeParams *sql_tpl.DeleteExecuteParams) error {
  249. if executor == nil {
  250. return errors.New("没有传递执行器")
  251. }
  252. if executeParams == nil {
  253. return errors.New("没有传递执行参数")
  254. }
  255. executeParamsMap, err := executeParams.Map()
  256. if err != nil {
  257. return err
  258. }
  259. _, err = executor.ExecuteRawSql(sql_tpl.DeleteTpl, executeParamsMap)
  260. if err != nil {
  261. return err
  262. }
  263. return nil
  264. }
  265. func Update(executor Executor, executeParams *sql_tpl.UpdateExecuteParams) error {
  266. if executor == nil {
  267. return errors.New("没有传递执行器")
  268. }
  269. if executeParams == nil {
  270. return errors.New("没有传递执行参数")
  271. }
  272. executeParamsMap, err := executeParams.Map()
  273. if err != nil {
  274. return err
  275. }
  276. _, err = executor.ExecuteRawSql(sql_tpl.UpdateTpl, executeParamsMap)
  277. if err != nil {
  278. return err
  279. }
  280. return nil
  281. }
  282. func Query(executor Executor, executeParams *sql_tpl.QueryExecuteParams) ([]map[string]any, int64, error) {
  283. if executor == nil {
  284. return nil, 0, errors.New("没有传递执行器")
  285. }
  286. if executeParams == nil {
  287. return nil, 0, errors.New("没有传递执行参数")
  288. }
  289. queryExecuteParamsMap, err := executeParams.Map()
  290. if err != nil {
  291. return nil, 0, err
  292. }
  293. countExecuteParamsMap, err := sql_tpl.CountExecuteParams{
  294. TableName: executeParams.TableName,
  295. Conditions: executeParams.Conditions,
  296. }.Map()
  297. if err != nil {
  298. return nil, 0, err
  299. }
  300. tableRows, err := executor.ExecuteRawSql(sql_tpl.QueryTpl, queryExecuteParamsMap)
  301. if err != nil {
  302. return nil, 0, err
  303. }
  304. countTableRow, err := executor.ExecuteRawSql(sql_tpl.CountTpl, countExecuteParamsMap)
  305. if err != nil {
  306. return nil, 0, err
  307. }
  308. return tableRows, int64(countTableRow[0]["count"].(float64)), nil
  309. }
  310. func QueryOne(executor Executor, executeParams *sql_tpl.QueryOneExecuteParams) (map[string]any, error) {
  311. if executor == nil {
  312. return nil, errors.New("没有传递执行器")
  313. }
  314. if executeParams == nil {
  315. return nil, errors.New("没有传递执行参数")
  316. }
  317. executeParamsMap, err := executeParams.Map()
  318. if err != nil {
  319. return nil, err
  320. }
  321. tableRows, err := executor.ExecuteRawSql(sql_tpl.QueryTpl, executeParamsMap)
  322. if err != nil {
  323. return nil, err
  324. }
  325. if tableRows == nil || len(tableRows) == 0 {
  326. return nil, sdk.ErrDBRecordNotExist
  327. }
  328. return tableRows[0], nil
  329. }
  330. func Count(executor Executor, executeParams *sql_tpl.CountExecuteParams) (int64, error) {
  331. if executor == nil {
  332. return 0, errors.New("没有传递执行器")
  333. }
  334. if executeParams == nil {
  335. return 0, errors.New("没有传递执行参数")
  336. }
  337. executeParamsMap, err := executeParams.Map()
  338. if err != nil {
  339. return 0, err
  340. }
  341. tableRows, err := executor.ExecuteRawSql(sql_tpl.CountTpl, executeParamsMap)
  342. if err != nil {
  343. return 0, err
  344. }
  345. return int64(tableRows[0]["count"].(float64)), nil
  346. }
  347. func CheckExist(executor Executor, executeParams *sql_tpl.CheckExistExecuteParams) (bool, error) {
  348. if executor == nil {
  349. return false, errors.New("没有传递执行器")
  350. }
  351. if executeParams == nil {
  352. return false, errors.New("没有传递执行参数")
  353. }
  354. executeParamsMap, err := executeParams.Map()
  355. if err != nil {
  356. return false, err
  357. }
  358. tableRows, err := executor.ExecuteRawSql(sql_tpl.CountTpl, executeParamsMap)
  359. if err != nil {
  360. return false, err
  361. }
  362. return int64(tableRows[0]["count"].(float64)) > 0, nil
  363. }
  364. func CheckHasOnlyOne(executor Executor, executeParams *sql_tpl.CheckHasOnlyOneExecuteParams) (bool, error) {
  365. if executor == nil {
  366. return false, errors.New("没有传递执行器")
  367. }
  368. if executeParams == nil {
  369. return false, errors.New("没有传递执行参数")
  370. }
  371. executeParamsMap, err := executeParams.Map()
  372. if err != nil {
  373. return false, err
  374. }
  375. tableRows, err := executor.ExecuteRawSql(sql_tpl.CountTpl, executeParamsMap)
  376. if err != nil {
  377. return false, err
  378. }
  379. return int64(tableRows[0]["count"].(float64)) == 1, nil
  380. }
  381. func ExecuteRawSql(executor Executor, sql string, executeParams map[string]any) ([]map[string]any, error) {
  382. if executor == nil {
  383. return nil, errors.New("没有传递执行器")
  384. }
  385. if strutils.IsStringEmpty(sql) {
  386. return nil, errors.New("没有sql")
  387. }
  388. tableRows, err := executor.ExecuteRawSql(sql, executeParams)
  389. if err != nil {
  390. return nil, err
  391. }
  392. return tableRows, nil
  393. }
  394. func ExecuteSql(executor Executor, name string, executeParams map[string]any) ([]map[string]any, error) {
  395. if executor == nil {
  396. return nil, errors.New("没有传递执行器")
  397. }
  398. if strutils.IsStringEmpty(name) {
  399. return nil, errors.New("没有sql资源名称")
  400. }
  401. tableRows, err := executor.ExecuteSql(name, executeParams)
  402. if err != nil {
  403. return nil, err
  404. }
  405. return tableRows, nil
  406. }