@carno.js/orm 0.2.3
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/LICENSE +674 -0
- package/dist/SqlBuilder.d.ts +103 -0
- package/dist/SqlBuilder.js +618 -0
- package/dist/cache/cache-key-generator.d.ts +13 -0
- package/dist/cache/cache-key-generator.js +66 -0
- package/dist/cache/query-cache-manager.d.ts +14 -0
- package/dist/cache/query-cache-manager.js +44 -0
- package/dist/common/email.vo.d.ts +4 -0
- package/dist/common/email.vo.js +11 -0
- package/dist/common/uuid.d.ts +4 -0
- package/dist/common/uuid.js +10 -0
- package/dist/common/value-object.d.ts +95 -0
- package/dist/common/value-object.js +99 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +9 -0
- package/dist/decorators/computed.decorator.d.ts +1 -0
- package/dist/decorators/computed.decorator.js +12 -0
- package/dist/decorators/entity.decorator.d.ts +3 -0
- package/dist/decorators/entity.decorator.js +12 -0
- package/dist/decorators/enum.decorator.d.ts +2 -0
- package/dist/decorators/enum.decorator.js +16 -0
- package/dist/decorators/event-hook.decorator.d.ts +4 -0
- package/dist/decorators/event-hook.decorator.js +31 -0
- package/dist/decorators/index.decorator.d.ts +17 -0
- package/dist/decorators/index.decorator.js +36 -0
- package/dist/decorators/one-many.decorator.d.ts +6 -0
- package/dist/decorators/one-many.decorator.js +42 -0
- package/dist/decorators/primary-key.decorator.d.ts +2 -0
- package/dist/decorators/primary-key.decorator.js +8 -0
- package/dist/decorators/property.decorator.d.ts +24 -0
- package/dist/decorators/property.decorator.js +44 -0
- package/dist/decorators/unique.decorator.d.ts +9 -0
- package/dist/decorators/unique.decorator.js +44 -0
- package/dist/domain/base-entity.d.ts +57 -0
- package/dist/domain/base-entity.js +198 -0
- package/dist/domain/collection.d.ts +6 -0
- package/dist/domain/collection.js +15 -0
- package/dist/domain/entities.d.ts +49 -0
- package/dist/domain/entities.js +259 -0
- package/dist/domain/reference.d.ts +86 -0
- package/dist/domain/reference.js +86 -0
- package/dist/driver/bun-driver.base.d.ts +72 -0
- package/dist/driver/bun-driver.base.js +270 -0
- package/dist/driver/bun-mysql.driver.d.ts +53 -0
- package/dist/driver/bun-mysql.driver.js +256 -0
- package/dist/driver/bun-pg.driver.d.ts +52 -0
- package/dist/driver/bun-pg.driver.js +263 -0
- package/dist/driver/driver.interface.d.ts +333 -0
- package/dist/driver/driver.interface.js +2 -0
- package/dist/entry.d.ts +2 -0
- package/dist/entry.js +13 -0
- package/dist/identity-map/entity-key-generator.d.ts +10 -0
- package/dist/identity-map/entity-key-generator.js +45 -0
- package/dist/identity-map/entity-registry.d.ts +11 -0
- package/dist/identity-map/entity-registry.js +41 -0
- package/dist/identity-map/identity-map-context.d.ts +9 -0
- package/dist/identity-map/identity-map-context.js +22 -0
- package/dist/identity-map/identity-map-integration.d.ts +5 -0
- package/dist/identity-map/identity-map-integration.js +37 -0
- package/dist/identity-map/identity-map.d.ts +11 -0
- package/dist/identity-map/identity-map.js +35 -0
- package/dist/identity-map/index.d.ts +5 -0
- package/dist/identity-map/index.js +14 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +48 -0
- package/dist/middleware/identity-map.middleware.d.ts +4 -0
- package/dist/middleware/identity-map.middleware.js +22 -0
- package/dist/orm-session-context.d.ts +16 -0
- package/dist/orm-session-context.js +22 -0
- package/dist/orm.d.ts +20 -0
- package/dist/orm.js +69 -0
- package/dist/orm.service.d.ts +13 -0
- package/dist/orm.service.js +361 -0
- package/dist/query/index-condition-builder.d.ts +41 -0
- package/dist/query/index-condition-builder.js +235 -0
- package/dist/query/model-transformer.d.ts +27 -0
- package/dist/query/model-transformer.js +201 -0
- package/dist/query/sql-column-manager.d.ts +28 -0
- package/dist/query/sql-column-manager.js +157 -0
- package/dist/query/sql-condition-builder.d.ts +51 -0
- package/dist/query/sql-condition-builder.js +264 -0
- package/dist/query/sql-join-manager.d.ts +39 -0
- package/dist/query/sql-join-manager.js +242 -0
- package/dist/query/sql-subquery-builder.d.ts +20 -0
- package/dist/query/sql-subquery-builder.js +119 -0
- package/dist/repository/Repository.d.ts +121 -0
- package/dist/repository/Repository.js +174 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +17 -0
- package/dist/testing/with-database.d.ts +20 -0
- package/dist/testing/with-database.js +311 -0
- package/dist/transaction/transaction-context.d.ts +10 -0
- package/dist/transaction/transaction-context.js +19 -0
- package/dist/utils/value-processor.d.ts +14 -0
- package/dist/utils/value-processor.js +94 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +24 -0
- package/package.json +59 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BunMysqlDriver = void 0;
|
|
4
|
+
const bun_driver_base_1 = require("./bun-driver.base");
|
|
5
|
+
class BunMysqlDriver extends bun_driver_base_1.BunDriverBase {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super(options);
|
|
8
|
+
this.dbType = 'mysql';
|
|
9
|
+
}
|
|
10
|
+
getProtocol() {
|
|
11
|
+
return 'mysql';
|
|
12
|
+
}
|
|
13
|
+
getIdentifierQuote() {
|
|
14
|
+
return '`';
|
|
15
|
+
}
|
|
16
|
+
buildAutoIncrementType(colDiff) {
|
|
17
|
+
return 'INT AUTO_INCREMENT';
|
|
18
|
+
}
|
|
19
|
+
buildEnumType(schema, tableName, colDiff) {
|
|
20
|
+
const enumValues = colDiff.colChanges.enumItems
|
|
21
|
+
.map((item) => `'${item}'`)
|
|
22
|
+
.join(', ');
|
|
23
|
+
return {
|
|
24
|
+
beforeSql: '',
|
|
25
|
+
columnType: `ENUM(${enumValues})`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
appendReturningClause(sql, statement) {
|
|
29
|
+
return sql;
|
|
30
|
+
}
|
|
31
|
+
async handleInsertReturn(statement, result, sql, startTime) {
|
|
32
|
+
if (!statement.columns) {
|
|
33
|
+
return {
|
|
34
|
+
query: { rows: Array.isArray(result) ? result : [] },
|
|
35
|
+
startTime,
|
|
36
|
+
sql,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const insertId = result.lastInsertRowid;
|
|
40
|
+
const cols = statement.columns.join(', ').replaceAll(`${statement.alias}.`, '');
|
|
41
|
+
const selectSql = `SELECT ${cols} FROM ${statement.table} WHERE id = ${insertId}`;
|
|
42
|
+
const selectResult = await this.sql.unsafe(selectSql);
|
|
43
|
+
return {
|
|
44
|
+
query: { rows: Array.isArray(selectResult) ? selectResult : [] },
|
|
45
|
+
startTime,
|
|
46
|
+
sql,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
buildLimitAndOffsetClause(statement) {
|
|
50
|
+
const { offset, limit } = statement;
|
|
51
|
+
if (offset && limit) {
|
|
52
|
+
return ` LIMIT ${offset}, ${limit}`;
|
|
53
|
+
}
|
|
54
|
+
if (limit) {
|
|
55
|
+
return this.buildLimitClause(limit);
|
|
56
|
+
}
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
getCreateTableInstruction(schema, tableName, creates) {
|
|
60
|
+
let beforeSql = ``;
|
|
61
|
+
const st = `CREATE TABLE \`${schema}\`.\`${tableName}\` (${creates
|
|
62
|
+
.map((colDiff) => {
|
|
63
|
+
const isAutoIncrement = colDiff.colChanges?.autoIncrement;
|
|
64
|
+
let sql = ``;
|
|
65
|
+
if (colDiff.colChanges?.enumItems) {
|
|
66
|
+
const enumValues = colDiff.colChanges.enumItems
|
|
67
|
+
.map((item) => `'${item}'`)
|
|
68
|
+
.join(', ');
|
|
69
|
+
sql += `\`${colDiff.colName}\` ENUM(${enumValues})`;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const type = isAutoIncrement
|
|
73
|
+
? 'INT AUTO_INCREMENT'
|
|
74
|
+
: colDiff.colType + (colDiff.colLength ? `(${colDiff.colLength})` : '');
|
|
75
|
+
sql += `\`${colDiff.colName}\` ${type}`;
|
|
76
|
+
}
|
|
77
|
+
if (!colDiff.colChanges?.nullable) {
|
|
78
|
+
sql += ' NOT NULL';
|
|
79
|
+
}
|
|
80
|
+
if (colDiff.colChanges?.primary) {
|
|
81
|
+
sql += ' PRIMARY KEY';
|
|
82
|
+
}
|
|
83
|
+
if (colDiff.colChanges?.unique) {
|
|
84
|
+
sql += ' UNIQUE';
|
|
85
|
+
}
|
|
86
|
+
if (colDiff.colChanges?.default) {
|
|
87
|
+
sql += ` DEFAULT ${colDiff.colChanges.default}`;
|
|
88
|
+
}
|
|
89
|
+
return sql;
|
|
90
|
+
})
|
|
91
|
+
.join(', ')});`;
|
|
92
|
+
return beforeSql + st;
|
|
93
|
+
}
|
|
94
|
+
getAlterTableFkInstruction(schema, tableName, colDiff, fk) {
|
|
95
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD CONSTRAINT \`${tableName}_${colDiff.colName}_fk\` FOREIGN KEY (\`${colDiff.colName}\`) REFERENCES \`${fk.referencedTableName}\` (\`${fk.referencedColumnName}\`);`;
|
|
96
|
+
}
|
|
97
|
+
getCreateIndex(index, schema, tableName) {
|
|
98
|
+
const properties = index.properties || [];
|
|
99
|
+
if (properties.length === 0) {
|
|
100
|
+
throw new Error("Index properties are required.");
|
|
101
|
+
}
|
|
102
|
+
if (index.where) {
|
|
103
|
+
throw new Error("Partial indexes are only supported on postgres.");
|
|
104
|
+
}
|
|
105
|
+
const columns = properties.map((prop) => `\`${prop}\``).join(', ');
|
|
106
|
+
return `CREATE INDEX \`${index.name}\` ON \`${schema}\`.\`${tableName}\` (${columns});`;
|
|
107
|
+
}
|
|
108
|
+
getAddColumn(schema, tableName, colName, colDiff, colDiffInstructions) {
|
|
109
|
+
let sql = ``;
|
|
110
|
+
if (colDiff.colChanges?.enumItems) {
|
|
111
|
+
const enumValues = colDiff.colChanges.enumItems
|
|
112
|
+
.map((item) => `'${item}'`)
|
|
113
|
+
.join(', ');
|
|
114
|
+
sql += `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD COLUMN \`${colDiff.colName}\` ENUM(${enumValues})`;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
sql += `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD COLUMN \`${colName}\` ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''}`;
|
|
118
|
+
}
|
|
119
|
+
if (!colDiff.colChanges?.nullable) {
|
|
120
|
+
sql += ' NOT NULL';
|
|
121
|
+
}
|
|
122
|
+
if (colDiff.colChanges?.primary) {
|
|
123
|
+
sql += ' PRIMARY KEY';
|
|
124
|
+
}
|
|
125
|
+
if (colDiff.colChanges?.unique) {
|
|
126
|
+
sql += ' UNIQUE';
|
|
127
|
+
}
|
|
128
|
+
if (colDiff.colChanges?.default) {
|
|
129
|
+
sql += ` DEFAULT ${colDiff.colChanges.default}`;
|
|
130
|
+
}
|
|
131
|
+
colDiffInstructions.push(sql.concat(';'));
|
|
132
|
+
if (colDiff.colChanges?.foreignKeys) {
|
|
133
|
+
colDiff.colChanges.foreignKeys.forEach((fk) => {
|
|
134
|
+
colDiffInstructions.push(`ALTER TABLE \`${schema}\`.\`${tableName}\` ADD CONSTRAINT \`${tableName}_${colName}_fk\` FOREIGN KEY (\`${colName}\`) REFERENCES \`${fk.referencedTableName}\` (\`${fk.referencedColumnName}\`);`);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
getDropColumn(colDiffInstructions, schema, tableName, colName) {
|
|
139
|
+
colDiffInstructions.push(`ALTER TABLE \`${schema}\`.\`${tableName}\` DROP COLUMN IF EXISTS \`${colName}\`;`);
|
|
140
|
+
}
|
|
141
|
+
getDropIndex(index, schema, tableName) {
|
|
142
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` DROP INDEX \`${index.name}\`;`;
|
|
143
|
+
}
|
|
144
|
+
getCreateUniqueConstraint(unique, schema, tableName) {
|
|
145
|
+
const properties = unique.properties || [];
|
|
146
|
+
if (properties.length === 0) {
|
|
147
|
+
throw new Error("Unique properties are required.");
|
|
148
|
+
}
|
|
149
|
+
const columns = properties.map((prop) => `\`${prop}\``).join(', ');
|
|
150
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD CONSTRAINT \`${unique.name}\` UNIQUE (${columns});`;
|
|
151
|
+
}
|
|
152
|
+
getDropUniqueConstraint(unique, schema, tableName) {
|
|
153
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` DROP INDEX \`${unique.name}\`;`;
|
|
154
|
+
}
|
|
155
|
+
getAlterTableType(schema, tableName, colName, colDiff) {
|
|
156
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''};`;
|
|
157
|
+
}
|
|
158
|
+
getAlterTableDefaultInstruction(schema, tableName, colName, colDiff) {
|
|
159
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` ALTER COLUMN \`${colName}\` SET DEFAULT ${colDiff.colChanges.default};`;
|
|
160
|
+
}
|
|
161
|
+
getAlterTablePrimaryKeyInstruction(schema, tableName, colName, colDiff) {
|
|
162
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD PRIMARY KEY (\`${colName}\`);`;
|
|
163
|
+
}
|
|
164
|
+
getDropConstraint(param, schema, tableName) {
|
|
165
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` DROP FOREIGN KEY \`${param.name}\`;`;
|
|
166
|
+
}
|
|
167
|
+
getAddUniqueConstraint(schema, tableName, colName) {
|
|
168
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` ADD UNIQUE (\`${colName}\`);`;
|
|
169
|
+
}
|
|
170
|
+
getAlterTableDropNullInstruction(schema, tableName, colName, colDiff) {
|
|
171
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType} NULL;`;
|
|
172
|
+
}
|
|
173
|
+
getAlterTableDropNotNullInstruction(schema, tableName, colName, colDiff) {
|
|
174
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ${colDiff.colType} NOT NULL;`;
|
|
175
|
+
}
|
|
176
|
+
getAlterTableEnumInstruction(schema, tableName, colName, colDiff) {
|
|
177
|
+
const enumValues = colDiff.colChanges.enumItems
|
|
178
|
+
.map((item) => `'${item}'`)
|
|
179
|
+
.join(', ');
|
|
180
|
+
return `ALTER TABLE \`${schema}\`.\`${tableName}\` MODIFY COLUMN \`${colName}\` ENUM(${enumValues});`;
|
|
181
|
+
}
|
|
182
|
+
getDropTypeEnumInstruction(param, schema, tableName) {
|
|
183
|
+
return '';
|
|
184
|
+
}
|
|
185
|
+
async snapshot(tableName, options) {
|
|
186
|
+
const schema = (options && options.schema) || 'information_schema';
|
|
187
|
+
const sql = `SELECT * FROM information_schema.columns WHERE table_name = '${tableName}' AND table_schema = DATABASE()`;
|
|
188
|
+
const result = await this.sql.unsafe(sql);
|
|
189
|
+
if (!result || result.length === 0) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const indexes = (await this.index(tableName, options)) || [];
|
|
193
|
+
const constraints = (await this.constraints(tableName, options)) || [];
|
|
194
|
+
return {
|
|
195
|
+
tableName,
|
|
196
|
+
schema,
|
|
197
|
+
indexes,
|
|
198
|
+
columns: result.map((row) => {
|
|
199
|
+
return {
|
|
200
|
+
default: row.COLUMN_DEFAULT,
|
|
201
|
+
length: row.CHARACTER_MAXIMUM_LENGTH ||
|
|
202
|
+
row.NUMERIC_PRECISION ||
|
|
203
|
+
row.DATETIME_PRECISION,
|
|
204
|
+
name: row.COLUMN_NAME,
|
|
205
|
+
nullable: row.IS_NULLABLE === 'YES',
|
|
206
|
+
primary: row.COLUMN_KEY === 'PRI',
|
|
207
|
+
unique: row.COLUMN_KEY === 'UNI' || row.COLUMN_KEY === 'PRI',
|
|
208
|
+
type: row.DATA_TYPE,
|
|
209
|
+
foreignKeys: this.getForeignKeysFromConstraints(constraints, row, 'COLUMN_NAME'),
|
|
210
|
+
isEnum: row.DATA_TYPE === 'enum',
|
|
211
|
+
enumItems: row.DATA_TYPE === 'enum' ? this.parseEnumValues(row.COLUMN_TYPE) : undefined,
|
|
212
|
+
precision: row.NUMERIC_PRECISION,
|
|
213
|
+
scale: row.NUMERIC_SCALE,
|
|
214
|
+
isDecimal: row.DATA_TYPE === 'decimal',
|
|
215
|
+
};
|
|
216
|
+
}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
parseEnumValues(columnType) {
|
|
220
|
+
const match = columnType.match(/enum\((.*)\)/);
|
|
221
|
+
if (!match) {
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
return match[1].split(',').map((v) => v.trim().replace(/'/g, ''));
|
|
225
|
+
}
|
|
226
|
+
async index(tableName, options) {
|
|
227
|
+
const result = await this.sql.unsafe(`SHOW INDEX FROM \`${tableName}\` FROM \`${options.schema || 'information_schema'}\``);
|
|
228
|
+
return result
|
|
229
|
+
.filter((row) => row.Key_name !== 'PRIMARY')
|
|
230
|
+
.map((row) => {
|
|
231
|
+
return {
|
|
232
|
+
table: tableName,
|
|
233
|
+
indexName: row.Key_name,
|
|
234
|
+
columnName: row.Column_name,
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
async constraints(tableName, options) {
|
|
239
|
+
const result = await this.sql.unsafe(`SELECT
|
|
240
|
+
CONSTRAINT_NAME as index_name,
|
|
241
|
+
CONCAT('REFERENCES \`', REFERENCED_TABLE_NAME, '\` (\`', REFERENCED_COLUMN_NAME, '\`)') as consdef,
|
|
242
|
+
'FOREIGN KEY' as constraint_type
|
|
243
|
+
FROM information_schema.KEY_COLUMN_USAGE
|
|
244
|
+
WHERE TABLE_NAME = '${tableName}'
|
|
245
|
+
AND TABLE_SCHEMA = DATABASE()
|
|
246
|
+
AND REFERENCED_TABLE_NAME IS NOT NULL`);
|
|
247
|
+
return result.map((row) => {
|
|
248
|
+
return {
|
|
249
|
+
indexName: row.index_name,
|
|
250
|
+
type: row.constraint_type,
|
|
251
|
+
consDef: row.consdef,
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.BunMysqlDriver = BunMysqlDriver;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ColDiff, ConnectionSettings, DriverInterface, ForeignKeyInfo, IndexStatement, SnapshotConstraintInfo, SnapshotIndexInfo, SnapshotTable, Statement } from './driver.interface';
|
|
2
|
+
import { BunDriverBase } from './bun-driver.base';
|
|
3
|
+
export declare class BunPgDriver extends BunDriverBase implements DriverInterface {
|
|
4
|
+
readonly dbType: "postgres";
|
|
5
|
+
constructor(options: ConnectionSettings);
|
|
6
|
+
protected getProtocol(): string;
|
|
7
|
+
protected getIdentifierQuote(): string;
|
|
8
|
+
protected buildAutoIncrementType(colDiff: ColDiff): string;
|
|
9
|
+
protected buildEnumType(schema: string | undefined, tableName: string, colDiff: ColDiff): {
|
|
10
|
+
beforeSql: string;
|
|
11
|
+
columnType: string;
|
|
12
|
+
};
|
|
13
|
+
protected appendReturningClause(sql: string, statement: Statement<any>): string;
|
|
14
|
+
protected handleInsertReturn(statement: Statement<any>, result: any, sql: string, startTime: number): Promise<{
|
|
15
|
+
query: any;
|
|
16
|
+
startTime: number;
|
|
17
|
+
sql: string;
|
|
18
|
+
}>;
|
|
19
|
+
getCreateTableInstruction(schema: string | undefined, tableName: string, creates: ColDiff[]): string;
|
|
20
|
+
getAlterTableFkInstruction(schema: string | undefined, tableName: string, colDiff: ColDiff, fk: ForeignKeyInfo): string;
|
|
21
|
+
getCreateIndex(index: IndexStatement, schema: string | undefined, tableName: string): string;
|
|
22
|
+
getAddColumn(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff, colDiffInstructions: string[]): void;
|
|
23
|
+
getDropColumn(colDiffInstructions: string[], schema: string | undefined, tableName: string, colName: string): void;
|
|
24
|
+
getDropIndex(index: {
|
|
25
|
+
name: string;
|
|
26
|
+
properties?: string[];
|
|
27
|
+
}, schema: string | undefined, tableName: string): string;
|
|
28
|
+
getCreateUniqueConstraint(unique: {
|
|
29
|
+
name: string;
|
|
30
|
+
properties?: string[];
|
|
31
|
+
}, schema: string | undefined, tableName: string): string;
|
|
32
|
+
getDropUniqueConstraint(unique: {
|
|
33
|
+
name: string;
|
|
34
|
+
}, schema: string | undefined, tableName: string): string;
|
|
35
|
+
getAlterTableType(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
36
|
+
getAlterTableDefaultInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
37
|
+
getAlterTablePrimaryKeyInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
38
|
+
getDropConstraint(param: {
|
|
39
|
+
name: string;
|
|
40
|
+
}, schema: string | undefined, tableName: string): string;
|
|
41
|
+
getAddUniqueConstraint(schema: string | undefined, tableName: string, colName: string): string;
|
|
42
|
+
getAlterTableDropNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
43
|
+
getAlterTableDropNotNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
44
|
+
getAlterTableEnumInstruction(schema: string, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
45
|
+
getDropTypeEnumInstruction(param: {
|
|
46
|
+
name: string;
|
|
47
|
+
}, schema: string | undefined, tableName: string): string;
|
|
48
|
+
snapshot(tableName: string, options: any): Promise<SnapshotTable | undefined>;
|
|
49
|
+
index(tableName: string, options: any): Promise<SnapshotIndexInfo[] | undefined>;
|
|
50
|
+
constraints(tableName: string, options: any): Promise<SnapshotConstraintInfo[] | undefined>;
|
|
51
|
+
private getEnums;
|
|
52
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BunPgDriver = void 0;
|
|
4
|
+
const bun_driver_base_1 = require("./bun-driver.base");
|
|
5
|
+
class BunPgDriver extends bun_driver_base_1.BunDriverBase {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super(options);
|
|
8
|
+
this.dbType = 'postgres';
|
|
9
|
+
}
|
|
10
|
+
getProtocol() {
|
|
11
|
+
return 'postgres';
|
|
12
|
+
}
|
|
13
|
+
getIdentifierQuote() {
|
|
14
|
+
return '"';
|
|
15
|
+
}
|
|
16
|
+
buildAutoIncrementType(colDiff) {
|
|
17
|
+
return 'SERIAL';
|
|
18
|
+
}
|
|
19
|
+
buildEnumType(schema, tableName, colDiff) {
|
|
20
|
+
const enumName = `${schema}_${tableName}_${colDiff.colName}_enum`;
|
|
21
|
+
const enumValues = colDiff.colChanges.enumItems
|
|
22
|
+
.map((item) => `'${item}'`)
|
|
23
|
+
.join(', ');
|
|
24
|
+
const beforeSql = `CREATE TYPE "${enumName}" AS ENUM (${enumValues});`;
|
|
25
|
+
const columnType = `"${enumName}"`;
|
|
26
|
+
return { beforeSql, columnType };
|
|
27
|
+
}
|
|
28
|
+
appendReturningClause(sql, statement) {
|
|
29
|
+
const cols = statement.columns.join(', ').replaceAll(`${statement.alias}.`, '');
|
|
30
|
+
return `${sql} RETURNING ${cols}`;
|
|
31
|
+
}
|
|
32
|
+
async handleInsertReturn(statement, result, sql, startTime) {
|
|
33
|
+
return {
|
|
34
|
+
query: { rows: Array.isArray(result) ? result : [] },
|
|
35
|
+
startTime,
|
|
36
|
+
sql,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
getCreateTableInstruction(schema, tableName, creates) {
|
|
40
|
+
let beforeSql = ``;
|
|
41
|
+
const st = `CREATE TABLE "${schema}"."${tableName}" (${creates
|
|
42
|
+
.map((colDiff) => {
|
|
43
|
+
const isAutoIncrement = colDiff.colChanges?.autoIncrement;
|
|
44
|
+
let sql = ``;
|
|
45
|
+
if (colDiff.colChanges?.enumItems) {
|
|
46
|
+
beforeSql += `CREATE TYPE "${schema}_${tableName}_${colDiff.colName}_enum" AS ENUM (${colDiff.colChanges.enumItems.map((item) => `'${item}'`).join(', ')});`;
|
|
47
|
+
sql += `"${colDiff.colName}" "${schema}_${tableName}_${colDiff.colName}_enum"`;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
sql += `"${colDiff.colName}" ${isAutoIncrement ? 'SERIAL' : colDiff.colType + (colDiff.colLength ? `(${colDiff.colLength})` : '')}`;
|
|
51
|
+
}
|
|
52
|
+
if (!colDiff.colChanges?.nullable) {
|
|
53
|
+
sql += ' NOT NULL';
|
|
54
|
+
}
|
|
55
|
+
if (colDiff.colChanges?.primary) {
|
|
56
|
+
sql += ' PRIMARY KEY';
|
|
57
|
+
}
|
|
58
|
+
if (colDiff.colChanges?.unique) {
|
|
59
|
+
sql += ' UNIQUE';
|
|
60
|
+
}
|
|
61
|
+
if (colDiff.colChanges?.default) {
|
|
62
|
+
sql += ` DEFAULT ${colDiff.colChanges.default}`;
|
|
63
|
+
}
|
|
64
|
+
return sql;
|
|
65
|
+
})
|
|
66
|
+
.join(', ')});`;
|
|
67
|
+
return beforeSql + st;
|
|
68
|
+
}
|
|
69
|
+
getAlterTableFkInstruction(schema, tableName, colDiff, fk) {
|
|
70
|
+
return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${tableName}_${colDiff.colName}_fk" FOREIGN KEY ("${colDiff.colName}") REFERENCES "${fk.referencedTableName}" ("${fk.referencedColumnName}");`;
|
|
71
|
+
}
|
|
72
|
+
getCreateIndex(index, schema, tableName) {
|
|
73
|
+
const properties = index.properties || [];
|
|
74
|
+
if (properties.length === 0) {
|
|
75
|
+
throw new Error("Index properties are required.");
|
|
76
|
+
}
|
|
77
|
+
const columns = properties.map((prop) => `"${prop}"`).join(', ');
|
|
78
|
+
const where = this.buildWhereClause(index.where);
|
|
79
|
+
return `CREATE INDEX "${index.name}" ON "${schema}"."${tableName}" (${columns})${where};`;
|
|
80
|
+
}
|
|
81
|
+
getAddColumn(schema, tableName, colName, colDiff, colDiffInstructions) {
|
|
82
|
+
let beforeSql = ``;
|
|
83
|
+
let sql = ``;
|
|
84
|
+
if (colDiff.colChanges?.enumItems) {
|
|
85
|
+
beforeSql += `CREATE TYPE "${schema}_${tableName}_${colDiff.colName}_enum" AS ENUM (${colDiff.colChanges.enumItems.map((item) => `'${item}'`).join(', ')});`;
|
|
86
|
+
colDiffInstructions.push(beforeSql);
|
|
87
|
+
sql += `ALTER TABLE "${schema}"."${tableName}" ADD COLUMN "${colDiff.colName}" "${schema}_${tableName}_${colDiff.colName}_enum"`;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
sql += `ALTER TABLE "${schema}"."${tableName}" ADD COLUMN "${colName}" ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''}`;
|
|
91
|
+
}
|
|
92
|
+
if (!colDiff.colChanges?.nullable) {
|
|
93
|
+
sql += ' NOT NULL';
|
|
94
|
+
}
|
|
95
|
+
if (colDiff.colChanges?.primary) {
|
|
96
|
+
sql += ' PRIMARY KEY';
|
|
97
|
+
}
|
|
98
|
+
if (colDiff.colChanges?.unique) {
|
|
99
|
+
sql += ' UNIQUE';
|
|
100
|
+
}
|
|
101
|
+
if (colDiff.colChanges?.default) {
|
|
102
|
+
sql += ` DEFAULT ${colDiff.colChanges.default}`;
|
|
103
|
+
}
|
|
104
|
+
colDiffInstructions.push(sql.concat(';'));
|
|
105
|
+
if (colDiff.colChanges?.foreignKeys) {
|
|
106
|
+
colDiff.colChanges.foreignKeys.forEach((fk) => {
|
|
107
|
+
colDiffInstructions.push(`ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${tableName}_${colName}_fk" FOREIGN KEY ("${colName}") REFERENCES "${fk.referencedTableName}" ("${fk.referencedColumnName}");`);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
getDropColumn(colDiffInstructions, schema, tableName, colName) {
|
|
112
|
+
colDiffInstructions.push(`ALTER TABLE "${schema}"."${tableName}" DROP COLUMN IF EXISTS "${colName}";`);
|
|
113
|
+
}
|
|
114
|
+
getDropIndex(index, schema, tableName) {
|
|
115
|
+
return this.getDropConstraint(index, schema, tableName);
|
|
116
|
+
}
|
|
117
|
+
getCreateUniqueConstraint(unique, schema, tableName) {
|
|
118
|
+
const properties = unique.properties || [];
|
|
119
|
+
if (properties.length === 0) {
|
|
120
|
+
throw new Error("Unique properties are required.");
|
|
121
|
+
}
|
|
122
|
+
const columns = properties.map((prop) => `"${prop}"`).join(', ');
|
|
123
|
+
return `ALTER TABLE "${schema}"."${tableName}" ADD CONSTRAINT "${unique.name}" UNIQUE (${columns});`;
|
|
124
|
+
}
|
|
125
|
+
getDropUniqueConstraint(unique, schema, tableName) {
|
|
126
|
+
return this.getDropConstraint(unique, schema, tableName);
|
|
127
|
+
}
|
|
128
|
+
getAlterTableType(schema, tableName, colName, colDiff) {
|
|
129
|
+
return `ALTER TABLE "${schema}"."${tableName}" ALTER COLUMN "${colName}" TYPE ${colDiff.colType}${colDiff.colLength ? `(${colDiff.colLength})` : ''};`;
|
|
130
|
+
}
|
|
131
|
+
getAlterTableDefaultInstruction(schema, tableName, colName, colDiff) {
|
|
132
|
+
return `ALTER TABLE "${schema}"."${tableName}" ALTER COLUMN "${colName}" SET DEFAULT ${colDiff.colChanges.default};`;
|
|
133
|
+
}
|
|
134
|
+
getAlterTablePrimaryKeyInstruction(schema, tableName, colName, colDiff) {
|
|
135
|
+
return `ALTER TABLE "${schema}"."${tableName}" ADD PRIMARY KEY ("${colName}");`;
|
|
136
|
+
}
|
|
137
|
+
getDropConstraint(param, schema, tableName) {
|
|
138
|
+
return `ALTER TABLE "${schema}"."${tableName}" DROP CONSTRAINT "${param.name}";`;
|
|
139
|
+
}
|
|
140
|
+
getAddUniqueConstraint(schema, tableName, colName) {
|
|
141
|
+
return `ALTER TABLE "${schema}"."${tableName}" ADD UNIQUE ("${colName}");`;
|
|
142
|
+
}
|
|
143
|
+
getAlterTableDropNullInstruction(schema, tableName, colName, colDiff) {
|
|
144
|
+
return `ALTER TABLE "${schema}"."${tableName}" ALTER COLUMN "${colName}" DROP NOT NULL;`;
|
|
145
|
+
}
|
|
146
|
+
getAlterTableDropNotNullInstruction(schema, tableName, colName, colDiff) {
|
|
147
|
+
return `ALTER TABLE "${schema}"."${tableName}" ALTER COLUMN "${colName}" SET NOT NULL;`;
|
|
148
|
+
}
|
|
149
|
+
getAlterTableEnumInstruction(schema, tableName, colName, colDiff) {
|
|
150
|
+
return `ALTER TABLE "${schema}"."${tableName}" ALTER COLUMN "${colName}" TYPE varchar(255);DROP TYPE IF EXISTS "${schema}_${tableName}_${colName}_enum";CREATE TYPE "${schema}_${tableName}_${colName}_enum" AS ENUM (${colDiff.colChanges.enumItems.map((item) => `'${item}'`).join(', ')});ALTER TABLE "${schema}"."${tableName}" ALTER COLUMN "${colName}" TYPE "${schema}_${tableName}_${colName}_enum" USING "${colName}"::text::"${schema}_${tableName}_${colName}_enum"`;
|
|
151
|
+
}
|
|
152
|
+
getDropTypeEnumInstruction(param, schema, tableName) {
|
|
153
|
+
return `DROP TYPE IF EXISTS "${param.name}";`;
|
|
154
|
+
}
|
|
155
|
+
async snapshot(tableName, options) {
|
|
156
|
+
const schema = (options && options.schema) || 'public';
|
|
157
|
+
const sql = `SELECT * FROM information_schema.columns WHERE table_name = '${tableName}' AND table_schema = '${schema}'`;
|
|
158
|
+
const result = await this.sql.unsafe(sql);
|
|
159
|
+
if (!result || result.length === 0) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const indexes = (await this.index(tableName, options)) || [];
|
|
163
|
+
const constraints = (await this.constraints(tableName, options)) || [];
|
|
164
|
+
let enums = await this.getEnums(tableName, schema);
|
|
165
|
+
enums = enums.reduce((acc, curr) => {
|
|
166
|
+
if (!acc[curr.type]) {
|
|
167
|
+
acc[curr.type] = [];
|
|
168
|
+
}
|
|
169
|
+
acc[curr.type].push(curr.label);
|
|
170
|
+
return acc;
|
|
171
|
+
}, {});
|
|
172
|
+
return {
|
|
173
|
+
tableName,
|
|
174
|
+
schema,
|
|
175
|
+
indexes,
|
|
176
|
+
columns: result.map((row) => {
|
|
177
|
+
return {
|
|
178
|
+
default: row.column_default,
|
|
179
|
+
length: row.character_maximum_length ||
|
|
180
|
+
row.numeric_precision ||
|
|
181
|
+
row.datetime_precision,
|
|
182
|
+
name: row.column_name,
|
|
183
|
+
nullable: row.is_nullable === 'YES',
|
|
184
|
+
primary: constraints.some((c) => c.type === 'PRIMARY KEY' && c.consDef.includes(row.column_name)),
|
|
185
|
+
unique: constraints.some((c) => (c.type === 'UNIQUE' || c.type === 'PRIMARY KEY') &&
|
|
186
|
+
c.consDef.includes(row.column_name)),
|
|
187
|
+
type: row.data_type,
|
|
188
|
+
foreignKeys: this.getForeignKeysFromConstraints(constraints, row, 'column_name'),
|
|
189
|
+
isEnum: row.data_type === 'USER-DEFINED',
|
|
190
|
+
enumItems: row.data_type === 'USER-DEFINED'
|
|
191
|
+
? enums[`${schema}_${tableName}_${row.column_name}_enum`]
|
|
192
|
+
: undefined,
|
|
193
|
+
precision: row.numeric_precision,
|
|
194
|
+
scale: row.numeric_scale,
|
|
195
|
+
isDecimal: row.data_type === 'numeric',
|
|
196
|
+
};
|
|
197
|
+
}),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
async index(tableName, options) {
|
|
201
|
+
const schema = (options && options.schema) || 'public';
|
|
202
|
+
let result = await this.sql.unsafe(`SELECT indexname AS index_name, indexdef AS column_name, tablename AS table_name
|
|
203
|
+
FROM pg_indexes
|
|
204
|
+
WHERE tablename = '${tableName}' AND schemaname = '${schema}'`);
|
|
205
|
+
result = result.filter((row) => row.index_name.includes('_pkey') || !row.column_name.includes('UNIQUE INDEX'));
|
|
206
|
+
return result.map((row) => {
|
|
207
|
+
return {
|
|
208
|
+
table: tableName,
|
|
209
|
+
indexName: row.index_name,
|
|
210
|
+
columnName: row.column_name,
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
async constraints(tableName, options) {
|
|
215
|
+
const schema = (options && options.schema) || 'public';
|
|
216
|
+
const result = await this.sql.unsafe(`SELECT
|
|
217
|
+
conname AS index_name,
|
|
218
|
+
pg_get_constraintdef(pg_constraint.oid) as consdef,
|
|
219
|
+
CASE contype
|
|
220
|
+
WHEN 'c' THEN 'CHECK'
|
|
221
|
+
WHEN 'f' THEN 'FOREIGN KEY'
|
|
222
|
+
WHEN 'p' THEN 'PRIMARY KEY'
|
|
223
|
+
WHEN 'u' THEN 'UNIQUE'
|
|
224
|
+
WHEN 't' THEN 'TRIGGER'
|
|
225
|
+
WHEN 'x' THEN 'EXCLUSION'
|
|
226
|
+
ELSE 'UNKNOWN'
|
|
227
|
+
END AS constraint_type
|
|
228
|
+
FROM pg_constraint
|
|
229
|
+
where conrelid = (
|
|
230
|
+
SELECT oid
|
|
231
|
+
FROM pg_class
|
|
232
|
+
WHERE relname = '${tableName}'
|
|
233
|
+
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = '${schema}')
|
|
234
|
+
)
|
|
235
|
+
AND conkey @> ARRAY(
|
|
236
|
+
SELECT attnum
|
|
237
|
+
FROM pg_attribute
|
|
238
|
+
WHERE attrelid = conrelid
|
|
239
|
+
AND attname = '${schema}'
|
|
240
|
+
)`);
|
|
241
|
+
return result.map((row) => {
|
|
242
|
+
return {
|
|
243
|
+
indexName: row.index_name,
|
|
244
|
+
type: row.constraint_type,
|
|
245
|
+
consDef: row.consdef,
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async getEnums(tableName, schema) {
|
|
250
|
+
const result = await this.sql.unsafe(`SELECT e.enumlabel as label, t.typname as type
|
|
251
|
+
FROM pg_type t
|
|
252
|
+
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
253
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
254
|
+
WHERE n.nspname = '${schema}'`);
|
|
255
|
+
return result.map((row) => {
|
|
256
|
+
return {
|
|
257
|
+
label: row.label,
|
|
258
|
+
type: row.type,
|
|
259
|
+
};
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
exports.BunPgDriver = BunPgDriver;
|