Files
ai_site/platform/internal/schema/alter.go
whm cb56e6847e feat: add Z12/Z13 bind APIs, stock import, and sync docs
Enable auto default sync channels on agent activate, bind-code/phone confirm flows, publish ALTER, and align admin/yuheng docs with the production bind path.
2026-08-05 11:47:20 +08:00

93 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package schema
import (
"context"
"database/sql"
"fmt"
"strings"
"aijianzhan/platform/internal/blueprint"
)
// BuildPostgresAlterDDL 对比蓝图与已有表,生成 ADD COLUMN IF NOT EXISTSZ11a
// db 可为 nil则只返回空调用方应先 CREATE TABLE
func BuildPostgresAlterDDL(ctx context.Context, db *sql.DB, bp *blueprint.Blueprint) ([]string, error) {
if bp == nil || bp.Storage.SchemaName == "" {
return nil, fmt.Errorf("schema_name empty")
}
if db == nil {
return nil, nil
}
schemaName := bp.Storage.SchemaName
var stmts []string
for _, e := range bp.Entities {
existing, err := listTableColumns(ctx, db, schemaName, e.Table)
if err != nil {
return nil, err
}
if existing == nil {
// 表尚不存在:由 CREATE TABLE IF NOT EXISTS 处理
continue
}
for _, f := range e.Fields {
if _, ok := existing[f.Name]; ok {
continue
}
sqlType, err := mapType(f)
if err != nil {
return nil, err
}
// 存量表补列一律可空,避免非空约束导致迁库失败
stmts = append(stmts, fmt.Sprintf(
`ALTER TABLE %s.%s ADD COLUMN IF NOT EXISTS %s %s`,
quoteIdent(schemaName), quoteIdent(e.Table), quoteIdent(f.Name), sqlType,
))
}
}
return stmts, nil
}
func listTableColumns(ctx context.Context, db *sql.DB, schemaName, table string) (map[string]struct{}, error) {
const q = `
SELECT column_name FROM information_schema.columns
WHERE table_schema = $1 AND table_name = $2`
rows, err := db.QueryContext(ctx, q, schemaName, table)
if err != nil {
return nil, err
}
defer rows.Close()
out := map[string]struct{}{}
found := false
for rows.Next() {
found = true
var name string
if err := rows.Scan(&name); err != nil {
return nil, err
}
out[name] = struct{}{}
}
if err := rows.Err(); err != nil {
return nil, err
}
if !found {
return nil, nil
}
return out, nil
}
// MergeDDL 将 alter 语句追加到 create ddl 之后。
func MergeDDL(create, alter []string) []string {
if len(alter) == 0 {
return create
}
out := make([]string, 0, len(create)+len(alter))
out = append(out, create...)
out = append(out, alter...)
return out
}
// Quote for tests
func normalizeSchemaTable(s string) string {
return strings.TrimSpace(s)
}