Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit 7eb0327

Browse files
authored
fix: default schema defined in entity/connection leads to unnecessary queries during schema sync (typeorm#7575)
* working on typeorm#7276 * minor fix * fix typeorm#7276 * lint fix * added `getCurrentDatabase()` and `getCurrentSchema()` methods in QueryRunner * fixed falling test; * fixed default schema in other drivers
1 parent b2ac41a commit 7eb0327

File tree

15 files changed

+320
-77
lines changed

15 files changed

+320
-77
lines changed

src/driver/aurora-data-api/AuroraDataApiQueryRunner.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,29 @@ export class AuroraDataApiQueryRunner extends BaseQueryRunner implements QueryRu
204204
return result.length ? true : false;
205205
}
206206

207+
/**
208+
* Loads currently using database
209+
*/
210+
async getCurrentDatabase(): Promise<string> {
211+
const query = await this.query(`SELECT DATABASE() AS \`db_name\``);
212+
return query[0]["db_name"];
213+
}
214+
207215
/**
208216
* Checks if schema with the given name exist.
209217
*/
210218
async hasSchema(schema: string): Promise<boolean> {
211219
throw new Error(`MySql driver does not support table schemas`);
212220
}
213221

222+
/**
223+
* Loads currently using database schema
224+
*/
225+
async getCurrentSchema(): Promise<string> {
226+
const query = await this.query(`SELECT SCHEMA() AS \`schema_name\``);
227+
return query[0]["schema_name"];
228+
}
229+
214230
/**
215231
* Checks if table with the given name exist in the database.
216232
*/
@@ -1133,14 +1149,6 @@ export class AuroraDataApiQueryRunner extends BaseQueryRunner implements QueryRu
11331149
// Protected Methods
11341150
// -------------------------------------------------------------------------
11351151

1136-
/**
1137-
* Returns current database.
1138-
*/
1139-
protected async getCurrentDatabase(): Promise<string> {
1140-
const currentDBQuery = await this.query(`SELECT DATABASE() AS \`db_name\``);
1141-
return currentDBQuery[0]["db_name"];
1142-
}
1143-
11441152
protected async loadViews(viewNames: string[]): Promise<View[]> {
11451153
const hasTable = await this.hasTable(this.getTypeormMetadataTableName());
11461154
if (!hasTable)

src/driver/cockroachdb/CockroachQueryRunner.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,14 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
297297
return result.length ? true : false;
298298
}
299299

300+
/**
301+
* Loads currently using database
302+
*/
303+
async getCurrentDatabase(): Promise<string> {
304+
const query = await this.query(`SELECT * FROM current_database()`);
305+
return query[0]["current_database"];
306+
}
307+
300308
/**
301309
* Checks if schema with the given name exist.
302310
*/
@@ -305,6 +313,14 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
305313
return result.length ? true : false;
306314
}
307315

316+
/**
317+
* Loads currently using database schema
318+
*/
319+
async getCurrentSchema(): Promise<string> {
320+
const query = await this.query(`SELECT * FROM current_schema()`);
321+
return query[0]["current_schema"];
322+
}
323+
308324
/**
309325
* Checks if table with the given name exist in the database.
310326
*/
@@ -1452,9 +1468,15 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
14521468
return Promise.all(dbTables.map(async dbTable => {
14531469
const table = new Table();
14541470

1471+
const getSchemaFromKey = (dbObject: any, key: string) => {
1472+
return dbObject[key] === currentSchema && (!this.driver.options.schema || this.driver.options.schema === currentSchema)
1473+
? undefined
1474+
: dbObject[key]
1475+
};
1476+
14551477
// We do not need to join schema name, when database is by default.
1456-
// In this case we need local variable `tableFullName` for below comparision.
1457-
const schema = dbTable["table_schema"] === currentSchema && !this.driver.options.schema ? undefined : dbTable["table_schema"];
1478+
// In this case we need local variable `tableFullName` for below comparison.
1479+
const schema = getSchemaFromKey(dbTable, "table_schema");
14581480
table.name = this.driver.buildTableName(dbTable["table_name"], schema);
14591481
const tableFullName = this.driver.buildTableName(dbTable["table_name"], dbTable["table_schema"]);
14601482

@@ -1591,7 +1613,7 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
15911613
const foreignKeys = dbForeignKeys.filter(dbFk => dbFk["constraint_name"] === dbForeignKey["constraint_name"]);
15921614

15931615
// if referenced table located in currently used schema, we don't need to concat schema name to table name.
1594-
const schema = dbForeignKey["referenced_table_schema"] === currentSchema ? undefined : dbForeignKey["referenced_table_schema"];
1616+
const schema = getSchemaFromKey(dbTable, "referenced_table_schema");
15951617
const referencedTableName = this.driver.buildTableName(dbForeignKey["referenced_table_name"], schema);
15961618

15971619
return new TableForeignKey({

src/driver/mongodb/MongoQueryRunner.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,13 +513,27 @@ export class MongoQueryRunner implements QueryRunner {
513513
throw new Error(`Check database queries are not supported by MongoDB driver.`);
514514
}
515515

516+
/**
517+
* Loads currently using database
518+
*/
519+
async getCurrentDatabase(): Promise<undefined> {
520+
throw new Error(`Check database queries are not supported by MongoDB driver.`);
521+
}
522+
516523
/**
517524
* Checks if schema with the given name exist.
518525
*/
519526
async hasSchema(schema: string): Promise<boolean> {
520527
throw new Error(`Check schema queries are not supported by MongoDB driver.`);
521528
}
522529

530+
/**
531+
* Loads currently using database schema
532+
*/
533+
async getCurrentSchema(): Promise<undefined> {
534+
throw new Error(`Check schema queries are not supported by MongoDB driver.`);
535+
}
536+
523537
/**
524538
* Checks if table with the given name exist in the database.
525539
*/

src/driver/mysql/MysqlQueryRunner.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,29 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
247247
return result.length ? true : false;
248248
}
249249

250+
/**
251+
* Loads currently using database
252+
*/
253+
async getCurrentDatabase(): Promise<string> {
254+
const query = await this.query(`SELECT DATABASE() AS \`db_name\``);
255+
return query[0]["db_name"];
256+
}
257+
250258
/**
251259
* Checks if schema with the given name exist.
252260
*/
253261
async hasSchema(schema: string): Promise<boolean> {
254262
throw new Error(`MySql driver does not support table schemas`);
255263
}
256264

265+
/**
266+
* Loads currently using database schema
267+
*/
268+
async getCurrentSchema(): Promise<string> {
269+
const query = await this.query(`SELECT SCHEMA() AS \`schema_name\``);
270+
return query[0]["schema_name"];
271+
}
272+
257273
/**
258274
* Checks if table with the given name exist in the database.
259275
*/
@@ -1180,14 +1196,6 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
11801196
// Protected Methods
11811197
// -------------------------------------------------------------------------
11821198

1183-
/**
1184-
* Returns current database.
1185-
*/
1186-
protected async getCurrentDatabase(): Promise<string> {
1187-
const currentDBQuery = await this.query(`SELECT DATABASE() AS \`db_name\``);
1188-
return currentDBQuery[0]["db_name"];
1189-
}
1190-
11911199
protected async loadViews(viewNames: string[]): Promise<View[]> {
11921200
const hasTable = await this.hasTable(this.getTypeormMetadataTableName());
11931201
if (!hasTable)

src/driver/oracle/OracleQueryRunner.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,29 @@ export class OracleQueryRunner extends BaseQueryRunner implements QueryRunner {
246246
return Promise.resolve(false);
247247
}
248248

249+
/**
250+
* Loads currently using database
251+
*/
252+
async getCurrentDatabase(): Promise<undefined> {
253+
const query = await this.query(`SELECT SYS_CONTEXT('USERENV','DB_NAME') AS "db_name" FROM dual`)
254+
return query[0]["db_name"]
255+
}
256+
249257
/**
250258
* Checks if schema with the given name exist.
251259
*/
252260
async hasSchema(schema: string): Promise<boolean> {
253261
return Promise.resolve(false);
254262
}
255263

264+
/**
265+
* Loads currently using database schema
266+
*/
267+
async getCurrentSchema(): Promise<string> {
268+
const query = await this.query(`SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') AS "schema_name" FROM dual`)
269+
return query[0]["schema_name"]
270+
}
271+
256272
/**
257273
* Checks if table with the given name exist in the database.
258274
*/

src/driver/postgres/PostgresQueryRunner.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
274274
return Promise.resolve(false);
275275
}
276276

277+
/**
278+
* Loads currently using database
279+
*/
280+
async getCurrentDatabase(): Promise<string> {
281+
const query = await this.query(`SELECT * FROM current_database()`);
282+
return query[0]["current_database"];
283+
}
284+
277285
/**
278286
* Checks if schema with the given name exist.
279287
*/
@@ -282,6 +290,14 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
282290
return result.length ? true : false;
283291
}
284292

293+
/**
294+
* Loads currently using database schema
295+
*/
296+
async getCurrentSchema(): Promise<string> {
297+
const query = await this.query(`SELECT * FROM current_schema()`);
298+
return query[0]["current_schema"];
299+
}
300+
285301
/**
286302
* Checks if table with the given name exist in the database.
287303
*/
@@ -1404,9 +1420,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
14041420
if (!hasTable)
14051421
return Promise.resolve([]);
14061422

1407-
const currentSchemaQuery = await this.query(`SELECT * FROM current_schema()`);
1408-
const currentSchema = currentSchemaQuery[0]["current_schema"];
1409-
1423+
const currentSchema = await this.getCurrentSchema()
14101424
const viewsCondition = viewNames.map(viewName => {
14111425
let [schema, name] = viewName.split(".");
14121426
if (!name) {
@@ -1438,7 +1452,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
14381452
return [];
14391453

14401454
const currentSchemaQuery = await this.query(`SELECT * FROM current_schema()`);
1441-
const currentSchema = currentSchemaQuery[0]["current_schema"];
1455+
const currentSchema: string = currentSchemaQuery[0]["current_schema"];
14421456

14431457
const tablesCondition = tableNames.map(tableName => {
14441458
let [schema, name] = tableName.split(".");
@@ -1549,9 +1563,13 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
15491563
return Promise.all(dbTables.map(async dbTable => {
15501564
const table = new Table();
15511565

1552-
const getSchemaFromKey = (dbObject: any, key: string) => dbObject[key] === currentSchema && !this.driver.options.schema ? undefined : dbObject[key];
1566+
const getSchemaFromKey = (dbObject: any, key: string) => {
1567+
return dbObject[key] === currentSchema && (!this.driver.options.schema || this.driver.options.schema === currentSchema)
1568+
? undefined
1569+
: dbObject[key]
1570+
};
15531571
// We do not need to join schema name, when database is by default.
1554-
// In this case we need local variable `tableFullName` for below comparision.
1572+
// In this case we need local variable `tableFullName` for below comparison.
15551573
const schema = getSchemaFromKey(dbTable, "table_schema");
15561574
table.name = this.driver.buildTableName(dbTable["table_name"], schema);
15571575
const tableFullName = this.driver.buildTableName(dbTable["table_name"], dbTable["table_schema"]);
@@ -2141,8 +2159,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
21412159
}
21422160

21432161
protected async getEnumTypeName(table: Table, column: TableColumn) {
2144-
const currentSchemaQuery = await this.query(`SELECT * FROM current_schema()`);
2145-
const currentSchema = currentSchemaQuery[0]["current_schema"];
2162+
const currentSchema = await this.getCurrentSchema()
21462163
let [schema, name] = table.name.split(".");
21472164
if (!name) {
21482165
name = schema;

src/driver/sap/SapQueryRunner.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
279279
return databases.indexOf(database) !== -1;
280280
}
281281

282+
/**
283+
* Returns current database.
284+
*/
285+
async getCurrentDatabase(): Promise<string> {
286+
const currentDBQuery = await this.query(`SELECT "VALUE" AS "db_name" FROM "SYS"."M_SYSTEM_OVERVIEW" WHERE "SECTION" = 'System' and "NAME" = 'Instance ID'`);
287+
return currentDBQuery[0]["db_name"];
288+
}
289+
282290
/**
283291
* Checks if schema with the given name exist.
284292
*/
@@ -287,6 +295,14 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
287295
return schemas.indexOf(schema) !== -1;
288296
}
289297

298+
/**
299+
* Returns current schema.
300+
*/
301+
async getCurrentSchema(): Promise<string> {
302+
const currentSchemaQuery = await this.query(`SELECT CURRENT_SCHEMA AS "schema_name" FROM "SYS"."DUMMY"`);
303+
return currentSchemaQuery[0]["schema_name"];
304+
}
305+
290306
/**
291307
* Checks if table with the given name exist in the database.
292308
*/
@@ -1417,22 +1433,6 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
14171433
// Protected Methods
14181434
// -------------------------------------------------------------------------
14191435

1420-
/**
1421-
* Return current database.
1422-
*/
1423-
protected async getCurrentDatabase(): Promise<string> {
1424-
const currentDBQuery = await this.query(`SELECT "VALUE" AS "db_name" FROM "SYS"."M_SYSTEM_OVERVIEW" WHERE "SECTION" = 'System' and "NAME" = 'Instance ID'`);
1425-
return currentDBQuery[0]["db_name"];
1426-
}
1427-
1428-
/**
1429-
* Return current schema.
1430-
*/
1431-
protected async getCurrentSchema(): Promise<string> {
1432-
const currentSchemaQuery = await this.query(`SELECT CURRENT_SCHEMA AS "schema_name" FROM "SYS"."DUMMY"`);
1433-
return currentSchemaQuery[0]["schema_name"];
1434-
}
1435-
14361436
protected async loadViews(viewNames: string[]): Promise<View[]> {
14371437
const hasTable = await this.hasTable(this.getTypeormMetadataTableName());
14381438
if (!hasTable)
@@ -1529,10 +1529,15 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
15291529
// create tables for loaded tables
15301530
return Promise.all(dbTables.map(async dbTable => {
15311531
const table = new Table();
1532+
const getSchemaFromKey = (dbObject: any, key: string) => {
1533+
return dbObject[key] === currentSchema && (!this.driver.options.schema || this.driver.options.schema === currentSchema)
1534+
? undefined
1535+
: dbObject[key]
1536+
};
15321537

15331538
// We do not need to join schema name, when database is by default.
15341539
// In this case we need local variable `tableFullName` for below comparision.
1535-
const schema = dbTable["SCHEMA_NAME"] === currentSchema && !this.driver.options.schema ? undefined : dbTable["SCHEMA_NAME"];
1540+
const schema = getSchemaFromKey(dbTable, "SCHEMA_NAME");
15361541
table.name = this.driver.buildTableName(dbTable["TABLE_NAME"], schema);
15371542
const tableFullName = this.driver.buildTableName(dbTable["TABLE_NAME"], dbTable["SCHEMA_NAME"]);
15381543

@@ -1649,7 +1654,7 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
16491654
const foreignKeys = dbForeignKeys.filter(dbFk => dbFk["CONSTRAINT_NAME"] === dbForeignKey["CONSTRAINT_NAME"]);
16501655

16511656
// if referenced table located in currently used schema, we don't need to concat schema name to table name.
1652-
const schema = dbForeignKey["REFERENCED_SCHEMA_NAME"] === currentSchema ? undefined : dbForeignKey["REFERENCED_SCHEMA_NAME"];
1657+
const schema = getSchemaFromKey(dbTable, "REFERENCED_SCHEMA_NAME");
16531658
const referencedTableName = this.driver.buildTableName(dbForeignKey["REFERENCED_TABLE_NAME"], schema);
16541659

16551660
return new TableForeignKey({

src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,27 @@ export abstract class AbstractSqliteQueryRunner extends BaseQueryRunner implemen
166166
return Promise.resolve(false);
167167
}
168168

169+
/**
170+
* Loads currently using database
171+
*/
172+
async getCurrentDatabase(): Promise<undefined> {
173+
return Promise.resolve(undefined);
174+
}
175+
169176
/**
170177
* Checks if schema with the given name exist.
171178
*/
172179
async hasSchema(schema: string): Promise<boolean> {
173180
throw new Error(`This driver does not support table schemas`);
174181
}
175182

183+
/**
184+
* Loads currently using database schema
185+
*/
186+
async getCurrentSchema(): Promise<undefined> {
187+
return Promise.resolve(undefined);
188+
}
189+
176190
/**
177191
* Checks if table with the given name exist in the database.
178192
*/

0 commit comments

Comments
 (0)