package aceboot::orm.postgres
import std.collection.*
import aceboot::orm.common.*
/** PostgreSQL 方言:占位 "$n",自增 `SERIAL PRIMARY KEY`,RETURNING 取 id。 */
public class PostgresDialect <: Dialect {
public func placeholder(index: Int64): String {
"$" + (index + 1).toString()
}
public func usesReturning(): Bool {
true
}
public func sqlType(t: DbType): String {
match (t) {
case TInt => "INTEGER"
case TBool => "BOOLEAN"
case TReal => "DOUBLE PRECISION"
case TText => "TEXT"
case TDateTime => "BIGINT"
case TDate => "BIGINT"
case TJson => "JSONB"
case TBlob => "BYTEA"
case TDecimal => "NUMERIC"
}
}
public func createTable(table: String, cols: Array<ColumnSpec>, checks: Array<CheckSpec>): String {
buildCreateTable(table, cols, {name => name + " SERIAL PRIMARY KEY"}, {t => sqlType(t)}, checks: checks)
}
public func createIndex(table: String, idx: IndexSpec): String {
buildCreateIndex(table, idx, true)
}
public func upsertClause(conflictColumns: Array<String>, updateColumns: Array<String>): String {
onConflictClause(conflictColumns, updateColumns)
}
public func alterColumnType(table: String, col: ColumnSpec): ?String {
Some("ALTER TABLE " + table + " ALTER COLUMN " + col.name + " TYPE " + columnType(col, {t => sqlType(t)}))
}
public func columnTypeMatches(currentRaw: String, target: ColumnSpec): Bool {
normalizeSqlType(currentRaw) == normalizeSqlType(columnType(target, {t => sqlType(t)}))
}
// PG 列注释走独立语句(须在 CREATE TABLE 之后发,表已存在)。用 ArrayList 累积(勿闭包重赋 var)。
public func columnComments(table: String, cols: Array<ColumnSpec>): Array<String> {
let out = ArrayList<String>()
for (c in cols) {
if (c.comment != "") {
out.add("COMMENT ON COLUMN " + table + "." + c.name + " IS " + sqlStringLiteral(c.comment))
}
}
out.toArray()
}
}