Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

table_manager.go 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // table_manager.go
  2. package sqldef
  3. import (
  4. "fmt"
  5. "sync"
  6. "git.x2erp.com/qdy/go-db/sqldef/generators"
  7. )
  8. // TableManager 表管理器
  9. type TableManager struct {
  10. ddlExecutor DDLExecutor
  11. initialized bool
  12. mu sync.RWMutex
  13. }
  14. // DDLExecutor DDL执行器接口
  15. type DDLExecutor interface {
  16. ExecuteDDL(ddl string) error
  17. TableExists(tableName string) (bool, error)
  18. }
  19. // TableManagerFactory 表管理器工厂
  20. type TableManagerFactory struct {
  21. instance *TableManager
  22. mu sync.RWMutex
  23. }
  24. var factory = &TableManagerFactory{}
  25. // GetTableManager 获取或创建表管理器实例(懒加载)
  26. func GetTableManager() *TableManager {
  27. return factory.GetInstance()
  28. }
  29. // GetTableManagerWithExecutor 使用指定的执行器获取表管理器
  30. func GetTableManagerWithExecutor(executor DDLExecutor) *TableManager {
  31. return factory.GetInstanceWithExecutor(executor)
  32. }
  33. // GetInstance 获取单例实例(懒加载)
  34. func (f *TableManagerFactory) GetInstance() *TableManager {
  35. f.mu.RLock()
  36. if f.instance != nil && f.instance.initialized {
  37. f.mu.RUnlock()
  38. return f.instance
  39. }
  40. f.mu.RUnlock()
  41. f.mu.Lock()
  42. defer f.mu.Unlock()
  43. // 双重检查
  44. if f.instance != nil && f.instance.initialized {
  45. return f.instance
  46. }
  47. // 创建新实例(但未初始化执行器)
  48. f.instance = &TableManager{}
  49. return f.instance
  50. }
  51. // GetInstanceWithExecutor 使用执行器获取实例
  52. func (f *TableManagerFactory) GetInstanceWithExecutor(executor DDLExecutor) *TableManager {
  53. f.mu.Lock()
  54. defer f.mu.Unlock()
  55. // 如果已存在实例且有执行器,则直接返回
  56. if f.instance != nil && f.instance.initialized && f.instance.ddlExecutor != nil {
  57. return f.instance
  58. }
  59. // 创建或更新实例
  60. if f.instance == nil {
  61. f.instance = &TableManager{
  62. ddlExecutor: executor,
  63. initialized: true,
  64. }
  65. } else {
  66. f.instance.ddlExecutor = executor
  67. f.instance.initialized = true
  68. }
  69. return f.instance
  70. }
  71. // SyncTables 同步所有注册的表结构(懒加载执行器)
  72. // recreate: true - 如果表存在则删除重建;false - 如果表不存在则创建
  73. func (tm *TableManager) SyncTables(recreate bool) error {
  74. // 确保注册表已初始化
  75. globalRegistry.ensureInit()
  76. // 检查执行器是否初始化
  77. if !tm.isExecutorInitialized() {
  78. return fmt.Errorf("DDL执行器未初始化,请先调用SetExecutor方法")
  79. }
  80. // 获取所有注册的表定义
  81. tables := GetAll()
  82. // 按顺序处理所有表
  83. for _, table := range tables {
  84. err := tm.syncTable(table, recreate)
  85. if err != nil {
  86. return fmt.Errorf("同步表 %s 失败: %w", table.Name, err)
  87. }
  88. }
  89. return nil
  90. }
  91. // SetExecutor 设置DDL执行器
  92. func (tm *TableManager) SetExecutor(executor DDLExecutor) {
  93. tm.mu.Lock()
  94. defer tm.mu.Unlock()
  95. tm.ddlExecutor = executor
  96. tm.initialized = true
  97. }
  98. // isExecutorInitialized 检查执行器是否初始化
  99. func (tm *TableManager) isExecutorInitialized() bool {
  100. tm.mu.RLock()
  101. defer tm.mu.RUnlock()
  102. return tm.initialized && tm.ddlExecutor != nil
  103. }
  104. // syncTable 同步单个表
  105. func (tm *TableManager) syncTable(table generators.TableDDL, recreate bool) error {
  106. // 检查表是否存在
  107. exists, err := tm.ddlExecutor.TableExists(table.Name)
  108. if err != nil {
  109. return fmt.Errorf("检查表 %s 是否存在失败: %w", table.Name, err)
  110. }
  111. if recreate {
  112. // 如果存在就删除重建
  113. if exists {
  114. // 删除表
  115. dropSQL := fmt.Sprintf("DROP TABLE IF EXISTS %s", table.Name)
  116. if err := tm.ddlExecutor.ExecuteDDL(dropSQL); err != nil {
  117. return fmt.Errorf("删除表 %s 失败: %w", table.Name, err)
  118. }
  119. fmt.Printf("表 %s 已删除\n", table.Name)
  120. // 重新创建表
  121. if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil {
  122. return fmt.Errorf("创建表 %s 失败: %w", table.Name, err)
  123. }
  124. fmt.Printf("表 %s 已创建\n", table.Name)
  125. } else {
  126. // 不存在直接创建
  127. if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil {
  128. return fmt.Errorf("创建表 %s 失败: %w", table.Name, err)
  129. }
  130. fmt.Printf("表 %s 已创建\n", table.Name)
  131. }
  132. } else {
  133. // 如果不存在就建立
  134. if !exists {
  135. if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil {
  136. return fmt.Errorf("创建表 %s 失败: %w", table.Name, err)
  137. }
  138. fmt.Printf("表 %s 已创建\n", table.Name)
  139. } else {
  140. fmt.Printf("表 %s 已存在,跳过创建\n", table.Name)
  141. }
  142. }
  143. return nil
  144. }
  145. // CreateTables 创建所有表(不存在则创建)
  146. func (tm *TableManager) CreateTables() error {
  147. return tm.SyncTables(false)
  148. }
  149. // RecreateTables 重建所有表(存在则删除重建)
  150. func (tm *TableManager) RecreateTables() error {
  151. return tm.SyncTables(true)
  152. }
  153. // CreateIndexes 创建索引
  154. func (tm *TableManager) CreateIndexes() error {
  155. // 这里可以添加索引创建的逻辑
  156. // 由于TableDDL中没有包含索引信息,所以暂时为空
  157. // 暂时返回nil,表示索引创建成功(实际上是空的)
  158. fmt.Println("创建索引方法(空实现)")
  159. return nil
  160. }
  161. // CreateTablesAndIndexes 创建表及其索引(便捷方法)
  162. func (tm *TableManager) CreateTablesAndIndexes(recreateTables bool) error {
  163. if err := tm.SyncTables(recreateTables); err != nil {
  164. return err
  165. }
  166. return tm.CreateIndexes()
  167. }
  168. // GetRegisteredTables 获取所有注册的表名
  169. func (tm *TableManager) GetRegisteredTables() []string {
  170. globalRegistry.ensureInit()
  171. globalRegistry.mu.RLock()
  172. defer globalRegistry.mu.RUnlock()
  173. tables := make([]string, 0, len(globalRegistry.tables))
  174. for name := range globalRegistry.tables {
  175. tables = append(tables, name)
  176. }
  177. return tables
  178. }
  179. // GetTableDDL 获取指定表的DDL语句
  180. func (tm *TableManager) GetTableDDL(tableName string) (string, bool) {
  181. table, exists := Get(tableName)
  182. return table.SQL, exists
  183. }
  184. // PrintRegisteredTables 打印所有注册的表信息
  185. func (tm *TableManager) PrintRegisteredTables() {
  186. tables := tm.GetRegisteredTables()
  187. fmt.Printf("注册的表数量: %d\n", len(tables))
  188. for i, name := range tables {
  189. fmt.Printf("%d. %s\n", i+1, name)
  190. }
  191. }
  192. // 包级便捷函数
  193. // CreateAllTables 创建所有表(便捷函数,自动获取单例)
  194. func CreateAllTables(executor DDLExecutor) error {
  195. tm := GetTableManagerWithExecutor(executor)
  196. return tm.CreateTables()
  197. }
  198. // RecreateAllTables 重建所有表(便捷函数,自动获取单例)
  199. func RecreateAllTables(executor DDLExecutor) error {
  200. tm := GetTableManagerWithExecutor(executor)
  201. return tm.RecreateTables()
  202. }
  203. // SyncAllTables 同步所有表(便捷函数,自动获取单例)
  204. func SyncAllTables(executor DDLExecutor, recreate bool) error {
  205. tm := GetTableManagerWithExecutor(executor)
  206. return tm.SyncTables(recreate)
  207. }