node-pg-migrate
Version:
PostgreSQL database migration management tool for node.js
1,465 lines (1,388 loc) • 124 kB
JavaScript
// src/migration.ts
import { glob } from "glob";
import { createReadStream, createWriteStream } from "fs";
import { mkdir, readdir } from "fs/promises";
import { basename, extname, join, resolve } from "path";
import { cwd } from "process";
// src/operations/casts/dropCast.ts
function dropCast(mOptions) {
const _drop = (sourceType, targetType, options = {}) => {
const { ifExists = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
return `DROP CAST${ifExistsStr} (${sourceType} AS ${targetType});`;
};
return _drop;
}
// src/operations/casts/createCast.ts
function createCast(mOptions) {
const _create = (sourceType, targetType, options = {}) => {
const { functionName, argumentTypes, inout = false, as } = options;
let conversion = "";
if (functionName) {
const args = argumentTypes || [sourceType];
conversion = ` WITH FUNCTION ${mOptions.literal(functionName)}(${args.join(", ")})`;
} else if (inout) {
conversion = " WITH INOUT";
} else {
conversion = " WITHOUT FUNCTION";
}
const implicit = as ? ` AS ${as}` : "";
return `CREATE CAST (${sourceType} AS ${targetType})${conversion}${implicit};`;
};
_create.reverse = dropCast(mOptions);
return _create;
}
// src/utils/decamelize.ts
var REPLACEMENT = "$1_$2";
function decamelize(text) {
if (text.length < 2) {
return text.toLowerCase();
}
const decamelized = text.replace(
new RegExp("([\\p{Lowercase_Letter}\\d])(\\p{Uppercase_Letter})", "gu"),
REPLACEMENT
);
return decamelized.replace(
new RegExp("(\\p{Uppercase_Letter})(\\p{Uppercase_Letter}\\p{Lowercase_Letter}+)", "gu"),
REPLACEMENT
).toLowerCase();
}
// src/utils/identity.ts
function identity(v) {
return v;
}
// src/utils/quote.ts
function quote(str) {
return `"${str}"`;
}
// src/utils/createSchemalize.ts
function createSchemalize(options) {
const { shouldDecamelize, shouldQuote } = options;
const transform = [
shouldDecamelize ? decamelize : identity,
shouldQuote ? quote : identity
].reduce((acc, fn) => fn === identity ? acc : (str) => acc(fn(str)));
return (value) => {
if (typeof value === "object") {
const { schema, name } = value;
return (schema ? `${transform(schema)}.` : "") + transform(name);
}
return transform(value);
};
}
// src/utils/createTransformer.ts
function createTransformer(literal) {
return (statement, mapping = {}) => Object.keys(mapping).reduce((str, param) => {
const val = mapping?.[param];
return str.replace(
new RegExp(`{${param}}`, "g"),
val === void 0 ? "" : typeof val === "string" || typeof val === "object" && val !== null && "name" in val ? literal(val) : String(escapeValue(val)).replace(/\$/g, "$$$$")
);
}, statement);
}
// src/utils/escapeValue.ts
function escapeValue(val) {
if (val === null) {
return "NULL";
}
if (typeof val === "boolean") {
return val.toString();
}
if (typeof val === "string") {
let dollars;
const ids = new StringIdGenerator();
let index;
do {
index = ids.next();
dollars = `$pg${index}$`;
} while (val.includes(dollars));
return `${dollars}${val}${dollars}`;
}
if (typeof val === "number") {
return val;
}
if (Array.isArray(val)) {
const arrayStr = val.map(escapeValue).join(",").replace(/ARRAY/g, "");
return `ARRAY[${arrayStr}]`;
}
if (isPgLiteral(val)) {
return val.value;
}
return "";
}
// src/utils/formatLines.ts
function formatLines(lines, replace = " ", separator = ",") {
return lines.map((line) => line.replace(/(?:\r\n|\r|\n)+/g, " ")).join(`${separator}
`).replace(/^/gm, replace);
}
// src/utils/formatParams.ts
function formatParam(mOptions) {
return (param) => {
const {
mode,
name,
type,
default: defaultValue
} = applyType(param, mOptions.typeShorthands);
const options = [];
if (mode) {
options.push(mode);
}
if (name) {
options.push(mOptions.literal(name));
}
if (type) {
options.push(type);
}
if (defaultValue) {
options.push(`DEFAULT ${escapeValue(defaultValue)}`);
}
return options.join(" ");
};
}
function formatParams(params, mOptions) {
return `(${params.map(formatParam(mOptions)).join(", ")})`;
}
// src/utils/toArray.ts
function toArray(item) {
return Array.isArray(item) ? [...item] : [item];
}
// src/utils/formatPartitionColumns.ts
function formatPartitionColumn(column, literal) {
if (typeof column === "string") {
return literal(column);
}
let formatted = literal(column.name);
if (column.collate) {
formatted += ` COLLATE ${column.collate}`;
}
if (column.opclass) {
formatted += ` ${column.opclass}`;
}
return formatted;
}
function formatPartitionColumns(partition, literal) {
const columns = toArray(partition.columns);
return columns.map((col) => formatPartitionColumn(col, literal)).join(", ");
}
// src/utils/getMigrationTableSchema.ts
function getMigrationTableSchema(options) {
return options.migrationsSchema === void 0 ? getSchemas(options.schema)[0] : options.migrationsSchema;
}
// src/utils/getSchemas.ts
function getSchemas(schema) {
const schemas = toArray(schema).filter(
(s) => typeof s === "string" && s.length > 0
);
return schemas.length > 0 ? schemas : ["public"];
}
// src/utils/intersection.ts
function intersection(list1, list2) {
return list1.filter((element) => list2.includes(element));
}
// src/utils/makeComment.ts
function makeComment(object, name, text = null) {
const literal = escapeValue(text);
return `COMMENT ON ${object} ${name} IS ${literal};`;
}
// src/utils/PgLiteral.ts
var PgLiteral = class _PgLiteral {
/**
* Creates a new `PgLiteral` instance.
*
* @param str The string value.
* @returns The new `PgLiteral` instance.
*/
static create(str) {
return new _PgLiteral(str);
}
/**
* Indicates that this object is a `PgLiteral`.
*/
literal = true;
/**
* Value of the literal.
*/
value;
/**
* Creates a new `PgLiteral` instance.
*
* @param value The string value.
*/
constructor(value) {
this.value = value;
}
/**
* Returns the string value.
*
* @returns The string value.
*/
toString() {
return this.value;
}
};
function isPgLiteral(val) {
return val instanceof PgLiteral || typeof val === "object" && val !== null && "literal" in val && val.literal === true;
}
// src/utils/StringIdGenerator.ts
var StringIdGenerator = class {
chars;
ids = [0];
constructor(chars = "abcdefghijklmnopqrstuvwxyz") {
this.chars = chars;
}
next() {
const idsChars = this.ids.map((id) => this.chars[id]);
this.increment();
return idsChars.join("");
}
increment() {
for (let i = this.ids.length - 1; i >= 0; i -= 1) {
this.ids[i] += 1;
if (this.ids[i] < this.chars.length) {
return;
}
this.ids[i] = 0;
}
this.ids.unshift(0);
}
};
// src/utils/types.ts
var TYPE_ADAPTERS = Object.freeze({
int: "integer",
string: "text",
float: "real",
double: "double precision",
datetime: "timestamp",
bool: "boolean"
});
var DEFAULT_TYPE_SHORTHANDS = Object.freeze({
id: { type: "serial", primaryKey: true }
// convenience type for serial primary keys
});
function applyTypeAdapters(type) {
return type in TYPE_ADAPTERS ? TYPE_ADAPTERS[type] : type;
}
function toType(type) {
return typeof type === "string" ? { type } : type;
}
function removeType({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type,
...rest
}) {
return rest;
}
function applyType(type, extendingTypeShorthands = {}) {
const typeShorthands = {
...DEFAULT_TYPE_SHORTHANDS,
...extendingTypeShorthands
};
const options = toType(type);
let ext = null;
const types = [options.type];
while (typeShorthands[types[types.length - 1]]) {
ext = {
...toType(typeShorthands[types[types.length - 1]]),
...ext === null ? {} : removeType(ext)
};
if (types.includes(ext.type)) {
throw new Error(
`Shorthands contain cyclic dependency: ${types.join(", ")}, ${ext.type}`
);
} else {
types.push(ext.type);
}
}
return {
...ext,
...options,
type: applyTypeAdapters(ext?.type ?? options.type)
};
}
// src/operations/domains/alterDomain.ts
function alterDomain(mOptions) {
const _alter = (domainName, options) => {
const {
default: defaultValue,
notNull,
allowNull = false,
check,
constraintName
} = options;
const actions = [];
if (defaultValue === null) {
actions.push("DROP DEFAULT");
} else if (defaultValue !== void 0) {
actions.push(`SET DEFAULT ${escapeValue(defaultValue)}`);
}
if (notNull) {
actions.push("SET NOT NULL");
} else if (notNull === false || allowNull) {
actions.push("DROP NOT NULL");
}
if (check) {
actions.push(
`${constraintName ? `CONSTRAINT ${mOptions.literal(constraintName)} ` : ""}CHECK (${check})`
);
}
return `${actions.map((action) => `ALTER DOMAIN ${mOptions.literal(domainName)} ${action}`).join(";\n")};`;
};
return _alter;
}
// src/operations/domains/dropDomain.ts
function dropDomain(mOptions) {
const _drop = (domainName, options = {}) => {
const { ifExists = false, cascade = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
const domainNameStr = mOptions.literal(domainName);
return `DROP DOMAIN${ifExistsStr} ${domainNameStr}${cascadeStr};`;
};
return _drop;
}
// src/operations/domains/createDomain.ts
function createDomain(mOptions) {
const _create = (domainName, type, options = {}) => {
const {
default: defaultValue,
collation,
notNull = false,
check,
constraintName
} = options;
const constraints = [];
if (collation) {
constraints.push(`COLLATE ${collation}`);
}
if (defaultValue !== void 0) {
constraints.push(`DEFAULT ${escapeValue(defaultValue)}`);
}
if (notNull && check) {
throw new Error(`"notNull" and "check" can't be specified together`);
} else if (notNull || check) {
if (constraintName) {
constraints.push(`CONSTRAINT ${mOptions.literal(constraintName)}`);
}
if (notNull) {
constraints.push("NOT NULL");
} else if (check) {
constraints.push(`CHECK (${check})`);
}
}
const constraintsStr = constraints.length > 0 ? ` ${constraints.join(" ")}` : "";
const typeStr = applyType(type, mOptions.typeShorthands).type;
const domainNameStr = mOptions.literal(domainName);
return `CREATE DOMAIN ${domainNameStr} AS ${typeStr}${constraintsStr};`;
};
_create.reverse = (domainName, type, options) => dropDomain(mOptions)(domainName, options);
return _create;
}
// src/operations/domains/renameDomain.ts
function renameDomain(mOptions) {
const _rename = (domainName, newDomainName) => {
const domainNameStr = mOptions.literal(domainName);
const newDomainNameStr = mOptions.literal(newDomainName);
return `ALTER DOMAIN ${domainNameStr} RENAME TO ${newDomainNameStr};`;
};
_rename.reverse = (domainName, newDomainName) => _rename(newDomainName, domainName);
return _rename;
}
// src/operations/extensions/dropExtension.ts
function dropExtension(mOptions) {
const _drop = (_extensions, options = {}) => {
const { ifExists = false, cascade = false } = options;
const extensions = toArray(_extensions);
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return extensions.map((extension) => {
const extensionStr = mOptions.literal(extension);
return `DROP EXTENSION${ifExistsStr} ${extensionStr}${cascadeStr};`;
});
};
return _drop;
}
// src/operations/extensions/createExtension.ts
function createExtension(mOptions) {
const _create = (_extensions, options = {}) => {
const { ifNotExists = false, schema } = options;
const extensions = toArray(_extensions);
const ifNotExistsStr = ifNotExists ? " IF NOT EXISTS" : "";
const schemaStr = schema ? ` SCHEMA ${mOptions.literal(schema)}` : "";
return extensions.map((extension) => {
const extensionStr = mOptions.literal(extension);
return `CREATE EXTENSION${ifNotExistsStr} ${extensionStr}${schemaStr};`;
});
};
_create.reverse = dropExtension(mOptions);
return _create;
}
// src/operations/functions/dropFunction.ts
function dropFunction(mOptions) {
const _drop = (functionName, functionParams = [], options = {}) => {
const { ifExists = false, cascade = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
const paramsStr = formatParams(functionParams, mOptions);
const functionNameStr = mOptions.literal(functionName);
return `DROP FUNCTION${ifExistsStr} ${functionNameStr}${paramsStr}${cascadeStr};`;
};
return _drop;
}
// src/operations/functions/createFunction.ts
function createFunction(mOptions) {
const _create = (functionName, functionParams = [], functionOptions, definition) => {
const {
replace = false,
returns = "void",
language,
window = false,
behavior = "VOLATILE",
security = "INVOKER",
onNull = false,
parallel,
set
} = functionOptions;
const options = [];
if (behavior) {
options.push(behavior);
}
if (language) {
options.push(`LANGUAGE ${language}`);
} else {
throw new Error(
`Language for function ${functionName} have to be specified`
);
}
if (security !== "INVOKER") {
options.push(`SECURITY ${security}`);
}
if (window) {
options.push("WINDOW");
}
if (onNull) {
options.push("RETURNS NULL ON NULL INPUT");
}
if (parallel) {
options.push(`PARALLEL ${parallel}`);
}
if (set) {
for (const { configurationParameter, value } of set) {
if (value === "FROM CURRENT") {
options.push(
`SET ${mOptions.literal(configurationParameter)} FROM CURRENT`
);
} else {
options.push(
`SET ${mOptions.literal(configurationParameter)} TO ${value}`
);
}
}
}
const replaceStr = replace ? " OR REPLACE" : "";
const paramsStr = formatParams(functionParams, mOptions);
const functionNameStr = mOptions.literal(functionName);
return `CREATE${replaceStr} FUNCTION ${functionNameStr}${paramsStr}
RETURNS ${returns}
AS ${escapeValue(definition)}
${options.join("\n ")};`;
};
_create.reverse = dropFunction(mOptions);
return _create;
}
// src/operations/functions/renameFunction.ts
function renameFunction(mOptions) {
const _rename = (oldFunctionName, functionParams = [], newFunctionName) => {
const paramsStr = formatParams(functionParams, mOptions);
const oldFunctionNameStr = mOptions.literal(oldFunctionName);
const newFunctionNameStr = mOptions.literal(newFunctionName);
return `ALTER FUNCTION ${oldFunctionNameStr}${paramsStr} RENAME TO ${newFunctionNameStr};`;
};
_rename.reverse = (oldFunctionName, functionParams, newFunctionName) => _rename(newFunctionName, functionParams, oldFunctionName);
return _rename;
}
// src/operations/grants/shared.ts
function isAllTablesOptions(options) {
return "schema" in options;
}
function asRolesStr(roles, mOptions) {
return toArray(roles).map((role) => role === "PUBLIC" ? role : mOptions.literal(role)).join(", ");
}
function asTablesStr(options, mOptions) {
return isAllTablesOptions(options) ? `ALL TABLES IN SCHEMA ${mOptions.literal(options.schema)}` : toArray(options.tables).map(mOptions.literal).join(", ");
}
// src/operations/grants/revokeOnSchemas.ts
function revokeOnSchemas(mOptions) {
const _revokeOnSchemas = (options) => {
const {
privileges,
schemas,
roles,
onlyGrantOption = false,
cascade = false
} = options;
const rolesStr = asRolesStr(roles, mOptions);
const schemasStr = toArray(schemas).map(mOptions.literal).join(", ");
const privilegesStr = toArray(privileges).map(String).join(", ");
const onlyGrantOptionStr = onlyGrantOption ? " GRANT OPTION FOR" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return `REVOKE${onlyGrantOptionStr} ${privilegesStr} ON SCHEMA ${schemasStr} FROM ${rolesStr}${cascadeStr};`;
};
return _revokeOnSchemas;
}
// src/operations/grants/grantOnSchemas.ts
function grantOnSchemas(mOptions) {
const _grantOnSchemas = (options) => {
const { privileges, schemas, roles, withGrantOption = false } = options;
const rolesStr = asRolesStr(roles, mOptions);
const schemasStr = toArray(schemas).map(mOptions.literal).join(", ");
const privilegesStr = toArray(privileges).map(String).join(", ");
const withGrantOptionStr = withGrantOption ? " WITH GRANT OPTION" : "";
return `GRANT ${privilegesStr} ON SCHEMA ${schemasStr} TO ${rolesStr}${withGrantOptionStr};`;
};
_grantOnSchemas.reverse = revokeOnSchemas(mOptions);
return _grantOnSchemas;
}
// src/operations/grants/revokeOnTables.ts
function revokeOnTables(mOptions) {
const _revokeOnTables = (options) => {
const {
privileges,
roles,
onlyGrantOption = false,
cascade = false
} = options;
const rolesStr = asRolesStr(roles, mOptions);
const privilegesStr = toArray(privileges).map(String).join(", ");
const tablesStr = asTablesStr(options, mOptions);
const onlyGrantOptionStr = onlyGrantOption ? " GRANT OPTION FOR" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return `REVOKE${onlyGrantOptionStr} ${privilegesStr} ON ${tablesStr} FROM ${rolesStr}${cascadeStr};`;
};
return _revokeOnTables;
}
// src/operations/grants/grantOnTables.ts
function grantOnTables(mOptions) {
const _grantOnTables = (options) => {
const { privileges, roles, withGrantOption = false } = options;
const rolesStr = asRolesStr(roles, mOptions);
const privilegesStr = toArray(privileges).map(String).join(", ");
const tablesStr = asTablesStr(options, mOptions);
const withGrantOptionStr = withGrantOption ? " WITH GRANT OPTION" : "";
return `GRANT ${privilegesStr} ON ${tablesStr} TO ${rolesStr}${withGrantOptionStr};`;
};
_grantOnTables.reverse = revokeOnTables(mOptions);
return _grantOnTables;
}
// src/operations/grants/revokeRoles.ts
function revokeRoles(mOptions) {
const _revokeRoles = (roles, rolesFrom, options = {}) => {
const { onlyAdminOption = false, cascade = false } = options;
const rolesStr = toArray(roles).map(mOptions.literal).join(", ");
const rolesToStr = toArray(rolesFrom).map(mOptions.literal).join(", ");
const onlyAdminOptionStr = onlyAdminOption ? " ADMIN OPTION FOR" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return `REVOKE${onlyAdminOptionStr} ${rolesStr} FROM ${rolesToStr}${cascadeStr};`;
};
return _revokeRoles;
}
// src/operations/grants/grantRoles.ts
function grantRoles(mOptions) {
const _grantRoles = (rolesFrom, rolesTo, options = {}) => {
const { withAdminOption = false } = options;
const rolesFromStr = toArray(rolesFrom).map(mOptions.literal).join(", ");
const rolesToStr = toArray(rolesTo).map(mOptions.literal).join(", ");
const withAdminOptionStr = withAdminOption ? " WITH ADMIN OPTION" : "";
return `GRANT ${rolesFromStr} TO ${rolesToStr}${withAdminOptionStr};`;
};
_grantRoles.reverse = revokeRoles(mOptions);
return _grantRoles;
}
// src/operations/indexes/shared.ts
function generateIndexName(table, columns, options, schemalize) {
if (options.name) {
return typeof table === "object" ? { schema: table.schema, name: options.name } : options.name;
}
const cols = columns.map((col) => schemalize(typeof col === "string" ? col : col.name)).join("_");
const uniq = "unique" in options && options.unique ? "_unique" : "";
return typeof table === "object" ? {
schema: table.schema,
name: `${table.name}_${cols}${uniq}_index`
} : `${table}_${cols}${uniq}_index`;
}
function generateColumnString(column, mOptions) {
const name = mOptions.schemalize(column);
const isSpecial = /[ ().]/.test(name);
return isSpecial ? name : mOptions.literal(name);
}
function generateColumnsString(columns, mOptions) {
return columns.map(
(column) => typeof column === "string" ? generateColumnString(column, mOptions) : [
generateColumnString(column.name, mOptions),
column.opclass ? mOptions.literal(column.opclass) : void 0,
column.sort
].filter((s) => typeof s === "string" && s !== "").join(" ")
).join(", ");
}
// src/operations/indexes/dropIndex.ts
function dropIndex(mOptions) {
const _drop = (tableName, rawColumns, options = {}) => {
const { concurrently = false, ifExists = false, cascade = false } = options;
const columns = toArray(rawColumns);
const concurrentlyStr = concurrently ? " CONCURRENTLY" : "";
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const indexName = generateIndexName(
tableName,
columns,
options,
mOptions.schemalize
);
const cascadeStr = cascade ? " CASCADE" : "";
const indexNameStr = mOptions.literal(indexName);
return `DROP INDEX${concurrentlyStr}${ifExistsStr} ${indexNameStr}${cascadeStr};`;
};
return _drop;
}
// src/operations/indexes/createIndex.ts
function createIndex(mOptions) {
const _create = (tableName, rawColumns, options = {}) => {
const {
unique = false,
concurrently = false,
ifNotExists = false,
method,
where,
include
} = options;
const columns = toArray(rawColumns);
const indexName = generateIndexName(
typeof tableName === "object" ? tableName.name : tableName,
columns,
options,
mOptions.schemalize
);
const columnsString = generateColumnsString(columns, mOptions);
const uniqueStr = unique ? " UNIQUE" : "";
const concurrentlyStr = concurrently ? " CONCURRENTLY" : "";
const ifNotExistsStr = ifNotExists ? " IF NOT EXISTS" : "";
const methodStr = method ? ` USING ${method}` : "";
const whereStr = where ? ` WHERE ${where}` : "";
const includeStr = include ? ` INCLUDE (${toArray(include).map(mOptions.literal).join(", ")})` : "";
const indexNameStr = mOptions.literal(indexName);
const tableNameStr = mOptions.literal(tableName);
return `CREATE${uniqueStr} INDEX${concurrentlyStr}${ifNotExistsStr} ${indexNameStr} ON ${tableNameStr}${methodStr} (${columnsString})${includeStr}${whereStr};`;
};
_create.reverse = dropIndex(mOptions);
return _create;
}
// src/operations/materializedViews/shared.ts
function dataClause(data) {
return data === void 0 ? "" : ` WITH${data ? "" : " NO"} DATA`;
}
function storageParameterStr(storageParameters) {
return (key) => {
const value = storageParameters[key] === true ? "" : ` = ${storageParameters[key]}`;
return `${key}${value}`;
};
}
// src/operations/materializedViews/alterMaterializedView.ts
function alterMaterializedView(mOptions) {
const _alter = (viewName, options) => {
const { cluster, extension, storageParameters = {} } = options;
const clauses = [];
if (cluster !== void 0) {
if (cluster) {
clauses.push(`CLUSTER ON ${mOptions.literal(cluster)}`);
} else {
clauses.push("SET WITHOUT CLUSTER");
}
}
if (extension) {
clauses.push(`DEPENDS ON EXTENSION ${mOptions.literal(extension)}`);
}
const withOptions = Object.keys(storageParameters).filter((key) => storageParameters[key] !== null).map(storageParameterStr(storageParameters)).join(", ");
if (withOptions) {
clauses.push(`SET (${withOptions})`);
}
const resetOptions = Object.keys(storageParameters).filter((key) => storageParameters[key] === null).join(", ");
if (resetOptions) {
clauses.push(`RESET (${resetOptions})`);
}
const clausesStr = formatLines(clauses);
const viewNameStr = mOptions.literal(viewName);
return `ALTER MATERIALIZED VIEW ${viewNameStr}
${clausesStr};`;
};
return _alter;
}
// src/operations/materializedViews/dropMaterializedView.ts
function dropMaterializedView(mOptions) {
const _drop = (viewName, options = {}) => {
const { ifExists = false, cascade = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
const viewNameStr = mOptions.literal(viewName);
return `DROP MATERIALIZED VIEW${ifExistsStr} ${viewNameStr}${cascadeStr};`;
};
return _drop;
}
// src/operations/materializedViews/createMaterializedView.ts
function createMaterializedView(mOptions) {
const _create = (viewName, options, definition) => {
const {
ifNotExists = false,
columns = [],
tablespace,
storageParameters = {},
data
} = options;
const columnNames = toArray(columns).map(mOptions.literal).join(", ");
const withOptions = Object.keys(storageParameters).map(storageParameterStr(storageParameters)).join(", ");
const ifNotExistsStr = ifNotExists ? " IF NOT EXISTS" : "";
const columnsStr = columnNames ? `(${columnNames})` : "";
const withOptionsStr = withOptions ? ` WITH (${withOptions})` : "";
const tablespaceStr = tablespace ? ` TABLESPACE ${mOptions.literal(tablespace)}` : "";
const dataStr = dataClause(data);
const viewNameStr = mOptions.literal(viewName);
return `CREATE MATERIALIZED VIEW${ifNotExistsStr} ${viewNameStr}${columnsStr}${withOptionsStr}${tablespaceStr} AS ${definition}${dataStr};`;
};
_create.reverse = dropMaterializedView(mOptions);
return _create;
}
// src/operations/materializedViews/refreshMaterializedView.ts
function refreshMaterializedView(mOptions) {
const _refresh = (viewName, options = {}) => {
const { concurrently = false, data } = options;
const concurrentlyStr = concurrently ? " CONCURRENTLY" : "";
const dataStr = dataClause(data);
const viewNameStr = mOptions.literal(viewName);
return `REFRESH MATERIALIZED VIEW${concurrentlyStr} ${viewNameStr}${dataStr};`;
};
_refresh.reverse = _refresh;
return _refresh;
}
// src/operations/materializedViews/renameMaterializedView.ts
function renameMaterializedView(mOptions) {
const _rename = (viewName, newViewName) => {
const viewNameStr = mOptions.literal(viewName);
const newViewNameStr = mOptions.literal(newViewName);
return `ALTER MATERIALIZED VIEW ${viewNameStr} RENAME TO ${newViewNameStr};`;
};
_rename.reverse = (viewName, newViewName) => _rename(newViewName, viewName);
return _rename;
}
// src/operations/materializedViews/renameMaterializedViewColumn.ts
function renameMaterializedViewColumn(mOptions) {
const _rename = (viewName, columnName, newColumnName) => {
const viewNameStr = mOptions.literal(viewName);
const columnNameStr = mOptions.literal(columnName);
const newColumnNameStr = mOptions.literal(newColumnName);
return `ALTER MATERIALIZED VIEW ${viewNameStr} RENAME COLUMN ${columnNameStr} TO ${newColumnNameStr};`;
};
_rename.reverse = (viewName, columnName, newColumnName) => _rename(viewName, newColumnName, columnName);
return _rename;
}
// src/operations/operators/shared.ts
function operatorMap(mOptions) {
return ({ type, number, name, params = [] }) => {
const nameStr = mOptions.literal(name);
if (String(type).toLowerCase() === "operator") {
if (params.length > 2) {
throw new Error("Operator can't have more than 2 parameters");
}
const paramsStr = params.length > 0 ? formatParams(params, mOptions) : "";
return `OPERATOR ${number} ${nameStr}${paramsStr}`;
}
if (String(type).toLowerCase() === "function") {
const paramsStr = formatParams(params, mOptions);
return `FUNCTION ${number} ${nameStr}${paramsStr}`;
}
throw new Error('Operator "type" must be either "function" or "operator"');
};
}
// src/operations/operators/removeFromOperatorFamily.ts
var removeFromOperatorFamily = (mOptions) => {
const method = (operatorFamilyName, indexMethod, operatorList) => {
const operatorFamilyNameStr = mOptions.literal(operatorFamilyName);
const operatorListStr = operatorList.map(operatorMap(mOptions)).join(",\n ");
return `ALTER OPERATOR FAMILY ${operatorFamilyNameStr} USING ${indexMethod} DROP
${operatorListStr};`;
};
return method;
};
// src/operations/operators/addToOperatorFamily.ts
var addToOperatorFamily = (mOptions) => {
const method = (operatorFamilyName, indexMethod, operatorList) => {
const operatorFamilyNameStr = mOptions.literal(operatorFamilyName);
const operatorListStr = operatorList.map(operatorMap(mOptions)).join(",\n ");
return `ALTER OPERATOR FAMILY ${operatorFamilyNameStr} USING ${indexMethod} ADD
${operatorListStr};`;
};
method.reverse = removeFromOperatorFamily(mOptions);
return method;
};
// src/operations/operators/dropOperator.ts
function dropOperator(mOptions) {
const _drop = (operatorName, options = {}) => {
const {
left = "none",
right = "none",
ifExists = false,
cascade = false
} = options;
const operatorNameStr = mOptions.schemalize(operatorName);
const leftStr = mOptions.literal(left);
const rightStr = mOptions.literal(right);
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return `DROP OPERATOR${ifExistsStr} ${operatorNameStr}(${leftStr}, ${rightStr})${cascadeStr};`;
};
return _drop;
}
// src/operations/operators/createOperator.ts
function createOperator(mOptions) {
const _create = (operatorName, options) => {
const {
procedure,
left,
right,
commutator,
negator,
restrict,
join: join2,
hashes = false,
merges = false
} = options;
const defs = [];
defs.push(`PROCEDURE = ${mOptions.literal(procedure)}`);
if (left) {
defs.push(`LEFTARG = ${mOptions.literal(left)}`);
}
if (right) {
defs.push(`RIGHTARG = ${mOptions.literal(right)}`);
}
if (commutator) {
defs.push(`COMMUTATOR = ${mOptions.schemalize(commutator)}`);
}
if (negator) {
defs.push(`NEGATOR = ${mOptions.schemalize(negator)}`);
}
if (restrict) {
defs.push(`RESTRICT = ${mOptions.literal(restrict)}`);
}
if (join2) {
defs.push(`JOIN = ${mOptions.literal(join2)}`);
}
if (hashes) {
defs.push("HASHES");
}
if (merges) {
defs.push("MERGES");
}
const operatorNameStr = mOptions.schemalize(operatorName);
return `CREATE OPERATOR ${operatorNameStr} (${defs.join(", ")});`;
};
_create.reverse = dropOperator(mOptions);
return _create;
}
// src/operations/operators/dropOperatorClass.ts
function dropOperatorClass(mOptions) {
const _drop = (operatorClassName, indexMethod, options = {}) => {
const { ifExists = false, cascade = false } = options;
const operatorClassNameStr = mOptions.literal(operatorClassName);
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return `DROP OPERATOR CLASS${ifExistsStr} ${operatorClassNameStr} USING ${indexMethod}${cascadeStr};`;
};
return _drop;
}
// src/operations/operators/createOperatorClass.ts
function createOperatorClass(mOptions) {
const _create = (operatorClassName, type, indexMethod, operatorList, options) => {
const { default: isDefault, family } = options;
const operatorClassNameStr = mOptions.literal(operatorClassName);
const defaultStr = isDefault ? " DEFAULT" : "";
const typeStr = mOptions.literal(applyType(type).type);
const indexMethodStr = mOptions.literal(indexMethod);
const familyStr = family ? ` FAMILY ${family}` : "";
const operatorListStr = operatorList.map(operatorMap(mOptions)).join(",\n ");
return `CREATE OPERATOR CLASS ${operatorClassNameStr}${defaultStr} FOR TYPE ${typeStr} USING ${indexMethodStr}${familyStr} AS
${operatorListStr};`;
};
_create.reverse = (operatorClassName, type, indexMethod, operatorList, options) => dropOperatorClass(mOptions)(operatorClassName, indexMethod, options);
return _create;
}
// src/operations/operators/dropOperatorFamily.ts
function dropOperatorFamily(mOptions) {
const _drop = (operatorFamilyName, indexMethod, options = {}) => {
const { ifExists = false, cascade = false } = options;
const operatorFamilyNameStr = mOptions.literal(operatorFamilyName);
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
return `DROP OPERATOR FAMILY${ifExistsStr} ${operatorFamilyNameStr} USING ${indexMethod}${cascadeStr};`;
};
return _drop;
}
// src/operations/operators/createOperatorFamily.ts
function createOperatorFamily(mOptions) {
const _create = (operatorFamilyName, indexMethod) => {
const operatorFamilyNameStr = mOptions.literal(operatorFamilyName);
return `CREATE OPERATOR FAMILY ${operatorFamilyNameStr} USING ${indexMethod};`;
};
_create.reverse = dropOperatorFamily(mOptions);
return _create;
}
// src/operations/operators/renameOperatorClass.ts
function renameOperatorClass(mOptions) {
const _rename = (oldOperatorClassName, indexMethod, newOperatorClassName) => {
const oldOperatorClassNameStr = mOptions.literal(oldOperatorClassName);
const newOperatorClassNameStr = mOptions.literal(newOperatorClassName);
return `ALTER OPERATOR CLASS ${oldOperatorClassNameStr} USING ${indexMethod} RENAME TO ${newOperatorClassNameStr};`;
};
_rename.reverse = (oldOperatorClassName, indexMethod, newOperatorClassName) => _rename(newOperatorClassName, indexMethod, oldOperatorClassName);
return _rename;
}
// src/operations/operators/renameOperatorFamily.ts
function renameOperatorFamily(mOptions) {
const _rename = (oldOperatorFamilyName, indexMethod, newOperatorFamilyName) => {
const oldOperatorFamilyNameStr = mOptions.literal(oldOperatorFamilyName);
const newOperatorFamilyNameStr = mOptions.literal(newOperatorFamilyName);
return `ALTER OPERATOR FAMILY ${oldOperatorFamilyNameStr} USING ${indexMethod} RENAME TO ${newOperatorFamilyNameStr};`;
};
_rename.reverse = (oldOperatorFamilyName, indexMethod, newOperatorFamilyName) => _rename(newOperatorFamilyName, indexMethod, oldOperatorFamilyName);
return _rename;
}
// src/operations/policies/shared.ts
function makeClauses({ role, using, check }) {
const roles = toArray(role).join(", ");
const clauses = [];
if (roles) {
clauses.push(`TO ${roles}`);
}
if (using) {
clauses.push(`USING (${using})`);
}
if (check) {
clauses.push(`WITH CHECK (${check})`);
}
return clauses;
}
// src/operations/policies/alterPolicy.ts
function alterPolicy(mOptions) {
const _alter = (tableName, policyName, options = {}) => {
const clausesStr = makeClauses(options).join(" ");
const policyNameStr = mOptions.literal(policyName);
const tableNameStr = mOptions.literal(tableName);
return `ALTER POLICY ${policyNameStr} ON ${tableNameStr} ${clausesStr};`;
};
return _alter;
}
// src/operations/policies/dropPolicy.ts
function dropPolicy(mOptions) {
const _drop = (tableName, policyName, options = {}) => {
const { ifExists = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const policyNameStr = mOptions.literal(policyName);
const tableNameStr = mOptions.literal(tableName);
return `DROP POLICY${ifExistsStr} ${policyNameStr} ON ${tableNameStr};`;
};
return _drop;
}
// src/operations/policies/createPolicy.ts
function createPolicy(mOptions) {
const _create = (tableName, policyName, options = {}) => {
const { role = "PUBLIC", command = "ALL" } = options;
const createOptions = {
...options,
role
};
const clauses = [`FOR ${command}`, ...makeClauses(createOptions)];
const clausesStr = clauses.join(" ");
const policyNameStr = mOptions.literal(policyName);
const tableNameStr = mOptions.literal(tableName);
return `CREATE POLICY ${policyNameStr} ON ${tableNameStr} ${clausesStr};`;
};
_create.reverse = dropPolicy(mOptions);
return _create;
}
// src/operations/policies/renamePolicy.ts
function renamePolicy(mOptions) {
const _rename = (tableName, policyName, newPolicyName) => {
const policyNameStr = mOptions.literal(policyName);
const newPolicyNameStr = mOptions.literal(newPolicyName);
const tableNameStr = mOptions.literal(tableName);
return `ALTER POLICY ${policyNameStr} ON ${tableNameStr} RENAME TO ${newPolicyNameStr};`;
};
_rename.reverse = (tableName, policyName, newPolicyName) => _rename(tableName, newPolicyName, policyName);
return _rename;
}
// src/operations/roles/shared.ts
function formatRoleOptions(roleOptions = {}) {
const options = [];
if (roleOptions.superuser !== void 0) {
options.push(roleOptions.superuser ? "SUPERUSER" : "NOSUPERUSER");
}
if (roleOptions.createdb !== void 0) {
options.push(roleOptions.createdb ? "CREATEDB" : "NOCREATEDB");
}
if (roleOptions.createrole !== void 0) {
options.push(roleOptions.createrole ? "CREATEROLE" : "NOCREATEROLE");
}
if (roleOptions.inherit !== void 0) {
options.push(roleOptions.inherit ? "INHERIT" : "NOINHERIT");
}
if (roleOptions.login !== void 0) {
options.push(roleOptions.login ? "LOGIN" : "NOLOGIN");
}
if (roleOptions.replication !== void 0) {
options.push(roleOptions.replication ? "REPLICATION" : "NOREPLICATION");
}
if (roleOptions.bypassrls !== void 0) {
options.push(roleOptions.bypassrls ? "BYPASSRLS" : "NOBYPASSRLS");
}
if (roleOptions.limit) {
options.push(`CONNECTION LIMIT ${Number(roleOptions.limit)}`);
}
if (roleOptions.password !== void 0) {
const encrypted = roleOptions.encrypted === false ? "UNENCRYPTED" : "ENCRYPTED";
options.push(`${encrypted} PASSWORD ${escapeValue(roleOptions.password)}`);
}
if (roleOptions.valid !== void 0) {
const valid = roleOptions.valid ? escapeValue(roleOptions.valid) : "'infinity'";
options.push(`VALID UNTIL ${valid}`);
}
if (roleOptions.inRole) {
const inRole = toArray(roleOptions.inRole).join(", ");
options.push(`IN ROLE ${inRole}`);
}
if (roleOptions.role) {
const role = toArray(roleOptions.role).join(", ");
options.push(`ROLE ${role}`);
}
if (roleOptions.admin) {
const admin = toArray(roleOptions.admin).join(", ");
options.push(`ADMIN ${admin}`);
}
return options.join(" ");
}
// src/operations/roles/alterRole.ts
function alterRole(mOptions) {
const _alter = (roleName, roleOptions = {}) => {
const options = formatRoleOptions(roleOptions);
return options ? `ALTER ROLE ${mOptions.literal(roleName)} WITH ${options};` : "";
};
return _alter;
}
// src/operations/roles/dropRole.ts
function dropRole(mOptions) {
const _drop = (roleName, options = {}) => {
const { ifExists = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const roleNameStr = mOptions.literal(roleName);
return `DROP ROLE${ifExistsStr} ${roleNameStr};`;
};
return _drop;
}
// src/operations/roles/createRole.ts
function createRole(mOptions) {
const _create = (roleName, roleOptions = {}) => {
const options = formatRoleOptions({
...roleOptions,
superuser: roleOptions.superuser || false,
createdb: roleOptions.createdb || false,
createrole: roleOptions.createrole || false,
inherit: roleOptions.inherit !== false,
login: roleOptions.login || false,
replication: roleOptions.replication || false
});
const optionsStr = options ? ` WITH ${options}` : "";
return `CREATE ROLE ${mOptions.literal(roleName)}${optionsStr};`;
};
_create.reverse = dropRole(mOptions);
return _create;
}
// src/operations/roles/renameRole.ts
function renameRole(mOptions) {
const _rename = (oldRoleName, newRoleName) => {
const oldRoleNameStr = mOptions.literal(oldRoleName);
const newRoleNameStr = mOptions.literal(newRoleName);
return `ALTER ROLE ${oldRoleNameStr} RENAME TO ${newRoleNameStr};`;
};
_rename.reverse = (oldRoleName, newRoleName) => _rename(newRoleName, oldRoleName);
return _rename;
}
// src/operations/schemas/dropSchema.ts
function dropSchema(mOptions) {
const _drop = (schemaName, options = {}) => {
const { ifExists = false, cascade = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
const schemaNameStr = mOptions.literal(schemaName);
return `DROP SCHEMA${ifExistsStr} ${schemaNameStr}${cascadeStr};`;
};
return _drop;
}
// src/operations/schemas/createSchema.ts
function createSchema(mOptions) {
const _create = (schemaName, options = {}) => {
const { ifNotExists = false, authorization } = options;
const ifNotExistsStr = ifNotExists ? " IF NOT EXISTS" : "";
const schemaNameStr = mOptions.literal(schemaName);
const authorizationStr = authorization ? ` AUTHORIZATION ${authorization}` : "";
return `CREATE SCHEMA${ifNotExistsStr} ${schemaNameStr}${authorizationStr};`;
};
_create.reverse = dropSchema(mOptions);
return _create;
}
// src/operations/schemas/renameSchema.ts
function renameSchema(mOptions) {
const _rename = (schemaName, newSchemaName) => {
const schemaNameStr = mOptions.literal(schemaName);
const newSchemaNameStr = mOptions.literal(newSchemaName);
return `ALTER SCHEMA ${schemaNameStr} RENAME TO ${newSchemaNameStr};`;
};
_rename.reverse = (schemaName, newSchemaName) => _rename(newSchemaName, schemaName);
return _rename;
}
// src/operations/sequences/shared.ts
function parseSequenceOptions(typeShorthands, options) {
const { type, increment, minvalue, maxvalue, start, cache, cycle, owner } = options;
const clauses = [];
if (type) {
clauses.push(`AS ${applyType(type, typeShorthands).type}`);
}
if (increment) {
clauses.push(`INCREMENT BY ${increment}`);
}
if (minvalue) {
clauses.push(`MINVALUE ${minvalue}`);
} else if (minvalue === null || minvalue === false) {
clauses.push("NO MINVALUE");
}
if (maxvalue) {
clauses.push(`MAXVALUE ${maxvalue}`);
} else if (maxvalue === null || maxvalue === false) {
clauses.push("NO MAXVALUE");
}
if (start) {
clauses.push(`START WITH ${start}`);
}
if (cache) {
clauses.push(`CACHE ${cache}`);
}
if (cycle) {
clauses.push("CYCLE");
} else if (cycle === false) {
clauses.push("NO CYCLE");
}
if (owner) {
clauses.push(`OWNED BY ${owner}`);
} else if (owner === null || owner === false) {
clauses.push("OWNED BY NONE");
}
return clauses;
}
// src/operations/sequences/alterSequence.ts
function alterSequence(mOptions) {
return (sequenceName, options) => {
const { restart } = options;
const clauses = parseSequenceOptions(mOptions.typeShorthands, options);
if (restart) {
if (restart === true) {
clauses.push("RESTART");
} else {
clauses.push(`RESTART WITH ${restart}`);
}
}
return `ALTER SEQUENCE ${mOptions.literal(sequenceName)}
${clauses.join("\n ")};`;
};
}
// src/operations/sequences/dropSequence.ts
function dropSequence(mOptions) {
const _drop = (sequenceName, options = {}) => {
const { ifExists = false, cascade = false } = options;
const ifExistsStr = ifExists ? " IF EXISTS" : "";
const cascadeStr = cascade ? " CASCADE" : "";
const sequenceNameStr = mOptions.literal(sequenceName);
return `DROP SEQUENCE${ifExistsStr} ${sequenceNameStr}${cascadeStr};`;
};
return _drop;
}
// src/operations/sequences/createSequence.ts
function createSequence(mOptions) {
const _create = (sequenceName, options = {}) => {
const { temporary = false, ifNotExists = false } = options;
const temporaryStr = temporary ? " TEMPORARY" : "";
const ifNotExistsStr = ifNotExists ? " IF NOT EXISTS" : "";
const sequenceNameStr = mOptions.literal(sequenceName);
const clausesStr = parseSequenceOptions(
mOptions.typeShorthands,
options
).join("\n ");
return `CREATE${temporaryStr} SEQUENCE${ifNotExistsStr} ${sequenceNameStr}
${clausesStr};`;
};
_create.reverse = dropSequence(mOptions);
return _create;
}
// src/operations/sequences/renameSequence.ts
function renameSequence(mOptions) {
const _rename = (sequenceName, newSequenceName) => {
const sequenceNameStr = mOptions.literal(sequenceName);
const newSequenceNameStr = mOptions.literal(newSequenceName);
return `ALTER SEQUENCE ${sequenceNameStr} RENAME TO ${newSequenceNameStr};`;
};
_rename.reverse = (sequenceName, newSequenceName) => _rename(newSequenceName, sequenceName);
return _rename;
}
// src/operations/sql.ts
function sql(mOptions) {
const t = createTransformer(mOptions.literal);
return (sqlStr, args) => {
let statement = t(sqlStr, args);
if (statement.lastIndexOf(";") !== statement.length - 1) {
statement += ";";
}
return statement;
};
}
// src/operations/tables/dropColumns.ts
function dropColumns(mOptions) {
const _drop = (tableName, columns, options = {}) => {
const { ifExists = false, cascade = false } = options;
if (typeof columns === "string") {
columns = [columns];
} else if (!Array.isArray(columns) && typeof columns === "object") {
columns = Object.keys(columns);
}
const ifExistsStr = ifExists ? "IF EXISTS " : "";
const cascadeStr = cascade ? " CASCADE" : "";
const lines = columns.map(mOptions.literal).map((column) => `DROP ${ifExistsStr}${column}${cascadeStr}`);
return `ALTER TABLE ${mOptions.literal(tableName)}
${formatLines(lines)};`;
};
return _drop;
}
// src/operations/tables/shared.ts
function parseReferences(options, literal) {
const { references, match, onDelete, onUpdate } = options;
const clauses = [];
clauses.push(
typeof references === "string" && (references.startsWith('"') || references.endsWith(")")) ? `REFERENCES ${references}` : `REFERENCES ${literal(references)}`
);
if (match) {
clauses.push(`MATCH ${match}`);
}
if (onDelete) {
clauses.push(`ON DELETE ${onDelete}`);
}
if (onUpdate) {
clauses.push(`ON UPDATE ${onUpdate}`);
}
return clauses.join(" ");
}
function parseDeferrable(options) {
return `DEFERRABLE INITIALLY ${options.deferred ? "DEFERRED" : "IMMEDIATE"}`;
}
function parseColumns(tableName, columns, mOptions) {
const extendingTypeShorthands = mOptions.typeShorthands;
let columnsWithOptions = Object.keys(columns).reduce(
(previous, column) => ({
...previous,
[column]: applyType(columns[column], extendingTypeShorthands)
}),
{}
);
const primaryColumns = Object.entries(columnsWithOptions).filter(([, { primaryKey }]) => Boolean(primaryKey)).map(([columnName]) => columnName);
const multiplePrimaryColumns = primaryColumns.length > 1;
if (multiplePrimaryColumns) {
columnsWithOptions = Object.fromEntries(
Object.entries(columnsWithOptions).map(([columnName, options]) => [
columnName,
{
...options,
primaryKey: false
}
])
);
}
const comments = Object.entries(columnsWithOptions).map(([columnName, { comment }]) => {
return comment !== void 0 && makeComment(
"COLUMN",
`${mOptions.literal(tableName)}.${mOptions.literal(columnName)}`,
comment
);
}).filter((comment) => Boolean(comment));
return {
columns: Object.entries(columnsWithOptions).map(([columnName, options]) => {
const {
type,
collation,
default: defaultValue,
unique,
primaryKey,
notNull,
check,
references,
referencesConstraintName,
referencesConstraintComment,
deferrable,
expressionGenerated
} = options;
const sequenceGenerated = options.sequenceGenerated;
const constraints = [];
if (collation) {
constraints.push(`COLLATE ${collation}`);
}
if (defaultValue !== void 0) {
constraints.push(`DEFAULT ${escapeValue(defaultValue)}`);
}
if (unique) {
constraints.push("UNIQUE");
}
if (primaryKey) {
constraints.push("PRIMARY KEY");
}
if (notNull) {
constraints.push("NOT NULL");
}
if (check) {
constraints.push(`CHECK (${check})`);
}
if (references) {
const name = referencesConstraintName || (referencesConstraintComment ? `${tableName}_fk_${columnName}` : "");
const constraintName = name ? `CONSTRAINT ${mOptions.literal(name)} ` : "";
constraints.push(
`${constraintName}${parseReferences(options, mOptions.literal)}`
);
if (referencesConstraintComment) {
comments.push(
makeComment(
`CONSTRAINT ${mOptions.literal(name)} ON`,
mOptions.literal(tableName),
referencesConstraintComment
)
);
}
}
if (deferrable) {
constraints.push(parseDeferrable(options));
}
if (sequenceGenerated) {
const sequenceOptions = parseSequenceOptions(
extendingTypeShorthands,
sequenceGenerated
).join(" ");
constraints.push(
`GENERATED ${sequenceGenerated.precedence} AS IDENTITY${sequenceOptions ? ` (${sequenceOptions})` : ""}`
);
}
if (expressionGenerated) {
constraints.push(`GENERATED ALWAYS AS (${expressionGenerated}) STORED`);
}
const constraintsStr = constraints.length > 0 ? ` ${constraints.join(" ")}` : "";
const sType = typeof type === "object" ? mOptions.literal(type) : type;
return `${mOptions.literal(columnName)} ${sType}${constraintsStr}`;
}),
constr