sdk_test.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. package main
  2. import (
  3. "fmt"
  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"
  7. "git.sxidc.com/service-supports/ds-sdk/sql/sql_tpl"
  8. "github.com/iancoleman/strcase"
  9. "math/rand"
  10. "strings"
  11. "sync"
  12. "testing"
  13. "time"
  14. )
  15. type IDField struct {
  16. ID string
  17. }
  18. type TimeFields struct {
  19. CreatedTime *time.Time
  20. LastUpdatedTime time.Time
  21. }
  22. type GraduatedTimeTestStruct struct {
  23. Field *string `sqlmapping:"-" sqlresult:"column:graduated_time;parseTime:2006-01-02 15:04:05"`
  24. }
  25. type Class struct {
  26. IDField
  27. Name string `sqlmapping:"updateClear;aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;" sqlresult:"aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;"`
  28. StudentNum int `sqlmapping:"column:student_num;notUpdate;" sqlresult:"column:student_num_alias"`
  29. GraduatedTime *time.Time
  30. StudentIDs []string `sqlmapping:"column:student_ids;joinWith:'\n'" sqlresult:"column:student_ids;splitWith:'\n'"`
  31. TimeFields
  32. Ignored string `sqlmapping:"-" sqlresult:"-"`
  33. *GraduatedTimeTestStruct
  34. }
  35. const (
  36. token = "IpTTwAQweh/BP51fz5CzWKQFaXHvZe6ewvk6yOcAOkU="
  37. address = "localhost"
  38. httpPort = "10000"
  39. grpcPort = "10001"
  40. namespace = "ns-sdk-demo"
  41. dataSource = "ds-sdk-demo"
  42. deleteSql = "delete-sdk-demo"
  43. goRoutineCount = 100
  44. tableName = "test.classes"
  45. )
  46. var (
  47. sqlSpec = sdk.SqlSpec{
  48. Clauses: "- DELETE FROM {{ .table_name }} WHERE id = '{{ .id }}'",
  49. }
  50. )
  51. const (
  52. sqlResultTimeMicroFormat = "2006-01-02T15:04:05.000000+08:00"
  53. sqlResultTimeMilliFormat = "2006-01-02T15:04:05.000+08:00"
  54. sqlResultTimeSecFormat = "2006-01-02T15:04:05+08:00"
  55. )
  56. func chooseTimeLayout(timeStr string) string {
  57. if strings.HasSuffix(timeStr, ".000000+08:00") {
  58. return sqlResultTimeMicroFormat
  59. } else if strings.HasSuffix(timeStr, ".000+08:00") {
  60. return sqlResultTimeMilliFormat
  61. } else {
  62. return sqlResultTimeSecFormat
  63. }
  64. }
  65. func TestBasic(t *testing.T) {
  66. classID := strutils.SimpleUUID()
  67. className := strutils.SimpleUUID()
  68. studentNum := rand.Int31n(100)
  69. studentIDs := []string{strutils.SimpleUUID(), strutils.SimpleUUID()}
  70. now := time.Now()
  71. insertExecuteParams, err := sql_tpl.InsertExecuteParams{
  72. TableName: tableName,
  73. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  74. Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  75. Add("student_num", studentNum).
  76. Add("student_ids", strings.Join(studentIDs, "\n")).
  77. Add("graduated_time", now).
  78. Add("created_time", now).
  79. Add("last_updated_time", now),
  80. }.Map()
  81. if err != nil {
  82. t.Fatal(err)
  83. }
  84. deleteExecuteParams := map[string]any{
  85. "table_name": tableName,
  86. "id": classID,
  87. }
  88. err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  89. if err != nil {
  90. t.Fatal(err)
  91. }
  92. defer func() {
  93. err := sdk.DestroyInstance()
  94. if err != nil {
  95. t.Fatal(err)
  96. }
  97. }()
  98. err = sdk.GetInstance().CreateSQL(deleteSql, sqlSpec.ToMap())
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. defer func() {
  103. err = sdk.GetInstance().DeleteSQL(deleteSql)
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. }()
  108. _, err = sdk.GetInstance().ExecuteRawSql(sql_tpl.InsertTpl, insertExecuteParams)
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. _, err = sdk.GetInstance().ExecuteSql(deleteSql, deleteExecuteParams)
  113. if err != nil {
  114. t.Fatal(err)
  115. }
  116. wg := sync.WaitGroup{}
  117. wg.Add(goRoutineCount)
  118. start := time.Now()
  119. for i := 0; i < goRoutineCount; i++ {
  120. go func() {
  121. defer wg.Done()
  122. err = sdk.GetInstance().Transaction(func(tx *sdk.Transaction) error {
  123. _, err := tx.ExecuteRawSql(sql_tpl.InsertTpl, insertExecuteParams)
  124. if err != nil {
  125. return err
  126. }
  127. _, err = tx.ExecuteSql(deleteSql, deleteExecuteParams)
  128. if err != nil {
  129. return err
  130. }
  131. return nil
  132. })
  133. if err != nil {
  134. panic(err)
  135. }
  136. }()
  137. }
  138. wg.Wait()
  139. end := time.Now()
  140. fmt.Println(end.Sub(start).Milliseconds())
  141. }
  142. func TestRawSqlTemplate(t *testing.T) {
  143. classID := strutils.SimpleUUID()
  144. className := strutils.SimpleUUID()
  145. studentNum := rand.Int31n(100)
  146. studentIDs := []string{strutils.SimpleUUID(), strutils.SimpleUUID()}
  147. newClassName := strutils.SimpleUUID()
  148. newStudentNum := rand.Int31n(100)
  149. newStudentIDs := []string{strutils.SimpleUUID(), strutils.SimpleUUID()}
  150. now := time.Now()
  151. insertExecuteParams, err := sql_tpl.InsertExecuteParams{
  152. TableName: tableName,
  153. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  154. Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  155. Add("student_num", studentNum).
  156. Add("student_ids", strings.Join(studentIDs, "\n")).
  157. Add("graduated_time", now).
  158. Add("created_time", now).
  159. Add("last_updated_time", now),
  160. }.Map()
  161. if err != nil {
  162. t.Fatal(err)
  163. }
  164. deleteExecuteParams, err := sql_tpl.DeleteExecuteParams{
  165. TableName: tableName,
  166. Conditions: sql_tpl.NewConditions().Equal("id", classID),
  167. }.Map()
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. updateExecuteParams, err := sql_tpl.UpdateExecuteParams{
  172. TableName: tableName,
  173. TableRow: sql_tpl.NewTableRow().
  174. Add("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  175. Add("student_num", newStudentNum).
  176. Add("student_ids", strings.Join(newStudentIDs, "\n")),
  177. Conditions: sql_tpl.NewConditions().Equal("id", classID),
  178. }.Map()
  179. if err != nil {
  180. t.Fatal(err)
  181. }
  182. queryExecuteParams, err := sql_tpl.QueryExecuteParams{
  183. TableName: tableName,
  184. SelectColumns: []string{"id", "name", "student_num as student_num_alias", "student_ids", "graduated_time", "created_time", "last_updated_time"},
  185. Conditions: sql_tpl.NewConditions().
  186. Equal("id", classID).
  187. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  188. Equal("student_num", studentNum),
  189. PageNo: 1,
  190. PageSize: 1,
  191. }.Map()
  192. if err != nil {
  193. t.Fatal(err)
  194. }
  195. newQueryExecuteParams, err := sql_tpl.QueryExecuteParams{
  196. TableName: tableName,
  197. SelectColumns: []string{"id", "name", "student_num as student_num_alias", "student_ids", "graduated_time", "created_time", "last_updated_time"},
  198. Conditions: sql_tpl.NewConditions().
  199. Equal("id", classID).
  200. Equal("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  201. Equal("student_num", newStudentNum),
  202. PageNo: 0,
  203. PageSize: 0,
  204. }.Map()
  205. if err != nil {
  206. t.Fatal(err)
  207. }
  208. countExecuteParams, err := sql_tpl.CountExecuteParams{
  209. TableName: tableName,
  210. Conditions: sql_tpl.NewConditions().
  211. Equal("id", classID).
  212. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  213. Equal("student_num", studentNum),
  214. }.Map()
  215. if err != nil {
  216. t.Fatal(err)
  217. }
  218. newCountExecuteParams, err := sql_tpl.CountExecuteParams{
  219. TableName: tableName,
  220. Conditions: sql_tpl.NewConditions().
  221. Equal("id", classID).
  222. Equal("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  223. Equal("student_num", newStudentNum),
  224. }.Map()
  225. if err != nil {
  226. t.Fatal(err)
  227. }
  228. err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  229. if err != nil {
  230. t.Fatal(err)
  231. }
  232. defer func() {
  233. err := sdk.DestroyInstance()
  234. if err != nil {
  235. t.Fatal(err)
  236. }
  237. }()
  238. _, err = sdk.GetInstance().ExecuteRawSql(sql_tpl.InsertTpl, insertExecuteParams)
  239. if err != nil {
  240. t.Fatal(err)
  241. }
  242. queryResults, err := sdk.GetInstance().ExecuteRawSql(sql_tpl.QueryTpl, queryExecuteParams)
  243. if err != nil {
  244. t.Fatal(err)
  245. }
  246. countResults, err := sdk.GetInstance().ExecuteRawSql(sql_tpl.CountTpl, countExecuteParams)
  247. if err != nil {
  248. t.Fatal(err)
  249. }
  250. classes, err := sql.ParseSqlResult[[]Class](queryResults)
  251. if err != nil {
  252. t.Fatal(err)
  253. }
  254. if float64(len(classes)) != countResults[0]["count"].(float64) {
  255. t.Fatal("总数不正确")
  256. }
  257. graduatedTimeLayout := chooseTimeLayout(queryResults[0]["graduated_time"].(string))
  258. createdTimeLayout := chooseTimeLayout(queryResults[0]["created_time"].(string))
  259. lastUpdatedTimeLayout := chooseTimeLayout(queryResults[0]["last_updated_time"].(string))
  260. if classes[0].ID != classID ||
  261. classes[0].Name != className ||
  262. classes[0].StudentNum != int(studentNum) ||
  263. strings.Join(classes[0].StudentIDs, "\n") != strings.Join(studentIDs, "\n") ||
  264. classes[0].GraduatedTime.Format(graduatedTimeLayout) != now.Format(graduatedTimeLayout) ||
  265. classes[0].CreatedTime.Format(createdTimeLayout) != now.Format(createdTimeLayout) ||
  266. classes[0].LastUpdatedTime.Format(lastUpdatedTimeLayout) != now.Format(lastUpdatedTimeLayout) {
  267. t.Fatal("查询数据不正确")
  268. }
  269. _, err = sdk.GetInstance().ExecuteRawSql(sql_tpl.UpdateTpl, updateExecuteParams)
  270. if err != nil {
  271. t.Fatal(err)
  272. }
  273. queryResults, err = sdk.GetInstance().ExecuteRawSql(sql_tpl.QueryTpl, newQueryExecuteParams)
  274. if err != nil {
  275. t.Fatal(err)
  276. }
  277. countResults, err = sdk.GetInstance().ExecuteRawSql(sql_tpl.CountTpl, newCountExecuteParams)
  278. if err != nil {
  279. t.Fatal(err)
  280. }
  281. classes, err = sql.ParseSqlResult[[]Class](queryResults)
  282. if err != nil {
  283. t.Fatal(err)
  284. }
  285. if float64(len(classes)) != countResults[0]["count"].(float64) {
  286. t.Fatal("总数不正确")
  287. }
  288. graduatedTimeLayout = chooseTimeLayout(queryResults[0]["graduated_time"].(string))
  289. createdTimeLayout = chooseTimeLayout(queryResults[0]["created_time"].(string))
  290. lastUpdatedTimeLayout = chooseTimeLayout(queryResults[0]["last_updated_time"].(string))
  291. if classes[0].ID != classID ||
  292. classes[0].Name != newClassName ||
  293. classes[0].StudentNum != int(newStudentNum) ||
  294. strings.Join(classes[0].StudentIDs, "\n") != strings.Join(newStudentIDs, "\n") ||
  295. classes[0].GraduatedTime.Format(graduatedTimeLayout) != now.Format(graduatedTimeLayout) ||
  296. classes[0].CreatedTime.Format(createdTimeLayout) != now.Format(createdTimeLayout) ||
  297. classes[0].LastUpdatedTime.Format(lastUpdatedTimeLayout) != now.Format(lastUpdatedTimeLayout) {
  298. t.Fatal("查询数据不正确")
  299. }
  300. _, err = sdk.GetInstance().ExecuteRawSql(sql_tpl.DeleteTpl, deleteExecuteParams)
  301. if err != nil {
  302. t.Fatal(err)
  303. }
  304. }
  305. func TestSqlMapping(t *testing.T) {
  306. sqlMapping, err := sql.ParseSqlMappingTag(&Class{})
  307. if err != nil {
  308. t.Fatal(err)
  309. }
  310. checkSqlMapping(t, sqlMapping)
  311. }
  312. func checkSqlMapping(t *testing.T, sqlMapping *sql.Mapping) {
  313. for fieldName, mappingElement := range sqlMapping.MappingElement {
  314. switch element := mappingElement.(type) {
  315. case *sql.Mapping:
  316. checkSqlMapping(t, element)
  317. case *sql.MappingColumn:
  318. if fieldName != "ID" && fieldName != "Name" &&
  319. fieldName != "StudentNum" && fieldName != "StudentIDs" &&
  320. fieldName != "GraduatedTime" && fieldName != "CreatedTime" &&
  321. fieldName != "LastUpdatedTime" {
  322. t.Fatal("字段名不正确")
  323. }
  324. if element.Name != "id" && element.Name != "name" &&
  325. element.Name != "student_num" && element.Name != "student_ids" &&
  326. element.Name != "graduated_time" && element.Name != "created_time" &&
  327. element.Name != "last_updated_time" {
  328. t.Fatal("列名不正确")
  329. }
  330. if element.Name != "student_ids" && element.Name != strcase.ToSnake(fieldName) {
  331. t.Fatal("列名不正确")
  332. }
  333. if element.Name == "id" {
  334. if !element.IsKey || element.CanUpdate || element.CanUpdateClear ||
  335. strutils.IsStringNotEmpty(element.AESKey) {
  336. t.Fatal("id字段Tag不正确")
  337. }
  338. }
  339. if element.Name == "name" {
  340. if element.IsKey || !element.CanUpdate || !element.CanUpdateClear ||
  341. strutils.IsStringEmpty(element.AESKey) || element.AESKey != "@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L" {
  342. t.Fatal("name字段Tag不正确")
  343. }
  344. }
  345. if element.Name == "student_num" {
  346. if element.IsKey || element.CanUpdate || element.CanUpdateClear ||
  347. strutils.IsStringNotEmpty(element.AESKey) {
  348. t.Fatal("student_num字段Tag不正确")
  349. }
  350. }
  351. if element.Name == "student_ids" {
  352. if element.JoinWith != "\n" {
  353. t.Fatal("student_ids字段Tag不正确")
  354. }
  355. }
  356. default:
  357. t.Fatal("不支持的元素类型")
  358. }
  359. }
  360. }
  361. func TestSqlResult(t *testing.T) {
  362. sqlResult, err := sql.ParseSqlResultTag(&Class{})
  363. if err != nil {
  364. t.Fatal(err)
  365. }
  366. checkSqlResult(t, sqlResult)
  367. }
  368. func checkSqlResult(t *testing.T, sqlResult *sql.Result) {
  369. for fieldName, resultElement := range sqlResult.ResultElement {
  370. switch element := resultElement.(type) {
  371. case *sql.Result:
  372. checkSqlResult(t, element)
  373. case *sql.ResultColumn:
  374. if fieldName != "ID" && fieldName != "Name" &&
  375. fieldName != "StudentNum" && fieldName != "StudentIDs" &&
  376. fieldName != "GraduatedTime" && fieldName != "CreatedTime" &&
  377. fieldName != "LastUpdatedTime" && fieldName != "Field" {
  378. t.Fatal("字段名不正确")
  379. }
  380. if element.Name != "id" && element.Name != "name" &&
  381. element.Name != "student_num_alias" && element.Name != "student_ids" &&
  382. element.Name != "graduated_time" && element.Name != "created_time" &&
  383. element.Name != "last_updated_time" && element.Name != "graduated_time_test" {
  384. t.Fatal("列名不正确")
  385. }
  386. if element.Name != "student_num_alias" &&
  387. element.Name != "graduated_time" &&
  388. element.Name != "student_ids" &&
  389. element.Name != strcase.ToSnake(fieldName) {
  390. t.Fatal("列名不正确")
  391. }
  392. if element.Name == "id" {
  393. if strutils.IsStringNotEmpty(element.ParseTime) ||
  394. strutils.IsStringNotEmpty(element.AESKey) {
  395. t.Fatal("id字段Tag不正确")
  396. }
  397. }
  398. if element.Name == "name" {
  399. if strutils.IsStringNotEmpty(element.ParseTime) ||
  400. strutils.IsStringEmpty(element.AESKey) ||
  401. element.AESKey != "@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L" {
  402. t.Fatal("name字段Tag不正确")
  403. }
  404. }
  405. if element.Name == "student_num" {
  406. if strutils.IsStringNotEmpty(element.ParseTime) ||
  407. strutils.IsStringNotEmpty(element.AESKey) {
  408. t.Fatal("student_num字段Tag不正确")
  409. }
  410. }
  411. if element.Name == "student_ids" {
  412. if element.SplitWith != "\n" {
  413. t.Fatal("student_ids字段Tag不正确")
  414. }
  415. }
  416. if element.Name == "graduate_time" {
  417. if strutils.IsStringEmpty(element.ParseTime) ||
  418. strutils.IsStringNotEmpty(element.AESKey) {
  419. t.Fatal("graduate_time字段Tag不正确")
  420. }
  421. }
  422. }
  423. }
  424. }
  425. func TestSql(t *testing.T) {
  426. classID := strutils.SimpleUUID()
  427. className := strutils.SimpleUUID()
  428. studentNum := rand.Int31n(100)
  429. studentIDs := []string{strutils.SimpleUUID(), strutils.SimpleUUID()}
  430. newClassName := strutils.SimpleUUID()
  431. newStudentNum := rand.Int31n(100)
  432. newStudentIDs := []string{strutils.SimpleUUID(), strutils.SimpleUUID()}
  433. now := time.Now()
  434. newNow := time.Now()
  435. insertExecuteParams, err := sql_tpl.InsertExecuteParams{
  436. TableName: tableName,
  437. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  438. Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  439. Add("student_num", studentNum).
  440. Add("student_ids", strings.Join(studentIDs, "\n")).
  441. Add("graduated_time", now).
  442. Add("created_time", now).
  443. Add("last_updated_time", now),
  444. }.Map()
  445. if err != nil {
  446. t.Fatal(err)
  447. }
  448. deleteExecuteParams := map[string]any{
  449. "table_name": tableName,
  450. "id": classID,
  451. }
  452. class := &Class{
  453. IDField: IDField{ID: classID},
  454. Name: className,
  455. StudentNum: int(studentNum),
  456. StudentIDs: studentIDs,
  457. GraduatedTime: &now,
  458. Ignored: "",
  459. }
  460. newClass := &Class{
  461. IDField: IDField{ID: classID},
  462. Name: newClassName,
  463. StudentNum: int(newStudentNum),
  464. StudentIDs: newStudentIDs,
  465. GraduatedTime: &newNow,
  466. Ignored: "",
  467. }
  468. err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  469. if err != nil {
  470. t.Fatal(err)
  471. }
  472. defer func() {
  473. err := sdk.DestroyInstance()
  474. if err != nil {
  475. t.Fatal(err)
  476. }
  477. }()
  478. err = sdk.GetInstance().CreateSQL(deleteSql, sqlSpec.ToMap())
  479. if err != nil {
  480. t.Fatal(err)
  481. }
  482. defer func() {
  483. err = sdk.GetInstance().DeleteSQL(deleteSql)
  484. if err != nil {
  485. t.Fatal(err)
  486. }
  487. }()
  488. err = sql.InsertEntity(sdk.GetInstance(), tableName, class)
  489. if err != nil {
  490. t.Fatal(err)
  491. }
  492. err = sql.UpdateEntity(sdk.GetInstance(), tableName, newClass)
  493. if err != nil {
  494. t.Fatal(err)
  495. }
  496. err = sql.DeleteEntity(sdk.GetInstance(), tableName, class)
  497. if err != nil {
  498. t.Fatal(err)
  499. }
  500. err = sql.Insert(sdk.GetInstance(), &sql_tpl.InsertExecuteParams{
  501. TableName: tableName,
  502. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  503. Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  504. Add("student_num", studentNum).
  505. Add("student_ids", strings.Join(studentIDs, "\n")).
  506. Add("graduated_time", now).
  507. Add("created_time", now).
  508. Add("last_updated_time", now),
  509. })
  510. if err != nil {
  511. t.Fatal(err)
  512. }
  513. err = sql.Update(sdk.GetInstance(), &sql_tpl.UpdateExecuteParams{
  514. TableName: tableName,
  515. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  516. Add("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  517. Add("student_ids", strings.Join(newStudentIDs, "\n")).
  518. Add("student_num", newStudentNum),
  519. Conditions: sql_tpl.NewConditions().
  520. Equal("id", classID),
  521. })
  522. if err != nil {
  523. t.Fatal(err)
  524. }
  525. err = sql.Delete(sdk.GetInstance(), &sql_tpl.DeleteExecuteParams{
  526. TableName: tableName,
  527. Conditions: sql_tpl.NewConditions().
  528. Equal("id", classID),
  529. })
  530. if err != nil {
  531. t.Fatal(err)
  532. }
  533. _, err = sql.ExecuteRawSql(sdk.GetInstance(), sql_tpl.InsertTpl, insertExecuteParams)
  534. if err != nil {
  535. t.Fatal(err)
  536. }
  537. _, err = sql.ExecuteSql(sdk.GetInstance(), deleteSql, deleteExecuteParams)
  538. if err != nil {
  539. t.Fatal(err)
  540. }
  541. err = sdk.GetInstance().Transaction(func(tx *sdk.Transaction) error {
  542. err = sql.InsertEntity(tx, tableName, class)
  543. if err != nil {
  544. t.Fatal(err)
  545. }
  546. err = sql.UpdateEntity(tx, tableName, newClass)
  547. if err != nil {
  548. t.Fatal(err)
  549. }
  550. err = sql.DeleteEntity(tx, tableName, class)
  551. if err != nil {
  552. t.Fatal(err)
  553. }
  554. err = sql.Insert(tx, &sql_tpl.InsertExecuteParams{
  555. TableName: tableName,
  556. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  557. Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  558. Add("student_num", studentNum).
  559. Add("student_ids", strings.Join(studentIDs, "\n")).
  560. Add("graduated_time", now).
  561. Add("created_time", now).
  562. Add("last_updated_time", now),
  563. })
  564. if err != nil {
  565. t.Fatal(err)
  566. }
  567. err = sql.Update(tx, &sql_tpl.UpdateExecuteParams{
  568. TableName: tableName,
  569. TableRow: sql_tpl.NewTableRow().Add("id", classID).
  570. Add("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  571. Add("student_num", newStudentNum).
  572. Add("student_ids", strings.Join(newStudentIDs, "\n")),
  573. Conditions: sql_tpl.NewConditions().
  574. Equal("id", classID),
  575. })
  576. if err != nil {
  577. t.Fatal(err)
  578. }
  579. err = sql.Delete(tx, &sql_tpl.DeleteExecuteParams{
  580. TableName: tableName,
  581. Conditions: sql_tpl.NewConditions().
  582. Equal("id", classID),
  583. })
  584. if err != nil {
  585. t.Fatal(err)
  586. }
  587. _, err = sql.ExecuteRawSql(tx, sql_tpl.InsertTpl, insertExecuteParams)
  588. if err != nil {
  589. t.Fatal(err)
  590. }
  591. _, err = sql.ExecuteSql(tx, deleteSql, deleteExecuteParams)
  592. if err != nil {
  593. t.Fatal(err)
  594. }
  595. return nil
  596. })
  597. if err != nil {
  598. t.Fatal(err)
  599. }
  600. err = sql.InsertEntity(sdk.GetInstance(), tableName, class)
  601. if err != nil {
  602. t.Fatal(err)
  603. }
  604. tableRows, totalCount, err := sql.Query(sdk.GetInstance(), &sql_tpl.QueryExecuteParams{
  605. TableName: tableName,
  606. SelectColumns: []string{"id", "name", "student_ids"},
  607. Conditions: sql_tpl.NewConditions().
  608. Equal("id", classID).
  609. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  610. Equal("student_num", studentNum),
  611. PageNo: 0,
  612. PageSize: 0,
  613. })
  614. if err != nil {
  615. t.Fatal(err)
  616. }
  617. if totalCount != 1 || len(tableRows) != int(totalCount) {
  618. t.Fatal("总数不正确")
  619. }
  620. queryClasses, err := sql.ParseSqlResult[[]Class](tableRows)
  621. if err != nil {
  622. t.Fatal(err)
  623. }
  624. if queryClasses[0].ID != classID ||
  625. queryClasses[0].Name != className ||
  626. queryClasses[0].StudentNum != 0 ||
  627. strings.Join(queryClasses[0].StudentIDs, "\n") != strings.Join(studentIDs, "\n") ||
  628. !queryClasses[0].GraduatedTime.IsZero() ||
  629. (queryClasses[0].CreatedTime != nil && !queryClasses[0].CreatedTime.IsZero()) ||
  630. !queryClasses[0].LastUpdatedTime.IsZero() {
  631. t.Fatal("查询数据不正确")
  632. }
  633. tableRow, err := sql.QueryOne(sdk.GetInstance(), &sql_tpl.QueryOneExecuteParams{
  634. TableName: tableName,
  635. SelectColumns: []string{"id", "name"},
  636. Conditions: sql_tpl.NewConditions().
  637. Equal("id", classID).
  638. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  639. Equal("student_num", studentNum),
  640. })
  641. if err != nil {
  642. t.Fatal(err)
  643. }
  644. queryClass, err := sql.ParseSqlResult[Class](tableRow)
  645. if err != nil {
  646. t.Fatal(err)
  647. }
  648. if queryClass.ID != classID ||
  649. queryClass.Name != className ||
  650. queryClass.StudentNum != 0 ||
  651. strings.Join(queryClasses[0].StudentIDs, "\n") != strings.Join(studentIDs, "\n") ||
  652. !queryClass.GraduatedTime.IsZero() ||
  653. (queryClass.CreatedTime != nil && !queryClass.CreatedTime.IsZero()) ||
  654. !queryClass.LastUpdatedTime.IsZero() {
  655. t.Fatal("查询数据不正确")
  656. }
  657. queryCount, err := sql.Count(sdk.GetInstance(), &sql_tpl.CountExecuteParams{
  658. TableName: tableName,
  659. Conditions: sql_tpl.NewConditions().
  660. Equal("id", classID).
  661. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  662. Equal("student_num", studentNum),
  663. })
  664. if err != nil {
  665. t.Fatal(err)
  666. }
  667. if queryCount != 1 {
  668. t.Fatal("数量不正确")
  669. }
  670. exist, err := sql.CheckExist(sdk.GetInstance(), &sql_tpl.CheckExistExecuteParams{
  671. TableName: tableName,
  672. Conditions: sql_tpl.NewConditions().
  673. Equal("id", classID).
  674. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  675. Equal("student_num", studentNum),
  676. })
  677. if err != nil {
  678. t.Fatal(err)
  679. }
  680. if !exist {
  681. t.Fatal("存在状态错误")
  682. }
  683. hasOnlyOne, err := sql.CheckHasOnlyOne(sdk.GetInstance(), &sql_tpl.CheckHasOnlyOneExecuteParams{
  684. TableName: tableName,
  685. Conditions: sql_tpl.NewConditions().
  686. Equal("id", classID).
  687. Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  688. Equal("student_num", studentNum),
  689. })
  690. if err != nil {
  691. t.Fatal(err)
  692. }
  693. if !hasOnlyOne {
  694. t.Fatal("唯一性错误")
  695. }
  696. err = sql.DeleteEntity(sdk.GetInstance(), tableName, class)
  697. if err != nil {
  698. t.Fatal(err)
  699. }
  700. }
  701. func TestInsertBatch(t *testing.T) {
  702. classID1 := strutils.SimpleUUID()
  703. className1 := strutils.SimpleUUID()
  704. studentNum1 := rand.Int31n(100)
  705. classID2 := strutils.SimpleUUID()
  706. className2 := strutils.SimpleUUID()
  707. studentNum2 := rand.Int31n(100)
  708. now := time.Now()
  709. insertBatchExecuteParams := &sql_tpl.InsertBatchExecuteParams{
  710. TableName: tableName,
  711. TableRowBatch: []sql_tpl.TableRow{
  712. *(sql_tpl.NewTableRow().Add("id", classID1).
  713. Add("name", className1, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  714. Add("student_num", studentNum1).
  715. Add("student_ids", "").
  716. Add("created_time", now).
  717. Add("last_updated_time", now)),
  718. *(sql_tpl.NewTableRow().Add("id", classID2).
  719. Add("name", className2, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
  720. Add("student_num", studentNum2).
  721. Add("student_ids", "").
  722. Add("created_time", now).
  723. Add("last_updated_time", now)),
  724. },
  725. }
  726. class1 := &Class{
  727. IDField: IDField{ID: classID1},
  728. Name: className1,
  729. StudentNum: int(studentNum1),
  730. StudentIDs: make([]string, 0),
  731. }
  732. class2 := &Class{
  733. IDField: IDField{ID: classID2},
  734. Name: className2,
  735. StudentNum: int(studentNum2),
  736. StudentIDs: make([]string, 0),
  737. }
  738. err := sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  739. if err != nil {
  740. t.Fatal(err)
  741. }
  742. defer func() {
  743. err := sdk.DestroyInstance()
  744. if err != nil {
  745. t.Fatal(err)
  746. }
  747. }()
  748. err = sql.InsertBatch(sdk.GetInstance(), insertBatchExecuteParams)
  749. if err != nil {
  750. t.Fatal(err)
  751. }
  752. results, _, err := sql.Query(sdk.GetInstance(), &sql_tpl.QueryExecuteParams{
  753. TableName: tableName,
  754. SelectColumns: []string{"id", "name", "student_num as student_num_alias"},
  755. Conditions: sql_tpl.NewConditions().In("id", []string{classID1, classID2}),
  756. PageNo: 0,
  757. PageSize: 0,
  758. })
  759. if err != nil {
  760. t.Fatal(err)
  761. }
  762. classInfos, err := sql.ParseSqlResult[[]Class](results)
  763. if err != nil {
  764. t.Fatal(err)
  765. }
  766. for _, classInfo := range classInfos {
  767. if classInfo.ID != classID1 && classInfo.ID != classID2 {
  768. t.Fatal("id不正确")
  769. }
  770. if classInfo.ID == classID1 &&
  771. (classInfo.Name != className1 || classInfo.StudentNum != int(studentNum1)) {
  772. t.Fatal("数据不正确")
  773. }
  774. if classInfo.ID == classID2 &&
  775. (classInfo.Name != className2 || classInfo.StudentNum != int(studentNum2)) {
  776. t.Fatal("数据不正确")
  777. }
  778. }
  779. err = sql.Delete(sdk.GetInstance(), &sql_tpl.DeleteExecuteParams{
  780. TableName: tableName,
  781. Conditions: sql_tpl.NewConditions().In("id", []string{classID1, classID2}),
  782. })
  783. if err != nil {
  784. t.Fatal(err)
  785. }
  786. err = sql.InsertEntity(sdk.GetInstance(), tableName, []*Class{class1, class2})
  787. if err != nil {
  788. t.Fatal(err)
  789. }
  790. results, _, err = sql.Query(sdk.GetInstance(), &sql_tpl.QueryExecuteParams{
  791. TableName: tableName,
  792. SelectColumns: []string{"id", "name", "student_num as student_num_alias"},
  793. Conditions: sql_tpl.NewConditions().In("id", []string{classID1, classID2}),
  794. PageNo: 0,
  795. PageSize: 0,
  796. })
  797. if err != nil {
  798. t.Fatal(err)
  799. }
  800. classInfos, err = sql.ParseSqlResult[[]Class](results)
  801. if err != nil {
  802. t.Fatal(err)
  803. }
  804. for _, classInfo := range classInfos {
  805. if classInfo.ID != classID1 && classInfo.ID != classID2 {
  806. t.Fatal("id不正确")
  807. }
  808. if classInfo.ID == classID1 &&
  809. (classInfo.Name != className1 || classInfo.StudentNum != int(studentNum1)) {
  810. t.Fatal("数据不正确")
  811. }
  812. if classInfo.ID == classID2 &&
  813. (classInfo.Name != className2 || classInfo.StudentNum != int(studentNum2)) {
  814. t.Fatal("数据不正确")
  815. }
  816. }
  817. err = sql.Delete(sdk.GetInstance(), &sql_tpl.DeleteExecuteParams{
  818. TableName: tableName,
  819. Conditions: sql_tpl.NewConditions().In("id", []string{classID1, classID2}),
  820. })
  821. if err != nil {
  822. t.Fatal(err)
  823. }
  824. }