// table_manager.go package sqldef import ( "fmt" "log" "sync" "git.x2erp.com/qdy/go-db/sqldef/generators" ) // TableManager 表管理器 type TableManager struct { ddlExecutor DDLExecutor initialized bool mu sync.RWMutex } // DDLExecutor DDL执行器接口 type DDLExecutor interface { ExecuteDDL(ddl string) error TableExists(tableName string) (bool, error) } // TableManagerFactory 表管理器工厂 type TableManagerFactory struct { instance *TableManager mu sync.RWMutex } var factory = &TableManagerFactory{} // GetTableManager 获取或创建表管理器实例(懒加载) func GetTableManager() *TableManager { return factory.GetInstance() } // GetTableManagerWithExecutor 使用指定的执行器获取表管理器 func GetTableManagerWithExecutor(executor DDLExecutor) *TableManager { return factory.GetInstanceWithExecutor(executor) } // GetInstance 获取单例实例(懒加载) func (f *TableManagerFactory) GetInstance() *TableManager { f.mu.RLock() if f.instance != nil && f.instance.initialized { f.mu.RUnlock() return f.instance } f.mu.RUnlock() f.mu.Lock() defer f.mu.Unlock() // 双重检查 if f.instance != nil && f.instance.initialized { return f.instance } // 创建新实例(但未初始化执行器) f.instance = &TableManager{} return f.instance } // GetInstanceWithExecutor 使用执行器获取实例 func (f *TableManagerFactory) GetInstanceWithExecutor(executor DDLExecutor) *TableManager { f.mu.Lock() defer f.mu.Unlock() // 如果已存在实例且有执行器,则直接返回 if f.instance != nil && f.instance.initialized && f.instance.ddlExecutor != nil { return f.instance } // 创建或更新实例 if f.instance == nil { f.instance = &TableManager{ ddlExecutor: executor, initialized: true, } } else { f.instance.ddlExecutor = executor f.instance.initialized = true } return f.instance } // createTables 建立所有注册的表结构(懒加载执行器) // recreate: true - 如果表存在则删除重建;false - 如果表不存在则创建 func (tm *TableManager) createTables(recreate bool) error { // 确保注册表已初始化 globalRegistry.ensureInit() // 检查执行器是否初始化 if !tm.isExecutorInitialized() { return fmt.Errorf("DDL执行器未初始化,请先调用SetExecutor方法") } // 获取所有注册的表定义 tables := GetAll() // 按顺序处理所有表 for _, table := range tables { err := tm.createTable(table, recreate) if err != nil { return fmt.Errorf("建立表 %s 失败: %w", table.Name, err) } } return nil } // SetExecutor 设置DDL执行器 func (tm *TableManager) SetExecutor(executor DDLExecutor) { tm.mu.Lock() defer tm.mu.Unlock() tm.ddlExecutor = executor tm.initialized = true } // isExecutorInitialized 检查执行器是否初始化 func (tm *TableManager) isExecutorInitialized() bool { tm.mu.RLock() defer tm.mu.RUnlock() return tm.initialized && tm.ddlExecutor != nil } // createTable 建立单个表 func (tm *TableManager) createTable(table generators.TableDDL, recreate bool) error { // 检查表是否存在 exists, err := tm.ddlExecutor.TableExists(table.Name) if err != nil { return fmt.Errorf("检查表 %s 是否存在失败: %w", table.Name, err) } if recreate { // 如果存在就删除重建 if exists { // 删除表 dropSQL := fmt.Sprintf("DROP TABLE IF EXISTS %s", table.Name) if err := tm.ddlExecutor.ExecuteDDL(dropSQL); err != nil { return fmt.Errorf("删除表 %s 失败: %w", table.Name, err) } log.Printf("表 %s 已删除\n", table.Name) // 重新创建表 if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil { return fmt.Errorf("创建表 %s 失败: %w", table.Name, err) } log.Printf("表 %s 已创建\n", table.Name) } else { // 不存在直接创建 if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil { return fmt.Errorf("创建表 %s 失败: %w", table.Name, err) } log.Printf("表 %s 已创建\n", table.Name) } } else { // 如果不存在就建立 if !exists { if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil { return fmt.Errorf("创建表 %s 失败: %w", table.Name, err) } log.Printf("表 %s 已创建\n", table.Name) } else { log.Printf("表 %s 已存在,跳过创建\n", table.Name) } } return nil } // RecreateTables 重建所有表(存在则删除重建) func (tm *TableManager) RecreateTables() error { return tm.createTables(true) } // GetRegisteredTables 获取所有注册的表名 func (tm *TableManager) GetRegisteredTables() []string { globalRegistry.ensureInit() globalRegistry.mu.RLock() defer globalRegistry.mu.RUnlock() tables := make([]string, 0, len(globalRegistry.tables)) for name := range globalRegistry.tables { tables = append(tables, name) } return tables } // GetTableDDL 获取指定表的DDL语句 func (tm *TableManager) GetTableDDL(tableName string) (string, bool) { table, exists := Get(tableName) return table.SQL, exists } // PrintRegisteredTables 打印所有注册的表信息 func (tm *TableManager) PrintRegisteredTables() { tables := tm.GetRegisteredTables() log.Printf("注册的表数量: %d\n", len(tables)) for i, name := range tables { log.Printf("%d. %s\n", i+1, name) } } // 包级便捷函数 // CreateAllTables 创建所有表(便捷函数,自动获取单例) func CreateAllTables(executor DDLExecutor) error { tm := GetTableManagerWithExecutor(executor) return tm.createTables(false) } // DeleteAanCreateAllTables 删除并建立所有表(便捷函数,自动获取单例) func DeleteAanCreateAllTables(executor DDLExecutor) error { tm := GetTableManagerWithExecutor(executor) return tm.createTables(true) } // GenerateDictSQLs 生成表的字典表SQL func (tm *TableManager) GenerateDictSQLs(tableName string) (string, map[string]string, error) { // 获取表的DDL定义 tableDDL, exists := Get(tableName) if !exists { return "", nil, fmt.Errorf("表 %s 不存在或未注册", tableName) } // 生成字典SQL generator := NewDictSQLGenerator() sqls, err := generator.GenerateDictSQLsFromTable(tableDDL) if err != nil { return "", nil, fmt.Errorf("生成字典SQL失败: %w", err) } return sqls.TableSQL, sqls.ColumnSQLs, nil } // GenerateAllDictSQLs 生成所有注册表的字典表SQL func (tm *TableManager) GenerateAllDictSQLs() (map[string]struct { TableSQL string ColumnSQLs map[string]string }, error) { // 生成所有字典SQL generator := NewDictSQLGenerator() allSQLs, err := generator.GenerateDictSQLsFromRegistry() if err != nil { return nil, fmt.Errorf("生成所有字典SQL失败: %w", err) } // 转换为返回格式 result := make(map[string]struct { TableSQL string ColumnSQLs map[string]string }) for tableName, sqls := range allSQLs { result[tableName] = struct { TableSQL string ColumnSQLs map[string]string }{ TableSQL: sqls.TableSQL, ColumnSQLs: sqls.ColumnSQLs, } } return result, nil } // 包级便捷函数 // GenerateDictSQLs 生成表的字典表SQL(便捷函数) func GenerateDictSQLs(tableName string) (string, map[string]string, error) { tm := GetTableManager() return tm.GenerateDictSQLs(tableName) } // GenerateAllDictSQLs 生成所有表的字典表SQL(便捷函数) func GenerateAllDictSQLs() (map[string]struct { TableSQL string ColumnSQLs map[string]string }, error) { tm := GetTableManager() return tm.GenerateAllDictSQLs() }