Smail/backend/db/migration/index.go
smail f60d3b0880
Some checks are pending
Security Checks / security (push) Waiting to run
整理前后端与测试构建目录并完善配置和安全引导
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
2026-09-05 19:19:52 +08:00

60 lines
1.9 KiB
Go

package migration
import (
"context"
"fmt"
"strings"
)
func ensureIndex(ctx context.Context, exec executor, dialect Dialect, table, index string, unique bool, columns []string) error {
exists, err := indexExists(ctx, exec, dialect, table, index)
if err != nil {
return fmt.Errorf("check index %s: %w", index, err)
}
if exists {
return nil
}
quotedTable, quotedIndex, err := quotedIdentifiers(dialect, table, index)
if err != nil {
return err
}
quotedColumns := make([]string, 0, len(columns))
for _, column := range columns {
_, quotedColumn, err := quotedIdentifiers(dialect, table, column)
if err != nil {
return err
}
quotedColumns = append(quotedColumns, quotedColumn)
}
indexType := "INDEX"
if unique {
indexType = "UNIQUE INDEX"
}
statement := fmt.Sprintf("CREATE %s %s ON %s (%s)", indexType, quotedIndex, quotedTable, strings.Join(quotedColumns, ", "))
if _, err := exec.ExecContext(ctx, statement); err != nil {
return fmt.Errorf("create index %s: %w", index, err)
}
return nil
}
func indexExists(ctx context.Context, exec executor, dialect Dialect, table, index string) (bool, error) {
var count int
switch dialect {
case DialectSQLite:
if err := exec.QueryRowContext(ctx, `SELECT COUNT(*) FROM pragma_index_list(?) WHERE name = ?`, table, index).Scan(&count); err != nil {
return false, err
}
case DialectMySQL:
if err := exec.QueryRowContext(ctx, "SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", table, index).Scan(&count); err != nil {
return false, err
}
case DialectPostgres:
if err := exec.QueryRowContext(ctx, "SELECT COUNT(*) FROM pg_indexes WHERE schemaname = current_schema() AND tablename = $1 AND indexname = $2", table, index).Scan(&count); err != nil {
return false, err
}
default:
return false, fmt.Errorf("unsupported index dialect %q", dialect)
}
return count > 0, nil
}