@mikro-orm/sql 7.0.0-dev.175 → 7.0.0-dev.177
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/dialects/postgresql/BasePostgreSqlPlatform.d.ts +1 -0
- package/dialects/postgresql/BasePostgreSqlPlatform.js +3 -0
- package/dialects/postgresql/PostgreSqlSchemaHelper.d.ts +5 -0
- package/dialects/postgresql/PostgreSqlSchemaHelper.js +27 -0
- package/package.json +2 -2
- package/schema/DatabaseSchema.d.ts +1 -1
- package/schema/DatabaseSchema.js +7 -3
- package/schema/SchemaHelper.d.ts +5 -0
- package/schema/SchemaHelper.js +15 -0
- package/schema/SqlSchemaGenerator.js +36 -6
- package/tsconfig.build.tsbuildinfo +1 -1
- package/typings.d.ts +4 -0
|
@@ -12,6 +12,7 @@ export declare class BasePostgreSqlPlatform extends AbstractSqlPlatform {
|
|
|
12
12
|
usesCascadeStatement(): boolean;
|
|
13
13
|
supportsNativeEnums(): boolean;
|
|
14
14
|
usesEnumCheckConstraints(): boolean;
|
|
15
|
+
supportsMaterializedViews(): boolean;
|
|
15
16
|
supportsCustomPrimaryKeyNames(): boolean;
|
|
16
17
|
getCurrentTimestampSQL(length: number): string;
|
|
17
18
|
getDateTimeTypeDeclarationSQL(column: {
|
|
@@ -19,6 +19,11 @@ export declare class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
19
19
|
getListTablesSQL(): string;
|
|
20
20
|
getListViewsSQL(): string;
|
|
21
21
|
loadViews(schema: DatabaseSchema, connection: AbstractSqlConnection): Promise<void>;
|
|
22
|
+
getListMaterializedViewsSQL(): string;
|
|
23
|
+
loadMaterializedViews(schema: DatabaseSchema, connection: AbstractSqlConnection, schemaName?: string): Promise<void>;
|
|
24
|
+
createMaterializedView(name: string, schema: string | undefined, definition: string, withData?: boolean): string;
|
|
25
|
+
dropMaterializedViewIfExists(name: string, schema?: string): string;
|
|
26
|
+
refreshMaterializedView(name: string, schema?: string, concurrently?: boolean): string;
|
|
22
27
|
getNamespaces(connection: AbstractSqlConnection): Promise<string[]>;
|
|
23
28
|
private getIgnoredNamespacesConditionSQL;
|
|
24
29
|
loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[], schemas?: string[]): Promise<void>;
|
|
@@ -44,6 +44,33 @@ export class PostgreSqlSchemaHelper extends SchemaHelper {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
getListMaterializedViewsSQL() {
|
|
48
|
+
return `select matviewname as view_name, schemaname as schema_name, definition as view_definition `
|
|
49
|
+
+ `from pg_matviews `
|
|
50
|
+
+ `where ${this.getIgnoredNamespacesConditionSQL('schemaname')} `
|
|
51
|
+
+ `order by matviewname`;
|
|
52
|
+
}
|
|
53
|
+
async loadMaterializedViews(schema, connection, schemaName) {
|
|
54
|
+
const views = await connection.execute(this.getListMaterializedViewsSQL());
|
|
55
|
+
for (const view of views) {
|
|
56
|
+
const definition = view.view_definition?.trim().replace(/;$/, '') ?? '';
|
|
57
|
+
if (definition) {
|
|
58
|
+
schema.addView(view.view_name, view.schema_name, definition, true);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
createMaterializedView(name, schema, definition, withData = true) {
|
|
63
|
+
const viewName = this.quote(this.getTableName(name, schema));
|
|
64
|
+
const dataClause = withData ? ' with data' : ' with no data';
|
|
65
|
+
return `create materialized view ${viewName} as ${definition}${dataClause}`;
|
|
66
|
+
}
|
|
67
|
+
dropMaterializedViewIfExists(name, schema) {
|
|
68
|
+
return `drop materialized view if exists ${this.quote(this.getTableName(name, schema))} cascade`;
|
|
69
|
+
}
|
|
70
|
+
refreshMaterializedView(name, schema, concurrently = false) {
|
|
71
|
+
const concurrent = concurrently ? ' concurrently' : '';
|
|
72
|
+
return `refresh materialized view${concurrent} ${this.quote(this.getTableName(name, schema))}`;
|
|
73
|
+
}
|
|
47
74
|
async getNamespaces(connection) {
|
|
48
75
|
const sql = `select schema_name from information_schema.schemata `
|
|
49
76
|
+ `where ${this.getIgnoredNamespacesConditionSQL()} `
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.177",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -56,6 +56,6 @@
|
|
|
56
56
|
"@mikro-orm/core": "^6.6.4"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
59
|
+
"@mikro-orm/core": "7.0.0-dev.177"
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -18,7 +18,7 @@ export declare class DatabaseSchema {
|
|
|
18
18
|
getTables(): DatabaseTable[];
|
|
19
19
|
getTable(name: string): DatabaseTable | undefined;
|
|
20
20
|
hasTable(name: string): boolean;
|
|
21
|
-
addView(name: string, schema: string | undefined | null, definition: string): DatabaseView;
|
|
21
|
+
addView(name: string, schema: string | undefined | null, definition: string, materialized?: boolean, withData?: boolean): DatabaseView;
|
|
22
22
|
getViews(): DatabaseView[];
|
|
23
23
|
getView(name: string): DatabaseView | undefined;
|
|
24
24
|
hasView(name: string): boolean;
|
package/schema/DatabaseSchema.js
CHANGED
|
@@ -34,9 +34,9 @@ export class DatabaseSchema {
|
|
|
34
34
|
hasTable(name) {
|
|
35
35
|
return !!this.getTable(name);
|
|
36
36
|
}
|
|
37
|
-
addView(name, schema, definition) {
|
|
37
|
+
addView(name, schema, definition, materialized, withData) {
|
|
38
38
|
const namespaceName = schema ?? this.name;
|
|
39
|
-
const view = { name, schema: namespaceName, definition };
|
|
39
|
+
const view = { name, schema: namespaceName, definition, materialized, withData };
|
|
40
40
|
this.views.push(view);
|
|
41
41
|
if (namespaceName != null) {
|
|
42
42
|
this.namespaces.add(namespaceName);
|
|
@@ -85,6 +85,10 @@ export class DatabaseSchema {
|
|
|
85
85
|
await platform.getSchemaHelper().loadInformationSchema(schema, connection, tables, schemas && schemas.length > 0 ? schemas : undefined);
|
|
86
86
|
// Load views from database
|
|
87
87
|
await platform.getSchemaHelper().loadViews(schema, connection);
|
|
88
|
+
// Load materialized views (PostgreSQL only)
|
|
89
|
+
if (platform.supportsMaterializedViews()) {
|
|
90
|
+
await platform.getSchemaHelper().loadMaterializedViews(schema, connection, schemaName);
|
|
91
|
+
}
|
|
88
92
|
return schema;
|
|
89
93
|
}
|
|
90
94
|
static fromMetadata(metadata, platform, config, schemaName, em) {
|
|
@@ -124,7 +128,7 @@ export class DatabaseSchema {
|
|
|
124
128
|
if (meta.view) {
|
|
125
129
|
const viewDefinition = this.getViewDefinition(meta, em, platform);
|
|
126
130
|
if (viewDefinition) {
|
|
127
|
-
schema.addView(meta.collection, this.getSchemaName(meta, config, schemaName), viewDefinition);
|
|
131
|
+
schema.addView(meta.collection, this.getSchemaName(meta, config, schemaName), viewDefinition, meta.materialized, meta.withData);
|
|
128
132
|
}
|
|
129
133
|
continue;
|
|
130
134
|
}
|
package/schema/SchemaHelper.d.ts
CHANGED
|
@@ -79,4 +79,9 @@ export declare abstract class SchemaHelper {
|
|
|
79
79
|
dropTableIfExists(name: string, schema?: string): string;
|
|
80
80
|
createView(name: string, schema: string | undefined, definition: string): string;
|
|
81
81
|
dropViewIfExists(name: string, schema?: string): string;
|
|
82
|
+
createMaterializedView(name: string, schema: string | undefined, definition: string, withData?: boolean): string;
|
|
83
|
+
dropMaterializedViewIfExists(name: string, schema?: string): string;
|
|
84
|
+
refreshMaterializedView(name: string, schema?: string, concurrently?: boolean): string;
|
|
85
|
+
getListMaterializedViewsSQL(): string;
|
|
86
|
+
loadMaterializedViews(schema: DatabaseSchema, connection: AbstractSqlConnection, schemaName?: string): Promise<void>;
|
|
82
87
|
}
|
package/schema/SchemaHelper.js
CHANGED
|
@@ -558,4 +558,19 @@ export class SchemaHelper {
|
|
|
558
558
|
}
|
|
559
559
|
return sql;
|
|
560
560
|
}
|
|
561
|
+
createMaterializedView(name, schema, definition, withData = true) {
|
|
562
|
+
throw new Error('Not supported by given driver');
|
|
563
|
+
}
|
|
564
|
+
dropMaterializedViewIfExists(name, schema) {
|
|
565
|
+
throw new Error('Not supported by given driver');
|
|
566
|
+
}
|
|
567
|
+
refreshMaterializedView(name, schema, concurrently = false) {
|
|
568
|
+
throw new Error('Not supported by given driver');
|
|
569
|
+
}
|
|
570
|
+
getListMaterializedViewsSQL() {
|
|
571
|
+
throw new Error('Not supported by given driver');
|
|
572
|
+
}
|
|
573
|
+
async loadMaterializedViews(schema, connection, schemaName) {
|
|
574
|
+
throw new Error('Not supported by given driver');
|
|
575
|
+
}
|
|
561
576
|
}
|
|
@@ -91,7 +91,12 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
91
91
|
// Sort views by dependencies (views depending on other views come later)
|
|
92
92
|
const sortedViews = this.sortViewsByDependencies(toSchema.getViews());
|
|
93
93
|
for (const view of sortedViews) {
|
|
94
|
-
|
|
94
|
+
if (view.materialized) {
|
|
95
|
+
this.append(ret, this.helper.createMaterializedView(view.name, view.schema, view.definition, view.withData ?? true));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.append(ret, this.helper.createView(view.name, view.schema, view.definition), true);
|
|
99
|
+
}
|
|
95
100
|
}
|
|
96
101
|
return this.wrapSchema(ret, options);
|
|
97
102
|
}
|
|
@@ -141,7 +146,12 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
141
146
|
const targetSchema = this.getTargetSchema(options.schema);
|
|
142
147
|
const sortedViews = this.sortViewsByDependencies(targetSchema.getViews()).reverse();
|
|
143
148
|
for (const view of sortedViews) {
|
|
144
|
-
|
|
149
|
+
if (view.materialized) {
|
|
150
|
+
this.append(ret, this.helper.dropMaterializedViewIfExists(view.name, view.schema));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
this.append(ret, this.helper.dropViewIfExists(view.name, view.schema));
|
|
154
|
+
}
|
|
145
155
|
}
|
|
146
156
|
// remove FKs explicitly if we can't use a cascading statement and we don't disable FK checks (we need this for circular relations)
|
|
147
157
|
for (const meta of metadata) {
|
|
@@ -235,7 +245,12 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
235
245
|
if (options.dropTables && !options.safe) {
|
|
236
246
|
const sortedRemovedViews = this.sortViewsByDependencies(Object.values(schemaDiff.removedViews)).reverse();
|
|
237
247
|
for (const view of sortedRemovedViews) {
|
|
238
|
-
|
|
248
|
+
if (view.materialized) {
|
|
249
|
+
this.append(ret, this.helper.dropMaterializedViewIfExists(view.name, view.schema));
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
this.append(ret, this.helper.dropViewIfExists(view.name, view.schema));
|
|
253
|
+
}
|
|
239
254
|
}
|
|
240
255
|
}
|
|
241
256
|
// Drop changed views (they will be recreated after table changes)
|
|
@@ -243,7 +258,12 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
243
258
|
const changedViewsFrom = Object.values(schemaDiff.changedViews).map(v => v.from);
|
|
244
259
|
const sortedChangedViewsFrom = this.sortViewsByDependencies(changedViewsFrom).reverse();
|
|
245
260
|
for (const view of sortedChangedViewsFrom) {
|
|
246
|
-
|
|
261
|
+
if (view.materialized) {
|
|
262
|
+
this.append(ret, this.helper.dropMaterializedViewIfExists(view.name, view.schema));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
this.append(ret, this.helper.dropViewIfExists(view.name, view.schema));
|
|
266
|
+
}
|
|
247
267
|
}
|
|
248
268
|
if (!options.safe && this.options.createForeignKeyConstraints) {
|
|
249
269
|
for (const orphanedForeignKey of schemaDiff.orphanedForeignKeys) {
|
|
@@ -304,13 +324,23 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
304
324
|
// Sort views by dependencies (views depending on other views come later)
|
|
305
325
|
const sortedNewViews = this.sortViewsByDependencies(Object.values(schemaDiff.newViews));
|
|
306
326
|
for (const view of sortedNewViews) {
|
|
307
|
-
|
|
327
|
+
if (view.materialized) {
|
|
328
|
+
this.append(ret, this.helper.createMaterializedView(view.name, view.schema, view.definition, view.withData ?? true));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
this.append(ret, this.helper.createView(view.name, view.schema, view.definition), true);
|
|
332
|
+
}
|
|
308
333
|
}
|
|
309
334
|
// Recreate changed views (also sorted by dependencies)
|
|
310
335
|
const changedViews = Object.values(schemaDiff.changedViews).map(v => v.to);
|
|
311
336
|
const sortedChangedViews = this.sortViewsByDependencies(changedViews);
|
|
312
337
|
for (const view of sortedChangedViews) {
|
|
313
|
-
|
|
338
|
+
if (view.materialized) {
|
|
339
|
+
this.append(ret, this.helper.createMaterializedView(view.name, view.schema, view.definition, view.withData ?? true));
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
this.append(ret, this.helper.createView(view.name, view.schema, view.definition), true);
|
|
343
|
+
}
|
|
314
344
|
}
|
|
315
345
|
return this.wrapSchema(ret, options);
|
|
316
346
|
}
|