uql-orm 0.21.0 → 0.22.0
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/README.md +5 -4
- package/dist/bunSql/bunSqlCockroachDialect.d.ts +2 -2
- package/dist/bunSql/bunSqlCockroachDialect.js +4 -10
- package/dist/bunSql/bunSqlPostgresDialect.d.ts +2 -2
- package/dist/bunSql/bunSqlPostgresDialect.js +4 -10
- package/dist/cockroachdb/cockroachDialect.d.ts +20 -4
- package/dist/cockroachdb/cockroachDialect.js +33 -18
- package/dist/d1/d1Querier.d.ts +4 -3
- package/dist/d1/d1Querier.js +0 -3
- package/dist/d1/d1SqliteDialect.d.ts +7 -0
- package/dist/d1/d1SqliteDialect.js +9 -0
- package/dist/dialect/abstractDialect.d.ts +8 -3
- package/dist/dialect/abstractDialect.js +9 -4
- package/dist/dialect/abstractSqlDialect.d.ts +35 -7
- package/dist/dialect/abstractSqlDialect.js +76 -35
- package/dist/dialect/index.d.ts +1 -0
- package/dist/dialect/index.js +1 -0
- package/dist/dialect/indexSqlDialect.d.ts +57 -0
- package/dist/dialect/indexSqlDialect.js +101 -0
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +16 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +32 -1
- package/dist/dialect/pgLikeSqlDialect.d.ts +33 -15
- package/dist/dialect/pgLikeSqlDialect.js +90 -56
- package/dist/dialect/vectorCast.d.ts +21 -0
- package/dist/dialect/vectorCast.js +28 -0
- package/dist/dialect/vectorSqlDialect.d.ts +10 -3
- package/dist/dialect/vectorSqlDialect.js +19 -8
- package/dist/entity/decorator/index-decorator.d.ts +2 -9
- package/dist/entity/metadata/definition.d.ts +5 -4
- package/dist/entity/metadata/definition.js +4 -3
- package/dist/libsql/libsqlDialect.d.ts +12 -2
- package/dist/libsql/libsqlDialect.js +14 -2
- package/dist/libsql/libsqlQuerier.d.ts +9 -22
- package/dist/libsql/libsqlQuerier.js +9 -85
- package/dist/libsql/libsqlQuerierPool.d.ts +10 -8
- package/dist/libsql/libsqlQuerierPool.js +17 -15
- package/dist/maria/mariaDialect.d.ts +26 -4
- package/dist/maria/mariaDialect.js +54 -15
- package/dist/migrate/builder/migrationBuilder.d.ts +9 -29
- package/dist/migrate/builder/migrationBuilder.js +58 -76
- package/dist/migrate/builder/splitSqlStatements.d.ts +0 -2
- package/dist/migrate/builder/splitSqlStatements.js +0 -2
- package/dist/migrate/builder/tableBuilder.d.ts +12 -2
- package/dist/migrate/builder/tableBuilder.js +71 -119
- package/dist/migrate/builder/types.d.ts +30 -41
- package/dist/migrate/cli.d.ts +3 -2
- package/dist/migrate/cli.js +21 -48
- package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -4
- package/dist/migrate/codegen/entityCodeGenerator.js +5 -63
- package/dist/migrate/codegen/fieldOptionsSource.d.ts +10 -0
- package/dist/migrate/codegen/fieldOptionsSource.js +55 -0
- package/dist/migrate/codegen/index.d.ts +0 -2
- package/dist/migrate/codegen/index.js +0 -4
- package/dist/migrate/generator/indexNodeToSchema.d.ts +9 -0
- package/dist/migrate/generator/indexNodeToSchema.js +14 -0
- package/dist/migrate/generator/mongoCommand.d.ts +57 -0
- package/dist/migrate/generator/mongoCommand.js +26 -0
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +9 -20
- package/dist/migrate/generator/mongoSchemaGenerator.js +40 -82
- package/dist/migrate/index.d.ts +0 -1
- package/dist/migrate/index.js +0 -1
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +25 -10
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +46 -32
- package/dist/migrate/introspection/baseSqlIntrospector.d.ts +0 -1
- package/dist/migrate/introspection/baseSqlIntrospector.js +3 -12
- package/dist/migrate/introspection/mongoIntrospector.js +2 -2
- package/dist/migrate/introspection/mysqlIntrospector.d.ts +5 -8
- package/dist/migrate/introspection/mysqlIntrospector.js +4 -10
- package/dist/migrate/introspection/postgresIntrospector.d.ts +5 -8
- package/dist/migrate/introspection/postgresIntrospector.js +4 -10
- package/dist/migrate/introspection/sqliteIntrospector.d.ts +6 -5
- package/dist/migrate/introspection/sqliteIntrospector.js +26 -18
- package/dist/migrate/migrator.d.ts +23 -3
- package/dist/migrate/migrator.js +57 -69
- package/dist/migrate/schemaGenerator.d.ts +26 -37
- package/dist/migrate/schemaGenerator.js +69 -174
- package/dist/migrate/schemaGeneratorAsync.d.ts +2 -2
- package/dist/migrate/schemaGeneratorAsync.js +3 -3
- package/dist/migrate/storage/databaseStorage.js +4 -4
- package/dist/mongo/mongoDialect.d.ts +2 -0
- package/dist/mongo/mongoDialect.js +14 -3
- package/dist/mysql/mysqlDialect.d.ts +8 -0
- package/dist/mysql/mysqlDialect.js +13 -0
- package/dist/schema/canonicalType.d.ts +14 -2
- package/dist/schema/canonicalType.js +41 -31
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/schemaASTBuilder.d.ts +8 -1
- package/dist/schema/schemaASTBuilder.js +56 -47
- package/dist/schema/types.d.ts +10 -37
- package/dist/sqlite/abstractSqliteQuerier.d.ts +39 -0
- package/dist/sqlite/abstractSqliteQuerier.js +44 -0
- package/dist/sqlite/bunSqliteAdapter.bun.d.ts +26 -0
- package/dist/sqlite/bunSqliteAdapter.bun.js +25 -0
- package/dist/sqlite/hranaQuerier.d.ts +54 -0
- package/dist/sqlite/hranaQuerier.js +90 -0
- package/dist/sqlite/hranaQuerierPool.d.ts +21 -0
- package/dist/sqlite/hranaQuerierPool.js +25 -0
- package/dist/sqlite/index.d.ts +2 -1
- package/dist/sqlite/index.js +2 -1
- package/dist/sqlite/sqliteDialect.d.ts +18 -4
- package/dist/sqlite/sqliteDialect.js +24 -24
- package/dist/sqlite/sqliteQuerier.d.ts +16 -9
- package/dist/sqlite/sqliteQuerier.js +4 -27
- package/dist/sqlite/sqliteQuerierPool.d.ts +14 -4
- package/dist/sqlite/sqliteQuerierPool.js +16 -5
- package/dist/turso/index.d.ts +3 -0
- package/dist/turso/index.js +3 -0
- package/dist/turso/local.d.ts +3 -0
- package/dist/turso/local.js +3 -0
- package/dist/turso/tursoDialect.d.ts +15 -0
- package/dist/turso/tursoDialect.js +18 -0
- package/dist/turso/tursoLocalQuerier.d.ts +25 -0
- package/dist/turso/tursoLocalQuerier.js +20 -0
- package/dist/turso/tursoLocalQuerierPool.d.ts +32 -0
- package/dist/turso/tursoLocalQuerierPool.js +39 -0
- package/dist/turso/tursoQuerier.d.ts +10 -0
- package/dist/turso/tursoQuerier.js +10 -0
- package/dist/turso/tursoQuerierPool.d.ts +39 -0
- package/dist/turso/tursoQuerierPool.js +38 -0
- package/dist/type/config.d.ts +0 -6
- package/dist/type/dialect.d.ts +12 -4
- package/dist/type/dialect.js +7 -1
- package/dist/type/entity.d.ts +66 -5
- package/dist/type/migration.d.ts +32 -23
- package/dist/type/vector.d.ts +5 -2
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.js +1 -0
- package/dist/util/indexColumn.util.d.ts +6 -0
- package/dist/util/indexColumn.util.js +26 -0
- package/package.json +16 -3
- package/dist/migrate/codegen/entityMerger.d.ts +0 -114
- package/dist/migrate/codegen/entityMerger.js +0 -293
- package/dist/migrate/codegen/migrationCodeGenerator.d.ts +0 -61
- package/dist/migrate/codegen/migrationCodeGenerator.js +0 -355
- package/dist/migrate/generator/index.d.ts +0 -2
- package/dist/migrate/generator/index.js +0 -2
- package/dist/migrate/sync/index.d.ts +0 -6
- package/dist/migrate/sync/index.js +0 -6
- package/dist/migrate/sync/schemaSync.d.ts +0 -131
- package/dist/migrate/sync/schemaSync.js +0 -259
- package/dist/sqlite/betterSqlite3Dialect.d.ts +0 -9
- package/dist/sqlite/betterSqlite3Dialect.js +0 -9
|
@@ -2,6 +2,8 @@ import { AbstractDialect } from '../../dialect/abstractDialect.js';
|
|
|
2
2
|
import { getMeta } from '../../entity/index.js';
|
|
3
3
|
import { mongoDialectFeatures } from '../../mongo/mongoDialect.js';
|
|
4
4
|
import { getKeys } from '../../util/index.js';
|
|
5
|
+
import { indexNodeToSchema } from './indexNodeToSchema.js';
|
|
6
|
+
import { serializeMongoCommand } from './mongoCommand.js';
|
|
5
7
|
export class MongoSchemaGenerator extends AbstractDialect {
|
|
6
8
|
defaultForeignKeyAction;
|
|
7
9
|
dialectName = 'mongodb';
|
|
@@ -22,17 +24,20 @@ export class MongoSchemaGenerator extends AbstractDialect {
|
|
|
22
24
|
const indexName = typeof field.index === 'string' ? field.index : `idx_${collectionName}_${columnName}`;
|
|
23
25
|
indexes.push({
|
|
24
26
|
name: indexName,
|
|
25
|
-
columns: [columnName],
|
|
27
|
+
columns: [{ column: columnName }],
|
|
26
28
|
unique: !!field.unique,
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
|
-
|
|
32
|
+
// One `createIndex` command each, mirroring the SQL generator's `[CREATE TABLE, ...CREATE INDEX]`,
|
|
33
|
+
// so the key spec is built here and the migrator only executes it.
|
|
34
|
+
return [
|
|
35
|
+
serializeMongoCommand({ action: 'createCollection', name: collectionName }),
|
|
36
|
+
...indexes.map((index) => this.generateCreateIndex(collectionName, index)),
|
|
37
|
+
];
|
|
31
38
|
}
|
|
32
|
-
generateDropTable(
|
|
33
|
-
|
|
34
|
-
const collectionName = this.resolveTableName(entity, meta);
|
|
35
|
-
return JSON.stringify({ action: 'dropCollection', name: collectionName });
|
|
39
|
+
generateDropTable(tableName) {
|
|
40
|
+
return serializeMongoCommand({ action: 'dropCollection', name: tableName });
|
|
36
41
|
}
|
|
37
42
|
generateAlterTable(diff) {
|
|
38
43
|
const statements = [];
|
|
@@ -52,12 +57,26 @@ export class MongoSchemaGenerator extends AbstractDialect {
|
|
|
52
57
|
}
|
|
53
58
|
return statements;
|
|
54
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* MongoDB's key spec is where its index options live: `-1` for a descending entry and `'text'` for a
|
|
62
|
+
* full-text index, which is what `$text` needs since a text index declares its own fields.
|
|
63
|
+
*
|
|
64
|
+
* @remarks The SQL-only modifiers are refused rather than dropped, for the same reason the SQL
|
|
65
|
+
* dialects refuse each other's - a silently weaker index is worse than a clear failure. `where`
|
|
66
|
+
* included: MongoDB's partial indexes take a filter document, not a SQL predicate.
|
|
67
|
+
*/
|
|
55
68
|
generateCreateIndex(tableName, index) {
|
|
56
69
|
const key = {};
|
|
57
|
-
for (const
|
|
58
|
-
|
|
70
|
+
for (const entry of index.columns) {
|
|
71
|
+
if (entry.expression || entry.length !== undefined || entry.nulls || entry.opsClass) {
|
|
72
|
+
throw new TypeError(`mongodb does not support that index column option (index "${index.name}")`);
|
|
73
|
+
}
|
|
74
|
+
key[entry.column] = index.type === 'fulltext' ? 'text' : entry.order === 'desc' ? -1 : 1;
|
|
59
75
|
}
|
|
60
|
-
|
|
76
|
+
if (index.where) {
|
|
77
|
+
throw new TypeError(`mongodb does not support partial indexes from a SQL predicate (index "${index.name}")`);
|
|
78
|
+
}
|
|
79
|
+
return serializeMongoCommand({
|
|
61
80
|
action: 'createIndex',
|
|
62
81
|
collection: tableName,
|
|
63
82
|
name: index.name,
|
|
@@ -66,7 +85,7 @@ export class MongoSchemaGenerator extends AbstractDialect {
|
|
|
66
85
|
});
|
|
67
86
|
}
|
|
68
87
|
generateDropIndex(tableName, indexName) {
|
|
69
|
-
return
|
|
88
|
+
return serializeMongoCommand({
|
|
70
89
|
action: 'dropIndex',
|
|
71
90
|
collection: tableName,
|
|
72
91
|
name: indexName,
|
|
@@ -75,84 +94,23 @@ export class MongoSchemaGenerator extends AbstractDialect {
|
|
|
75
94
|
getSqlType(fieldOptions, fieldType) {
|
|
76
95
|
return '';
|
|
77
96
|
}
|
|
78
|
-
getBooleanType() {
|
|
79
|
-
return '';
|
|
80
|
-
}
|
|
81
|
-
generateColumnDefinitions() {
|
|
82
|
-
return [];
|
|
83
|
-
}
|
|
84
|
-
generateColumnDefinition() {
|
|
85
|
-
return '';
|
|
86
|
-
}
|
|
87
|
-
generateColumnDefinitionFromSchema() {
|
|
88
|
-
return '';
|
|
89
|
-
}
|
|
90
|
-
generateTableConstraints() {
|
|
91
|
-
return [];
|
|
92
|
-
}
|
|
93
|
-
generateAlterColumnStatements() {
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
|
-
getTableOptions() {
|
|
97
|
-
return '';
|
|
98
|
-
}
|
|
99
|
-
generateColumnComment() {
|
|
100
|
-
return '';
|
|
101
|
-
}
|
|
102
|
-
formatDefaultValue() {
|
|
103
|
-
return '';
|
|
104
|
-
}
|
|
105
97
|
generateCreateTableFromNode(table, _options) {
|
|
106
|
-
return [
|
|
98
|
+
return [
|
|
99
|
+
serializeMongoCommand({ action: 'createCollection', name: table.name }),
|
|
100
|
+
...table.indexes.map((index) => this.generateCreateIndexFromNode(index)),
|
|
101
|
+
];
|
|
107
102
|
}
|
|
108
103
|
generateCreateIndexFromNode(index) {
|
|
109
|
-
|
|
110
|
-
for (const col of index.columns) {
|
|
111
|
-
key[col.name] = 1;
|
|
112
|
-
}
|
|
113
|
-
return JSON.stringify({
|
|
114
|
-
action: 'createIndex',
|
|
115
|
-
collection: index.table.name,
|
|
116
|
-
name: index.name,
|
|
117
|
-
key,
|
|
118
|
-
options: { unique: index.unique, name: index.name },
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
generateDropTableFromNode(table) {
|
|
122
|
-
return JSON.stringify({ action: 'dropCollection', name: table.name });
|
|
104
|
+
return this.generateCreateIndex(index.table.name, indexNodeToSchema(index));
|
|
123
105
|
}
|
|
124
106
|
generateCreateTableFromDefinition(table, _options) {
|
|
125
|
-
return [
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
107
|
+
return [
|
|
108
|
+
serializeMongoCommand({ action: 'createCollection', name: table.name }),
|
|
109
|
+
...table.indexes.map((index) => this.generateCreateIndex(table.name, index)),
|
|
110
|
+
];
|
|
129
111
|
}
|
|
130
112
|
generateRenameTableSql(oldName, newName) {
|
|
131
|
-
return
|
|
132
|
-
}
|
|
133
|
-
generateAddColumnSql() {
|
|
134
|
-
return '';
|
|
135
|
-
}
|
|
136
|
-
generateDropColumnSql() {
|
|
137
|
-
return '';
|
|
138
|
-
}
|
|
139
|
-
generateRenameColumnSql() {
|
|
140
|
-
return '';
|
|
141
|
-
}
|
|
142
|
-
generateAlterColumnSql() {
|
|
143
|
-
return '';
|
|
144
|
-
}
|
|
145
|
-
generateCreateIndexSql(tableName, index) {
|
|
146
|
-
return this.generateCreateIndex(tableName, index);
|
|
147
|
-
}
|
|
148
|
-
generateDropIndexSql(tableName, indexName) {
|
|
149
|
-
return this.generateDropIndex(tableName, indexName);
|
|
150
|
-
}
|
|
151
|
-
generateAddForeignKeySql() {
|
|
152
|
-
return '';
|
|
153
|
-
}
|
|
154
|
-
generateDropForeignKeySql() {
|
|
155
|
-
return '';
|
|
113
|
+
return serializeMongoCommand({ action: 'renameCollection', from: oldName, to: newName });
|
|
156
114
|
}
|
|
157
115
|
diffSchema(entity, currentTable) {
|
|
158
116
|
const meta = getMeta(entity);
|
|
@@ -170,7 +128,7 @@ export class MongoSchemaGenerator extends AbstractDialect {
|
|
|
170
128
|
if (!existingIndexes.has(indexName)) {
|
|
171
129
|
indexesToAdd.push({
|
|
172
130
|
name: indexName,
|
|
173
|
-
columns: [columnName],
|
|
131
|
+
columns: [{ column: columnName }],
|
|
174
132
|
unique: !!field.unique,
|
|
175
133
|
});
|
|
176
134
|
}
|
package/dist/migrate/index.d.ts
CHANGED
|
@@ -12,4 +12,3 @@ export { createSchemaGenerator, SqlSchemaGenerator } from './schemaGenerator.js'
|
|
|
12
12
|
export { createSchemaGeneratorAsync } from './schemaGeneratorAsync.js';
|
|
13
13
|
export { DatabaseMigrationStorage } from './storage/databaseStorage.js';
|
|
14
14
|
export { JsonMigrationStorage } from './storage/jsonStorage.js';
|
|
15
|
-
export * from './sync/index.js';
|
package/dist/migrate/index.js
CHANGED
|
@@ -4,6 +4,17 @@ import { BaseSqlIntrospector } from './baseSqlIntrospector.js';
|
|
|
4
4
|
* Referential action type for foreign key constraints.
|
|
5
5
|
*/
|
|
6
6
|
export type ReferentialAction = 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
|
|
7
|
+
/**
|
|
8
|
+
* Reads the rows of one statement while introspecting a table.
|
|
9
|
+
*
|
|
10
|
+
* Identical statements share a single round trip, which is what the mappers get instead of a querier:
|
|
11
|
+
* describing one table needs four facts, and on SQLite three of them come out of the same two PRAGMAs
|
|
12
|
+
* (`table_info` is both the column list and the primary key; the column mapper walks `index_list` and
|
|
13
|
+
* `index_info` for single-column uniqueness while the index mapper is walking them too). That was four
|
|
14
|
+
* redundant statements out of ten per table - on D1 and Turso, where every PRAGMA is an HTTP round trip,
|
|
15
|
+
* it is four avoidable ones.
|
|
16
|
+
*/
|
|
17
|
+
export type TableRowReader = <T extends RawRow>(sql: string, params?: unknown[]) => Promise<T[]>;
|
|
7
18
|
/**
|
|
8
19
|
* Abstract base class for SQL schema introspectors.
|
|
9
20
|
*
|
|
@@ -30,11 +41,11 @@ export declare abstract class AbstractSqlSchemaIntrospector extends BaseSqlIntro
|
|
|
30
41
|
getTableNames(): Promise<string[]>;
|
|
31
42
|
tableExists(tableName: string): Promise<boolean>;
|
|
32
43
|
protected getQuerier(): Promise<SqlQuerier>;
|
|
33
|
-
protected tableExistsInternal(
|
|
34
|
-
protected getColumns(
|
|
35
|
-
protected getIndexes(
|
|
36
|
-
protected getForeignKeys(
|
|
37
|
-
protected getPrimaryKey(
|
|
44
|
+
protected tableExistsInternal(read: TableRowReader, tableName: string): Promise<boolean>;
|
|
45
|
+
protected getColumns(read: TableRowReader, tableName: string): Promise<ColumnSchema[]>;
|
|
46
|
+
protected getIndexes(read: TableRowReader, tableName: string): Promise<IndexSchema[]>;
|
|
47
|
+
protected getForeignKeys(read: TableRowReader, tableName: string): Promise<ForeignKeySchema[]>;
|
|
48
|
+
protected getPrimaryKey(read: TableRowReader, tableName: string): Promise<string[] | undefined>;
|
|
38
49
|
protected tableExistsParams(tableName: string): unknown[];
|
|
39
50
|
protected getColumnsParams(tableName: string): unknown[];
|
|
40
51
|
protected getIndexesParams(tableName: string): unknown[];
|
|
@@ -65,13 +76,17 @@ export declare abstract class AbstractSqlSchemaIntrospector extends BaseSqlIntro
|
|
|
65
76
|
/** Extract table name from a row returned by getTableNamesQuery. */
|
|
66
77
|
protected abstract mapTableNameRow(row: RawRow): string;
|
|
67
78
|
/** Map column query results to ColumnSchema array. Allows async for SQLite's unique column check. */
|
|
68
|
-
protected abstract mapColumnsResult(
|
|
79
|
+
protected abstract mapColumnsResult(read: TableRowReader, tableName: string, results: RawRow[]): Promise<ColumnSchema[]>;
|
|
69
80
|
/** Map index query results to IndexSchema array. Allows async for SQLite's index_info calls. */
|
|
70
|
-
protected abstract mapIndexesResult(
|
|
81
|
+
protected abstract mapIndexesResult(read: TableRowReader, tableName: string, results: RawRow[]): Promise<IndexSchema[]>;
|
|
71
82
|
/** Map foreign key query results to ForeignKeySchema array. */
|
|
72
|
-
protected abstract mapForeignKeysResult(
|
|
73
|
-
/**
|
|
74
|
-
|
|
83
|
+
protected abstract mapForeignKeysResult(read: TableRowReader, tableName: string, results: RawRow[]): Promise<ForeignKeySchema[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Map primary key query results to column names, in key order. `information_schema` gives every SQL
|
|
86
|
+
* engine here a `column_name` per row; SQLite reads its key off `PRAGMA table_info` instead and
|
|
87
|
+
* overrides this.
|
|
88
|
+
*/
|
|
89
|
+
protected mapPrimaryKeyResult(results: RawRow[]): string[] | undefined;
|
|
75
90
|
/** Parse default value string to appropriate type. */
|
|
76
91
|
protected abstract parseDefaultValue(defaultValue: string | null): unknown;
|
|
77
92
|
}
|
|
@@ -30,16 +30,17 @@ export class AbstractSqlSchemaIntrospector extends BaseSqlIntrospector {
|
|
|
30
30
|
// ============================================================================
|
|
31
31
|
async getTableSchema(tableName) {
|
|
32
32
|
const querier = await this.getQuerier();
|
|
33
|
+
const read = createTableRowReader(querier);
|
|
33
34
|
try {
|
|
34
|
-
const exists = await this.tableExistsInternal(
|
|
35
|
+
const exists = await this.tableExistsInternal(read, tableName);
|
|
35
36
|
if (!exists) {
|
|
36
37
|
return undefined;
|
|
37
38
|
}
|
|
38
39
|
const [columns, indexes, foreignKeys, primaryKey] = await Promise.all([
|
|
39
|
-
this.getColumns(
|
|
40
|
-
this.getIndexes(
|
|
41
|
-
this.getForeignKeys(
|
|
42
|
-
this.getPrimaryKey(
|
|
40
|
+
this.getColumns(read, tableName),
|
|
41
|
+
this.getIndexes(read, tableName),
|
|
42
|
+
this.getForeignKeys(read, tableName),
|
|
43
|
+
this.getPrimaryKey(read, tableName),
|
|
43
44
|
]);
|
|
44
45
|
return {
|
|
45
46
|
name: tableName,
|
|
@@ -66,7 +67,7 @@ export class AbstractSqlSchemaIntrospector extends BaseSqlIntrospector {
|
|
|
66
67
|
async tableExists(tableName) {
|
|
67
68
|
const querier = await this.getQuerier();
|
|
68
69
|
try {
|
|
69
|
-
return this.tableExistsInternal(querier, tableName);
|
|
70
|
+
return this.tableExistsInternal(createTableRowReader(querier), tableName);
|
|
70
71
|
}
|
|
71
72
|
finally {
|
|
72
73
|
await querier.release();
|
|
@@ -80,34 +81,24 @@ export class AbstractSqlSchemaIntrospector extends BaseSqlIntrospector {
|
|
|
80
81
|
}
|
|
81
82
|
return querier;
|
|
82
83
|
}
|
|
83
|
-
async tableExistsInternal(
|
|
84
|
-
const
|
|
85
|
-
const params = this.tableExistsParams(tableName);
|
|
86
|
-
const results = await querier.all(sql, params);
|
|
84
|
+
async tableExistsInternal(read, tableName) {
|
|
85
|
+
const results = await read(this.tableExistsQuery(), this.tableExistsParams(tableName));
|
|
87
86
|
return this.parseTableExistsResult(results);
|
|
88
87
|
}
|
|
89
|
-
async getColumns(
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const results = await
|
|
99
|
-
return this.
|
|
100
|
-
}
|
|
101
|
-
async
|
|
102
|
-
const
|
|
103
|
-
const params = this.getForeignKeysParams(tableName);
|
|
104
|
-
const results = await querier.all(sql, params);
|
|
105
|
-
return this.mapForeignKeysResult(querier, tableName, results);
|
|
106
|
-
}
|
|
107
|
-
async getPrimaryKey(querier, tableName) {
|
|
108
|
-
const sql = this.getPrimaryKeyQuery(tableName);
|
|
109
|
-
const params = this.getPrimaryKeyParams(tableName);
|
|
110
|
-
const results = await querier.all(sql, params);
|
|
88
|
+
async getColumns(read, tableName) {
|
|
89
|
+
const results = await read(this.getColumnsQuery(tableName), this.getColumnsParams(tableName));
|
|
90
|
+
return this.mapColumnsResult(read, tableName, results);
|
|
91
|
+
}
|
|
92
|
+
async getIndexes(read, tableName) {
|
|
93
|
+
const results = await read(this.getIndexesQuery(tableName), this.getIndexesParams(tableName));
|
|
94
|
+
return this.mapIndexesResult(read, tableName, results);
|
|
95
|
+
}
|
|
96
|
+
async getForeignKeys(read, tableName) {
|
|
97
|
+
const results = await read(this.getForeignKeysQuery(tableName), this.getForeignKeysParams(tableName));
|
|
98
|
+
return this.mapForeignKeysResult(read, tableName, results);
|
|
99
|
+
}
|
|
100
|
+
async getPrimaryKey(read, tableName) {
|
|
101
|
+
const results = await read(this.getPrimaryKeyQuery(tableName), this.getPrimaryKeyParams(tableName));
|
|
111
102
|
return this.mapPrimaryKeyResult(results);
|
|
112
103
|
}
|
|
113
104
|
// ============================================================================
|
|
@@ -157,4 +148,27 @@ export class AbstractSqlSchemaIntrospector extends BaseSqlIntrospector {
|
|
|
157
148
|
}
|
|
158
149
|
return Number(value);
|
|
159
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Map primary key query results to column names, in key order. `information_schema` gives every SQL
|
|
153
|
+
* engine here a `column_name` per row; SQLite reads its key off `PRAGMA table_info` instead and
|
|
154
|
+
* overrides this.
|
|
155
|
+
*/
|
|
156
|
+
mapPrimaryKeyResult(results) {
|
|
157
|
+
const columns = results.map((row) => String(row['column_name']));
|
|
158
|
+
return columns.length ? columns : undefined;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** A {@link TableRowReader} over one querier: the same statement is only ever sent once. */
|
|
162
|
+
function createTableRowReader(querier) {
|
|
163
|
+
const sent = new Map();
|
|
164
|
+
return (sql, params) => {
|
|
165
|
+
const key = params?.length ? `${sql}\u0000${JSON.stringify(params)}` : sql;
|
|
166
|
+
let rows = sent.get(key);
|
|
167
|
+
if (!rows) {
|
|
168
|
+
// PRAGMA statements take no parameters at all, so they are sent as a bare statement.
|
|
169
|
+
rows = params?.length ? querier.all(sql, params) : querier.all(sql);
|
|
170
|
+
sent.set(key, rows);
|
|
171
|
+
}
|
|
172
|
+
return rows;
|
|
173
|
+
};
|
|
160
174
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { canonicalColumnType } from '../../schema/canonicalType.js';
|
|
2
2
|
import { SchemaAST } from '../../schema/schemaAST.js';
|
|
3
3
|
import { escapeSqlId } from '../../util/index.js';
|
|
4
4
|
/**
|
|
@@ -52,7 +52,7 @@ export class BaseSqlIntrospector {
|
|
|
52
52
|
for (const col of schema.columns) {
|
|
53
53
|
const column = {
|
|
54
54
|
name: col.name,
|
|
55
|
-
type:
|
|
55
|
+
type: canonicalColumnType(col.type, col),
|
|
56
56
|
nullable: col.nullable,
|
|
57
57
|
defaultValue: col.defaultValue,
|
|
58
58
|
isPrimaryKey: col.isPrimaryKey,
|
|
@@ -106,7 +106,7 @@ export class BaseSqlIntrospector {
|
|
|
106
106
|
if (!table)
|
|
107
107
|
continue;
|
|
108
108
|
for (const idx of schema.indexes) {
|
|
109
|
-
const columns = idx.columns.map((
|
|
109
|
+
const columns = idx.columns.map((e) => table.columns.get(e.column)).filter((c) => !!c);
|
|
110
110
|
if (columns.length > 0) {
|
|
111
111
|
const index = {
|
|
112
112
|
name: idx.name,
|
|
@@ -119,13 +119,4 @@ export class BaseSqlIntrospector {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
columnSchemaToCanonical(col) {
|
|
123
|
-
const base = sqlToCanonical(col.type);
|
|
124
|
-
return {
|
|
125
|
-
...base,
|
|
126
|
-
length: col.length ?? base.length,
|
|
127
|
-
precision: col.precision ?? base.precision,
|
|
128
|
-
scale: col.scale ?? base.scale,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
122
|
}
|
|
@@ -27,7 +27,7 @@ export class MongoSchemaIntrospector {
|
|
|
27
27
|
if (schema.indexes) {
|
|
28
28
|
for (const idx of schema.indexes) {
|
|
29
29
|
const indexColumns = [];
|
|
30
|
-
for (const colName of idx.columns) {
|
|
30
|
+
for (const { column: colName } of idx.columns) {
|
|
31
31
|
let column = columns.get(colName);
|
|
32
32
|
if (!column) {
|
|
33
33
|
column = {
|
|
@@ -72,7 +72,7 @@ export class MongoSchemaIntrospector {
|
|
|
72
72
|
columns: [], // We don't have columns in Mongo
|
|
73
73
|
indexes: indexes.map((idx) => ({
|
|
74
74
|
name: idx.name ?? Object.keys(idx.key).join('_'),
|
|
75
|
-
columns: Object.keys(idx.key),
|
|
75
|
+
columns: Object.keys(idx.key).map((column) => ({ column })),
|
|
76
76
|
unique: !!idx.unique,
|
|
77
77
|
})),
|
|
78
78
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ColumnSchema, ForeignKeySchema, IndexSchema
|
|
2
|
-
import { AbstractSqlSchemaIntrospector } from './abstractSqlSchemaIntrospector.js';
|
|
1
|
+
import type { ColumnSchema, ForeignKeySchema, IndexSchema } from '../../type/index.js';
|
|
2
|
+
import { AbstractSqlSchemaIntrospector, type TableRowReader } from './abstractSqlSchemaIntrospector.js';
|
|
3
3
|
/**
|
|
4
4
|
* MySQL/MariaDB schema introspector.
|
|
5
5
|
* Works with both MySQL and MariaDB as they share the same information_schema structure.
|
|
@@ -17,13 +17,13 @@ export declare class MysqlSchemaIntrospector extends AbstractSqlSchemaIntrospect
|
|
|
17
17
|
protected mapTableNameRow(row: {
|
|
18
18
|
table_name: string;
|
|
19
19
|
}): string;
|
|
20
|
-
protected mapColumnsResult(
|
|
21
|
-
protected mapIndexesResult(
|
|
20
|
+
protected mapColumnsResult(_read: TableRowReader, _tableName: string, results: MysqlColumnRow[]): Promise<ColumnSchema[]>;
|
|
21
|
+
protected mapIndexesResult(_read: TableRowReader, _tableName: string, results: {
|
|
22
22
|
index_name: string;
|
|
23
23
|
columns: string;
|
|
24
24
|
is_unique: number;
|
|
25
25
|
}[]): Promise<IndexSchema[]>;
|
|
26
|
-
protected mapForeignKeysResult(
|
|
26
|
+
protected mapForeignKeysResult(_read: TableRowReader, _tableName: string, results: {
|
|
27
27
|
constraint_name: string;
|
|
28
28
|
columns: string;
|
|
29
29
|
referenced_table: string;
|
|
@@ -31,9 +31,6 @@ export declare class MysqlSchemaIntrospector extends AbstractSqlSchemaIntrospect
|
|
|
31
31
|
delete_rule: string;
|
|
32
32
|
update_rule: string;
|
|
33
33
|
}[]): Promise<ForeignKeySchema[]>;
|
|
34
|
-
protected mapPrimaryKeyResult(results: {
|
|
35
|
-
column_name: string;
|
|
36
|
-
}[]): string[] | undefined;
|
|
37
34
|
protected parseDefaultValue(defaultValue: string | null): unknown;
|
|
38
35
|
}
|
|
39
36
|
type MysqlColumnRow = {
|
|
@@ -101,7 +101,7 @@ export class MysqlSchemaIntrospector extends AbstractSqlSchemaIntrospector {
|
|
|
101
101
|
mapTableNameRow(row) {
|
|
102
102
|
return row.table_name;
|
|
103
103
|
}
|
|
104
|
-
async mapColumnsResult(
|
|
104
|
+
async mapColumnsResult(_read, _tableName, results) {
|
|
105
105
|
return results.map((row) => ({
|
|
106
106
|
name: row.column_name,
|
|
107
107
|
type: (row.column_type || '').toUpperCase(),
|
|
@@ -116,14 +116,14 @@ export class MysqlSchemaIntrospector extends AbstractSqlSchemaIntrospector {
|
|
|
116
116
|
comment: row.column_comment || undefined,
|
|
117
117
|
}));
|
|
118
118
|
}
|
|
119
|
-
async mapIndexesResult(
|
|
119
|
+
async mapIndexesResult(_read, _tableName, results) {
|
|
120
120
|
return results.map((row) => ({
|
|
121
121
|
name: row.index_name,
|
|
122
|
-
columns: (row.columns || '').split(','),
|
|
122
|
+
columns: (row.columns || '').split(',').map((column) => ({ column })),
|
|
123
123
|
unique: Boolean(row.is_unique),
|
|
124
124
|
}));
|
|
125
125
|
}
|
|
126
|
-
async mapForeignKeysResult(
|
|
126
|
+
async mapForeignKeysResult(_read, _tableName, results) {
|
|
127
127
|
return results.map((row) => ({
|
|
128
128
|
name: row.constraint_name,
|
|
129
129
|
columns: (row.columns || '').split(','),
|
|
@@ -133,12 +133,6 @@ export class MysqlSchemaIntrospector extends AbstractSqlSchemaIntrospector {
|
|
|
133
133
|
onUpdate: this.normalizeReferentialAction(row.update_rule),
|
|
134
134
|
}));
|
|
135
135
|
}
|
|
136
|
-
mapPrimaryKeyResult(results) {
|
|
137
|
-
if (results.length === 0) {
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
return results.map((r) => r.column_name);
|
|
141
|
-
}
|
|
142
136
|
parseDefaultValue(defaultValue) {
|
|
143
137
|
if (defaultValue === null) {
|
|
144
138
|
return undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ColumnSchema, ForeignKeySchema, IndexSchema, RawRow
|
|
2
|
-
import { AbstractSqlSchemaIntrospector } from './abstractSqlSchemaIntrospector.js';
|
|
1
|
+
import type { ColumnSchema, ForeignKeySchema, IndexSchema, RawRow } from '../../type/index.js';
|
|
2
|
+
import { AbstractSqlSchemaIntrospector, type TableRowReader } from './abstractSqlSchemaIntrospector.js';
|
|
3
3
|
/**
|
|
4
4
|
* PostgreSQL schema introspector
|
|
5
5
|
*/
|
|
@@ -14,13 +14,13 @@ export declare class PostgresSchemaIntrospector extends AbstractSqlSchemaIntrosp
|
|
|
14
14
|
protected mapTableNameRow(row: {
|
|
15
15
|
table_name: string;
|
|
16
16
|
}): string;
|
|
17
|
-
protected mapColumnsResult(
|
|
18
|
-
protected mapIndexesResult(
|
|
17
|
+
protected mapColumnsResult(_read: TableRowReader, _tableName: string, results: PostgresColumnRow[]): Promise<ColumnSchema[]>;
|
|
18
|
+
protected mapIndexesResult(_read: TableRowReader, _tableName: string, results: {
|
|
19
19
|
index_name: string;
|
|
20
20
|
columns: string[];
|
|
21
21
|
is_unique: boolean;
|
|
22
22
|
}[]): Promise<IndexSchema[]>;
|
|
23
|
-
protected mapForeignKeysResult(
|
|
23
|
+
protected mapForeignKeysResult(_read: TableRowReader, _tableName: string, results: {
|
|
24
24
|
constraint_name: string;
|
|
25
25
|
columns: string[];
|
|
26
26
|
referenced_table: string;
|
|
@@ -28,9 +28,6 @@ export declare class PostgresSchemaIntrospector extends AbstractSqlSchemaIntrosp
|
|
|
28
28
|
delete_rule: string;
|
|
29
29
|
update_rule: string;
|
|
30
30
|
}[]): Promise<ForeignKeySchema[]>;
|
|
31
|
-
protected mapPrimaryKeyResult(results: {
|
|
32
|
-
column_name: string;
|
|
33
|
-
}[]): string[] | undefined;
|
|
34
31
|
protected normalizeType(dataType: string, udtName: string): string;
|
|
35
32
|
protected parseDefaultValue(defaultValue: string | null): unknown;
|
|
36
33
|
protected isAutoIncrement(columnDefault: string | null, isIdentity: string): boolean;
|
|
@@ -134,7 +134,7 @@ export class PostgresSchemaIntrospector extends AbstractSqlSchemaIntrospector {
|
|
|
134
134
|
mapTableNameRow(row) {
|
|
135
135
|
return row.table_name;
|
|
136
136
|
}
|
|
137
|
-
async mapColumnsResult(
|
|
137
|
+
async mapColumnsResult(_read, _tableName, results) {
|
|
138
138
|
return results.map((row) => ({
|
|
139
139
|
name: row.column_name,
|
|
140
140
|
type: this.normalizeType(row.data_type, row.udt_name),
|
|
@@ -149,14 +149,14 @@ export class PostgresSchemaIntrospector extends AbstractSqlSchemaIntrospector {
|
|
|
149
149
|
comment: row.column_comment ?? undefined,
|
|
150
150
|
}));
|
|
151
151
|
}
|
|
152
|
-
async mapIndexesResult(
|
|
152
|
+
async mapIndexesResult(_read, _tableName, results) {
|
|
153
153
|
return results.map((row) => ({
|
|
154
154
|
name: row.index_name,
|
|
155
|
-
columns: row.columns,
|
|
155
|
+
columns: row.columns.map((column) => ({ column })),
|
|
156
156
|
unique: row.is_unique,
|
|
157
157
|
}));
|
|
158
158
|
}
|
|
159
|
-
async mapForeignKeysResult(
|
|
159
|
+
async mapForeignKeysResult(_read, _tableName, results) {
|
|
160
160
|
return results.map((row) => ({
|
|
161
161
|
name: row.constraint_name,
|
|
162
162
|
columns: row.columns,
|
|
@@ -166,12 +166,6 @@ export class PostgresSchemaIntrospector extends AbstractSqlSchemaIntrospector {
|
|
|
166
166
|
onUpdate: this.normalizeReferentialAction(row.update_rule),
|
|
167
167
|
}));
|
|
168
168
|
}
|
|
169
|
-
mapPrimaryKeyResult(results) {
|
|
170
|
-
if (results.length === 0) {
|
|
171
|
-
return undefined;
|
|
172
|
-
}
|
|
173
|
-
return results.map((r) => r.column_name);
|
|
174
|
-
}
|
|
175
169
|
// ============================================================================
|
|
176
170
|
// PostgreSQL-specific helpers
|
|
177
171
|
// ============================================================================
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ColumnSchema, ForeignKeySchema, IndexSchema
|
|
2
|
-
import { AbstractSqlSchemaIntrospector } from './abstractSqlSchemaIntrospector.js';
|
|
1
|
+
import type { ColumnSchema, ForeignKeySchema, IndexSchema } from '../../type/index.js';
|
|
2
|
+
import { AbstractSqlSchemaIntrospector, type TableRowReader } from './abstractSqlSchemaIntrospector.js';
|
|
3
3
|
/**
|
|
4
4
|
* SQLite schema introspector
|
|
5
5
|
*/
|
|
@@ -18,11 +18,12 @@ export declare class SqliteSchemaIntrospector extends AbstractSqlSchemaIntrospec
|
|
|
18
18
|
protected mapTableNameRow(row: {
|
|
19
19
|
name: string;
|
|
20
20
|
}): string;
|
|
21
|
-
protected mapColumnsResult(
|
|
22
|
-
protected mapIndexesResult(
|
|
23
|
-
protected mapForeignKeysResult(
|
|
21
|
+
protected mapColumnsResult(read: TableRowReader, tableName: string, results: SqliteColumnRow[]): Promise<ColumnSchema[]>;
|
|
22
|
+
protected mapIndexesResult(read: TableRowReader, _tableName: string, results: SqliteIndexRow[]): Promise<IndexSchema[]>;
|
|
23
|
+
protected mapForeignKeysResult(_read: TableRowReader, tableName: string, results: SqliteForeignKeyRow[]): Promise<ForeignKeySchema[]>;
|
|
24
24
|
protected mapPrimaryKeyResult(results: SqliteColumnRow[]): string[] | undefined;
|
|
25
25
|
private getUniqueColumns;
|
|
26
|
+
private getIndexColumns;
|
|
26
27
|
protected normalizeType(type: string): string;
|
|
27
28
|
protected extractLength(type: string): number | undefined;
|
|
28
29
|
protected parseDefaultValue(defaultValue: string | null): unknown;
|