first commit

This commit is contained in:
2026-07-12 15:55:18 +05:30
commit ee98026cc5
404 changed files with 44522 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
/**
* SQL rendering shared by adapters and the migration runner. Column types are
* dialect-neutral in the model; this maps them to each dialect's SQL types and
* renders `CREATE TABLE`. (Postgres/MySQL land in later phases; the mappings are
* here so the model layer is already portable.)
*/
import type { ColumnDef, Model } from "./schema.ts";
export type Dialect = "sqlite" | "postgres" | "mysql";
function sqlType(def: ColumnDef, dialect: Dialect): string {
if (def.type === "id") {
if (dialect === "postgres") return "SERIAL";
if (dialect === "mysql") return "INT AUTO_INCREMENT";
return "INTEGER";
}
switch (def.type) {
case "int":
return "INTEGER";
case "real":
return dialect === "mysql" ? "DOUBLE" : "REAL";
case "bool":
return dialect === "postgres" ? "BOOLEAN" : "INTEGER";
case "timestamp":
return dialect === "sqlite" ? "TEXT" : "TIMESTAMP";
case "json":
return dialect === "postgres" ? "JSONB" : "TEXT";
default:
return dialect === "mysql" ? "VARCHAR(255)" : "TEXT";
}
}
function quoteId(id: string, dialect: Dialect): string {
return dialect === "mysql" ? `\`${id}\`` : `"${id}"`;
}
function renderDefault(value: unknown, dialect: Dialect): string {
if (value === "now") return "CURRENT_TIMESTAMP";
if (typeof value === "number") return String(value);
if (typeof value === "boolean") return dialect === "postgres" ? String(value) : value ? "1" : "0";
return `'${String(value).replace(/'/g, "''")}'`;
}
/** Render `CREATE TABLE` for a model in the given dialect. */
export function createTableSql(model: Model, dialect: Dialect, ifNotExists = true): string {
const cols: string[] = [];
for (const [name, column] of Object.entries(model.columns)) {
const def = column.def;
const parts = [quoteId(name, dialect), sqlType(def, dialect)];
if (def.primaryKey) {
parts.push(
dialect === "sqlite" && def.type === "id" ? "PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY",
);
}
if (def.notNull && !def.primaryKey) parts.push("NOT NULL");
if (def.unique && !def.primaryKey) parts.push("UNIQUE");
if (def.default !== undefined) parts.push(`DEFAULT ${renderDefault(def.default, dialect)}`);
if (def.references) {
parts.push(
`REFERENCES ${quoteId(def.references.table, dialect)}(${quoteId(def.references.column, dialect)})`,
);
}
cols.push(" " + parts.join(" "));
}
const head = `CREATE TABLE ${ifNotExists ? "IF NOT EXISTS " : ""}${quoteId(model.name, dialect)}`;
return `${head} (\n${cols.join(",\n")}\n);`;
}