diff --git a/src/AbstractNamingStrategy.ts b/src/AbstractNamingStrategy.ts new file mode 100644 index 0000000..ad4585b --- /dev/null +++ b/src/AbstractNamingStrategy.ts @@ -0,0 +1,10 @@ +import { RelationInfo } from "./models/RelationInfo"; +import { DatabaseModel } from "./models/DatabaseModel"; + +export abstract class AbstractNamingStrategy { + abstract relationName(columnName: string, relation: RelationInfo, dbModel: DatabaseModel): string; + + abstract entityName(entityName: string): string; + + abstract columnName(columnName: string): string; +} diff --git a/src/DefaultNamingStrategy.ts b/src/DefaultNamingStrategy.ts deleted file mode 100644 index b505c58..0000000 --- a/src/DefaultNamingStrategy.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { NamingStrategy } from "./NamingStrategy"; -import { RelationInfo } from "./models/RelationInfo"; -import { DatabaseModel } from "./models/DatabaseModel"; - -export class DefaultNamingStrategy extends NamingStrategy { - relationName( - columnOldName:string, - relation: RelationInfo, - dbModel:DatabaseModel - ): string { - let isRelationToMany = relation.isOneToMany || relation.isManyToMany - let ownerEntity = dbModel.entities.filter(v => { - return v.EntityName==relation.ownerTable - })[0] - let referencedEntity = dbModel.entities.filter(v => { - return v.EntityName == relation.relatedTable - })[0] - - - - let columnName = columnOldName[0].toLowerCase()+ columnOldName.substring(1,columnOldName.length); - if ( columnName.endsWith("id")) { - columnName = columnName.substring(0, columnName.lastIndexOf("id")); - } - if (!isNaN(parseInt(columnName[columnName.length-1]))) { - let num = columnName[columnName.length-1] - columnName = columnName.substring(0, columnName.length - 1) - columnName += (isRelationToMany ? "s" : "")+num.toString(); - } else { - columnName += isRelationToMany ? "s" : ""; - } - - if (relation.relationType!="ManyToMany") { - - if (columnOldName!=columnName) { - if (!relation.isOwner) { - if (ownerEntity.Columns.some(v => v.tsName == columnName)) { - columnName = columnName + "_" - for (let i = 2; i <= ownerEntity.Columns.length; i++) { - columnName = columnName.substring(0, columnName.length - 1) + i.toString(); - if (ownerEntity.Columns.every(v => v.tsName != columnName)) break; - } - } - } else { - if (referencedEntity.Columns.some(v => v.tsName == columnName)) { - columnName = columnName + "_" - for (let i = 2; i <= referencedEntity.Columns.length; i++) { - columnName = columnName.substring(0, columnName.length - 1) + i.toString(); - if (referencedEntity.Columns.every(v => v.tsName != columnName)) break; - } - } - } - } - } - - return columnName; - } - - entityName(entityName: string): string { - return entityName; - } - - columnName(columnName: string): string { - return columnName; - } -} diff --git a/src/Engine.ts b/src/Engine.ts index ed1e871..74d5d93 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -5,7 +5,7 @@ import fs = require("fs"); import path = require("path"); import * as TomgUtils from "./Utils"; import changeCase = require("change-case"); -import { NamingStrategy } from "./NamingStrategy"; +import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; export class Engine { constructor( @@ -42,7 +42,7 @@ export class Engine { password: string, schemaName: string, ssl: boolean, - namingStrategy: NamingStrategy + namingStrategy: AbstractNamingStrategy ): Promise { return await this.driver.GetDataFromServer( database, @@ -275,5 +275,5 @@ export interface EngineOptions { convertCaseProperty: "pascal" | "camel" | "none"; lazy: boolean; constructor: boolean; - namingStrategy: NamingStrategy; + namingStrategy: AbstractNamingStrategy; } diff --git a/src/NamingStrategy.ts b/src/NamingStrategy.ts index 1af86d8..aef42a4 100644 --- a/src/NamingStrategy.ts +++ b/src/NamingStrategy.ts @@ -1,10 +1,66 @@ +import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; import { RelationInfo } from "./models/RelationInfo"; import { DatabaseModel } from "./models/DatabaseModel"; -export abstract class NamingStrategy { - abstract relationName(columnName: string, relation: RelationInfo, dbModel: DatabaseModel): string; +export class NamingStrategy extends AbstractNamingStrategy { + relationName( + columnOldName:string, + relation: RelationInfo, + dbModel:DatabaseModel + ): string { + let isRelationToMany = relation.isOneToMany || relation.isManyToMany + let ownerEntity = dbModel.entities.filter(v => { + return v.EntityName==relation.ownerTable + })[0] + let referencedEntity = dbModel.entities.filter(v => { + return v.EntityName == relation.relatedTable + })[0] - abstract entityName(entityName: string): string; - abstract columnName(columnName: string): string; + + let columnName = columnOldName[0].toLowerCase()+ columnOldName.substring(1,columnOldName.length); + if ( columnName.endsWith("id")) { + columnName = columnName.substring(0, columnName.lastIndexOf("id")); + } + if (!isNaN(parseInt(columnName[columnName.length-1]))) { + let num = columnName[columnName.length-1] + columnName = columnName.substring(0, columnName.length - 1) + columnName += (isRelationToMany ? "s" : "")+num.toString(); + } else { + columnName += isRelationToMany ? "s" : ""; + } + + if (relation.relationType!="ManyToMany") { + + if (columnOldName!=columnName) { + if (!relation.isOwner) { + if (ownerEntity.Columns.some(v => v.tsName == columnName)) { + columnName = columnName + "_" + for (let i = 2; i <= ownerEntity.Columns.length; i++) { + columnName = columnName.substring(0, columnName.length - 1) + i.toString(); + if (ownerEntity.Columns.every(v => v.tsName != columnName)) break; + } + } + } else { + if (referencedEntity.Columns.some(v => v.tsName == columnName)) { + columnName = columnName + "_" + for (let i = 2; i <= referencedEntity.Columns.length; i++) { + columnName = columnName.substring(0, columnName.length - 1) + i.toString(); + if (referencedEntity.Columns.every(v => v.tsName != columnName)) break; + } + } + } + } + } + + return columnName; + } + + entityName(entityName: string): string { + return entityName; + } + + columnName(columnName: string): string { + return columnName; + } } diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index 29b22b0..aeb25b5 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -8,7 +8,7 @@ import { WithPrecisionColumnType, WithLengthColumnType } from "typeorm/driver/types/ColumnTypes"; -import { NamingStrategy } from "../NamingStrategy"; +import { AbstractNamingStrategy } from "../AbstractNamingStrategy"; export abstract class AbstractDriver { changeColumnNames(dbModel: DatabaseModel) { @@ -157,7 +157,7 @@ export abstract class AbstractDriver { "binary", "varbinary" ]; - namingStrategy: NamingStrategy; + namingStrategy: AbstractNamingStrategy; FindManyToManyRelations(dbModel: DatabaseModel) { let manyToManyEntities = dbModel.entities.filter(entity => { @@ -238,7 +238,7 @@ export abstract class AbstractDriver { password: string, schema: string, ssl: boolean, - namingStrategy: NamingStrategy + namingStrategy: AbstractNamingStrategy ): Promise { let dbModel = {}; this.namingStrategy = namingStrategy; diff --git a/src/index.ts b/src/index.ts index b7fae4d..af8c144 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,7 @@ import { Engine } from "./Engine"; import * as Yargs from "yargs"; import * as TomgUtils from "./Utils"; import path = require("path"); -import { DefaultNamingStrategy } from "./DefaultNamingStrategy"; +import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; import { NamingStrategy } from "./NamingStrategy"; var argv = Yargs.usage( @@ -86,6 +86,9 @@ var argv = Yargs.usage( boolean: true, default: false }) + .option("namingStrategy", { + describe: "Use custom naming strategy", + }) .option("generateConstructor", { describe: "Generate constructor allowing partial initialization", boolean: true, @@ -131,9 +134,17 @@ switch (argv.e) { default: TomgUtils.LogError("Database engine not recognized.", false); throw new Error("Database engine not recognized."); -} -let namingStrategy: NamingStrategy= new DefaultNamingStrategy(); +} + +let namingStrategy: AbstractNamingStrategy; +if (argv.namingStrategy && argv.namingStrategy!='') { + let req = require(argv.namingStrategy); + namingStrategy= new req.NamingStrategy(); +} else { + namingStrategy= new NamingStrategy(); +} +debugger; let engine = new Engine(driver, { host: argv.h, port: parseInt(argv.p) || standardPort, diff --git a/test/drivers/MssqlDriver.test.ts b/test/drivers/MssqlDriver.test.ts index 4797886..4a61143 100644 --- a/test/drivers/MssqlDriver.test.ts +++ b/test/drivers/MssqlDriver.test.ts @@ -6,7 +6,7 @@ import { EntityInfo } from '../../src/models/EntityInfo' import { ColumnInfo } from '../../src/models/ColumnInfo' import { RelationInfo } from '../../src/models/RelationInfo' import { Table, IColumnMetadata } from "mssql"; -import { DefaultNamingStrategy } from "../../src/DefaultNamingStrategy"; +import { NamingStrategy } from "../../src/NamingStrategy"; class fakeResponse implements MSSQL.IResult { recordsets: MSSQL.IRecordSet[]; @@ -28,7 +28,7 @@ describe('MssqlDriver', function () { beforeEach(() => { driver = new MssqlDriver(); - driver.namingStrategy = new DefaultNamingStrategy(); + driver.namingStrategy = new NamingStrategy(); }) afterEach(() => { diff --git a/test/utils/GeneralTestUtils.ts b/test/utils/GeneralTestUtils.ts index 7c68ccf..38e8d14 100644 --- a/test/utils/GeneralTestUtils.ts +++ b/test/utils/GeneralTestUtils.ts @@ -10,8 +10,8 @@ import { Engine } from "../../src/Engine"; import { createConnection, ConnectionOptions } from "typeorm"; import * as yn from "yn" import path = require('path') +import { AbstractNamingStrategy } from "../../src/AbstractNamingStrategy"; import { NamingStrategy } from "../../src/NamingStrategy"; -import { DefaultNamingStrategy } from "../../src/DefaultNamingStrategy"; export async function createMSSQLModels(filesOrgPath: string, resultsPath: string): Promise { @@ -47,7 +47,7 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin if (conn.isConnected) await conn.close() - let namingStrategy: NamingStrategy = new DefaultNamingStrategy(); + let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new MssqlDriver(); let engine = new Engine( @@ -114,7 +114,7 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st if (conn.isConnected) await conn.close() - let namingStrategy: NamingStrategy = new DefaultNamingStrategy(); + let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new PostgresDriver(); let engine = new Engine( @@ -173,7 +173,7 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri if (conn.isConnected) await conn.close() - let namingStrategy: NamingStrategy = new DefaultNamingStrategy(); + let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new SqliteDriver(); let engine = new Engine( @@ -230,7 +230,7 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin if (conn.isConnected) await conn.close() - let namingStrategy: NamingStrategy = new DefaultNamingStrategy(); + let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new MysqlDriver(); let engine = new Engine( @@ -280,7 +280,7 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str if (conn.isConnected) await conn.close() - let namingStrategy: NamingStrategy = new DefaultNamingStrategy(); + let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new MariaDbDriver(); let engine = new Engine( @@ -333,7 +333,7 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st if (conn.isConnected) await conn.close() - let namingStrategy: NamingStrategy = new DefaultNamingStrategy(); + let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new OracleDriver(); let engine = new Engine(