// table_manager.go package sqldef import ( "fmt" "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 } // SyncTables 同步所有注册的表结构(懒加载执行器) // recreate: true - 如果表存在则删除重建;false - 如果表不存在则创建 func (tm *TableManager) SyncTables(recreate bool) error { // 确保注册表已初始化 globalRegistry.ensureInit() // 检查执行器是否初始化 if !tm.isExecutorInitialized() { return fmt.Errorf("DDL执行器未初始化,请先调用SetExecutor方法") } // 获取所有注册的表定义 tables := GetAll() // 按顺序处理所有表 for _, table := range tables { err := tm.syncTable(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 } // syncTable 同步单个表 func (tm *TableManager) syncTable(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) } fmt.Printf("表 %s 已删除\n", table.Name) // 重新创建表 if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil { return fmt.Errorf("创建表 %s 失败: %w", table.Name, err) } fmt.Printf("表 %s 已创建\n", table.Name) } else { // 不存在直接创建 if err := tm.ddlExecutor.ExecuteDDL(table.SQL); err != nil { return fmt.Errorf("创建表 %s 失败: %w", table.Name, err) } fmt.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) } fmt.Printf("表 %s 已创建\n", table.Name) } else { fmt.Printf("表 %s 已存在,跳过创建\n", table.Name) } } return nil } // CreateTables 创建所有表(不存在则创建) func (tm *TableManager) CreateTables() error { return tm.SyncTables(false) } // RecreateTables 重建所有表(存在则删除重建) func (tm *TableManager) RecreateTables() error { return tm.SyncTables(true) } // CreateIndexes 创建索引 func (tm *TableManager) CreateIndexes() error { // 这里可以添加索引创建的逻辑 // 由于TableDDL中没有包含索引信息,所以暂时为空 // 暂时返回nil,表示索引创建成功(实际上是空的) fmt.Println("创建索引方法(空实现)") return nil } // CreateTablesAndIndexes 创建表及其索引(便捷方法) func (tm *TableManager) CreateTablesAndIndexes(recreateTables bool) error { if err := tm.SyncTables(recreateTables); err != nil { return err } return tm.CreateIndexes() } // 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() fmt.Printf("注册的表数量: %d\n", len(tables)) for i, name := range tables { fmt.Printf("%d. %s\n", i+1, name) } } // 包级便捷函数 // CreateAllTables 创建所有表(便捷函数,自动获取单例) func CreateAllTables(executor DDLExecutor) error { tm := GetTableManagerWithExecutor(executor) return tm.CreateTables() } // RecreateAllTables 重建所有表(便捷函数,自动获取单例) func RecreateAllTables(executor DDLExecutor) error { tm := GetTableManagerWithExecutor(executor) return tm.RecreateTables() } // SyncAllTables 同步所有表(便捷函数,自动获取单例) func SyncAllTables(executor DDLExecutor, recreate bool) error { tm := GetTableManagerWithExecutor(executor) return tm.SyncTables(recreate) }