Skip to content

Commit

Permalink
fix: default schema defined in entity/connection leads to unnecessa…
Browse files Browse the repository at this point in the history
…ry queries during schema sync (#7575)

* working on #7276

* minor fix

* fix #7276

* lint fix

* added `getCurrentDatabase()` and `getCurrentSchema()` methods in QueryRunner

* fixed falling test;

* fixed default schema in other drivers
  • Loading branch information
AlexMesser committed Apr 17, 2021
1 parent b2ac41a commit 7eb0327
Show file tree
Hide file tree
Showing 15 changed files with 320 additions and 77 deletions.
24 changes: 16 additions & 8 deletions src/driver/aurora-data-api/AuroraDataApiQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,29 @@ export class AuroraDataApiQueryRunner extends BaseQueryRunner implements QueryRu
return result.length ? true : false;
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<string> {
const query = await this.query(`SELECT DATABASE() AS \`db_name\``);
return query[0]["db_name"];
}

/**
* Checks if schema with the given name exist.
*/
async hasSchema(schema: string): Promise<boolean> {
throw new Error(`MySql driver does not support table schemas`);
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<string> {
const query = await this.query(`SELECT SCHEMA() AS \`schema_name\``);
return query[0]["schema_name"];
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down Expand Up @@ -1133,14 +1149,6 @@ export class AuroraDataApiQueryRunner extends BaseQueryRunner implements QueryRu
// Protected Methods
// -------------------------------------------------------------------------

/**
* Returns current database.
*/
protected async getCurrentDatabase(): Promise<string> {
const currentDBQuery = await this.query(`SELECT DATABASE() AS \`db_name\``);
return currentDBQuery[0]["db_name"];
}

protected async loadViews(viewNames: string[]): Promise<View[]> {
const hasTable = await this.hasTable(this.getTypeormMetadataTableName());
if (!hasTable)
Expand Down
28 changes: 25 additions & 3 deletions src/driver/cockroachdb/CockroachQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
return result.length ? true : false;
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<string> {
const query = await this.query(`SELECT * FROM current_database()`);
return query[0]["current_database"];
}

/**
* Checks if schema with the given name exist.
*/
Expand All @@ -305,6 +313,14 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
return result.length ? true : false;
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<string> {
const query = await this.query(`SELECT * FROM current_schema()`);
return query[0]["current_schema"];
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down Expand Up @@ -1452,9 +1468,15 @@ export class CockroachQueryRunner extends BaseQueryRunner implements QueryRunner
return Promise.all(dbTables.map(async dbTable => {
const table = new Table();

const getSchemaFromKey = (dbObject: any, key: string) => {
return dbObject[key] === currentSchema && (!this.driver.options.schema || this.driver.options.schema === currentSchema)
? undefined
: dbObject[key]
};

// We do not need to join schema name, when database is by default.
// In this case we need local variable `tableFullName` for below comparision.
const schema = dbTable["table_schema"] === currentSchema && !this.driver.options.schema ? undefined : dbTable["table_schema"];
// In this case we need local variable `tableFullName` for below comparison.
const schema = getSchemaFromKey(dbTable, "table_schema");
table.name = this.driver.buildTableName(dbTable["table_name"], schema);
const tableFullName = this.driver.buildTableName(dbTable["table_name"], dbTable["table_schema"]);

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

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

return new TableForeignKey({
Expand Down
14 changes: 14 additions & 0 deletions src/driver/mongodb/MongoQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,13 +513,27 @@ export class MongoQueryRunner implements QueryRunner {
throw new Error(`Check database queries are not supported by MongoDB driver.`);
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<undefined> {
throw new Error(`Check database queries are not supported by MongoDB driver.`);
}

/**
* Checks if schema with the given name exist.
*/
async hasSchema(schema: string): Promise<boolean> {
throw new Error(`Check schema queries are not supported by MongoDB driver.`);
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<undefined> {
throw new Error(`Check schema queries are not supported by MongoDB driver.`);
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down
24 changes: 16 additions & 8 deletions src/driver/mysql/MysqlQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,29 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
return result.length ? true : false;
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<string> {
const query = await this.query(`SELECT DATABASE() AS \`db_name\``);
return query[0]["db_name"];
}

/**
* Checks if schema with the given name exist.
*/
async hasSchema(schema: string): Promise<boolean> {
throw new Error(`MySql driver does not support table schemas`);
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<string> {
const query = await this.query(`SELECT SCHEMA() AS \`schema_name\``);
return query[0]["schema_name"];
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down Expand Up @@ -1180,14 +1196,6 @@ export class MysqlQueryRunner extends BaseQueryRunner implements QueryRunner {
// Protected Methods
// -------------------------------------------------------------------------

/**
* Returns current database.
*/
protected async getCurrentDatabase(): Promise<string> {
const currentDBQuery = await this.query(`SELECT DATABASE() AS \`db_name\``);
return currentDBQuery[0]["db_name"];
}

protected async loadViews(viewNames: string[]): Promise<View[]> {
const hasTable = await this.hasTable(this.getTypeormMetadataTableName());
if (!hasTable)
Expand Down
16 changes: 16 additions & 0 deletions src/driver/oracle/OracleQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,29 @@ export class OracleQueryRunner extends BaseQueryRunner implements QueryRunner {
return Promise.resolve(false);
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<undefined> {
const query = await this.query(`SELECT SYS_CONTEXT('USERENV','DB_NAME') AS "db_name" FROM dual`)
return query[0]["db_name"]
}

/**
* Checks if schema with the given name exist.
*/
async hasSchema(schema: string): Promise<boolean> {
return Promise.resolve(false);
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<string> {
const query = await this.query(`SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') AS "schema_name" FROM dual`)
return query[0]["schema_name"]
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down
33 changes: 25 additions & 8 deletions src/driver/postgres/PostgresQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
return Promise.resolve(false);
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<string> {
const query = await this.query(`SELECT * FROM current_database()`);
return query[0]["current_database"];
}

/**
* Checks if schema with the given name exist.
*/
Expand All @@ -282,6 +290,14 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
return result.length ? true : false;
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<string> {
const query = await this.query(`SELECT * FROM current_schema()`);
return query[0]["current_schema"];
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down Expand Up @@ -1404,9 +1420,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
if (!hasTable)
return Promise.resolve([]);

const currentSchemaQuery = await this.query(`SELECT * FROM current_schema()`);
const currentSchema = currentSchemaQuery[0]["current_schema"];

const currentSchema = await this.getCurrentSchema()
const viewsCondition = viewNames.map(viewName => {
let [schema, name] = viewName.split(".");
if (!name) {
Expand Down Expand Up @@ -1438,7 +1452,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
return [];

const currentSchemaQuery = await this.query(`SELECT * FROM current_schema()`);
const currentSchema = currentSchemaQuery[0]["current_schema"];
const currentSchema: string = currentSchemaQuery[0]["current_schema"];

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

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

protected async getEnumTypeName(table: Table, column: TableColumn) {
const currentSchemaQuery = await this.query(`SELECT * FROM current_schema()`);
const currentSchema = currentSchemaQuery[0]["current_schema"];
const currentSchema = await this.getCurrentSchema()
let [schema, name] = table.name.split(".");
if (!name) {
name = schema;
Expand Down
41 changes: 23 additions & 18 deletions src/driver/sap/SapQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
return databases.indexOf(database) !== -1;
}

/**
* Returns current database.
*/
async getCurrentDatabase(): Promise<string> {
const currentDBQuery = await this.query(`SELECT "VALUE" AS "db_name" FROM "SYS"."M_SYSTEM_OVERVIEW" WHERE "SECTION" = 'System' and "NAME" = 'Instance ID'`);
return currentDBQuery[0]["db_name"];
}

/**
* Checks if schema with the given name exist.
*/
Expand All @@ -287,6 +295,14 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
return schemas.indexOf(schema) !== -1;
}

/**
* Returns current schema.
*/
async getCurrentSchema(): Promise<string> {
const currentSchemaQuery = await this.query(`SELECT CURRENT_SCHEMA AS "schema_name" FROM "SYS"."DUMMY"`);
return currentSchemaQuery[0]["schema_name"];
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down Expand Up @@ -1417,22 +1433,6 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
// Protected Methods
// -------------------------------------------------------------------------

/**
* Return current database.
*/
protected async getCurrentDatabase(): Promise<string> {
const currentDBQuery = await this.query(`SELECT "VALUE" AS "db_name" FROM "SYS"."M_SYSTEM_OVERVIEW" WHERE "SECTION" = 'System' and "NAME" = 'Instance ID'`);
return currentDBQuery[0]["db_name"];
}

/**
* Return current schema.
*/
protected async getCurrentSchema(): Promise<string> {
const currentSchemaQuery = await this.query(`SELECT CURRENT_SCHEMA AS "schema_name" FROM "SYS"."DUMMY"`);
return currentSchemaQuery[0]["schema_name"];
}

protected async loadViews(viewNames: string[]): Promise<View[]> {
const hasTable = await this.hasTable(this.getTypeormMetadataTableName());
if (!hasTable)
Expand Down Expand Up @@ -1529,10 +1529,15 @@ export class SapQueryRunner extends BaseQueryRunner implements QueryRunner {
// create tables for loaded tables
return Promise.all(dbTables.map(async dbTable => {
const table = new Table();
const getSchemaFromKey = (dbObject: any, key: string) => {
return dbObject[key] === currentSchema && (!this.driver.options.schema || this.driver.options.schema === currentSchema)
? undefined
: dbObject[key]
};

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

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

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

return new TableForeignKey({
Expand Down
14 changes: 14 additions & 0 deletions src/driver/sqlite-abstract/AbstractSqliteQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,27 @@ export abstract class AbstractSqliteQueryRunner extends BaseQueryRunner implemen
return Promise.resolve(false);
}

/**
* Loads currently using database
*/
async getCurrentDatabase(): Promise<undefined> {
return Promise.resolve(undefined);
}

/**
* Checks if schema with the given name exist.
*/
async hasSchema(schema: string): Promise<boolean> {
throw new Error(`This driver does not support table schemas`);
}

/**
* Loads currently using database schema
*/
async getCurrentSchema(): Promise<undefined> {
return Promise.resolve(undefined);
}

/**
* Checks if table with the given name exist in the database.
*/
Expand Down
Loading

0 comments on commit 7eb0327

Please sign in to comment.