Skip to main content

sql-schema

@webda/sql-schema — relational schema plans​

A pure, driver-free function from compiled Webda model metadata (Schemas.Stored, Relations, Reflection, PrimaryKey, Ancestors) to a RelationalSchemaPlan: tables, typed columns, primary keys, foreign keys, junction tables and indexes. Relational stores render the same plan in their own dialect (#838 PostgresRelationalStore, #841 SequelizeStore).

It has no runtime dependency: no database, no logging, no Webda core. Warnings are returned in the plan.

import { blockingChanges, buildSchemaPlan, compareSchemaPlans, planHash } from "@webda/sql-schema";

const plan = buildSchemaPlan(
models.map(m => m.Metadata),
{
tables: { "MyApp/Post": "posts" },
knownModels: allModels.map(m => m.Metadata) // resolve references to models of other stores
}
);

// Before migrating a database shared by several running versions
const changes = compareSchemaPlans([{ version: "1.2.0", plan: livePlan }], plan);
if (blockingChanges(changes).length) {
// refuse to start
}

Mapping​

ModelPlan
string (maxLength, format, enum)text, varchar(n), timestamptz (date-time or Date), date, uuid, enum values
integer / number / booleanbigint / double (decimal with numericAsDecimal) / boolean
objects, arrays, unions, $ref, untypedjson
not in requirednullable
subclassesthe table of their closest planned ancestor (__type column), unless tables names their own
ModelParent / BelongTokey column(s) + foreign key ON DELETE CASCADE
ModelLink / RelateTo / ManyToOnekey column(s) + foreign key ON DELETE NO ACTION; OneToOne adds a unique index
ModelLinksSimpleArrayjunction <table>_<attribute> (owner key, target key, _position)
ModelLinksArray / ManyToMany / Containssame junction + one column per link attribute (attributes json when none is declared)
ModelLinksMapjunction keyed by (owner key, key)
ModelRelated / OneToMany / ModelsMappedno storage
reference to a model outside the plancolumn + index, no foreign key, CROSS_STORE_REFERENCE warning
unknown properties_extra json column (extraColumn: false to disable)

Composite primary keys are supported; a reference to a composite key gets one column per key part (<attribute>_<key>). Constraint and index names are cut with a hash suffix to fit 63 characters.

compareSchemaPlans classifies every difference with the plans of the live versions as SAFE (additive or relaxing), WARN or BLOCK (type change, narrowing, removed enum value, field becoming optional, relation kind/target/delete policy change, primary key change, hierarchy change, layout option change). allowIncompatible downgrades a BLOCK of a table, column, model or attribute to a forced WARN.