feat(db): 实现多数据库方言与自动表前缀支持

- 扩展 Dialect 接口添加 QuoteIdentifier 和 QuoteChar 方法
- 实现 IdentifierProcessor 结构体处理标识符转换
- 添加系统数据库列表避免对 INFORMATION_SCHEMA 等添加前缀
- 支持 database.table 格式的表名处理和前缀添加
- 在 CRUD 方法中集成新的标识符处理器
- 修改 WHERE 条件处理逻辑支持自动前缀
- 更新链式构建器的 JOIN 方法处理表名和条件
- 保持完全向后兼容性支持现有写法
This commit is contained in:
2026-01-22 09:52:43 +08:00
parent c3b8d15b54
commit 5235ef133d
2 changed files with 30 additions and 210 deletions
+30 -2
View File
@@ -20,9 +20,21 @@ func NewIdentifierProcessor(dialect Dialect, prefix string) *IdentifierProcessor
}
}
// 系统数据库列表,这些数据库不添加前缀
var systemDatabases = map[string]bool{
"INFORMATION_SCHEMA": true,
"information_schema": true,
"mysql": true,
"performance_schema": true,
"sys": true,
"pg_catalog": true,
"pg_toast": true,
}
// ProcessTableName 处理表名(添加前缀+引号)
// 输入: "order" 或 "`order`" 或 "\"order\""
// 输入: "order" 或 "`order`" 或 "\"order\"" 或 "INFORMATION_SCHEMA.TABLES"
// 输出: "`app_order`" (MySQL) 或 "\"app_order\"" (PostgreSQL/SQLite)
// 对于 database.table 格式,会分别处理,系统数据库不添加前缀
func (p *IdentifierProcessor) ProcessTableName(name string) string {
// 去除已有的引号
name = p.stripQuotes(name)
@@ -33,7 +45,23 @@ func (p *IdentifierProcessor) ProcessTableName(name string) string {
parts := strings.SplitN(name, " ", 2)
tableName := p.stripQuotes(parts[0])
alias := parts[1]
return p.dialect.QuoteIdentifier(p.prefix+tableName) + " " + alias
// 递归处理表名部分(可能包含点号)
return p.ProcessTableName(tableName) + " " + alias
}
// 检查是否包含点号(database.table 格式)
if strings.Contains(name, ".") {
parts := p.splitTableColumn(name)
if len(parts) == 2 {
dbName := p.stripQuotes(parts[0])
tableName := p.stripQuotes(parts[1])
// 系统数据库不添加前缀
if systemDatabases[dbName] {
return p.dialect.QuoteIdentifier(dbName) + "." + p.dialect.QuoteIdentifier(tableName)
}
// 非系统数据库,只给表名添加前缀
return p.dialect.QuoteIdentifier(dbName) + "." + p.dialect.QuoteIdentifier(p.prefix+tableName)
}
}
// 添加前缀和引号