暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

diagnose_temp_table_test.go 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "testing"
  6. _ "github.com/go-sql-driver/mysql"
  7. "github.com/google/uuid"
  8. )
  9. const (
  10. // 使用 svc-configure.yaml 中的配置
  11. mysqlHost = "69.235.172.218:3306"
  12. mysqlUser = "x6_archives"
  13. mysqlPassword = "mosdev"
  14. mysqlDatabase = "x6_archives"
  15. )
  16. // 创建测试表结构
  17. func createTestTables(db *sql.DB) error {
  18. // 创建 dic_table 测试表
  19. _, err := db.Exec(`
  20. CREATE TABLE IF NOT EXISTS test_dic_table (
  21. table_id VARCHAR(64) NOT NULL PRIMARY KEY,
  22. table_type VARCHAR(20) NOT NULL,
  23. table_name VARCHAR(100) NOT NULL,
  24. description VARCHAR(500) NOT NULL DEFAULT '',
  25. creator VARCHAR(32) NOT NULL,
  26. created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  27. updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  28. deleted_at TIMESTAMP NULL
  29. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  30. `)
  31. if err != nil {
  32. return fmt.Errorf("创建test_dic_table失败: %v", err)
  33. }
  34. // 创建 dic_table_field 测试表
  35. _, err = db.Exec(`
  36. CREATE TABLE IF NOT EXISTS test_dic_table_field (
  37. id VARCHAR(128) NOT NULL PRIMARY KEY,
  38. field_id VARCHAR(128) NOT NULL,
  39. table_id VARCHAR(64) NOT NULL,
  40. filed_type VARCHAR(20) NOT NULL,
  41. data_type VARCHAR(20) NOT NULL,
  42. field_name VARCHAR(64) NOT NULL,
  43. field_name_cn VARCHAR(64) NOT NULL DEFAULT '',
  44. description VARCHAR(500) NOT NULL DEFAULT '',
  45. creator VARCHAR(32) NOT NULL,
  46. created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  47. updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  48. deleted_at TIMESTAMP NULL
  49. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  50. `)
  51. if err != nil {
  52. return fmt.Errorf("创建test_dic_table_field失败: %v", err)
  53. }
  54. return nil
  55. }
  56. // 清理测试数据
  57. func cleanupTestTables(db *sql.DB) {
  58. db.Exec("DELETE FROM test_dic_table_field")
  59. db.Exec("DELETE FROM test_dic_table")
  60. }
  61. // TestTempTableUpsert 测试临时表更新插入操作
  62. func TestTempTableUpsert(t *testing.T) {
  63. // 连接数据库
  64. dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true&multiStatements=true",
  65. mysqlUser, mysqlPassword, mysqlHost, mysqlDatabase)
  66. db, err := sql.Open("mysql", dsn)
  67. if err != nil {
  68. t.Fatalf("连接数据库失败: %v", err)
  69. }
  70. defer db.Close()
  71. // 测试连接
  72. if err := db.Ping(); err != nil {
  73. t.Fatalf("数据库连接失败: %v", err)
  74. }
  75. // 创建测试表
  76. if err := createTestTables(db); err != nil {
  77. t.Fatalf("创建测试表失败: %v", err)
  78. }
  79. defer cleanupTestTables(db)
  80. // 插入一些基础数据到 test_dic_table_field
  81. _, err = db.Exec(`
  82. INSERT INTO test_dic_table_field
  83. (id, field_id, table_id, filed_type, data_type, field_name, field_name_cn, description, creator)
  84. VALUES
  85. ('table1.id', 'table1.id', 'table1', '实际字段', '数值型', 'id', '主键ID', '原始字段', 'test'),
  86. ('table1.name', 'table1.name', 'table1', '实际字段', '字符型', 'name', '名称', '原始名称字段', 'test'),
  87. ('table2.code', 'table2.code', 'table2', '实际字段', '字符型', 'code', '编码', '原始编码字段', 'test')
  88. `)
  89. if err != nil {
  90. t.Fatalf("插入基础数据失败: %v", err)
  91. }
  92. // 开始事务测试
  93. tx, err := db.Begin()
  94. if err != nil {
  95. t.Fatalf("开始事务失败: %v", err)
  96. }
  97. defer func() {
  98. if err != nil {
  99. tx.Rollback()
  100. }
  101. }()
  102. // 创建临时表
  103. tempTableName := "temp_dic_table_field_batch_" + uuid.New().String()[:8]
  104. createSQL := fmt.Sprintf(`
  105. CREATE TEMPORARY TABLE %s (
  106. id VARCHAR(128) NOT NULL PRIMARY KEY,
  107. field_id VARCHAR(128) NOT NULL,
  108. table_id VARCHAR(64) NOT NULL,
  109. filed_type VARCHAR(20) NOT NULL,
  110. data_type VARCHAR(20) NOT NULL,
  111. field_name VARCHAR(64) NOT NULL,
  112. field_name_cn VARCHAR(64) NOT NULL DEFAULT '',
  113. description VARCHAR(500) NOT NULL DEFAULT '',
  114. creator VARCHAR(32) NOT NULL
  115. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  116. `, tempTableName)
  117. _, err = tx.Exec(createSQL)
  118. if err != nil {
  119. t.Fatalf("创建临时表失败: %v", err)
  120. }
  121. // 插入测试数据到临时表
  122. insertSQL := fmt.Sprintf(`
  123. INSERT INTO %s (id, field_id, table_id, filed_type, data_type, field_name, field_name_cn, description, creator)
  124. VALUES
  125. ('table1.id', 'table1.id', 'table1', '实际字段', '数值型', 'id', '更新后的主键ID', '更新描述', 'test'),
  126. ('table1.status', 'table1.status', 'table1', '实际字段', '字符型', 'status', '状态', '新增状态字段', 'test')
  127. `, tempTableName)
  128. _, err = tx.Exec(insertSQL)
  129. if err != nil {
  130. t.Fatalf("插入临时表数据失败: %v", err)
  131. }
  132. // 执行UPDATE:存在则更新
  133. t.Run("UPDATE: 存在更新", func(t *testing.T) {
  134. query := fmt.Sprintf(`
  135. UPDATE test_dic_table_field dtf
  136. INNER JOIN %s tt ON dtf.id = tt.id
  137. SET dtf.field_name_cn = tt.field_name_cn,
  138. dtf.description = tt.description,
  139. dtf.updated_at = CURRENT_TIMESTAMP
  140. WHERE dtf.deleted_at IS NULL
  141. `, tempTableName)
  142. result, err := tx.Exec(query)
  143. if err != nil {
  144. t.Fatalf("UPDATE执行失败: %v", err)
  145. }
  146. rowsAffected, err := result.RowsAffected()
  147. if err != nil {
  148. t.Fatalf("获取UPDATE影响行数失败: %v", err)
  149. }
  150. t.Logf("UPDATE成功,影响行数: %d", rowsAffected)
  151. if rowsAffected != 1 {
  152. t.Errorf("UPDATE影响行数错误: 期望1, 实际%d", rowsAffected)
  153. }
  154. })
  155. // 执行INSERT:不存在则插入
  156. t.Run("INSERT: 不存在插入", func(t *testing.T) {
  157. query := fmt.Sprintf(`
  158. INSERT INTO test_dic_table_field
  159. (id, field_id, table_id, filed_type, data_type, field_name, field_name_cn, description, creator)
  160. SELECT tt.id, tt.field_id, tt.table_id, tt.filed_type, tt.data_type, tt.field_name,
  161. tt.field_name_cn, tt.description, tt.creator
  162. FROM %s tt
  163. LEFT JOIN test_dic_table_field dtf ON tt.id = dtf.id AND dtf.deleted_at IS NULL
  164. WHERE dtf.id IS NULL
  165. `, tempTableName)
  166. result, err := tx.Exec(query)
  167. if err != nil {
  168. t.Fatalf("INSERT执行失败: %v", err)
  169. }
  170. rowsAffected, err := result.RowsAffected()
  171. if err != nil {
  172. t.Fatalf("获取INSERT影响行数失败: %v", err)
  173. }
  174. t.Logf("INSERT成功,插入行数: %d", rowsAffected)
  175. if rowsAffected != 1 {
  176. t.Errorf("INSERT影响行数错误: 期望1, 实际%d", rowsAffected)
  177. }
  178. })
  179. // 提交事务
  180. err = tx.Commit()
  181. if err != nil {
  182. t.Logf("提交事务失败: %v", err)
  183. }
  184. }
  185. func main() {
  186. // 仅用于直接运行测试
  187. t := &testing.T{}
  188. TestTempTableUpsert(t)
  189. }