sql.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  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 fieldType.Kind() != reflect.Slice {
  71. if !element.FieldValueElem.IsZero() {
  72. value = element.FieldValueElem.Interface()
  73. }
  74. // 自动添加创建时间和更新时间
  75. if (fieldName == createdTimeFieldName || fieldName == lastUpdatedTimeFieldName) &&
  76. fieldType.String() == "time.Time" && value.(time.Time).IsZero() {
  77. value = now
  78. }
  79. } else {
  80. sliceElementType := fieldType.Elem()
  81. if sliceElementType.Kind() != reflect.String {
  82. return errors.New("slice仅支持[]string")
  83. }
  84. if element.FieldValueElem.Len() == 0 {
  85. continue
  86. }
  87. strValues := make([]string, 0, 0)
  88. for i := 0; i < element.FieldValueElem.Len(); i++ {
  89. strValues = append(strValues, element.FieldValueElem.Index(i).String())
  90. }
  91. value = strings.Join(strValues, element.JoinWith)
  92. }
  93. var opts []sql_tpl.AfterParsedStrValueOption
  94. if strutils.IsStringNotEmpty(element.AESKey) {
  95. opts = append(opts, sql_tpl.WithAESKey(element.AESKey))
  96. }
  97. tableRows.Add(element.Name, value, opts...)
  98. default:
  99. return errors.New("不支持的元素类型")
  100. }
  101. }
  102. return nil
  103. }
  104. func DeleteEntity[T any](executor Executor, tableName string, e T) error {
  105. if executor == nil {
  106. return errors.New("没有传递执行器")
  107. }
  108. if strutils.IsStringEmpty(tableName) {
  109. return errors.New("没有传递表名")
  110. }
  111. if reflect.TypeOf(e) == nil {
  112. return errors.New("没有传递实体")
  113. }
  114. conditions := sql_tpl.NewConditions()
  115. err := formDeleteConditions(e, conditions)
  116. if err != nil {
  117. return err
  118. }
  119. executeParamsMap, err := sql_tpl.DeleteExecuteParams{
  120. TableName: tableName,
  121. Conditions: conditions,
  122. }.Map()
  123. if err != nil {
  124. return err
  125. }
  126. _, err = executor.ExecuteRawSql(sql_tpl.DeleteTpl, executeParamsMap)
  127. if err != nil {
  128. return err
  129. }
  130. return nil
  131. }
  132. func formDeleteConditions(e any, conditions *sql_tpl.Conditions) error {
  133. sqlMapping, err := ParseSqlMapping(e)
  134. if err != nil {
  135. return err
  136. }
  137. for _, mappingElement := range sqlMapping.MappingElement {
  138. switch element := mappingElement.(type) {
  139. case *MappingStruct:
  140. err := formDeleteConditions(element.FieldValueElem.Addr().Interface(), conditions)
  141. if err != nil {
  142. return err
  143. }
  144. case *MappingColumn:
  145. // 不是键,字段跳过
  146. if !element.IsKey {
  147. continue
  148. }
  149. // 键字段没有赋值
  150. if element.FieldValueElem.IsZero() {
  151. return errors.New("键字段没有传值")
  152. }
  153. var opts []sql_tpl.AfterParsedStrValueOption
  154. if strutils.IsStringNotEmpty(element.AESKey) {
  155. opts = append(opts, sql_tpl.WithAESKey(element.AESKey))
  156. }
  157. conditions.Equal(element.Name, element.FieldValueElem.Interface(), opts...)
  158. default:
  159. return errors.New("不支持的元素类型")
  160. }
  161. }
  162. return nil
  163. }
  164. func UpdateEntity[T any](executor Executor, tableName string, e T) error {
  165. if executor == nil {
  166. return errors.New("没有传递执行器")
  167. }
  168. if strutils.IsStringEmpty(tableName) {
  169. return errors.New("没有传递表名")
  170. }
  171. if reflect.TypeOf(e) == nil {
  172. return errors.New("没有传递实体")
  173. }
  174. tableRows := sql_tpl.NewTableRows()
  175. conditions := sql_tpl.NewConditions()
  176. err := formUpdateTableRowsAndConditions(e, tableRows, conditions)
  177. if err != nil {
  178. return err
  179. }
  180. executeParamsMap, err := sql_tpl.UpdateExecuteParams{
  181. TableName: tableName,
  182. TableRows: tableRows,
  183. Conditions: conditions,
  184. }.Map()
  185. if err != nil {
  186. return err
  187. }
  188. _, err = executor.ExecuteRawSql(sql_tpl.UpdateTpl, executeParamsMap)
  189. if err != nil {
  190. return err
  191. }
  192. return nil
  193. }
  194. func formUpdateTableRowsAndConditions(e any, tableRows *sql_tpl.TableRows, conditions *sql_tpl.Conditions) error {
  195. sqlMapping, err := ParseSqlMapping(e)
  196. if err != nil {
  197. return err
  198. }
  199. now := time.Now()
  200. for fieldName, mappingElement := range sqlMapping.MappingElement {
  201. switch element := mappingElement.(type) {
  202. case *MappingStruct:
  203. err := formUpdateTableRowsAndConditions(element.FieldValueElem.Addr().Interface(), tableRows, conditions)
  204. if err != nil {
  205. return err
  206. }
  207. case *MappingColumn:
  208. if element.IsKey {
  209. // 键字段但是没有赋值
  210. if element.FieldValueElem.IsZero() {
  211. return errors.New("键字段没有传值")
  212. }
  213. } else {
  214. // 不是更新时间字段
  215. // 不是键字段
  216. // 不更新的字段或者字段为空且不能清空,跳过
  217. if fieldName != lastUpdatedTimeFieldName &&
  218. (!element.CanUpdate || (element.FieldValueElem.IsZero() && !element.CanUpdateClear)) {
  219. continue
  220. }
  221. }
  222. fieldType := element.FieldTypeElem
  223. value := reflect.Zero(fieldType).Interface()
  224. if fieldType.Kind() != reflect.Slice {
  225. if !element.FieldValueElem.IsZero() {
  226. value = element.FieldValueElem.Interface()
  227. }
  228. // 自动添加创建时间和更新时间
  229. if (fieldName == createdTimeFieldName || fieldName == lastUpdatedTimeFieldName) &&
  230. fieldType.String() == "time.Time" && value.(time.Time).IsZero() {
  231. value = now
  232. }
  233. } else {
  234. sliceElementType := fieldType.Elem()
  235. if sliceElementType.Kind() != reflect.String {
  236. return errors.New("slice仅支持[]string")
  237. }
  238. if element.FieldValueElem.Len() == 0 {
  239. continue
  240. }
  241. strValues := make([]string, 0, 0)
  242. for i := 0; i < element.FieldValueElem.Len(); i++ {
  243. strValues = append(strValues, element.FieldValueElem.Index(i).String())
  244. }
  245. value = strings.Join(strValues, element.JoinWith)
  246. }
  247. if fieldName == lastUpdatedTimeFieldName &&
  248. fieldType.String() == "time.Time" && value.(time.Time).IsZero() {
  249. value = now
  250. }
  251. var opts []sql_tpl.AfterParsedStrValueOption
  252. if strutils.IsStringNotEmpty(element.AESKey) {
  253. opts = append(opts, sql_tpl.WithAESKey(element.AESKey))
  254. }
  255. if element.IsKey {
  256. conditions.Equal(element.Name, value, opts...)
  257. } else {
  258. tableRows.Add(element.Name, value, opts...)
  259. }
  260. default:
  261. return errors.New("不支持的元素类型")
  262. }
  263. }
  264. return nil
  265. }
  266. func Insert(executor Executor, executeParams *sql_tpl.InsertExecuteParams) error {
  267. if executor == nil {
  268. return errors.New("没有传递执行器")
  269. }
  270. if executeParams == nil {
  271. return errors.New("没有传递执行参数")
  272. }
  273. executeParamsMap, err := executeParams.Map()
  274. if err != nil {
  275. return err
  276. }
  277. _, err = executor.ExecuteRawSql(sql_tpl.InsertTpl, executeParamsMap)
  278. if err != nil {
  279. return err
  280. }
  281. return nil
  282. }
  283. func Delete(executor Executor, executeParams *sql_tpl.DeleteExecuteParams) error {
  284. if executor == nil {
  285. return errors.New("没有传递执行器")
  286. }
  287. if executeParams == nil {
  288. return errors.New("没有传递执行参数")
  289. }
  290. executeParamsMap, err := executeParams.Map()
  291. if err != nil {
  292. return err
  293. }
  294. _, err = executor.ExecuteRawSql(sql_tpl.DeleteTpl, executeParamsMap)
  295. if err != nil {
  296. return err
  297. }
  298. return nil
  299. }
  300. func Update(executor Executor, executeParams *sql_tpl.UpdateExecuteParams) error {
  301. if executor == nil {
  302. return errors.New("没有传递执行器")
  303. }
  304. if executeParams == nil {
  305. return errors.New("没有传递执行参数")
  306. }
  307. executeParamsMap, err := executeParams.Map()
  308. if err != nil {
  309. return err
  310. }
  311. _, err = executor.ExecuteRawSql(sql_tpl.UpdateTpl, executeParamsMap)
  312. if err != nil {
  313. return err
  314. }
  315. return nil
  316. }
  317. func Query(executor Executor, executeParams *sql_tpl.QueryExecuteParams) ([]map[string]any, int64, error) {
  318. if executor == nil {
  319. return nil, 0, errors.New("没有传递执行器")
  320. }
  321. if executeParams == nil {
  322. return nil, 0, errors.New("没有传递执行参数")
  323. }
  324. queryExecuteParamsMap, err := executeParams.Map()
  325. if err != nil {
  326. return nil, 0, err
  327. }
  328. countExecuteParamsMap, err := sql_tpl.CountExecuteParams{
  329. TableName: executeParams.TableName,
  330. Conditions: executeParams.Conditions,
  331. }.Map()
  332. if err != nil {
  333. return nil, 0, err
  334. }
  335. tableRows, err := executor.ExecuteRawSql(sql_tpl.QueryTpl, queryExecuteParamsMap)
  336. if err != nil {
  337. return nil, 0, err
  338. }
  339. countTableRow, err := executor.ExecuteRawSql(sql_tpl.CountTpl, countExecuteParamsMap)
  340. if err != nil {
  341. return nil, 0, err
  342. }
  343. return tableRows, int64(countTableRow[0]["count"].(float64)), nil
  344. }
  345. func QueryOne(executor Executor, executeParams *sql_tpl.QueryOneExecuteParams) (map[string]any, error) {
  346. if executor == nil {
  347. return nil, errors.New("没有传递执行器")
  348. }
  349. if executeParams == nil {
  350. return nil, errors.New("没有传递执行参数")
  351. }
  352. executeParamsMap, err := executeParams.Map()
  353. if err != nil {
  354. return nil, err
  355. }
  356. tableRows, err := executor.ExecuteRawSql(sql_tpl.QueryTpl, executeParamsMap)
  357. if err != nil {
  358. return nil, err
  359. }
  360. if tableRows == nil || len(tableRows) == 0 {
  361. return nil, sdk.ErrDBRecordNotExist
  362. }
  363. return tableRows[0], nil
  364. }
  365. func Count(executor Executor, executeParams *sql_tpl.CountExecuteParams) (int64, error) {
  366. if executor == nil {
  367. return 0, errors.New("没有传递执行器")
  368. }
  369. if executeParams == nil {
  370. return 0, errors.New("没有传递执行参数")
  371. }
  372. executeParamsMap, err := executeParams.Map()
  373. if err != nil {
  374. return 0, err
  375. }
  376. tableRows, err := executor.ExecuteRawSql(sql_tpl.CountTpl, executeParamsMap)
  377. if err != nil {
  378. return 0, err
  379. }
  380. return int64(tableRows[0]["count"].(float64)), nil
  381. }
  382. func CheckExist(executor Executor, executeParams *sql_tpl.CheckExistExecuteParams) (bool, error) {
  383. if executor == nil {
  384. return false, errors.New("没有传递执行器")
  385. }
  386. if executeParams == nil {
  387. return false, errors.New("没有传递执行参数")
  388. }
  389. executeParamsMap, err := executeParams.Map()
  390. if err != nil {
  391. return false, err
  392. }
  393. tableRows, err := executor.ExecuteRawSql(sql_tpl.CountTpl, executeParamsMap)
  394. if err != nil {
  395. return false, err
  396. }
  397. return int64(tableRows[0]["count"].(float64)) > 0, nil
  398. }
  399. func CheckHasOnlyOne(executor Executor, executeParams *sql_tpl.CheckHasOnlyOneExecuteParams) (bool, error) {
  400. if executor == nil {
  401. return false, errors.New("没有传递执行器")
  402. }
  403. if executeParams == nil {
  404. return false, errors.New("没有传递执行参数")
  405. }
  406. executeParamsMap, err := executeParams.Map()
  407. if err != nil {
  408. return false, err
  409. }
  410. tableRows, err := executor.ExecuteRawSql(sql_tpl.CountTpl, executeParamsMap)
  411. if err != nil {
  412. return false, err
  413. }
  414. return int64(tableRows[0]["count"].(float64)) == 1, nil
  415. }
  416. func ExecuteRawSql(executor Executor, sql string, executeParams map[string]any) ([]map[string]any, error) {
  417. if executor == nil {
  418. return nil, errors.New("没有传递执行器")
  419. }
  420. if strutils.IsStringEmpty(sql) {
  421. return nil, errors.New("没有sql")
  422. }
  423. tableRows, err := executor.ExecuteRawSql(sql, executeParams)
  424. if err != nil {
  425. return nil, err
  426. }
  427. return tableRows, nil
  428. }
  429. func ExecuteSql(executor Executor, name string, executeParams map[string]any) ([]map[string]any, error) {
  430. if executor == nil {
  431. return nil, errors.New("没有传递执行器")
  432. }
  433. if strutils.IsStringEmpty(name) {
  434. return nil, errors.New("没有sql资源名称")
  435. }
  436. tableRows, err := executor.ExecuteSql(name, executeParams)
  437. if err != nil {
  438. return nil, err
  439. }
  440. return tableRows, nil
  441. }