ulthar-framework/packages/fabric/sqlite-store/sqlite/model-to-sql.ts

73 lines
2.0 KiB
TypeScript

// deno-lint-ignore-file no-explicit-any
import { Variant, VariantTag } from "@fabric/core";
import { Collection, FieldDefinition, getTargetKey } from "@fabric/domain";
type FieldSQLDefinitionMap = {
[K in FieldDefinition[VariantTag]]: (
name: string,
field: Extract<FieldDefinition, { [VariantTag]: K }>,
) => string;
};
const FieldSQLDefinitionMap: FieldSQLDefinitionMap = {
StringField: (n, f) => {
return [n, "TEXT", modifiersFromOpts(f)].join(" ");
},
UUIDField: (n, f) => {
return [
n,
"TEXT",
f.isPrimaryKey ? "PRIMARY KEY" : "",
modifiersFromOpts(f),
]
.filter((x) => x)
.join(" ");
},
IntegerField: (n, f): string => {
return [n, "INTEGER", modifiersFromOpts(f)].join(" ");
},
ReferenceField: (n, f): string => {
return [
n,
"TEXT",
modifiersFromOpts(f),
`REFERENCES ${f.targetModel}(${getTargetKey(f)})`,
].join(" ");
},
FloatField: (n, f): string => {
return [n, "REAL", modifiersFromOpts(f)].join(" ");
},
DecimalField: (n, f): string => {
return [n, "REAL", modifiersFromOpts(f)].join(" ");
},
TimestampField: (n, f): string => {
return [n, "NUMERIC", modifiersFromOpts(f)].join(" ");
},
EmbeddedField: (n, f): string => {
return [n, "TEXT", modifiersFromOpts(f)].join(" ");
},
};
function fieldDefinitionToSQL(name: string, field: FieldDefinition) {
return FieldSQLDefinitionMap[field[VariantTag]](name, field as any);
}
function modifiersFromOpts(field: FieldDefinition) {
if (Variant.is(field, "UUIDField") && field.isPrimaryKey) {
return;
}
return [!field.isOptional ? "NOT NULL" : "", field.isUnique ? "UNIQUE" : ""]
.filter((x) => x)
.join(" ");
}
export function modelToSql(
model: Collection<string, Record<string, FieldDefinition>>,
) {
const fields = Object.entries(model.fields)
.map(([name, type]) => fieldDefinitionToSQL(name, type))
.filter((x) => x)
.join(", ");
return `CREATE TABLE ${model.name} (${fields})`;
}