From 92cefc0983482aa8308705b9ca734e6be7148205 Mon Sep 17 00:00:00 2001 From: Gints Polis Date: Sat, 6 May 2017 14:38:38 +0300 Subject: [PATCH 1/3] Support Oracle for indices. --- src/driver/oracle/OracleQueryRunner.ts | 45 ++++++++++---------- src/naming-strategy/DefaultNamingStrategy.ts | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/driver/oracle/OracleQueryRunner.ts b/src/driver/oracle/OracleQueryRunner.ts index ab197dc15..c4bea1abd 100644 --- a/src/driver/oracle/OracleQueryRunner.ts +++ b/src/driver/oracle/OracleQueryRunner.ts @@ -275,16 +275,19 @@ export class OracleQueryRunner implements QueryRunner { const tableNamesString = tableNames.map(name => "'" + name + "'").join(", "); const tablesSql = `SELECT TABLE_NAME FROM user_tables WHERE TABLE_NAME IN (${tableNamesString})`; const columnsSql = `SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, IDENTITY_COLUMN FROM all_tab_cols WHERE TABLE_NAME IN (${tableNamesString})`; - const indicesSql = `SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = '${this.dbName}' AND INDEX_NAME != 'PRIMARY'`; + const indicesSql = `SELECT ind.INDEX_NAME, ind.TABLE_NAME, ind.UNIQUENESS, LISTAGG(cols.COLUMN_NAME, ',') WITHIN GROUP (ORDER BY cols.COLUMN_NAME) AS COLUMN_NAMES + FROM USER_INDEXES ind, USER_IND_COLUMNS cols + WHERE ind.INDEX_NAME = cols.INDEX_NAME AND ind.TABLE_NAME IN (${tableNamesString}) + GROUP BY ind.INDEX_NAME, ind.TABLE_NAME, ind.UNIQUENESS`; const foreignKeysSql = `SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '${this.dbName}' AND REFERENCED_COLUMN_NAME IS NOT NULL`; const uniqueKeysSql = `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = '${this.dbName}' AND CONSTRAINT_TYPE = 'UNIQUE'`; const constraintsSql = `SELECT cols.table_name, cols.column_name, cols.position, cons.constraint_type, cons.constraint_name FROM all_constraints cons, all_cons_columns cols WHERE cols.table_name IN (${tableNamesString}) AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDER BY cols.table_name, cols.position`; - const [dbTables, dbColumns, /*dbIndices, dbForeignKeys, dbUniqueKeys, */constraints]: ObjectLiteral[][] = await Promise.all([ + const [dbTables, dbColumns, dbIndices, /*dbForeignKeys, dbUniqueKeys, */constraints]: ObjectLiteral[][] = await Promise.all([ this.query(tablesSql), this.query(columnsSql), - // this.query(indicesSql), + this.query(indicesSql), // this.query(foreignKeysSql), // this.query(uniqueKeysSql), this.query(constraintsSql), @@ -333,32 +336,28 @@ AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDE // create primary key schema tableSchema.primaryKeys = constraints - .filter(constraint => constraint["TABLE_NAME"] === tableSchema.name && constraint["CONSTRAINT_TYPE"] === "P") - .map(constraint => new PrimaryKeySchema(constraint["CONSTRAINT_NAME"], constraint["COLUMN_NAME"])); + .filter(constraint => + constraint["TABLE_NAME"] === tableSchema.name && constraint["CONSTRAINT_TYPE"] === "P" + ) + .map(constraint => + new PrimaryKeySchema(constraint["CONSTRAINT_NAME"], constraint["COLUMN_NAME"]) + ); // create foreign key schemas from the loaded indices tableSchema.foreignKeys = constraints .filter(constraint => constraint["TABLE_NAME"] === tableSchema.name && constraint["CONSTRAINT_TYPE"] === "R") .map(constraint => new ForeignKeySchema(constraint["CONSTRAINT_NAME"], [], [], "", "")); // todo: fix missing params - // console.log(tableSchema); - // create index schemas from the loaded indices - // tableSchema.indices = dbIndices - // .filter(dbIndex => { - // return dbIndex["table_name"] === tableSchema.name && - // (!tableSchema.foreignKeys.find(foreignKey => foreignKey.name === dbIndex["INDEX_NAME"])) && - // (!tableSchema.primaryKeys.find(primaryKey => primaryKey.name === dbIndex["INDEX_NAME"])); - // }) - // .map(dbIndex => dbIndex["INDEX_NAME"]) - // .filter((value, index, self) => self.indexOf(value) === index) // unqiue - // .map(dbIndexName => { - // const columnNames = dbIndices - // .filter(dbIndex => dbIndex["TABLE_NAME"] === tableSchema.name && dbIndex["INDEX_NAME"] === dbIndexName) - // .map(dbIndex => dbIndex["COLUMN_NAME"]); - // - // return new IndexSchema(dbTable["TABLE_NAME"], dbIndexName, columnNames, false /* todo: uniqueness */); - // }); + tableSchema.indices = dbIndices + .filter(dbIndex => { + return dbIndex["TABLE_NAME"] === tableSchema.name && + (!tableSchema.foreignKeys.find(foreignKey => foreignKey.name === dbIndex["INDEX_NAME"])) && + (!tableSchema.primaryKeys.find(primaryKey => primaryKey.name === dbIndex["INDEX_NAME"])); + }) + .map(dbIndex => { + return new IndexSchema(dbTable["TABLE_NAME"], dbIndex["INDEX_NAME"], dbIndex["COLUMN_NAMES"], !!(dbIndex["COLUMN_NAMES"] === "UNIQUE")); + }); return tableSchema; }); @@ -840,7 +839,7 @@ AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDE * Database name shortcut. */ protected get dbName(): string { - return this.driver.options.database as string; + return this.driver.options.schemaName as string; } /** diff --git a/src/naming-strategy/DefaultNamingStrategy.ts b/src/naming-strategy/DefaultNamingStrategy.ts index 8cae408c6..5848eacd9 100644 --- a/src/naming-strategy/DefaultNamingStrategy.ts +++ b/src/naming-strategy/DefaultNamingStrategy.ts @@ -31,7 +31,7 @@ export class DefaultNamingStrategy implements NamingStrategyInterface { return customName; const key = "ind_" + tableName + "_" + columns.join("_"); - return "ind_" + RandomGenerator.sha1(key).substr(0, 27); + return "in_" + RandomGenerator.sha1(key).substr(0, 27); } joinColumnInverseSideName(joinColumnName: string, propertyName: string): string { From 598562e6ecea5acccfd71b1dbbbb4575a2b3aa94 Mon Sep 17 00:00:00 2001 From: Gints Polis Date: Thu, 11 May 2017 16:05:44 +0300 Subject: [PATCH 2/3] By default oracle returns all caps column names. --- src/repository/SpecificRepository.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repository/SpecificRepository.ts b/src/repository/SpecificRepository.ts index 360c7733e..bff55a2d1 100644 --- a/src/repository/SpecificRepository.ts +++ b/src/repository/SpecificRepository.ts @@ -454,7 +454,7 @@ export class SpecificRepository { const ids: any[] = []; const promises = (entityIds as any[]).map((entityId: any) => { const qb = new QueryBuilder(this.connection, this.queryRunnerProvider) - .select(escapeAlias("junction") + "." + escapeColumn(inverseEntityColumn.fullName) + " AS id") + .select(escapeAlias("junction") + "." + escapeColumn(inverseEntityColumn.fullName) + " AS " + escapeColumn("id")) .fromTable(relation.junctionEntityMetadata.table.name, "junction") .andWhere(escapeAlias("junction") + "." + escapeColumn(ownerEntityColumn.fullName) + "=:entityId", {entityId: entityId}); From d570a92ed5a6ef84737ef2ae6dc5c0f0c774100d Mon Sep 17 00:00:00 2001 From: Gints Polis Date: Thu, 11 May 2017 16:06:35 +0300 Subject: [PATCH 3/3] Use 26 sha1 instead --- src/naming-strategy/DefaultNamingStrategy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/naming-strategy/DefaultNamingStrategy.ts b/src/naming-strategy/DefaultNamingStrategy.ts index 5848eacd9..5384a2c2e 100644 --- a/src/naming-strategy/DefaultNamingStrategy.ts +++ b/src/naming-strategy/DefaultNamingStrategy.ts @@ -31,7 +31,7 @@ export class DefaultNamingStrategy implements NamingStrategyInterface { return customName; const key = "ind_" + tableName + "_" + columns.join("_"); - return "in_" + RandomGenerator.sha1(key).substr(0, 27); + return "ind_" + RandomGenerator.sha1(key).substr(0, 26); } joinColumnInverseSideName(joinColumnName: string, propertyName: string): string {