sdk_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  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/sdk/raw_sql_tpl"
  7. "git.sxidc.com/service-supports/ds-sdk/sdk/tag"
  8. "github.com/iancoleman/strcase"
  9. "math/rand"
  10. "strconv"
  11. "sync"
  12. "testing"
  13. "time"
  14. )
  15. type Class struct {
  16. ID string `sqlmapping:"key;"`
  17. Name string `sqlmapping:"update:canClear;notQuery;insertCallback;updateCallback;"`
  18. StudentNum int `sqlmapping:"column:student_num;notUpdate;queryCallback;" sqlresult:"column:student_num_alias;"`
  19. GraduatedTime time.Time `sqlresult:"callback"`
  20. CreatedTime *time.Time
  21. LastUpdatedTime time.Time
  22. Ignored string `sqlmapping:"-" sqlresult:"-"`
  23. }
  24. const (
  25. token = "IpTTwAQweh/BP51fz5CzWKQFaXHvZe6ewvk6yOcAOkU="
  26. address = "localhost"
  27. httpPort = "10000"
  28. grpcPort = "10001"
  29. namespace = "ns-sdk-demo"
  30. dataSource = "ds-sdk-demo"
  31. deleteSql = "delete-sdk-demo"
  32. goRoutineCount = 100
  33. tableName = "test.classes"
  34. )
  35. var (
  36. sqlSpec = sdk.SqlSpec{
  37. Clauses: "- DELETE FROM {{ .table_name }} WHERE id = '{{ .id }}'",
  38. }
  39. )
  40. func TestBasic(t *testing.T) {
  41. classID := strutils.SimpleUUID()
  42. className := strutils.SimpleUUID()
  43. studentNum := rand.Int31n(100)
  44. now := time.Now()
  45. nowStr := now.Format(time.DateTime + ".000000 +08:00")
  46. insertExecuteParams, err := raw_sql_tpl.InsertExecuteParams{
  47. TableName: tableName,
  48. TableRows: []raw_sql_tpl.TableRow{
  49. {
  50. Column: "id",
  51. Value: "'" + classID + "'",
  52. },
  53. {
  54. Column: "name",
  55. Value: "'" + className + "'",
  56. },
  57. {
  58. Column: "student_num",
  59. Value: strconv.FormatInt(int64(studentNum), 10),
  60. },
  61. {
  62. Column: "graduated_time",
  63. Value: "'" + nowStr + "'",
  64. },
  65. {
  66. Column: "created_time",
  67. Value: "'" + nowStr + "'",
  68. },
  69. {
  70. Column: "last_updated_time",
  71. Value: "'" + nowStr + "'",
  72. },
  73. },
  74. }.Map()
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. deleteExecuteParams := map[string]any{
  79. "table_name": tableName,
  80. "id": classID,
  81. }
  82. err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. defer func() {
  87. err := sdk.DestroyInstance()
  88. if err != nil {
  89. t.Fatal(err)
  90. }
  91. }()
  92. err = sdk.GetInstance().CreateSQL(deleteSql, sqlSpec.ToMap())
  93. if err != nil {
  94. t.Fatal(err)
  95. }
  96. _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.InsertTpl, insertExecuteParams)
  97. if err != nil {
  98. t.Fatal(err)
  99. }
  100. _, err = sdk.GetInstance().ExecuteSql(deleteSql, deleteExecuteParams)
  101. if err != nil {
  102. t.Fatal(err)
  103. }
  104. wg := sync.WaitGroup{}
  105. wg.Add(goRoutineCount)
  106. start := time.Now()
  107. for i := 0; i < goRoutineCount; i++ {
  108. go func() {
  109. defer wg.Done()
  110. err = sdk.GetInstance().Transaction(func(tx *sdk.Transaction) error {
  111. _, err := tx.ExecuteRawSql(raw_sql_tpl.InsertTpl, insertExecuteParams)
  112. if err != nil {
  113. return err
  114. }
  115. _, err = tx.ExecuteSql(deleteSql, deleteExecuteParams)
  116. if err != nil {
  117. return err
  118. }
  119. return nil
  120. })
  121. if err != nil {
  122. panic(err)
  123. }
  124. }()
  125. }
  126. wg.Wait()
  127. end := time.Now()
  128. fmt.Println(end.Sub(start).Milliseconds())
  129. }
  130. func TestRawSqlTemplate(t *testing.T) {
  131. classID := strutils.SimpleUUID()
  132. className := strutils.SimpleUUID()
  133. studentNum := rand.Int31n(100)
  134. newClassName := strutils.SimpleUUID()
  135. newStudentNum := rand.Int31n(100)
  136. now := time.Now()
  137. nowStr := now.Format(time.DateTime + ".000000 +08:00")
  138. exceptedNowStr := now.Format("2006-01-02T15:04:05.000000+08:00")
  139. insertExecuteParams, err := raw_sql_tpl.InsertExecuteParams{
  140. TableName: tableName,
  141. TableRows: []raw_sql_tpl.TableRow{
  142. {
  143. Column: "id",
  144. Value: "'" + classID + "'",
  145. },
  146. {
  147. Column: "name",
  148. Value: "'" + className + "'",
  149. },
  150. {
  151. Column: "student_num",
  152. Value: strconv.FormatInt(int64(studentNum), 10),
  153. },
  154. {
  155. Column: "graduated_time",
  156. Value: "'" + nowStr + "'",
  157. },
  158. {
  159. Column: "created_time",
  160. Value: "'" + nowStr + "'",
  161. },
  162. {
  163. Column: "last_updated_time",
  164. Value: "'" + nowStr + "'",
  165. },
  166. },
  167. }.Map()
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. deleteExecuteParams, err := raw_sql_tpl.DeleteExecuteParams{
  172. TableName: tableName,
  173. Conditions: []raw_sql_tpl.Condition{
  174. {
  175. Column: "id",
  176. Value: "'" + classID + "'",
  177. },
  178. },
  179. }.Map()
  180. if err != nil {
  181. t.Fatal(err)
  182. }
  183. updateExecuteParams, err := raw_sql_tpl.UpdateExecuteParams{
  184. TableName: tableName,
  185. TableRows: []raw_sql_tpl.TableRow{
  186. {
  187. Column: "name",
  188. Value: "'" + newClassName + "'",
  189. },
  190. {
  191. Column: "student_num",
  192. Value: strconv.FormatInt(int64(newStudentNum), 10),
  193. },
  194. },
  195. Conditions: []raw_sql_tpl.Condition{
  196. {
  197. Column: "id",
  198. Value: "'" + classID + "'",
  199. },
  200. },
  201. }.Map()
  202. if err != nil {
  203. t.Fatal(err)
  204. }
  205. queryExecuteParams, err := raw_sql_tpl.QueryExecuteParams{
  206. TableName: tableName,
  207. SelectColumns: []string{"id", "name", "student_num as student_num_alias", "graduated_time", "created_time", "last_updated_time"},
  208. Conditions: []raw_sql_tpl.Condition{
  209. {
  210. Column: "id",
  211. Value: "'" + classID + "'",
  212. },
  213. {
  214. Column: "name",
  215. Value: "'" + className + "'",
  216. },
  217. {
  218. Column: "student_num",
  219. Value: strconv.FormatInt(int64(studentNum), 10),
  220. },
  221. },
  222. Limit: 1,
  223. Offset: 0,
  224. }.Map()
  225. if err != nil {
  226. t.Fatal(err)
  227. }
  228. newQueryExecuteParams, err := raw_sql_tpl.QueryExecuteParams{
  229. TableName: tableName,
  230. SelectColumns: []string{"id", "name", "student_num as student_num_alias", "graduated_time", "created_time", "last_updated_time"},
  231. Conditions: []raw_sql_tpl.Condition{
  232. {
  233. Column: "id",
  234. Value: "'" + classID + "'",
  235. },
  236. {
  237. Column: "name",
  238. Value: "'" + newClassName + "'",
  239. },
  240. {
  241. Column: "student_num",
  242. Value: strconv.FormatInt(int64(newStudentNum), 10),
  243. },
  244. },
  245. Limit: 0,
  246. Offset: 0,
  247. }.Map()
  248. if err != nil {
  249. t.Fatal(err)
  250. }
  251. countExecuteParams, err := raw_sql_tpl.CountExecuteParams{
  252. TableName: tableName,
  253. Conditions: []raw_sql_tpl.Condition{
  254. {
  255. Column: "id",
  256. Value: "'" + classID + "'",
  257. },
  258. {
  259. Column: "name",
  260. Value: "'" + className + "'",
  261. },
  262. {
  263. Column: "student_num",
  264. Value: strconv.FormatInt(int64(studentNum), 10),
  265. },
  266. },
  267. }.Map()
  268. if err != nil {
  269. t.Fatal(err)
  270. }
  271. newCountExecuteParams, err := raw_sql_tpl.CountExecuteParams{
  272. TableName: tableName,
  273. Conditions: []raw_sql_tpl.Condition{
  274. {
  275. Column: "id",
  276. Value: "'" + classID + "'",
  277. },
  278. {
  279. Column: "name",
  280. Value: "'" + newClassName + "'",
  281. },
  282. {
  283. Column: "student_num",
  284. Value: strconv.FormatInt(int64(newStudentNum), 10),
  285. },
  286. },
  287. }.Map()
  288. if err != nil {
  289. t.Fatal(err)
  290. }
  291. err = sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  292. if err != nil {
  293. t.Fatal(err)
  294. }
  295. defer func() {
  296. err := sdk.DestroyInstance()
  297. if err != nil {
  298. t.Fatal(err)
  299. }
  300. }()
  301. _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.InsertTpl, insertExecuteParams)
  302. if err != nil {
  303. t.Fatal(err)
  304. }
  305. queryResults, err := sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.QueryTpl, queryExecuteParams)
  306. if err != nil {
  307. t.Fatal(err)
  308. }
  309. countResults, err := sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.CountTpl, countExecuteParams)
  310. if err != nil {
  311. t.Fatal(err)
  312. }
  313. if float64(len(queryResults)) != countResults[0]["count"].(float64) {
  314. t.Fatal("总数不正确")
  315. }
  316. if queryResults[0]["id"].(string) != classID ||
  317. queryResults[0]["name"].(string) != className ||
  318. queryResults[0]["student_num_alias"].(float64) != float64(studentNum) ||
  319. queryResults[0]["graduated_time"].(string) != exceptedNowStr ||
  320. queryResults[0]["created_time"].(string) != exceptedNowStr ||
  321. queryResults[0]["last_updated_time"].(string) != exceptedNowStr {
  322. t.Fatal("查询数据不正确")
  323. }
  324. _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.UpdateTpl, updateExecuteParams)
  325. if err != nil {
  326. t.Fatal(err)
  327. }
  328. queryResults, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.QueryTpl, newQueryExecuteParams)
  329. if err != nil {
  330. t.Fatal(err)
  331. }
  332. countResults, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.CountTpl, newCountExecuteParams)
  333. if err != nil {
  334. t.Fatal(err)
  335. }
  336. if float64(len(queryResults)) != countResults[0]["count"].(float64) {
  337. t.Fatal("总数不正确")
  338. }
  339. if queryResults[0]["id"].(string) != classID ||
  340. queryResults[0]["name"].(string) != newClassName ||
  341. queryResults[0]["student_num_alias"].(float64) != float64(newStudentNum) ||
  342. queryResults[0]["graduated_time"].(string) != exceptedNowStr ||
  343. queryResults[0]["created_time"].(string) != exceptedNowStr ||
  344. queryResults[0]["last_updated_time"].(string) != exceptedNowStr {
  345. t.Fatal("查询数据不正确")
  346. }
  347. _, err = sdk.GetInstance().ExecuteRawSql(raw_sql_tpl.DeleteTpl, deleteExecuteParams)
  348. if err != nil {
  349. t.Fatal(err)
  350. }
  351. }
  352. func TestSqlMapping(t *testing.T) {
  353. sqlMapping, err := tag.ParseSqlMapping(&Class{})
  354. if err != nil {
  355. t.Fatal(err)
  356. }
  357. for fieldName, sqlColumn := range sqlMapping.ColumnMap {
  358. if fieldName != "ID" && fieldName != "Name" &&
  359. fieldName != "StudentNum" && fieldName != "GraduatedTime" &&
  360. fieldName != "CreatedTime" && fieldName != "LastUpdatedTime" {
  361. t.Fatal("字段名不正确")
  362. }
  363. if sqlColumn.Name != "id" && sqlColumn.Name != "name" &&
  364. sqlColumn.Name != "student_num" && sqlColumn.Name != "graduated_time" &&
  365. sqlColumn.Name != "created_time" && sqlColumn.Name != "last_updated_time" {
  366. t.Fatal("列名不正确")
  367. }
  368. if sqlColumn.Name != strcase.ToSnake(fieldName) {
  369. t.Fatal("列名不正确")
  370. }
  371. if sqlColumn.IsKey && sqlColumn.Name != "id" {
  372. t.Fatal("键字段不正确")
  373. }
  374. if !sqlColumn.CanUpdate && (sqlColumn.Name != "id" && sqlColumn.Name != "student_num") {
  375. t.Fatal("不可更新字段不正确")
  376. }
  377. if sqlColumn.CanUpdateClear && sqlColumn.Name != "name" {
  378. t.Fatal("可清除字段不正确")
  379. }
  380. if !sqlColumn.CanQuery && sqlColumn.Name != "name" {
  381. t.Fatal("可清除字段不正确")
  382. }
  383. if sqlColumn.InsertCallback && sqlColumn.Name != "name" {
  384. t.Fatal("插入回调不正确")
  385. }
  386. if sqlColumn.UpdateCallback && sqlColumn.Name != "name" {
  387. t.Fatal("更新回调不正确")
  388. }
  389. if sqlColumn.QueryCallback && sqlColumn.Name != "student_num" {
  390. t.Fatal("查询回调不正确")
  391. }
  392. }
  393. }
  394. func TestSqlResult(t *testing.T) {
  395. sqlResult, err := tag.ParseSqlResult(&Class{})
  396. if err != nil {
  397. t.Fatal(err)
  398. }
  399. for fieldName, sqlColumn := range sqlResult.ColumnMap {
  400. if fieldName != "ID" && fieldName != "Name" &&
  401. fieldName != "StudentNum" && fieldName != "GraduatedTime" &&
  402. fieldName != "CreatedTime" && fieldName != "LastUpdatedTime" {
  403. t.Fatal("字段名不正确")
  404. }
  405. if sqlColumn.Name != "id" && sqlColumn.Name != "name" &&
  406. sqlColumn.Name != "student_num" && sqlColumn.Name != "graduated_time" &&
  407. sqlColumn.Name != "created_time" && sqlColumn.Name != "last_updated_time" {
  408. t.Fatal("列名不正确")
  409. }
  410. if sqlColumn.Name != strcase.ToSnake(fieldName) {
  411. t.Fatal("列名不正确")
  412. }
  413. if sqlColumn.Name == "student_num" {
  414. if sqlColumn.ResultColumnName != "student_num_alias" {
  415. t.Fatal("结果列名不正确")
  416. }
  417. }
  418. if sqlColumn.Callback && sqlColumn.Name != "graduated_time" {
  419. t.Fatal("回调不正确")
  420. }
  421. }
  422. }
  423. func TestSql(t *testing.T) {
  424. err := sdk.InitInstance(token, address, httpPort, grpcPort, namespace, dataSource)
  425. if err != nil {
  426. t.Fatal(err)
  427. }
  428. defer func() {
  429. err := sdk.DestroyInstance()
  430. if err != nil {
  431. t.Fatal(err)
  432. }
  433. }()
  434. classID := strutils.SimpleUUID()
  435. className := strutils.SimpleUUID()
  436. studentNum := rand.Int31n(100)
  437. class := &Class{
  438. ID: classID,
  439. Name: className,
  440. StudentNum: int(studentNum),
  441. GraduatedTime: time.Now(),
  442. Ignored: "",
  443. }
  444. err = sdk.Insert(sdk.GetInstance(), tableName, class, func(e *Class, fieldName string, value any) (retValue any, err error) {
  445. return value, nil
  446. })
  447. if err != nil {
  448. t.Fatal(err)
  449. }
  450. err = sdk.Delete(sdk.GetInstance(), tableName, class)
  451. if err != nil {
  452. t.Fatal(err)
  453. }
  454. }