@zyno-io/dk-server-foundation 26.412.2137 → 26.509.2227
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/proto/generated/devconsole/devconsole.js +1 -1
- package/dist/src/app/config.d.ts +1 -0
- package/dist/src/app/config.d.ts.map +1 -1
- package/dist/src/app/config.js +1 -1
- package/dist/src/app/config.js.map +1 -1
- package/dist/src/database/common.d.ts +3 -0
- package/dist/src/database/common.d.ts.map +1 -1
- package/dist/src/database/common.js +46 -1
- package/dist/src/database/common.js.map +1 -1
- package/dist/src/database/factory.d.ts +17 -0
- package/dist/src/database/factory.d.ts.map +1 -0
- package/dist/src/database/factory.js +53 -0
- package/dist/src/database/factory.js.map +1 -0
- package/dist/src/database/index.d.ts +2 -0
- package/dist/src/database/index.d.ts.map +1 -1
- package/dist/src/database/index.js +2 -0
- package/dist/src/database/index.js.map +1 -1
- package/dist/src/database/migration/MigrationResetCommand.d.ts.map +1 -1
- package/dist/src/database/migration/MigrationResetCommand.js +6 -20
- package/dist/src/database/migration/MigrationResetCommand.js.map +1 -1
- package/dist/src/database/migration/MigrationRunCommand.d.ts.map +1 -1
- package/dist/src/database/migration/MigrationRunCommand.js +2 -0
- package/dist/src/database/migration/MigrationRunCommand.js.map +1 -1
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts +2 -0
- package/dist/src/database/migration/create/MigrationCreateCommand.d.ts.map +1 -1
- package/dist/src/database/migration/create/MigrationCreateCommand.js +33 -11
- package/dist/src/database/migration/create/MigrationCreateCommand.js.map +1 -1
- package/dist/src/database/migration/create/builder-regenerator.d.ts +12 -0
- package/dist/src/database/migration/create/builder-regenerator.d.ts.map +1 -0
- package/dist/src/database/migration/create/builder-regenerator.js +300 -0
- package/dist/src/database/migration/create/builder-regenerator.js.map +1 -0
- package/dist/src/database/migration/create/db-reader.js +47 -6
- package/dist/src/database/migration/create/db-reader.js.map +1 -1
- package/dist/src/database/migration/create/ddl-generator.d.ts.map +1 -1
- package/dist/src/database/migration/create/ddl-generator.js +36 -206
- package/dist/src/database/migration/create/ddl-generator.js.map +1 -1
- package/dist/src/database/migration/create/file-generator.d.ts +2 -0
- package/dist/src/database/migration/create/file-generator.d.ts.map +1 -1
- package/dist/src/database/migration/create/file-generator.js +7 -2
- package/dist/src/database/migration/create/file-generator.js.map +1 -1
- package/dist/src/database/migration/create/schema-model.d.ts +2 -0
- package/dist/src/database/migration/create/schema-model.d.ts.map +1 -1
- package/dist/src/database/migration/create/schema-model.js +1 -1
- package/dist/src/database/mysql.d.ts.map +1 -1
- package/dist/src/database/mysql.js +5 -11
- package/dist/src/database/mysql.js.map +1 -1
- package/dist/src/database/postgres.d.ts +1 -0
- package/dist/src/database/postgres.d.ts.map +1 -1
- package/dist/src/database/postgres.js +1 -13
- package/dist/src/database/postgres.js.map +1 -1
- package/dist/src/database/schema/AlterBlueprint.d.ts +44 -0
- package/dist/src/database/schema/AlterBlueprint.d.ts.map +1 -0
- package/dist/src/database/schema/AlterBlueprint.js +82 -0
- package/dist/src/database/schema/AlterBlueprint.js.map +1 -0
- package/dist/src/database/schema/Blueprint.d.ts +16 -0
- package/dist/src/database/schema/Blueprint.d.ts.map +1 -0
- package/dist/src/database/schema/Blueprint.js +51 -0
- package/dist/src/database/schema/Blueprint.js.map +1 -0
- package/dist/src/database/schema/BlueprintBase.d.ts +59 -0
- package/dist/src/database/schema/BlueprintBase.d.ts.map +1 -0
- package/dist/src/database/schema/BlueprintBase.js +349 -0
- package/dist/src/database/schema/BlueprintBase.js.map +1 -0
- package/dist/src/database/schema/ColumnDefinition.d.ts +43 -0
- package/dist/src/database/schema/ColumnDefinition.d.ts.map +1 -0
- package/dist/src/database/schema/ColumnDefinition.js +117 -0
- package/dist/src/database/schema/ColumnDefinition.js.map +1 -0
- package/dist/src/database/schema/Schema.d.ts +32 -0
- package/dist/src/database/schema/Schema.d.ts.map +1 -0
- package/dist/src/database/schema/Schema.js +148 -0
- package/dist/src/database/schema/Schema.js.map +1 -0
- package/dist/src/database/schema/grammar/Grammar.d.ts +34 -0
- package/dist/src/database/schema/grammar/Grammar.d.ts.map +1 -0
- package/dist/src/database/schema/grammar/Grammar.js +36 -0
- package/dist/src/database/schema/grammar/Grammar.js.map +1 -0
- package/dist/src/database/schema/grammar/MySQLGrammar.d.ts +28 -0
- package/dist/src/database/schema/grammar/MySQLGrammar.d.ts.map +1 -0
- package/dist/src/database/schema/grammar/MySQLGrammar.js +190 -0
- package/dist/src/database/schema/grammar/MySQLGrammar.js.map +1 -0
- package/dist/src/database/schema/grammar/PostgresGrammar.d.ts +28 -0
- package/dist/src/database/schema/grammar/PostgresGrammar.d.ts.map +1 -0
- package/dist/src/database/schema/grammar/PostgresGrammar.js +223 -0
- package/dist/src/database/schema/grammar/PostgresGrammar.js.map +1 -0
- package/dist/src/database/schema/index.d.ts +9 -0
- package/dist/src/database/schema/index.d.ts.map +1 -0
- package/dist/src/database/schema/index.js +12 -0
- package/dist/src/database/schema/index.js.map +1 -0
- package/docs/content/cli.md +4 -1
- package/docs/content/configuration.md +6 -0
- package/docs/content/database.md +128 -0
- package/package.json +1 -1
- package/src/app/config.ts +2 -0
- package/src/database/common.ts +51 -0
- package/src/database/factory.ts +59 -0
- package/src/database/index.ts +2 -0
- package/src/database/migration/MigrationResetCommand.ts +6 -22
- package/src/database/migration/MigrationRunCommand.ts +2 -0
- package/src/database/migration/create/MigrationCreateCommand.ts +40 -12
- package/src/database/migration/create/builder-regenerator.ts +287 -0
- package/src/database/migration/create/db-reader.ts +43 -6
- package/src/database/migration/create/ddl-generator.ts +35 -212
- package/src/database/migration/create/file-generator.ts +5 -1
- package/src/database/migration/create/schema-model.ts +2 -0
- package/src/database/mysql.ts +7 -15
- package/src/database/postgres.ts +3 -17
- package/src/database/schema/AlterBlueprint.ts +85 -0
- package/src/database/schema/Blueprint.ts +43 -0
- package/src/database/schema/BlueprintBase.ts +386 -0
- package/src/database/schema/ColumnDefinition.ts +131 -0
- package/src/database/schema/Schema.ts +164 -0
- package/src/database/schema/grammar/Grammar.ts +61 -0
- package/src/database/schema/grammar/MySQLGrammar.ts +196 -0
- package/src/database/schema/grammar/PostgresGrammar.ts +232 -0
- package/src/database/schema/index.ts +8 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostgresGrammar = void 0;
|
|
4
|
+
function __assignType(fn, args) {
|
|
5
|
+
fn.__type = args;
|
|
6
|
+
return fn;
|
|
7
|
+
}
|
|
8
|
+
/*@ts-ignore*/
|
|
9
|
+
var { __ΩDialect } = require('../../dialect');
|
|
10
|
+
const dialect_1 = require("../../dialect");
|
|
11
|
+
/*@ts-ignore*/
|
|
12
|
+
var { __ΩTableSchema, __ΩIndexSchema, __ΩForeignKeySchema, __ΩColumnSchema } = require('../../migration/create/schema-model');
|
|
13
|
+
const Grammar_1 = require("./Grammar");
|
|
14
|
+
class PostgresGrammar extends Grammar_1.Grammar {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.dialect = 'postgres';
|
|
18
|
+
}
|
|
19
|
+
quote(name) {
|
|
20
|
+
return (0, dialect_1.quoteId)('postgres', name);
|
|
21
|
+
}
|
|
22
|
+
qualifiedTable(name) {
|
|
23
|
+
if (this.pgSchema && this.pgSchema !== 'public') {
|
|
24
|
+
return `${this.quote(this.pgSchema)}.${this.quote(name)}`;
|
|
25
|
+
}
|
|
26
|
+
return this.quote(name);
|
|
27
|
+
}
|
|
28
|
+
qualifiedType(typeName) {
|
|
29
|
+
if (this.pgSchema && this.pgSchema !== 'public') {
|
|
30
|
+
return `${this.quote(this.pgSchema)}.${this.quote(typeName)}`;
|
|
31
|
+
}
|
|
32
|
+
return this.quote(typeName);
|
|
33
|
+
}
|
|
34
|
+
createTable(table) {
|
|
35
|
+
const lines = [];
|
|
36
|
+
const pkCols = table.columns.filter(__assignType(c => c.isPrimaryKey, ['c', '', 'P"2!"/"'])).map(__assignType(c => c.name, ['c', '', 'P"2!"/"']));
|
|
37
|
+
for (const col of table.columns) {
|
|
38
|
+
lines.push(` ${this.columnDef(col)}`);
|
|
39
|
+
}
|
|
40
|
+
if (pkCols.length > 0) {
|
|
41
|
+
const quoted = pkCols.map(__assignType(c => this.quote(c), ['c', '', 'P"2!"/"'])).join(', ');
|
|
42
|
+
lines.push(` PRIMARY KEY (${quoted})`);
|
|
43
|
+
}
|
|
44
|
+
return `CREATE TABLE ${this.qualifiedTable(table.name)} (\n${lines.join(',\n')}\n)`;
|
|
45
|
+
}
|
|
46
|
+
createIndex(tableName, idx) {
|
|
47
|
+
const unique = idx.unique ? 'UNIQUE ' : '';
|
|
48
|
+
// PG has no SPATIAL prefix; spatial flag is silently ignored
|
|
49
|
+
const cols = idx.columns.map(__assignType(c => this.quote(c), ['c', '', 'P"2!"/"'])).join(', ');
|
|
50
|
+
return `CREATE ${unique}INDEX ${this.quote(idx.name)} ON ${this.qualifiedTable(tableName)} (${cols})`;
|
|
51
|
+
}
|
|
52
|
+
addForeignKey(tableName, fk) {
|
|
53
|
+
const cols = fk.columns.map(__assignType(c => this.quote(c), ['c', '', 'P"2!"/"'])).join(', ');
|
|
54
|
+
const refCols = fk.referencedColumns.map(__assignType(c => this.quote(c), ['c', '', 'P"2!"/"'])).join(', ');
|
|
55
|
+
const onDelete = (0, Grammar_1.validateFkAction)(fk.onDelete, this.dialect);
|
|
56
|
+
const onUpdate = (0, Grammar_1.validateFkAction)(fk.onUpdate, this.dialect);
|
|
57
|
+
return (`ALTER TABLE ${this.qualifiedTable(tableName)} ADD CONSTRAINT ${this.quote(fk.name)} ` +
|
|
58
|
+
`FOREIGN KEY (${cols}) REFERENCES ${this.qualifiedTable(fk.referencedTable)} (${refCols}) ` +
|
|
59
|
+
`ON DELETE ${onDelete} ON UPDATE ${onUpdate}`);
|
|
60
|
+
}
|
|
61
|
+
createEnumType(typeName, values) {
|
|
62
|
+
const qualifiedName = this.qualifiedType(typeName);
|
|
63
|
+
const vals = values.map(__assignType(v => `'${(0, Grammar_1.escapeStr)(v)}'`, ['v', '', 'P"2!"/"'])).join(', ');
|
|
64
|
+
const schemaFilter = this.pgSchema && this.pgSchema !== 'public'
|
|
65
|
+
? ` AND typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '${(0, Grammar_1.escapeStr)(this.pgSchema)}')`
|
|
66
|
+
: '';
|
|
67
|
+
return [
|
|
68
|
+
[
|
|
69
|
+
`DO $$ BEGIN`,
|
|
70
|
+
`IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '${(0, Grammar_1.escapeStr)(typeName)}'${schemaFilter}) THEN`,
|
|
71
|
+
` CREATE TYPE ${qualifiedName} AS ENUM (${vals});`,
|
|
72
|
+
`END IF;`,
|
|
73
|
+
`END $$`
|
|
74
|
+
].join('\n'),
|
|
75
|
+
`CREATE CAST (text AS ${qualifiedName}) WITH INOUT AS IMPLICIT`
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
dropTable(name) {
|
|
79
|
+
return `DROP TABLE ${this.qualifiedTable(name)}`;
|
|
80
|
+
}
|
|
81
|
+
dropTableIfExists(name) {
|
|
82
|
+
return `DROP TABLE IF EXISTS ${this.qualifiedTable(name)}`;
|
|
83
|
+
}
|
|
84
|
+
renameTable(from, to) {
|
|
85
|
+
return `ALTER TABLE ${this.qualifiedTable(from)} RENAME TO ${this.quote(to)}`;
|
|
86
|
+
}
|
|
87
|
+
addColumn(tableName, col) {
|
|
88
|
+
return `ALTER TABLE ${this.qualifiedTable(tableName)} ADD COLUMN ${this.columnDef(col)}`;
|
|
89
|
+
}
|
|
90
|
+
dropColumn(tableName, columnName) {
|
|
91
|
+
return `ALTER TABLE ${this.qualifiedTable(tableName)} DROP COLUMN ${this.quote(columnName)}`;
|
|
92
|
+
}
|
|
93
|
+
modifyColumn(tableName, col) {
|
|
94
|
+
const stmts = [];
|
|
95
|
+
const tbl = this.qualifiedTable(tableName);
|
|
96
|
+
const c = this.quote(col.name);
|
|
97
|
+
const typeDef = col.autoIncrement ? (col.type === 'bigint' ? 'BIGINT' : 'INTEGER') : this.typeDef(col);
|
|
98
|
+
stmts.push(`ALTER TABLE ${tbl} ALTER COLUMN ${c} TYPE ${typeDef}`);
|
|
99
|
+
stmts.push(`ALTER TABLE ${tbl} ALTER COLUMN ${c} ${col.nullable ? 'DROP NOT NULL' : 'SET NOT NULL'}`);
|
|
100
|
+
if (col.defaultExpression) {
|
|
101
|
+
stmts.push(`ALTER TABLE ${tbl} ALTER COLUMN ${c} SET DEFAULT ${col.defaultExpression}`);
|
|
102
|
+
}
|
|
103
|
+
else if (col.defaultValue !== undefined) {
|
|
104
|
+
stmts.push(`ALTER TABLE ${tbl} ALTER COLUMN ${c} SET DEFAULT ${renderPgDefault(col)}`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
stmts.push(`ALTER TABLE ${tbl} ALTER COLUMN ${c} DROP DEFAULT`);
|
|
108
|
+
}
|
|
109
|
+
return stmts;
|
|
110
|
+
}
|
|
111
|
+
renameColumn(tableName, from, to) {
|
|
112
|
+
return `ALTER TABLE ${this.qualifiedTable(tableName)} RENAME COLUMN ${this.quote(from)} TO ${this.quote(to)}`;
|
|
113
|
+
}
|
|
114
|
+
dropIndex(tableName, indexName) {
|
|
115
|
+
// Index names in PG are schema-qualified, not table-qualified
|
|
116
|
+
if (this.pgSchema && this.pgSchema !== 'public') {
|
|
117
|
+
return `DROP INDEX ${this.quote(this.pgSchema)}.${this.quote(indexName)}`;
|
|
118
|
+
}
|
|
119
|
+
return `DROP INDEX ${this.quote(indexName)}`;
|
|
120
|
+
}
|
|
121
|
+
dropForeignKey(tableName, constraintName) {
|
|
122
|
+
return `ALTER TABLE ${this.qualifiedTable(tableName)} DROP CONSTRAINT ${this.quote(constraintName)}`;
|
|
123
|
+
}
|
|
124
|
+
addPrimaryKey(tableName, columns) {
|
|
125
|
+
const cols = columns.map(__assignType(c => this.quote(c), ['c', '', 'P"2!"/"'])).join(', ');
|
|
126
|
+
return `ALTER TABLE ${this.qualifiedTable(tableName)} ADD PRIMARY KEY (${cols})`;
|
|
127
|
+
}
|
|
128
|
+
dropPrimaryKey(tableName, constraintName) {
|
|
129
|
+
const name = constraintName ?? `${tableName}_pkey`;
|
|
130
|
+
return `ALTER TABLE ${this.qualifiedTable(tableName)} DROP CONSTRAINT ${this.quote(name)}`;
|
|
131
|
+
}
|
|
132
|
+
columnType(col) {
|
|
133
|
+
return this.typeDef(col);
|
|
134
|
+
}
|
|
135
|
+
columnDef(col) {
|
|
136
|
+
let typeDef;
|
|
137
|
+
if (col.autoIncrement) {
|
|
138
|
+
typeDef = col.type === 'bigint' ? 'BIGSERIAL' : 'SERIAL';
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
typeDef = this.typeDef(col);
|
|
142
|
+
}
|
|
143
|
+
let def = `${this.quote(col.name)} ${typeDef}`;
|
|
144
|
+
if (!col.nullable && !col.autoIncrement)
|
|
145
|
+
def += ' NOT NULL';
|
|
146
|
+
if (!col.autoIncrement) {
|
|
147
|
+
if (col.defaultExpression) {
|
|
148
|
+
def += ` DEFAULT ${col.defaultExpression}`;
|
|
149
|
+
}
|
|
150
|
+
else if (col.defaultValue !== undefined) {
|
|
151
|
+
def += ` DEFAULT ${renderPgDefault(col)}`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return def;
|
|
155
|
+
}
|
|
156
|
+
typeDef(col) {
|
|
157
|
+
switch (col.type) {
|
|
158
|
+
case 'varchar':
|
|
159
|
+
return col.size ? `VARCHAR(${col.size})` : 'VARCHAR';
|
|
160
|
+
case 'char':
|
|
161
|
+
return `CHAR(${col.size || 1})`;
|
|
162
|
+
case 'smallint':
|
|
163
|
+
return 'SMALLINT';
|
|
164
|
+
case 'int':
|
|
165
|
+
case 'integer':
|
|
166
|
+
return 'INTEGER';
|
|
167
|
+
case 'bigint':
|
|
168
|
+
return 'BIGINT';
|
|
169
|
+
case 'real':
|
|
170
|
+
case 'float':
|
|
171
|
+
return 'REAL';
|
|
172
|
+
case 'double precision':
|
|
173
|
+
case 'double':
|
|
174
|
+
return 'DOUBLE PRECISION';
|
|
175
|
+
case 'decimal':
|
|
176
|
+
case 'numeric':
|
|
177
|
+
if (col.size === undefined)
|
|
178
|
+
return 'NUMERIC';
|
|
179
|
+
return col.scale !== undefined ? `NUMERIC(${col.size},${col.scale})` : `NUMERIC(${col.size})`;
|
|
180
|
+
case 'boolean':
|
|
181
|
+
return 'BOOLEAN';
|
|
182
|
+
case 'date':
|
|
183
|
+
return 'DATE';
|
|
184
|
+
case 'timestamp':
|
|
185
|
+
return 'TIMESTAMP';
|
|
186
|
+
case 'timestamptz':
|
|
187
|
+
return 'TIMESTAMPTZ';
|
|
188
|
+
case 'text':
|
|
189
|
+
return 'TEXT';
|
|
190
|
+
case 'bytea':
|
|
191
|
+
return 'BYTEA';
|
|
192
|
+
case 'json':
|
|
193
|
+
return 'JSON';
|
|
194
|
+
case 'jsonb':
|
|
195
|
+
return 'JSONB';
|
|
196
|
+
case 'uuid':
|
|
197
|
+
return 'UUID';
|
|
198
|
+
case 'enum':
|
|
199
|
+
return col.enumTypeName ? this.qualifiedType(col.enumTypeName) : 'TEXT';
|
|
200
|
+
default:
|
|
201
|
+
return col.type.toUpperCase();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.PostgresGrammar = PostgresGrammar;
|
|
206
|
+
PostgresGrammar.__type = [() => Grammar_1.Grammar, () => __ΩDialect, 'dialect', function () { return 'postgres'; }, 'name', 'quote', 'qualifiedTable', 'typeName', 'qualifiedType', () => __ΩTableSchema, 'table', 'createTable', 'tableName', () => __ΩIndexSchema, 'idx', 'createIndex', () => __ΩForeignKeySchema, 'fk', 'addForeignKey', 'values', 'createEnumType', 'dropTable', 'dropTableIfExists', 'from', 'to', 'renameTable', () => __ΩColumnSchema, 'col', 'addColumn', 'columnName', 'dropColumn', () => __ΩColumnSchema, 'modifyColumn', 'renameColumn', 'indexName', 'dropIndex', 'constraintName', 'dropForeignKey', 'columns', 'addPrimaryKey', 'dropPrimaryKey', () => __ΩColumnSchema, 'columnType', () => __ΩColumnSchema, 'columnDef', () => __ΩColumnSchema, 'typeDef', 'PostgresGrammar', 'P7!n"3#9>$P&2%&0&P&2%&0\'P&2(&0)Pn*2+&0,P&2-n.2/&00P&2-n122&03P&2(&F24&F05P&2%&06P&2%&07P&28&29&0:P&2-n;2<&0=P&2-&2>&0?P&2-n@2<&F0AP&2-&28&29&0BP&2-&2C&0DP&2-&2E&0FP&2-&F2G&0HP&2-&2E8&0IPnJ2<&0KPnL2<&0MPnN2<&0O;5wP'];
|
|
207
|
+
const PG_NUMERIC_TYPES = new Set(['smallint', 'int', 'integer', 'bigint', 'real', 'float', 'double', 'double precision', 'decimal', 'numeric']);
|
|
208
|
+
function renderPgDefault(col) {
|
|
209
|
+
const v = col.defaultValue;
|
|
210
|
+
if (v === null)
|
|
211
|
+
return 'NULL';
|
|
212
|
+
if (typeof v === 'boolean')
|
|
213
|
+
return v ? 'TRUE' : 'FALSE';
|
|
214
|
+
if (col.type === 'boolean') {
|
|
215
|
+
const s = String(v).toLowerCase();
|
|
216
|
+
return s === 'true' || s === '1' ? 'TRUE' : 'FALSE';
|
|
217
|
+
}
|
|
218
|
+
if (typeof v === 'number' || PG_NUMERIC_TYPES.has(col.type))
|
|
219
|
+
return String(v);
|
|
220
|
+
return `'${(0, Grammar_1.escapeStr)(String(v))}'`;
|
|
221
|
+
}
|
|
222
|
+
renderPgDefault.__type = [() => __ΩColumnSchema, 'col', 'renderPgDefault', 'Pn!2"&/#'];
|
|
223
|
+
//# sourceMappingURL=PostgresGrammar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresGrammar.js","sourceRoot":"","sources":["../../../../../src/database/schema/grammar/PostgresGrammar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './AlterBlueprint';
|
|
2
|
+
export * from './Blueprint';
|
|
3
|
+
export * from './BlueprintBase';
|
|
4
|
+
export * from './ColumnDefinition';
|
|
5
|
+
export * from './Schema';
|
|
6
|
+
export * from './grammar/Grammar';
|
|
7
|
+
export * from './grammar/MySQLGrammar';
|
|
8
|
+
export * from './grammar/PostgresGrammar';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/database/schema/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./AlterBlueprint"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./Blueprint"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./BlueprintBase"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./ColumnDefinition"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./Schema"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./grammar/Grammar"), exports);
|
|
10
|
+
tslib_1.__exportStar(require("./grammar/MySQLGrammar"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./grammar/PostgresGrammar"), exports);
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/database/schema/index.ts"],"names":[],"mappings":";;;AAAA,2DAAiC;AACjC,sDAA4B;AAC5B,0DAAgC;AAChC,6DAAmC;AACnC,mDAAyB;AACzB,4DAAkC;AAClC,iEAAuC;AACvC,oEAA0C"}
|
package/docs/content/cli.md
CHANGED
|
@@ -68,6 +68,9 @@ node app.js migration:create
|
|
|
68
68
|
|
|
69
69
|
# Non-interactive (CI-safe)
|
|
70
70
|
node app.js migration:create --non-interactive
|
|
71
|
+
|
|
72
|
+
# Emit dialect-specific raw SQL instead of dialect-portable schema-builder calls
|
|
73
|
+
node app.js migration:create --raw
|
|
71
74
|
```
|
|
72
75
|
|
|
73
76
|
Behavior:
|
|
@@ -76,7 +79,7 @@ Behavior:
|
|
|
76
79
|
2. Introspects the live database schema via `information_schema`
|
|
77
80
|
3. Compares the two and detects added/removed/modified tables, columns, indexes, foreign keys, primary key changes, and PostgreSQL enum types
|
|
78
81
|
4. In interactive mode, prompts to detect column renames (avoiding data loss from drop+add)
|
|
79
|
-
5.
|
|
82
|
+
5. **By default, emits dialect-portable `db.schema.create/alter` calls** so the generated migration runs on either MySQL or PostgreSQL. Pass `--raw` to fall back to the legacy dialect-specific SQL emitter.
|
|
80
83
|
6. Writes a timestamped migration file using `createMigration()` format
|
|
81
84
|
|
|
82
85
|
**Non-interactive mode**: Column renames cannot be detected without user input. Ambiguous changes (columns simultaneously added and removed on the same table) are treated as separate DROP/ADD operations, which may cause data loss. A warning is printed when this occurs.
|
|
@@ -22,6 +22,12 @@ Properties ending in `_SECRET` are treated as secrets by the config loader.
|
|
|
22
22
|
| `APP_ENV` | `string` | — | Application environment (`development`, `production`, etc.) |
|
|
23
23
|
| `PORT` | `number` | `3000` | HTTP server port |
|
|
24
24
|
|
|
25
|
+
### Database Selection
|
|
26
|
+
|
|
27
|
+
| Variable | Type | Default | Description |
|
|
28
|
+
| ------------ | -------------------------- | ------- | ------------------------------------------------------------------------------------------ |
|
|
29
|
+
| `DB_ADAPTER` | `'mysql'` \| `'postgres'` | — | Selects the database dialect when using `createDatabase(sharedConfig)` (see [Database](./database.md)). |
|
|
30
|
+
|
|
25
31
|
### MySQL Database
|
|
26
32
|
|
|
27
33
|
| Variable | Type | Default | Description |
|
package/docs/content/database.md
CHANGED
|
@@ -29,6 +29,25 @@ const app = createApp({
|
|
|
29
29
|
|
|
30
30
|
All other MySQL connection options are configured via environment variables (see [Configuration](./configuration.md)).
|
|
31
31
|
|
|
32
|
+
### Choosing the dialect at runtime — `createDatabase()`
|
|
33
|
+
|
|
34
|
+
For dialect-agnostic apps, use `createDatabase()` to select MySQL or PostgreSQL via configuration instead of importing one factory or the other.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { createDatabase } from '@zyno-io/dk-server-foundation';
|
|
38
|
+
|
|
39
|
+
// Reads DB_ADAPTER ('mysql' or 'postgres') from the environment at module load
|
|
40
|
+
class AppDB extends createDatabase({ enableLocksTable: true }, [User, Post, Comment]) {}
|
|
41
|
+
|
|
42
|
+
// Or be explicit (each form keeps its dialect-specific pool config)
|
|
43
|
+
class AppDB extends createDatabase('mysql', { connectionLimit: 20, enableLocksTable: true }, [User]) {}
|
|
44
|
+
class AppDB extends createDatabase('postgres', { max: 20, enableLocksTable: true }, [User]) {}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The shared form only accepts `enableLocksTable`; pool tuning is done via the `MYSQL_*` / `PG_*` env vars. The shared form requires `DB_ADAPTER` to be set and throws at call time if it isn't — use the explicit form when you don't want that dependency.
|
|
48
|
+
|
|
49
|
+
Both forms delegate to `createMySQLDatabase` or `createPostgresDatabase` and return the same kind of class — a subclass of `BaseDatabase`. The existing single-dialect factories remain available.
|
|
50
|
+
|
|
32
51
|
## Entity Creation
|
|
33
52
|
|
|
34
53
|
Type-safe entity creation with automatic inference of optional fields (auto-increment, nullable, or `HasDefault`).
|
|
@@ -340,6 +359,115 @@ class User {
|
|
|
340
359
|
}
|
|
341
360
|
```
|
|
342
361
|
|
|
362
|
+
## Schema Builder (multi-dialect)
|
|
363
|
+
|
|
364
|
+
`db.schema` is a Laravel-style fluent schema builder that emits dialect-appropriate SQL at runtime, so a single migration file works on both MySQL and PostgreSQL.
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
export default createMigration(async db => {
|
|
368
|
+
await db.schema.create('users', t => {
|
|
369
|
+
t.id();
|
|
370
|
+
t.string('email', 255).notNull().unique();
|
|
371
|
+
t.string('name', 255).nullable();
|
|
372
|
+
t.boolean('active').notNull().default(false);
|
|
373
|
+
t.json('metadata').nullable();
|
|
374
|
+
t.enum('status', ['active', 'pending']).notNull().default('pending');
|
|
375
|
+
t.dateTime('createdAt').notNull().defaultRaw('CURRENT_TIMESTAMP');
|
|
376
|
+
t.dateTime('updatedAt').notNull().defaultRaw('CURRENT_TIMESTAMP').onUpdate('CURRENT_TIMESTAMP');
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
await db.schema.create('posts', t => {
|
|
380
|
+
t.id();
|
|
381
|
+
t.bigInteger('userId').unsigned().notNull();
|
|
382
|
+
t.string('title', 200).notNull();
|
|
383
|
+
t.text('body').nullable();
|
|
384
|
+
t.foreign('userId').references('id').on('users').onDelete('cascade');
|
|
385
|
+
t.index('userId');
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// Escape hatches
|
|
389
|
+
await db.schema.raw(`UPDATE users SET active = TRUE WHERE id < 100`);
|
|
390
|
+
await db.schema.onlyOn('postgres', () => db.rawExecute(`CREATE EXTENSION IF NOT EXISTS pg_trgm`));
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Column types
|
|
395
|
+
|
|
396
|
+
| Method | MySQL | Postgres |
|
|
397
|
+
| ------ | ----- | -------- |
|
|
398
|
+
| `id(name='id')` | `BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY` | `BIGSERIAL PRIMARY KEY` |
|
|
399
|
+
| `string(name, len=255)` | `VARCHAR(len)` | `VARCHAR(len)` |
|
|
400
|
+
| `char(name, len=1)` | `CHAR(len)` | `CHAR(len)` |
|
|
401
|
+
| `text(name)` | `TEXT` | `TEXT` |
|
|
402
|
+
| `tinyint`, `smallint`, `integer`, `bigInteger` | `TINYINT`, `SMALLINT`, `INT`, `BIGINT` | `SMALLINT`, `INTEGER`, `BIGINT` (`tinyint` → `SMALLINT`) |
|
|
403
|
+
| `boolean(name)` | `TINYINT(1)` | `BOOLEAN` |
|
|
404
|
+
| `float`, `double`, `decimal(name, p?, s?)` | `FLOAT`, `DOUBLE`, `DECIMAL(p,s)` | `REAL`, `DOUBLE PRECISION`, `NUMERIC(p,s)` |
|
|
405
|
+
| `date(name)` | `DATE` | `DATE` |
|
|
406
|
+
| `dateTime(name)` | `DATETIME` | `TIMESTAMP` |
|
|
407
|
+
| `timestamp(name)` | `TIMESTAMP` | `TIMESTAMP` |
|
|
408
|
+
| `timestamptz(name)` | `TIMESTAMP` | `TIMESTAMPTZ` |
|
|
409
|
+
| `binary(name, len=16)` | `BINARY(len)` | `BYTEA` |
|
|
410
|
+
| `blob(name)` | `BLOB` | `BYTEA` |
|
|
411
|
+
| `json(name)` | `JSON` | `JSON` |
|
|
412
|
+
| `jsonb(name)` | `JSON` | `JSONB` |
|
|
413
|
+
| `uuid(name)` | `BINARY(16)` (canonical) | `UUID` |
|
|
414
|
+
| `uuidString(name)` | `CHAR(36)` | `CHAR(36)` |
|
|
415
|
+
| `enum(name, values, typeName?)` | `ENUM(...)` inline | `CREATE TYPE` (deduped) + qualified ref |
|
|
416
|
+
| `point(name)` | `POINT` | **throws** (MySQL-only) |
|
|
417
|
+
|
|
418
|
+
### Modifiers
|
|
419
|
+
|
|
420
|
+
`.nullable()`, `.notNull()`, `.default(value)`, `.defaultRaw(expression)`, `.unsigned()` (MySQL-only, ignored on PG), `.onUpdate(expression)` (MySQL-only), `.autoIncrement()`, `.primary()`, `.unique(name?)`, `.index(name?)`, `.references(col).on(table).onDelete(action).onUpdate(action)`.
|
|
421
|
+
|
|
422
|
+
### Table-level
|
|
423
|
+
|
|
424
|
+
`.timestamps()` (createdAt + updatedAt with `CURRENT_TIMESTAMP`), `.primary([cols])` (composite PK), `.index(cols, name?)`, `.unique(cols, name?)`, `.spatialIndex(cols, name?)` (MySQL POINT), `.foreign(cols, name?).references(...).on(...)`.
|
|
425
|
+
|
|
426
|
+
### Schema operations
|
|
427
|
+
|
|
428
|
+
`db.schema.create(name, fn)`, `db.schema.alter(name, fn)`, `db.schema.drop(name)`, `db.schema.dropIfExists(name)`, `db.schema.rename(from, to)`, `db.schema.enumType(name, values)` (PG explicit type), `db.schema.raw(sql)`, `db.schema.onlyOn(dialect, fn)`.
|
|
429
|
+
|
|
430
|
+
### Introspection (for idempotent migrations)
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
if (!(await db.schema.hasTable('users'))) { /* ... */ }
|
|
434
|
+
if (await db.schema.hasColumn('users', 'phone')) { /* ... */ }
|
|
435
|
+
if (await db.schema.hasIndex('users', 'users_email_unique')) { /* ... */ }
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### Altering tables — `db.schema.alter()`
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
await db.schema.alter('users', t => {
|
|
442
|
+
// Add columns (same syntax as create)
|
|
443
|
+
t.string('phone', 20).nullable();
|
|
444
|
+
t.boolean('archived').notNull().default(false);
|
|
445
|
+
|
|
446
|
+
// Modify an existing column (Laravel-style .change() suffix)
|
|
447
|
+
t.string('email', 500).notNull().change();
|
|
448
|
+
|
|
449
|
+
// Drop / rename columns
|
|
450
|
+
t.dropColumn('legacyField');
|
|
451
|
+
t.renameColumn('old_name', 'new_name');
|
|
452
|
+
|
|
453
|
+
// Indexes & foreign keys
|
|
454
|
+
t.index('phone');
|
|
455
|
+
t.dropUnique('users_email_unique');
|
|
456
|
+
t.foreign('orgId').references('id').on('orgs').onDelete('cascade');
|
|
457
|
+
t.dropForeign('users_old_fk');
|
|
458
|
+
|
|
459
|
+
// Primary key
|
|
460
|
+
t.dropPrimary();
|
|
461
|
+
t.primary(['a', 'b']);
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Operations execute in dependency-safe order: drop FKs → drop indexes → drop PK → drop columns → rename columns → PG enum type prep → add columns → modify columns → add PK → add indexes → defer added FKs to flush. Added FKs are deferred (same as `create()`) so cross-table refs resolve.
|
|
466
|
+
|
|
467
|
+
### How FK ordering works
|
|
468
|
+
|
|
469
|
+
Inline FKs declared via `t.foreign(...)` are deferred and emitted as `ALTER TABLE ... ADD CONSTRAINT` after all `CREATE TABLE`s in the migration complete. The migration runner calls `db.schema.flush()` automatically; you can also call it manually if you need FKs applied mid-migration. PG enum types are deduplicated per-migration via the `enumTypeName` (so the same shared enum across two tables emits only one `CREATE TYPE` + `CREATE CAST`).
|
|
470
|
+
|
|
343
471
|
## Migrations
|
|
344
472
|
|
|
345
473
|
### Generating Migrations
|
package/package.json
CHANGED
package/src/app/config.ts
CHANGED
package/src/database/common.ts
CHANGED
|
@@ -32,6 +32,34 @@ DatabaseSession.prototype.addPostCommitHook = function (hook: () => Promise<void
|
|
|
32
32
|
this[PostCommitHooksSymbol]!.push(hook);
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
type LocksAdapterState = SQLDatabaseAdapter & { _enableLocksTable?: boolean; _locksTableInit?: Promise<void> };
|
|
36
|
+
|
|
37
|
+
async function ensureMysqlLocksTable(adapter: SQLDatabaseAdapter): Promise<void> {
|
|
38
|
+
const a = adapter as LocksAdapterState;
|
|
39
|
+
if (!a._enableLocksTable) return; // creator opted out
|
|
40
|
+
if (a._locksTableInit) {
|
|
41
|
+
await a._locksTableInit;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
a._locksTableInit = (async () => {
|
|
45
|
+
const conn = await adapter.connectionPool.getConnection();
|
|
46
|
+
try {
|
|
47
|
+
await conn.run(
|
|
48
|
+
`CREATE TABLE IF NOT EXISTS \`_locks\` (
|
|
49
|
+
\`key\` VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
50
|
+
\`createdAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
51
|
+
\`lastTouched\` DATETIME
|
|
52
|
+
)`,
|
|
53
|
+
[]
|
|
54
|
+
);
|
|
55
|
+
await conn.run(`DELETE FROM _locks WHERE lastTouched < NOW() - INTERVAL 1 HOUR`, []);
|
|
56
|
+
} finally {
|
|
57
|
+
conn.release();
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
await a._locksTableInit;
|
|
61
|
+
}
|
|
62
|
+
|
|
35
63
|
DatabaseSession.prototype.acquireSessionLock = async function (key: MutexKey | MutexKey[]) {
|
|
36
64
|
const flattenedKey = flattenMutexKey(key);
|
|
37
65
|
const adapter = this.adapter as SQLDatabaseAdapter;
|
|
@@ -47,6 +75,10 @@ DatabaseSession.prototype.acquireSessionLock = async function (key: MutexKey | M
|
|
|
47
75
|
// then we can use an in-transaction row level update so that a row-level lock is acquired
|
|
48
76
|
// this will be automatically released when the transaction is committed or rolled back
|
|
49
77
|
|
|
78
|
+
// Lazy-initialize the _locks table on first use (gated by createMySQLDatabase's enableLocksTable flag).
|
|
79
|
+
// This avoids a constructor-time fire-and-forget that would race with pool teardown for fast CLIs.
|
|
80
|
+
await ensureMysqlLocksTable(adapter);
|
|
81
|
+
|
|
50
82
|
// insert the lock row outside the transaction on a separate connection
|
|
51
83
|
const insertConn = await adapter.connectionPool.getConnection();
|
|
52
84
|
try {
|
|
@@ -84,6 +116,25 @@ export class BaseDatabase<A extends DatabaseAdapter = DatabaseAdapter> extends D
|
|
|
84
116
|
// override existing definition
|
|
85
117
|
declare query: <T extends OrmEntity>(type?: QueryClassType<T>, txn?: DatabaseSession<DatabaseAdapter>) => SQLDatabaseQuery<T>;
|
|
86
118
|
|
|
119
|
+
private _schema?: import('./schema').Schema;
|
|
120
|
+
|
|
121
|
+
/** Multi-dialect schema builder. See src/database/schema/. */
|
|
122
|
+
get schema(): import('./schema').Schema {
|
|
123
|
+
if (!this._schema) {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
125
|
+
const { Schema, MySQLGrammar, PostgresGrammar } = require('./schema') as typeof import('./schema');
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
127
|
+
const { getDialect } = require('./dialect') as typeof import('./dialect');
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
129
|
+
const { getAppConfig } = require('../app/resolver') as typeof import('../app/resolver');
|
|
130
|
+
const dialect = getDialect(this.adapter as unknown as import('@deepkit/sql').SQLDatabaseAdapter);
|
|
131
|
+
const pgSchema = dialect === 'postgres' ? (getAppConfig().PG_SCHEMA ?? 'public') : 'public';
|
|
132
|
+
const grammar = dialect === 'postgres' ? new PostgresGrammar(pgSchema) : new MySQLGrammar(pgSchema);
|
|
133
|
+
this._schema = new Schema(this, grammar);
|
|
134
|
+
}
|
|
135
|
+
return this._schema;
|
|
136
|
+
}
|
|
137
|
+
|
|
87
138
|
async transaction<T>(callback: (session: DatabaseSession<A>) => Promise<T>): Promise<T> {
|
|
88
139
|
let session_: DatabaseSession<DatabaseAdapter> | undefined;
|
|
89
140
|
const result = await super.transaction(async session => {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ClassType } from '@deepkit/core';
|
|
2
|
+
import { Database } from '@deepkit/orm';
|
|
3
|
+
|
|
4
|
+
import { BaseDatabase } from './common';
|
|
5
|
+
import { Dialect } from './dialect';
|
|
6
|
+
import { createMySQLDatabase, IMySQLDatabaseAdapterConfig, MySQLDatabaseAdapter } from './mysql';
|
|
7
|
+
import { createPostgresDatabase, IPostgresDatabaseAdapterConfig, PostgresDatabaseAdapter } from './postgres';
|
|
8
|
+
|
|
9
|
+
export type AnyDatabaseAdapter = MySQLDatabaseAdapter | PostgresDatabaseAdapter;
|
|
10
|
+
|
|
11
|
+
export interface ICommonDatabaseAdapterConfig {
|
|
12
|
+
enableLocksTable?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type Entities = ConstructorParameters<typeof Database>[1];
|
|
16
|
+
|
|
17
|
+
export function createDatabase(config: ICommonDatabaseAdapterConfig, entities?: Entities): ClassType<BaseDatabase<AnyDatabaseAdapter>>;
|
|
18
|
+
export function createDatabase(
|
|
19
|
+
dialect: 'mysql',
|
|
20
|
+
config: IMySQLDatabaseAdapterConfig,
|
|
21
|
+
entities?: Entities
|
|
22
|
+
): ClassType<BaseDatabase<MySQLDatabaseAdapter>>;
|
|
23
|
+
export function createDatabase(
|
|
24
|
+
dialect: 'postgres',
|
|
25
|
+
config: IPostgresDatabaseAdapterConfig,
|
|
26
|
+
entities?: Entities
|
|
27
|
+
): ClassType<BaseDatabase<PostgresDatabaseAdapter>>;
|
|
28
|
+
export function createDatabase(
|
|
29
|
+
dialectOrConfig: Dialect | ICommonDatabaseAdapterConfig,
|
|
30
|
+
configOrEntities?: IMySQLDatabaseAdapterConfig | IPostgresDatabaseAdapterConfig | Entities,
|
|
31
|
+
maybeEntities?: Entities
|
|
32
|
+
): ClassType<BaseDatabase<AnyDatabaseAdapter>> {
|
|
33
|
+
let dialect: Dialect;
|
|
34
|
+
let config: IMySQLDatabaseAdapterConfig | IPostgresDatabaseAdapterConfig;
|
|
35
|
+
let entities: Entities;
|
|
36
|
+
|
|
37
|
+
if (typeof dialectOrConfig === 'string') {
|
|
38
|
+
dialect = dialectOrConfig;
|
|
39
|
+
config = configOrEntities as IMySQLDatabaseAdapterConfig | IPostgresDatabaseAdapterConfig;
|
|
40
|
+
entities = maybeEntities ?? [];
|
|
41
|
+
} else {
|
|
42
|
+
dialect = resolveDialectFromEnv();
|
|
43
|
+
config = dialectOrConfig;
|
|
44
|
+
entities = (configOrEntities as Entities | undefined) ?? [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return dialect === 'postgres'
|
|
48
|
+
? createPostgresDatabase(config as IPostgresDatabaseAdapterConfig, entities)
|
|
49
|
+
: createMySQLDatabase(config as IMySQLDatabaseAdapterConfig, entities);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function resolveDialectFromEnv(): Dialect {
|
|
53
|
+
const value = process.env.DB_ADAPTER;
|
|
54
|
+
if (value === 'mysql' || value === 'postgres') return value;
|
|
55
|
+
throw new Error(
|
|
56
|
+
`createDatabase(sharedConfig) requires the DB_ADAPTER env var to be 'mysql' or 'postgres' (got: ${value ?? 'undefined'}). ` +
|
|
57
|
+
`Either set DB_ADAPTER or call createDatabase(dialect, config) explicitly.`
|
|
58
|
+
);
|
|
59
|
+
}
|
package/src/database/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './common';
|
|
2
2
|
export * from './dialect';
|
|
3
3
|
export * from './entity';
|
|
4
|
+
export * from './factory';
|
|
4
5
|
export { createMigration, runMigrations, standardizeDbCollation } from './migration';
|
|
6
|
+
export * from './schema';
|
|
5
7
|
export * from './mysql';
|
|
6
8
|
export * from './postgres';
|
|
7
9
|
export * from './types';
|