diff --git a/.npmignore b/.npmignore index 26bb543..01817ea 100644 --- a/.npmignore +++ b/.npmignore @@ -23,3 +23,4 @@ codecov.yml tsconfig.json typings.json dist/test/ +src/tslint.json diff --git a/package-lock.json b/package-lock.json index b03a94e..c293e85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -338,6 +338,59 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -2147,6 +2200,12 @@ "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=" }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, "js-yaml": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", @@ -3510,6 +3569,12 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", @@ -4889,6 +4954,58 @@ "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==", "dev": true }, + "tslint": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.11.0.tgz", + "integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.27.2" + }, + "dependencies": { + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.17.0.tgz", + "integrity": "sha512-NKWNkThwqE4Snn4Cm6SZB7lV5RMDDFsBwz6fWUkTxOKGjMx8ycOHnjIbhn7dZd5XmssW3CwqUjlANR6EhP9YQw==", + "dev": true + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index 9737908..aef97b4 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,8 @@ "remap-istanbul": "^0.12.0", "rimraf": "^2.6.2", "sinon": "^6.0.0", - "sinon-chai": "^3.0.0" + "sinon-chai": "^3.0.0", + "tslint": "^5.11.0", + "tslint-config-prettier": "^1.17.0" } } diff --git a/src/AbstractNamingStrategy.ts b/src/AbstractNamingStrategy.ts index c0ea4bf..b739cd2 100644 --- a/src/AbstractNamingStrategy.ts +++ b/src/AbstractNamingStrategy.ts @@ -1,14 +1,14 @@ -import { RelationInfo } from "./models/RelationInfo"; import { DatabaseModel } from "./models/DatabaseModel"; +import { RelationInfo } from "./models/RelationInfo"; export abstract class AbstractNamingStrategy { - abstract relationName( + public abstract relationName( columnName: string, relation: RelationInfo, dbModel: DatabaseModel ): string; - abstract entityName(entityName: string): string; + public abstract entityName(entityName: string): string; - abstract columnName(columnName: string): string; + public abstract columnName(columnName: string): string; } diff --git a/src/Engine.ts b/src/Engine.ts index cbd2727..fefef16 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -1,11 +1,11 @@ +import changeCase = require("change-case"); +import fs = require("fs"); +import * as Handlebars from "handlebars"; +import path = require("path"); +import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; import { AbstractDriver } from "./drivers/AbstractDriver"; import { DatabaseModel } from "./models/DatabaseModel"; -import * as Handlebars from "handlebars"; -import fs = require("fs"); -import path = require("path"); import * as TomgUtils from "./Utils"; -import changeCase = require("change-case"); -import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; export class Engine { constructor( @@ -14,7 +14,7 @@ export class Engine { ) {} public async createModelFromDatabase(): Promise { - let dbModel = await this.getEntitiesInfo( + const dbModel = await this.getEntitiesInfo( this.Options.databaseName, this.Options.host, this.Options.port, @@ -60,18 +60,24 @@ export class Engine { } private createModelFromMetadata(databaseModel: DatabaseModel) { this.createHandlebarsHelpers(); - let templatePath = path.resolve(__dirname, "../../src/entity.mst"); - let template = fs.readFileSync(templatePath, "UTF-8"); - let resultPath = this.Options.resultsPath; - if (!fs.existsSync(resultPath)) fs.mkdirSync(resultPath); + const templatePath = path.resolve(__dirname, "../../src/entity.mst"); + const template = fs.readFileSync(templatePath, "UTF-8"); + const resultPath = this.Options.resultsPath; + if (!fs.existsSync(resultPath)) { + fs.mkdirSync(resultPath); + } let entitesPath = resultPath; if (!this.Options.noConfigs) { this.createTsConfigFile(resultPath); this.createTypeOrmConfig(resultPath); entitesPath = path.resolve(resultPath, "./entities"); - if (!fs.existsSync(entitesPath)) fs.mkdirSync(entitesPath); + if (!fs.existsSync(entitesPath)) { + fs.mkdirSync(entitesPath); + } } - let compliedTemplate = Handlebars.compile(template, { noEscape: true }); + const compliedTemplate = Handlebars.compile(template, { + noEscape: true + }); databaseModel.entities.forEach(element => { element.Imports = []; element.Columns.forEach(column => { @@ -100,11 +106,11 @@ export class Engine { casedFileName = element.EntityName; break; } - let resultFilePath = path.resolve( + const resultFilePath = path.resolve( entitesPath, casedFileName + ".ts" ); - let rendered = compliedTemplate(element); + const rendered = compliedTemplate(element); fs.writeFileSync(resultFilePath, rendered, { encoding: "UTF-8", flag: "w" @@ -173,8 +179,11 @@ export class Engine { }); Handlebars.registerHelper("toLowerCase", str => str.toLowerCase()); Handlebars.registerHelper("toLazy", str => { - if (this.Options.lazy) return `Promise<${str}>`; - else return str; + if (this.Options.lazy) { + return `Promise<${str}>`; + } else { + return str; + } }); Handlebars.registerHelper({ eq: (v1, v2) => v1 === v2, @@ -188,7 +197,7 @@ export class Engine { }); } - //TODO:Move to mustache template file + // TODO:Move to mustache template file private createTsConfigFile(resultPath) { fs.writeFileSync( path.resolve(resultPath, "tsconfig.json"), diff --git a/src/NamingStrategy.ts b/src/NamingStrategy.ts index 33882ec..f22c59a 100644 --- a/src/NamingStrategy.ts +++ b/src/NamingStrategy.ts @@ -1,15 +1,15 @@ import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; -import { RelationInfo } from "./models/RelationInfo"; import { DatabaseModel } from "./models/DatabaseModel"; +import { RelationInfo } from "./models/RelationInfo"; export class NamingStrategy extends AbstractNamingStrategy { - relationName( + public relationName( columnOldName: string, relation: RelationInfo, dbModel: DatabaseModel ): string { - let isRelationToMany = relation.isOneToMany || relation.isManyToMany; - let ownerEntity = dbModel.entities.find( + const isRelationToMany = relation.isOneToMany || relation.isManyToMany; + const ownerEntity = dbModel.entities.find( v => v.EntityName == relation.ownerTable )!; @@ -51,8 +51,9 @@ export class NamingStrategy extends AbstractNamingStrategy { v.tsName != columnName || columnName == columnOldName ) - ) + ) { break; + } } } } @@ -60,11 +61,11 @@ export class NamingStrategy extends AbstractNamingStrategy { return columnName; } - entityName(entityName: string): string { + public entityName(entityName: string): string { return entityName; } - columnName(columnName: string): string { + public columnName(columnName: string): string { return columnName; } } diff --git a/src/Utils.ts b/src/Utils.ts index 8e34d49..d62d204 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -9,12 +9,16 @@ export function LogError( console.error(`${packageVersion()} node@${process.version}`); console.error( `If you think this is a bug please open an issue including this log on ${ - (packagejson).bugs.url + (packagejson as any).bugs.url }` ); - if (isABug && !errObject) errObject = new Error().stack; - if (!!errObject) console.error(errObject); + if (isABug && !errObject) { + errObject = new Error().stack; + } + if (!!errObject) { + console.error(errObject); + } } export function packageVersion() { - return `${(packagejson).name}@${(packagejson).version}`; + return `${(packagejson as any).name}@${(packagejson as any).version}`; } diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index f84fb99..c47ff7d 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -1,119 +1,24 @@ -import { EntityInfo } from "../models/EntityInfo"; -import { DatabaseModel } from "../models/DatabaseModel"; -import * as TomgUtils from "../Utils"; -import { RelationInfo } from "../models/RelationInfo"; -import { ColumnInfo } from "../models/ColumnInfo"; import { - WithWidthColumnType, + WithLengthColumnType, WithPrecisionColumnType, - WithLengthColumnType + WithWidthColumnType } from "typeorm/driver/types/ColumnTypes"; import { AbstractNamingStrategy } from "../AbstractNamingStrategy"; +import { ColumnInfo } from "../models/ColumnInfo"; +import { DatabaseModel } from "../models/DatabaseModel"; +import { EntityInfo } from "../models/EntityInfo"; +import { RelationInfo } from "../models/RelationInfo"; +import * as TomgUtils from "../Utils"; export abstract class AbstractDriver { - changeColumnNames(dbModel: DatabaseModel) { - dbModel.entities.forEach(entity => { - entity.Columns.forEach(column => { - let newName = this.namingStrategy.columnName(column.tsName); - entity.Indexes.forEach(index => { - index.columns - .filter(column2 => column2.name == column.tsName) - .forEach(column2 => (column2.name = newName)); - }); - dbModel.entities.forEach(entity2 => { - entity2.Columns.forEach(column2 => { - column2.relations - .filter( - relation => - relation.relatedTable == - entity.EntityName && - relation.relatedColumn == column.tsName - ) - .map(v => (v.relatedColumn = newName)); - column2.relations - .filter( - relation => - relation.relatedTable == - entity.EntityName && - relation.ownerColumn == column.tsName - ) - .map(v => (v.ownerColumn = newName)); - }); - }); - - column.tsName = newName; - }); - }); - } - changeEntityNames(dbModel: DatabaseModel) { - dbModel.entities.forEach(entity => { - let newName = this.namingStrategy.entityName(entity.EntityName); - dbModel.entities.forEach(entity2 => { - entity2.Columns.forEach(column => { - column.relations.forEach(relation => { - if (relation.ownerTable == entity.EntityName) - relation.ownerTable = newName; - if (relation.relatedTable == entity.EntityName) - relation.relatedTable = newName; - }); - }); - }); - entity.EntityName = newName; - }); - } - changeRelationNames(dbModel: DatabaseModel) { - dbModel.entities.forEach(entity => { - entity.Columns.forEach(column => { - column.relations.forEach(relation => { - let newName = this.namingStrategy.relationName( - column.tsName, - relation, - dbModel - ); - dbModel.entities.forEach(entity2 => { - entity2.Columns.forEach(column2 => { - column2.relations.forEach(relation2 => { - if ( - relation2.relatedTable == - entity.EntityName && - relation2.ownerColumn == column.tsName - ) { - relation2.ownerColumn = newName; - } - if ( - relation2.relatedTable == - entity.EntityName && - relation2.relatedColumn == column.tsName - ) { - relation2.relatedColumn = newName; - } - if (relation.isOwner) { - entity.Indexes.forEach(ind => { - ind.columns - .filter( - col => col.name == column.tsName - ) - .forEach( - col => (col.name = newName) - ); - }); - } - }); - }); - }); - column.tsName = newName; - }); - }); - }); - } - ColumnTypesWithWidth: WithWidthColumnType[] = [ + public ColumnTypesWithWidth: WithWidthColumnType[] = [ "tinyint", "smallint", "mediumint", "int", "bigint" ]; - ColumnTypesWithPrecision: WithPrecisionColumnType[] = [ + public ColumnTypesWithPrecision: WithPrecisionColumnType[] = [ "float", "double", "dec", @@ -133,7 +38,7 @@ export abstract class AbstractDriver { "timestamp with time zone", "timestamp with local time zone" ]; - ColumnTypesWithLength: WithLengthColumnType[] = [ + public ColumnTypesWithLength: WithLengthColumnType[] = [ "character varying", "varying character", "nvarchar", @@ -148,19 +53,126 @@ export abstract class AbstractDriver { "binary", "varbinary" ]; - namingStrategy: AbstractNamingStrategy; - generateRelationsIds: boolean; + public namingStrategy: AbstractNamingStrategy; + public generateRelationsIds: boolean; - FindManyToManyRelations(dbModel: DatabaseModel) { - let manyToManyEntities = dbModel.entities.filter( + public abstract GetAllTablesQuery: ( + schema: string + ) => Promise< + Array<{ + TABLE_SCHEMA: string; + TABLE_NAME: string; + }> + >; + public changeColumnNames(dbModel: DatabaseModel) { + dbModel.entities.forEach(entity => { + entity.Columns.forEach(column => { + const newName = this.namingStrategy.columnName(column.tsName); + entity.Indexes.forEach(index => { + index.columns + .filter(column2 => column2.name === column.tsName) + .forEach(column2 => (column2.name = newName)); + }); + dbModel.entities.forEach(entity2 => { + entity2.Columns.forEach(column2 => { + column2.relations + .filter( + relation => + relation.relatedTable === + entity.EntityName && + relation.relatedColumn === column.tsName + ) + .map(v => (v.relatedColumn = newName)); + column2.relations + .filter( + relation => + relation.relatedTable === + entity.EntityName && + relation.ownerColumn === column.tsName + ) + .map(v => (v.ownerColumn = newName)); + }); + }); + + column.tsName = newName; + }); + }); + } + public changeEntityNames(dbModel: DatabaseModel) { + dbModel.entities.forEach(entity => { + const newName = this.namingStrategy.entityName(entity.EntityName); + dbModel.entities.forEach(entity2 => { + entity2.Columns.forEach(column => { + column.relations.forEach(relation => { + if (relation.ownerTable === entity.EntityName) { + relation.ownerTable = newName; + } + if (relation.relatedTable === entity.EntityName) { + relation.relatedTable = newName; + } + }); + }); + }); + entity.EntityName = newName; + }); + } + public changeRelationNames(dbModel: DatabaseModel) { + dbModel.entities.forEach(entity => { + entity.Columns.forEach(column => { + column.relations.forEach(relation => { + const newName = this.namingStrategy.relationName( + column.tsName, + relation, + dbModel + ); + dbModel.entities.forEach(entity2 => { + entity2.Columns.forEach(column2 => { + column2.relations.forEach(relation2 => { + if ( + relation2.relatedTable === + entity.EntityName && + relation2.ownerColumn === column.tsName + ) { + relation2.ownerColumn = newName; + } + if ( + relation2.relatedTable === + entity.EntityName && + relation2.relatedColumn === column.tsName + ) { + relation2.relatedColumn = newName; + } + if (relation.isOwner) { + entity.Indexes.forEach(ind => { + ind.columns + .filter( + col => + col.name === column.tsName + ) + .forEach( + col => (col.name = newName) + ); + }); + } + }); + }); + }); + column.tsName = newName; + }); + }); + }); + } + + public FindManyToManyRelations(dbModel: DatabaseModel) { + const manyToManyEntities = dbModel.entities.filter( entity => entity.Columns.filter(column => { return ( - column.relations.length == 1 && + column.relations.length === 1 && !column.relations[0].isOneToMany && column.relations[0].isOwner ); - }).length == entity.Columns.length + }).length === entity.Columns.length ); manyToManyEntities.map(entity => { let relations: RelationInfo[] = []; @@ -168,12 +180,12 @@ export abstract class AbstractDriver { (prev: RelationInfo[], curr) => prev.concat(curr.relations), relations ); - let namesOfRelatedTables = relations + const namesOfRelatedTables = relations .map(v => v.relatedTable) - .filter((v, i, s) => s.indexOf(v) == i); - if (namesOfRelatedTables.length == 2) { - let relatedTable1 = dbModel.entities.find( - v => v.EntityName == namesOfRelatedTables[0] + .filter((v, i, s) => s.indexOf(v) === i); + if (namesOfRelatedTables.length === 2) { + const relatedTable1 = dbModel.entities.find( + v => v.EntityName === namesOfRelatedTables[0] )!; relatedTable1.Columns = relatedTable1.Columns.filter( v => @@ -181,8 +193,8 @@ export abstract class AbstractDriver { .toLowerCase() .startsWith(entity.EntityName.toLowerCase()) ); - let relatedTable2 = dbModel.entities.find( - v => v.EntityName == namesOfRelatedTables[1] + const relatedTable2 = dbModel.entities.find( + v => v.EntityName === namesOfRelatedTables[1] )!; relatedTable2.Columns = relatedTable2.Columns.filter( v => @@ -191,13 +203,13 @@ export abstract class AbstractDriver { .startsWith(entity.EntityName.toLowerCase()) ); dbModel.entities = dbModel.entities.filter(ent => { - return ent.EntityName != entity.EntityName; + return ent.EntityName !== entity.EntityName; }); - let column1 = new ColumnInfo(); + const column1 = new ColumnInfo(); column1.tsName = namesOfRelatedTables[1]; - let col1Rel = new RelationInfo(); + const col1Rel = new RelationInfo(); col1Rel.relatedTable = namesOfRelatedTables[1]; col1Rel.relatedColumn = namesOfRelatedTables[1]; @@ -208,10 +220,10 @@ export abstract class AbstractDriver { column1.relations.push(col1Rel); relatedTable1.Columns.push(column1); - let column2 = new ColumnInfo(); + const column2 = new ColumnInfo(); column2.tsName = namesOfRelatedTables[0]; - let col2Rel = new RelationInfo(); + const col2Rel = new RelationInfo(); col2Rel.relatedTable = namesOfRelatedTables[0]; col2Rel.relatedColumn = namesOfRelatedTables[1]; @@ -222,7 +234,7 @@ export abstract class AbstractDriver { } }); } - async GetDataFromServer( + public async GetDataFromServer( database: string, server: string, port: number, @@ -234,10 +246,10 @@ export abstract class AbstractDriver { relationIds: boolean ): Promise { this.generateRelationsIds = relationIds; - let dbModel = {}; + const dbModel = {} as DatabaseModel; this.namingStrategy = namingStrategy; await this.ConnectToServer(database, server, port, user, password, ssl); - let sqlEscapedSchema = "'" + schema.split(",").join("','") + "'"; + const sqlEscapedSchema = "'" + schema.split(",").join("','") + "'"; dbModel.entities = await this.GetAllTables(sqlEscapedSchema); await this.GetCoulmnsFromEntity(dbModel.entities, sqlEscapedSchema); await this.GetIndexesFromEntity(dbModel.entities, sqlEscapedSchema); @@ -252,13 +264,7 @@ export abstract class AbstractDriver { return dbModel; } - private ApplyNamingStrategy(dbModel: DatabaseModel) { - this.changeRelationNames(dbModel); - this.changeEntityNames(dbModel); - this.changeColumnNames(dbModel); - } - - abstract async ConnectToServer( + public abstract async ConnectToServer( database: string, server: string, port: number, @@ -267,36 +273,27 @@ export abstract class AbstractDriver { ssl: boolean ); - abstract GetAllTablesQuery: ( - schema: string - ) => Promise< - { - TABLE_SCHEMA: string; - TABLE_NAME: string; - }[] - >; - - async GetAllTables(schema: string): Promise { - let response = await this.GetAllTablesQuery(schema); - let ret: EntityInfo[] = []; + public async GetAllTables(schema: string): Promise { + const response = await this.GetAllTablesQuery(schema); + const ret: EntityInfo[] = [] as EntityInfo[]; response.forEach(val => { - let ent: EntityInfo = new EntityInfo(); + const ent: EntityInfo = new EntityInfo(); ent.EntityName = val.TABLE_NAME; ent.Schema = val.TABLE_SCHEMA; - ent.Columns = []; - ent.Indexes = []; + ent.Columns = [] as ColumnInfo[]; + ent.Indexes = [] as IndexInfo[]; ret.push(ent); }); return ret; } - GetRelationsFromRelationTempInfo( + public GetRelationsFromRelationTempInfo( relationsTemp: RelationTempInfo[], entities: EntityInfo[] ) { relationsTemp.forEach(relationTmp => { - let ownerEntity = entities.find( - entitity => entitity.EntityName == relationTmp.ownerTable + const ownerEntity = entities.find( + entitity => entitity.EntityName === relationTmp.ownerTable ); if (!ownerEntity) { TomgUtils.LogError( @@ -306,8 +303,8 @@ export abstract class AbstractDriver { ); return; } - let referencedEntity = entities.find( - entitity => entitity.EntityName == relationTmp.referencedTable + const referencedEntity = entities.find( + entitity => entitity.EntityName === relationTmp.referencedTable ); if (!referencedEntity) { TomgUtils.LogError( @@ -322,9 +319,9 @@ export abstract class AbstractDriver { relationColumnIndex < relationTmp.ownerColumnsNames.length; relationColumnIndex++ ) { - let ownerColumn = ownerEntity.Columns.find( + const ownerColumn = ownerEntity.Columns.find( column => - column.tsName == + column.tsName === relationTmp.ownerColumnsNames[relationColumnIndex] ); if (!ownerColumn) { @@ -339,9 +336,9 @@ export abstract class AbstractDriver { ); return; } - let relatedColumn = referencedEntity.Columns.find( + const relatedColumn = referencedEntity.Columns.find( column => - column.tsName == + column.tsName === relationTmp.referencedColumnsNames[relationColumnIndex] ); if (!relatedColumn) { @@ -358,16 +355,16 @@ export abstract class AbstractDriver { } let isOneToMany: boolean; isOneToMany = false; - let index = ownerEntity.Indexes.find( + const index = ownerEntity.Indexes.find( index => index.isUnique && index.columns.some( - col => col.name == ownerColumn!.tsName + col => col.name === ownerColumn!.tsName ) ); isOneToMany = !index; - let ownerRelation = new RelationInfo(); + const ownerRelation = new RelationInfo(); ownerRelation.actionOnDelete = relationTmp.actionOnDelete; ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate; ownerRelation.isOwner = true; @@ -381,7 +378,7 @@ export abstract class AbstractDriver { let columnName = ownerEntity.EntityName; if ( - referencedEntity.Columns.some(v => v.tsName == columnName) + referencedEntity.Columns.some(v => v.tsName === columnName) ) { columnName = columnName + "_"; for (let i = 2; i <= referencedEntity.Columns.length; i++) { @@ -392,19 +389,20 @@ export abstract class AbstractDriver { ) + i.toString(); if ( referencedEntity.Columns.every( - v => v.tsName != columnName + v => v.tsName !== columnName ) - ) + ) { break; + } } } ownerRelation.ownerColumn = columnName; ownerColumn.relations.push(ownerRelation); if (isOneToMany) { - let col = new ColumnInfo(); + const col = new ColumnInfo(); col.tsName = columnName; - let referencedRelation = new RelationInfo(); + const referencedRelation = new RelationInfo(); col.relations.push(referencedRelation); referencedRelation.actionOnDelete = relationTmp.actionOnDelete; @@ -418,9 +416,9 @@ export abstract class AbstractDriver { referencedRelation.relationType = "OneToMany"; referencedEntity.Columns.push(col); } else { - let col = new ColumnInfo(); + const col = new ColumnInfo(); col.tsName = columnName; - let referencedRelation = new RelationInfo(); + const referencedRelation = new RelationInfo(); col.relations.push(referencedRelation); referencedRelation.actionOnDelete = relationTmp.actionOnDelete; @@ -438,27 +436,27 @@ export abstract class AbstractDriver { }); return entities; } - abstract async GetCoulmnsFromEntity( + public abstract async GetCoulmnsFromEntity( entities: EntityInfo[], schema: string ): Promise; - abstract async GetIndexesFromEntity( + public abstract async GetIndexesFromEntity( entities: EntityInfo[], schema: string ): Promise; - abstract async GetRelations( + public abstract async GetRelations( entities: EntityInfo[], schema: string ): Promise; - FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) { + public FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) { dbModel.entities.forEach(entity => { - let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey); + const primaryIndex = entity.Indexes.find(v => v.isPrimaryKey); entity.Columns.filter( col => primaryIndex && primaryIndex.columns.some( - cIndex => cIndex.name == col.tsName + cIndex => cIndex.name === col.tsName ) ).forEach(col => (col.isPrimary = true)); if ( @@ -474,9 +472,15 @@ export abstract class AbstractDriver { } }); } - abstract async DisconnectFromServer(); - abstract async CreateDB(dbName: string); - abstract async DropDB(dbName: string); - abstract async UseDB(dbName: string); - abstract async CheckIfDBExists(dbName: string): Promise; + public abstract async DisconnectFromServer(); + public abstract async CreateDB(dbName: string); + public abstract async DropDB(dbName: string); + public abstract async UseDB(dbName: string); + public abstract async CheckIfDBExists(dbName: string): Promise; + + private ApplyNamingStrategy(dbModel: DatabaseModel) { + this.changeRelationNames(dbModel); + this.changeEntityNames(dbModel); + this.changeColumnNames(dbModel); + } } diff --git a/src/drivers/MariaDbDriver.ts b/src/drivers/MariaDbDriver.ts index e0633a7..93c587a 100644 --- a/src/drivers/MariaDbDriver.ts +++ b/src/drivers/MariaDbDriver.ts @@ -1,5 +1,5 @@ import { MysqlDriver } from "./MysqlDriver"; export class MariaDbDriver extends MysqlDriver { - readonly EngineName: string = "MariaDb"; + public readonly EngineName: string = "MariaDb"; } diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index 7d3fe8c..c8eb5ba 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -6,8 +6,8 @@ import * as TomgUtils from "../Utils"; export class MssqlDriver extends AbstractDriver { GetAllTablesQuery = async (schema: string) => { - let request = new MSSQL.Request(this.Connection); - let response: { + const request = new MSSQL.Request(this.Connection); + const response: { TABLE_SCHEMA: string; TABLE_NAME: string; }[] = (await request.query( @@ -20,8 +20,8 @@ export class MssqlDriver extends AbstractDriver { entities: EntityInfo[], schema: string ): Promise { - let request = new MSSQL.Request(this.Connection); - let response: { + const request = new MSSQL.Request(this.Connection); + const response: { TABLE_NAME: string; COLUMN_NAME: string; COLUMN_DEFAULT: string; @@ -199,8 +199,8 @@ export class MssqlDriver extends AbstractDriver { entities: EntityInfo[], schema: string ): Promise { - let request = new MSSQL.Request(this.Connection); - let response: { + const request = new MSSQL.Request(this.Connection); + const response: { TableName: string; IndexName: string; ColumnName: string; @@ -258,8 +258,8 @@ ORDER BY entities: EntityInfo[], schema: string ): Promise { - let request = new MSSQL.Request(this.Connection); - let response: { + const request = new MSSQL.Request(this.Connection); + const response: { TableWithForeignKey: string; FK_PartNo: number; ForeignKeyColumn: string; @@ -365,7 +365,7 @@ order by } }; - let promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { this.Connection = new MSSQL.ConnectionPool(config, err => { if (!err) { resolve(true); @@ -383,20 +383,20 @@ order by await promise; } async CreateDB(dbName: string) { - let request = new MSSQL.Request(this.Connection); + const request = new MSSQL.Request(this.Connection); await request.query(`CREATE DATABASE ${dbName}; `); } async UseDB(dbName: string) { - let request = new MSSQL.Request(this.Connection); + const request = new MSSQL.Request(this.Connection); await request.query(`USE ${dbName}; `); } async DropDB(dbName: string) { - let request = new MSSQL.Request(this.Connection); + const request = new MSSQL.Request(this.Connection); await request.query(`DROP DATABASE ${dbName}; `); } async CheckIfDBExists(dbName: string): Promise { - let request = new MSSQL.Request(this.Connection); - let resp = await request.query( + const request = new MSSQL.Request(this.Connection); + const resp = await request.query( `SELECT name FROM master.sys.databases WHERE name = N'${dbName}' ` ); return resp.recordset.length > 0; diff --git a/src/drivers/MysqlDriver.ts b/src/drivers/MysqlDriver.ts index 2fa3bf3..c0826c8 100644 --- a/src/drivers/MysqlDriver.ts +++ b/src/drivers/MysqlDriver.ts @@ -1,14 +1,16 @@ -import { AbstractDriver } from "./AbstractDriver"; import * as MYSQL from "mysql"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; +import { AbstractDriver } from "./AbstractDriver"; export class MysqlDriver extends AbstractDriver { - readonly EngineName: string = "MySQL"; + public readonly EngineName: string = "MySQL"; - GetAllTablesQuery = async (schema: string) => { - let response = this.ExecQuery<{ + private Connection: MYSQL.Connection; + + public GetAllTablesQuery = async (schema: string) => { + const response = this.ExecQuery<{ TABLE_SCHEMA: string; TABLE_NAME: string; }>(`SELECT TABLE_SCHEMA, TABLE_NAME @@ -18,11 +20,11 @@ export class MysqlDriver extends AbstractDriver { return response; }; - async GetCoulmnsFromEntity( + public async GetCoulmnsFromEntity( entities: EntityInfo[], schema: string ): Promise { - let response = await this.ExecQuery<{ + const response = await this.ExecQuery<{ TABLE_NAME: string; COLUMN_NAME: string; COLUMN_DEFAULT: string; @@ -40,14 +42,14 @@ export class MysqlDriver extends AbstractDriver { FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA like DATABASE()`); entities.forEach(ent => { response - .filter(filterVal => filterVal.TABLE_NAME == ent.EntityName) + .filter(filterVal => filterVal.TABLE_NAME === ent.EntityName) .forEach(resp => { - let colInfo: ColumnInfo = new ColumnInfo(); + const colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.COLUMN_NAME; colInfo.sqlName = resp.COLUMN_NAME; - colInfo.is_nullable = resp.IS_NULLABLE == "YES"; - colInfo.is_generated = resp.IsIdentity == 1; - colInfo.is_unique = resp.column_key == "UNI"; + colInfo.is_nullable = resp.IS_NULLABLE === "YES"; + colInfo.is_generated = resp.IsIdentity === 1; + colInfo.is_unique = resp.column_key === "UNI"; colInfo.default = resp.COLUMN_DEFAULT; colInfo.sql_type = resp.DATA_TYPE; switch (resp.DATA_TYPE) { @@ -55,7 +57,7 @@ export class MysqlDriver extends AbstractDriver { colInfo.ts_type = "number"; break; case "tinyint": - if (resp.column_type == "tinyint(1)") { + if (resp.column_type === "tinyint(1)") { colInfo.width = 1; colInfo.ts_type = "boolean"; } else { @@ -173,7 +175,7 @@ export class MysqlDriver extends AbstractDriver { } if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sql_type + v => v === colInfo.sql_type ) ) { colInfo.numericPrecision = resp.NUMERIC_PRECISION; @@ -181,7 +183,7 @@ export class MysqlDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sql_type + v => v === colInfo.sql_type ) ) { colInfo.lenght = @@ -192,8 +194,8 @@ export class MysqlDriver extends AbstractDriver { if ( this.ColumnTypesWithWidth.some( v => - v == colInfo.sql_type && - colInfo.ts_type != "boolean" + v === colInfo.sql_type && + colInfo.ts_type !== "boolean" ) ) { colInfo.width = @@ -202,16 +204,18 @@ export class MysqlDriver extends AbstractDriver { : null; } - if (colInfo.sql_type) ent.Columns.push(colInfo); + if (colInfo.sql_type) { + ent.Columns.push(colInfo); + } }); }); return entities; } - async GetIndexesFromEntity( + public async GetIndexesFromEntity( entities: EntityInfo[], schema: string ): Promise { - let response = await this.ExecQuery<{ + const response = await this.ExecQuery<{ TableName: string; IndexName: string; ColumnName: string; @@ -224,23 +228,23 @@ export class MysqlDriver extends AbstractDriver { `); entities.forEach(ent => { response - .filter(filterVal => filterVal.TableName == ent.EntityName) + .filter(filterVal => filterVal.TableName === ent.EntityName) .forEach(resp => { - let indexInfo: IndexInfo = {}; - let indexColumnInfo: IndexColumnInfo = {}; + let indexInfo: IndexInfo = {} as IndexInfo; + const indexColumnInfo: IndexColumnInfo = {} as IndexColumnInfo; if ( ent.Indexes.filter( - filterVal => filterVal.name == resp.IndexName + filterVal => filterVal.name === resp.IndexName ).length > 0 ) { indexInfo = ent.Indexes.find( - filterVal => filterVal.name == resp.IndexName + filterVal => filterVal.name === resp.IndexName )!; } else { - indexInfo.columns = []; + indexInfo.columns = [] as IndexColumnInfo[]; indexInfo.name = resp.IndexName; - indexInfo.isUnique = resp.is_unique == 1; - indexInfo.isPrimaryKey = resp.is_primary_key == 1; + indexInfo.isUnique = resp.is_unique === 1; + indexInfo.isPrimaryKey = resp.is_primary_key === 1; ent.Indexes.push(indexInfo); } indexColumnInfo.name = resp.ColumnName; @@ -250,11 +254,11 @@ export class MysqlDriver extends AbstractDriver { return entities; } - async GetRelations( + public async GetRelations( entities: EntityInfo[], schema: string ): Promise { - let response = await this.ExecQuery<{ + const response = await this.ExecQuery<{ TableWithForeignKey: string; FK_PartNo: number; ForeignKeyColumn: string; @@ -280,19 +284,19 @@ export class MysqlDriver extends AbstractDriver { TABLE_SCHEMA = SCHEMA() AND CU.REFERENCED_TABLE_NAME IS NOT NULL; `); - let relationsTemp: RelationTempInfo[] = []; + const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( - val => val.object_id == resp.object_id + val => val.object_id === resp.object_id ); - if (rels == undefined) { - rels = {}; + if (rels === undefined) { + rels = {} as RelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = - resp.onDelete == "NO_ACTION" ? null : resp.onDelete; + resp.onDelete === "NO_ACTION" ? null : resp.onDelete; rels.actionOnUpdate = - resp.onUpdate == "NO_ACTION" ? null : resp.onUpdate; + resp.onUpdate === "NO_ACTION" ? null : resp.onUpdate; rels.object_id = resp.object_id; rels.ownerTable = resp.TableWithForeignKey; rels.referencedTable = resp.TableReferenced; @@ -307,8 +311,8 @@ export class MysqlDriver extends AbstractDriver { ); return entities; } - async DisconnectFromServer() { - let promise = new Promise((resolve, reject) => { + public async DisconnectFromServer() { + const promise = new Promise((resolve, reject) => { this.Connection.end(err => { if (!err) { resolve(true); @@ -322,11 +326,11 @@ export class MysqlDriver extends AbstractDriver { } }); }); - if (this.Connection) await promise; + if (this.Connection) { + await promise; + } } - - private Connection: MYSQL.Connection; - async ConnectToServer( + public async ConnectToServer( database: string, server: string, port: number, @@ -337,26 +341,26 @@ export class MysqlDriver extends AbstractDriver { let config: MYSQL.ConnectionConfig; if (ssl) { config = { - database: database, + database, host: server, - port: port, - user: user, - password: password, + port, + user, + password, ssl: { rejectUnauthorized: false } }; } else { config = { - database: database, + database, host: server, - port: port, - user: user, - password: password + port, + user, + password }; } - let promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { this.Connection = MYSQL.createConnection(config); this.Connection.connect(err => { @@ -375,28 +379,28 @@ export class MysqlDriver extends AbstractDriver { await promise; } - async CreateDB(dbName: string) { + public async CreateDB(dbName: string) { await this.ExecQuery(`CREATE DATABASE ${dbName}; `); } - async UseDB(dbName: string) { + public async UseDB(dbName: string) { await this.ExecQuery(`USE ${dbName}; `); } - async DropDB(dbName: string) { + public async DropDB(dbName: string) { await this.ExecQuery(`DROP DATABASE ${dbName}; `); } - async CheckIfDBExists(dbName: string): Promise { - let resp = await this.ExecQuery( + public async CheckIfDBExists(dbName: string): Promise { + const resp = await this.ExecQuery( `SHOW DATABASES LIKE '${dbName}' ` ); return resp.length > 0; } - async ExecQuery(sql: string): Promise> { - let ret: Array = []; - let query = this.Connection.query(sql); - let stream = query.stream({}); - let promise = new Promise((resolve, reject) => { + public async ExecQuery(sql: string): Promise { + const ret: T[] = []; + const query = this.Connection.query(sql); + const stream = query.stream({}); + const promise = new Promise((resolve, reject) => { stream.on("data", chunk => { - ret.push((chunk)); + ret.push((chunk as any) as T); }); stream.on("error", err => reject(err)); stream.on("end", () => resolve(true)); diff --git a/src/drivers/OracleDriver.ts b/src/drivers/OracleDriver.ts index 4ac6580..6cda297 100644 --- a/src/drivers/OracleDriver.ts +++ b/src/drivers/OracleDriver.ts @@ -1,10 +1,12 @@ -import { AbstractDriver } from "./AbstractDriver"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; +import { AbstractDriver } from "./AbstractDriver"; export class OracleDriver extends AbstractDriver { - Oracle: any; + public Oracle: any; + + private Connection: any /*Oracle.IConnection*/; constructor() { super(); try { @@ -16,21 +18,21 @@ export class OracleDriver extends AbstractDriver { } } - GetAllTablesQuery = async (schema: string) => { - let response: { + public GetAllTablesQuery = async (schema: string) => { + const response: Array<{ TABLE_SCHEMA: string; TABLE_NAME: string; - }[] = (await this.Connection.execute( + }> = (await this.Connection.execute( ` SELECT NULL AS TABLE_SCHEMA, TABLE_NAME FROM all_tables WHERE owner = (select user from dual)` )).rows!; return response; }; - async GetCoulmnsFromEntity( + public async GetCoulmnsFromEntity( entities: EntityInfo[], schema: string ): Promise { - let response: { + const response: Array<{ TABLE_NAME: string; COLUMN_NAME: string; DATA_DEFAULT: string; @@ -41,7 +43,7 @@ export class OracleDriver extends AbstractDriver { DATA_SCALE: number; IDENTITY_COLUMN: string; IS_UNIQUE: Number; - }[] = (await this.Connection + }> = (await this.Connection .execute(`SELECT utc.TABLE_NAME, utc.COLUMN_NAME, DATA_DEFAULT, NULLABLE, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, IDENTITY_COLUMN, (select count(*) from USER_CONS_COLUMNS ucc @@ -51,13 +53,13 @@ export class OracleDriver extends AbstractDriver { entities.forEach(ent => { response - .filter(filterVal => filterVal.TABLE_NAME == ent.EntityName) + .filter(filterVal => filterVal.TABLE_NAME === ent.EntityName) .forEach(resp => { - let colInfo: ColumnInfo = new ColumnInfo(); + const colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.COLUMN_NAME; colInfo.sqlName = resp.COLUMN_NAME; - colInfo.is_nullable = resp.NULLABLE == "Y"; - colInfo.is_generated = resp.IDENTITY_COLUMN == "YES"; + colInfo.is_nullable = resp.NULLABLE === "Y"; + colInfo.is_generated = resp.IDENTITY_COLUMN === "YES"; colInfo.default = !resp.DATA_DEFAULT || resp.DATA_DEFAULT.includes('"') ? null @@ -161,7 +163,7 @@ export class OracleDriver extends AbstractDriver { } if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sql_type + v => v === colInfo.sql_type ) ) { colInfo.numericPrecision = resp.DATA_PRECISION; @@ -169,29 +171,31 @@ export class OracleDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sql_type + v => v === colInfo.sql_type ) ) { colInfo.lenght = resp.DATA_LENGTH > 0 ? resp.DATA_LENGTH : null; } - if (colInfo.sql_type) ent.Columns.push(colInfo); + if (colInfo.sql_type) { + ent.Columns.push(colInfo); + } }); }); return entities; } - async GetIndexesFromEntity( + public async GetIndexesFromEntity( entities: EntityInfo[], schema: string ): Promise { - let response: { + const response: Array<{ COLUMN_NAME: string; TABLE_NAME: string; INDEX_NAME: string; UNIQUENESS: string; ISPRIMARYKEY: number; - }[] = (await this.Connection + }> = (await this.Connection .execute(`SELECT ind.TABLE_NAME, ind.INDEX_NAME, col.COLUMN_NAME,ind.UNIQUENESS, CASE WHEN uc.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARYKEY FROM USER_INDEXES ind JOIN USER_IND_COLUMNS col ON ind.INDEX_NAME=col.INDEX_NAME @@ -200,23 +204,23 @@ export class OracleDriver extends AbstractDriver { entities.forEach(ent => { response - .filter(filterVal => filterVal.TABLE_NAME == ent.EntityName) + .filter(filterVal => filterVal.TABLE_NAME === ent.EntityName) .forEach(resp => { - let indexInfo: IndexInfo = {}; - let indexColumnInfo: IndexColumnInfo = {}; + let indexInfo: IndexInfo = {} as IndexInfo; + const indexColumnInfo: IndexColumnInfo = {} as IndexColumnInfo; if ( ent.Indexes.filter( - filterVal => filterVal.name == resp.INDEX_NAME + filterVal => filterVal.name === resp.INDEX_NAME ).length > 0 ) { indexInfo = ent.Indexes.find( - filterVal => filterVal.name == resp.INDEX_NAME + filterVal => filterVal.name === resp.INDEX_NAME )!; } else { - indexInfo.columns = []; + indexInfo.columns = [] as IndexColumnInfo[]; indexInfo.name = resp.INDEX_NAME; - indexInfo.isUnique = resp.UNIQUENESS == "UNIQUE"; - indexInfo.isPrimaryKey = resp.ISPRIMARYKEY == 1; + indexInfo.isUnique = resp.UNIQUENESS === "UNIQUE"; + indexInfo.isPrimaryKey = resp.ISPRIMARYKEY === 1; ent.Indexes.push(indexInfo); } indexColumnInfo.name = resp.COLUMN_NAME; @@ -226,11 +230,11 @@ export class OracleDriver extends AbstractDriver { return entities; } - async GetRelations( + public async GetRelations( entities: EntityInfo[], schema: string ): Promise { - let response: { + const response: Array<{ OWNER_TABLE_NAME: string; OWNER_POSITION: string; OWNER_COLUMN_NAME: string; @@ -238,7 +242,7 @@ export class OracleDriver extends AbstractDriver { CHILD_COLUMN_NAME: string; DELETE_RULE: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"; CONSTRAINT_NAME: string; - }[] = (await this.Connection + }> = (await this.Connection .execute(`select owner.TABLE_NAME OWNER_TABLE_NAME,ownCol.POSITION OWNER_POSITION,ownCol.COLUMN_NAME OWNER_COLUMN_NAME, child.TABLE_NAME CHILD_TABLE_NAME ,childCol.COLUMN_NAME CHILD_COLUMN_NAME, owner.DELETE_RULE, @@ -250,17 +254,17 @@ export class OracleDriver extends AbstractDriver { ORDER BY OWNER_TABLE_NAME ASC, owner.CONSTRAINT_NAME ASC, OWNER_POSITION ASC`)) .rows!; - let relationsTemp: RelationTempInfo[] = []; + const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( - val => val.object_id == resp.CONSTRAINT_NAME + val => val.object_id === resp.CONSTRAINT_NAME ); - if (rels == undefined) { - rels = {}; + if (rels === undefined) { + rels = {} as RelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = - resp.DELETE_RULE == "NO ACTION" ? null : resp.DELETE_RULE; + resp.DELETE_RULE === "NO ACTION" ? null : resp.DELETE_RULE; rels.actionOnUpdate = null; rels.object_id = resp.CONSTRAINT_NAME; rels.ownerTable = resp.OWNER_TABLE_NAME; @@ -276,12 +280,12 @@ export class OracleDriver extends AbstractDriver { ); return entities; } - async DisconnectFromServer() { - if (this.Connection) await this.Connection.close(); + public async DisconnectFromServer() { + if (this.Connection) { + await this.Connection.close(); + } } - - private Connection: any /*Oracle.IConnection*/; - async ConnectToServer( + public async ConnectToServer( database: string, server: string, port: number, @@ -290,24 +294,24 @@ export class OracleDriver extends AbstractDriver { ssl: boolean ) { let config: any; - if (user == String(process.env.ORACLE_UsernameSys)) { + if (user === String(process.env.ORACLE_UsernameSys)) { config /*Oracle.IConnectionAttributes*/ = { - user: user, - password: password, + user, + password, connectString: `${server}:${port}/${database}`, externalAuth: ssl, privilege: this.Oracle.SYSDBA }; } else { config /*Oracle.IConnectionAttributes*/ = { - user: user, - password: password, + user, + password, connectString: `${server}:${port}/${database}`, externalAuth: ssl }; } - let that = this; - let promise = new Promise((resolve, reject) => { + const that = this; + const promise = new Promise((resolve, reject) => { this.Oracle.getConnection(config, function(err, connection) { if (!err) { that.Connection = connection; @@ -326,7 +330,7 @@ export class OracleDriver extends AbstractDriver { await promise; } - async CreateDB(dbName: string) { + public async CreateDB(dbName: string) { await this.Connection.execute( `CREATE USER ${dbName} IDENTIFIED BY ${String( process.env.ORACLE_Password @@ -334,12 +338,12 @@ export class OracleDriver extends AbstractDriver { ); await this.Connection.execute(`GRANT CONNECT TO ${dbName}`); } - async UseDB(dbName: string) {} - async DropDB(dbName: string) { + public async UseDB(dbName: string) {} + public async DropDB(dbName: string) { await this.Connection.execute(`DROP USER ${dbName} CASCADE`); } - async CheckIfDBExists(dbName: string): Promise { - var x = await this.Connection.execute( + public async CheckIfDBExists(dbName: string): Promise { + const x = await this.Connection.execute( `select count(*) as CNT from dba_users where username='${dbName.toUpperCase()}'` ); return x.rows[0][0] > 0 || x.rows[0].CNT; diff --git a/src/drivers/PostgresDriver.ts b/src/drivers/PostgresDriver.ts index d91411d..4db71f6 100644 --- a/src/drivers/PostgresDriver.ts +++ b/src/drivers/PostgresDriver.ts @@ -8,7 +8,7 @@ export class PostgresDriver extends AbstractDriver { private Connection: PG.Client; GetAllTablesQuery = async (schema: string) => { - let response: { + const response: { TABLE_SCHEMA: string; TABLE_NAME: string; }[] = (await this.Connection.query( @@ -21,7 +21,7 @@ export class PostgresDriver extends AbstractDriver { entities: EntityInfo[], schema: string ): Promise { - let response: { + const response: { table_name: string; column_name: string; udt_name: string; @@ -62,7 +62,7 @@ export class PostgresDriver extends AbstractDriver { ? null : resp.column_default; - var columnTypes = this.MatchColumnTypes( + const columnTypes = this.MatchColumnTypes( resp.data_type, resp.udt_name ); @@ -338,7 +338,10 @@ export class PostgresDriver extends AbstractDriver { ret.ts_type = "string"; break; case "ARRAY": - let z = this.MatchColumnTypes(udt_name.substring(1), udt_name); + const z = this.MatchColumnTypes( + udt_name.substring(1), + udt_name + ); ret.ts_type = z.ts_type; ret.sql_type = z.sql_type; ret.is_array = true; @@ -368,7 +371,7 @@ export class PostgresDriver extends AbstractDriver { entities: EntityInfo[], schema: string ): Promise { - let response: { + const response: { tablename: string; indexname: string; columnname: string; @@ -433,7 +436,7 @@ export class PostgresDriver extends AbstractDriver { entities: EntityInfo[], schema: string ): Promise { - let response: { + const response: { tablewithforeignkey: string; fk_partno: number; foreignkeycolumn: string; @@ -509,7 +512,7 @@ export class PostgresDriver extends AbstractDriver { } async DisconnectFromServer() { if (this.Connection) { - let promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { this.Connection.end(err => { if (!err) { resolve(true); @@ -544,7 +547,7 @@ export class PostgresDriver extends AbstractDriver { ssl: ssl }); - let promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { this.Connection.connect(err => { if (!err) { resolve(true); @@ -572,7 +575,7 @@ export class PostgresDriver extends AbstractDriver { await this.Connection.query(`DROP DATABASE ${dbName}; `); } async CheckIfDBExists(dbName: string): Promise { - let resp = await this.Connection.query( + const resp = await this.Connection.query( `SELECT datname FROM pg_database WHERE datname ='${dbName}' ` ); return resp.rowCount > 0; diff --git a/src/drivers/SqliteDriver.ts b/src/drivers/SqliteDriver.ts index f9ac79d..ec64f3d 100644 --- a/src/drivers/SqliteDriver.ts +++ b/src/drivers/SqliteDriver.ts @@ -1,24 +1,24 @@ -import { AbstractDriver } from "./AbstractDriver"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; +import { AbstractDriver } from "./AbstractDriver"; export class SqliteDriver extends AbstractDriver { - sqlite = require("sqlite3").verbose(); - db: any; - tablesWithGeneratedPrimaryKey: String[] = new Array(); - GetAllTablesQuery: any; + public sqlite = require("sqlite3").verbose(); + public db: any; + public tablesWithGeneratedPrimaryKey: String[] = new Array(); + public GetAllTablesQuery: any; - async GetAllTables(schema: string): Promise { - let ret: EntityInfo[] = []; - let rows = await this.ExecQuery<{ tbl_name: string; sql: string }>( + public async GetAllTables(schema: string): Promise { + const ret: EntityInfo[] = [] as EntityInfo[]; + const rows = await this.ExecQuery<{ tbl_name: string; sql: string }>( `SELECT tbl_name, sql FROM "sqlite_master" WHERE "type" = 'table' AND name NOT LIKE 'sqlite_%'` ); rows.forEach(val => { - let ent: EntityInfo = new EntityInfo(); + const ent: EntityInfo = new EntityInfo(); ent.EntityName = val.tbl_name; - ent.Columns = []; - ent.Indexes = []; + ent.Columns = [] as ColumnInfo[]; + ent.Indexes = [] as IndexInfo[]; if (val.sql.includes("AUTOINCREMENT")) { this.tablesWithGeneratedPrimaryKey.push(ent.EntityName); } @@ -26,12 +26,12 @@ export class SqliteDriver extends AbstractDriver { }); return ret; } - async GetCoulmnsFromEntity( + public async GetCoulmnsFromEntity( entities: EntityInfo[], schema: string ): Promise { for (const ent of entities) { - let response = await this.ExecQuery<{ + const response = await this.ExecQuery<{ cid: number; name: string; type: string; @@ -40,7 +40,7 @@ export class SqliteDriver extends AbstractDriver { pk: number; }>(`PRAGMA table_info('${ent.EntityName}');`); response.forEach(resp => { - let colInfo: ColumnInfo = new ColumnInfo(); + const colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.name; colInfo.sqlName = resp.name; colInfo.is_nullable = resp.notnull == 0; @@ -146,19 +146,19 @@ export class SqliteDriver extends AbstractDriver { ); break; } - let options = resp.type.match(/\([0-9 ,]+\)/g); + const options = resp.type.match(/\([0-9 ,]+\)/g); if ( this.ColumnTypesWithPrecision.some( v => v == colInfo.sql_type ) && options ) { - colInfo.numericPrecision = options[0] + colInfo.numericPrecision = options[0] .substring(1, options[0].length - 1) - .split(",")[0]; - colInfo.numericScale = options[0] + .split(",")[0] as any; + colInfo.numericScale = options[0] .substring(1, options[0].length - 1) - .split(",")[1]; + .split(",")[1] as any; } if ( this.ColumnTypesWithLength.some( @@ -166,10 +166,10 @@ export class SqliteDriver extends AbstractDriver { ) && options ) { - colInfo.lenght = options[0].substring( + colInfo.lenght = options[0].substring( 1, options[0].length - 1 - ); + ) as any; } if ( this.ColumnTypesWithWidth.some( @@ -179,24 +179,26 @@ export class SqliteDriver extends AbstractDriver { ) && options ) { - colInfo.width = options[0].substring( + colInfo.width = options[0].substring( 1, options[0].length - 1 - ); + ) as any; } - if (colInfo.sql_type) ent.Columns.push(colInfo); + if (colInfo.sql_type) { + ent.Columns.push(colInfo); + } }); } return entities; } - async GetIndexesFromEntity( + public async GetIndexesFromEntity( entities: EntityInfo[], schema: string ): Promise { for (const ent of entities) { - let response = await this.ExecQuery<{ + const response = await this.ExecQuery<{ seq: number; name: string; unique: number; @@ -204,14 +206,14 @@ export class SqliteDriver extends AbstractDriver { partial: number; }>(`PRAGMA index_list('${ent.EntityName}');`); for (const resp of response) { - let indexColumnsResponse = await this.ExecQuery<{ + const indexColumnsResponse = await this.ExecQuery<{ seqno: number; cid: number; name: string; }>(`PRAGMA index_info('${resp.name}');`); indexColumnsResponse.forEach(element => { - let indexInfo: IndexInfo = {}; - let indexColumnInfo: IndexColumnInfo = {}; + let indexInfo: IndexInfo = {} as IndexInfo; + const indexColumnInfo: IndexColumnInfo = {} as IndexColumnInfo; if ( ent.Indexes.filter(filterVal => { return filterVal.name == resp.name; @@ -221,7 +223,7 @@ export class SqliteDriver extends AbstractDriver { filterVal => filterVal.name == resp.name )!; } else { - indexInfo.columns = []; + indexInfo.columns = [] as IndexColumnInfo[]; indexInfo.name = resp.name; indexInfo.isUnique = resp.unique == 1; ent.Indexes.push(indexInfo); @@ -242,12 +244,12 @@ export class SqliteDriver extends AbstractDriver { return entities; } - async GetRelations( + public async GetRelations( entities: EntityInfo[], schema: string ): Promise { for (const entity of entities) { - let response = await this.ExecQuery<{ + const response = await this.ExecQuery<{ id: number; seq: number; table: string; @@ -257,9 +259,9 @@ export class SqliteDriver extends AbstractDriver { on_delete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"; match: string; }>(`PRAGMA foreign_key_list('${entity.EntityName}');`); - let relationsTemp: RelationTempInfo[] = []; + const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[]; response.forEach(resp => { - let rels = {}; + const rels = {} as RelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = @@ -279,11 +281,11 @@ export class SqliteDriver extends AbstractDriver { } return entities; } - async DisconnectFromServer() { + public async DisconnectFromServer() { this.db.close(); } - async ConnectToServer( + public async ConnectToServer( database: string, server: string, port: number, @@ -294,9 +296,9 @@ export class SqliteDriver extends AbstractDriver { await this.UseDB(database); } - async CreateDB(dbName: string) {} - async UseDB(dbName: string) { - let promise = new Promise((resolve, reject) => { + public async CreateDB(dbName: string) {} + public async UseDB(dbName: string) { + const promise = new Promise((resolve, reject) => { this.db = new this.sqlite.Database(dbName, err => { if (err) { console.error(err.message); @@ -308,14 +310,14 @@ export class SqliteDriver extends AbstractDriver { }); return promise; } - async DropDB(dbName: string) {} - async CheckIfDBExists(dbName: string): Promise { + public async DropDB(dbName: string) {} + public async CheckIfDBExists(dbName: string): Promise { return true; } - async ExecQuery(sql: string): Promise> { + public async ExecQuery(sql: string): Promise { let ret: any; - let promise = new Promise((resolve, reject) => { + const promise = new Promise((resolve, reject) => { this.db.serialize(() => { this.db.all(sql, [], function(err, row) { if (!err) { diff --git a/src/index.ts b/src/index.ts index fcdb6f1..a4a2a4e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,18 +1,18 @@ +import path = require("path"); +import * as Yargs from "yargs"; +import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; import { AbstractDriver } from "./drivers/AbstractDriver"; +import { MariaDbDriver } from "./drivers/MariaDbDriver"; import { MssqlDriver } from "./drivers/MssqlDriver"; +import { MysqlDriver } from "./drivers/MysqlDriver"; +import { OracleDriver } from "./drivers/OracleDriver"; import { PostgresDriver } from "./drivers/PostgresDriver"; import { SqliteDriver } from "./drivers/SqliteDriver"; -import { MysqlDriver } from "./drivers/MysqlDriver"; -import { MariaDbDriver } from "./drivers/MariaDbDriver"; -import { OracleDriver } from "./drivers/OracleDriver"; import { Engine } from "./Engine"; -import * as Yargs from "yargs"; -import * as TomgUtils from "./Utils"; -import path = require("path"); -import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; import { NamingStrategy } from "./NamingStrategy"; +import * as TomgUtils from "./Utils"; -var argv = Yargs.usage( +const argv = Yargs.usage( "Usage: typeorm-model-generator -h -d -p [port] -u -x [password] -e [engine]" ) .option("h", { @@ -148,13 +148,13 @@ switch (argv.e) { } let namingStrategy: AbstractNamingStrategy; if (argv.namingStrategy && argv.namingStrategy != "") { - let req = require(argv.namingStrategy); + const req = require(argv.namingStrategy); namingStrategy = new req.NamingStrategy(); } else { namingStrategy = new NamingStrategy(); } -let engine = new Engine(driver, { +const engine = new Engine(driver, { host: argv.h, port: parseInt(argv.p) || standardPort, databaseName: argv.d ? argv.d.toString() : null, @@ -172,7 +172,7 @@ let engine = new Engine(driver, { lazy: argv.lazy, constructor: argv.generateConstructor, relationIds: argv.relationIds, - namingStrategy: namingStrategy + namingStrategy }); console.log(TomgUtils.packageVersion()); diff --git a/src/models/ColumnInfo.ts b/src/models/ColumnInfo.ts index 056c2f7..44964bb 100644 --- a/src/models/ColumnInfo.ts +++ b/src/models/ColumnInfo.ts @@ -1,12 +1,12 @@ import { RelationInfo } from "./RelationInfo"; export class ColumnInfo { - tsName: string = ""; - sqlName: string = ""; - default: string | null = null; - is_nullable: boolean = false; - is_unique: boolean = false; - ts_type: + public tsName: string = ""; + public sqlName: string = ""; + public default: string | null = null; + public is_nullable: boolean = false; + public is_unique: boolean = false; + public ts_type: | "number" | "string" | "boolean" @@ -16,16 +16,16 @@ export class ColumnInfo { | "string | Object" | "string | string[]" | "any"; - sql_type: string; - lenght: number | null = null; - width: number | null = null; - isPrimary: boolean = false; - is_generated: boolean = false; - is_array: boolean = false; - numericPrecision: number | null = null; - numericScale: number | null = null; - enumOptions: string | null = null; - relations: RelationInfo[]; + public sql_type: string; + public lenght: number | null = null; + public width: number | null = null; + public isPrimary: boolean = false; + public is_generated: boolean = false; + public is_array: boolean = false; + public numericPrecision: number | null = null; + public numericScale: number | null = null; + public enumOptions: string | null = null; + public relations: RelationInfo[]; constructor() { this.relations = []; } diff --git a/src/models/DatabaseModel.ts b/src/models/DatabaseModel.ts index 27c6b7b..8dd6410 100644 --- a/src/models/DatabaseModel.ts +++ b/src/models/DatabaseModel.ts @@ -1,4 +1,4 @@ import { EntityInfo } from "./EntityInfo"; export class DatabaseModel { - entities: EntityInfo[]; + public entities: EntityInfo[]; } diff --git a/src/models/EntityInfo.ts b/src/models/EntityInfo.ts index ecae01c..286d107 100644 --- a/src/models/EntityInfo.ts +++ b/src/models/EntityInfo.ts @@ -1,20 +1,21 @@ import { ColumnInfo } from "./ColumnInfo"; export class EntityInfo { - EntityName: string; - Columns: ColumnInfo[]; - Imports: string[]; - UniqueImports: string[]; - Indexes: IndexInfo[]; - Schema: string; - GenerateConstructor: boolean; + public EntityName: string; + public Columns: ColumnInfo[]; + public Imports: string[]; + public UniqueImports: string[]; + public Indexes: IndexInfo[]; + public Schema: string; + public GenerateConstructor: boolean; - relationImports() { - var imports: string[] = []; + public relationImports() { + const imports: string[] = []; this.Columns.forEach(column => { column.relations.forEach(relation => { - if (this.EntityName != relation.relatedTable) + if (this.EntityName != relation.relatedTable) { imports.push(relation.relatedTable); + } }); }); this.UniqueImports = imports.filter( diff --git a/src/models/RelationInfo.ts b/src/models/RelationInfo.ts index fb74a3f..5ec6336 100644 --- a/src/models/RelationInfo.ts +++ b/src/models/RelationInfo.ts @@ -1,19 +1,24 @@ export class RelationInfo { - isOwner: boolean; - relationType: "OneToOne" | "OneToMany" | "ManyToOne" | "ManyToMany"; - relatedTable: string; - relatedColumn: string; - ownerTable: string; - ownerColumn: string; - actionOnDelete: + public isOwner: boolean; + public relationType: "OneToOne" | "OneToMany" | "ManyToOne" | "ManyToMany"; + public relatedTable: string; + public relatedColumn: string; + public ownerTable: string; + public ownerColumn: string; + public actionOnDelete: | "RESTRICT" | "CASCADE" | "SET NULL" | "DEFAULT" | "NO ACTION" | null; - actionOnUpdate: "RESTRICT" | "CASCADE" | "SET NULL" | "DEFAULT" | null; - relationIdField: boolean = false; + public actionOnUpdate: + | "RESTRICT" + | "CASCADE" + | "SET NULL" + | "DEFAULT" + | null; + public relationIdField: boolean = false; get isOneToMany(): boolean { return this.relationType == "OneToMany"; diff --git a/src/tslint.json b/src/tslint.json new file mode 100644 index 0000000..b48b355 --- /dev/null +++ b/src/tslint.json @@ -0,0 +1,9 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended", "tslint-config-prettier" + ], + "jsRules": {}, + "rules": {}, + "rulesDirectory": [] +} diff --git a/test/drivers/MssqlDriver.test.ts b/test/drivers/MssqlDriver.test.ts index 5cf0fa3..20bd41b 100644 --- a/test/drivers/MssqlDriver.test.ts +++ b/test/drivers/MssqlDriver.test.ts @@ -1,30 +1,30 @@ import { expect } from "chai"; -import { MssqlDriver } from '../../src/drivers/MssqlDriver' -import * as Sinon from 'sinon' import * as MSSQL from 'mssql' -import { EntityInfo } from '../../src/models/EntityInfo' +import { IColumnMetadata, Table } from "mssql"; +import * as Sinon from 'sinon' +import { MssqlDriver } from '../../src/drivers/MssqlDriver' import { ColumnInfo } from '../../src/models/ColumnInfo' +import { EntityInfo } from '../../src/models/EntityInfo' import { RelationInfo } from '../../src/models/RelationInfo' -import { Table, IColumnMetadata } from "mssql"; import { NamingStrategy } from "../../src/NamingStrategy"; class fakeResponse implements MSSQL.IResult { - recordsets: MSSQL.IRecordSet[]; - recordset: MSSQL.IRecordSet; - rowsAffected: number[]; - output: { [key: string]: any; }; + public recordsets: Array>; + public recordset: MSSQL.IRecordSet; + public rowsAffected: number[]; + public output: { [key: string]: any; }; } class fakeRecordset extends Array implements MSSQL.IRecordSet{ - columns: IColumnMetadata; - toTable(): Table { + public columns: IColumnMetadata; + public toTable(): Table { return new Table(); } } describe('MssqlDriver', function () { let driver: MssqlDriver - let sandbox = Sinon.sandbox.create() + const sandbox = Sinon.sandbox.create() beforeEach(() => { driver = new MssqlDriver(); @@ -40,19 +40,19 @@ describe('MssqlDriver', function () { .returns( { query: (q) => { - let response = new fakeResponse(); + const response = new fakeResponse(); response.recordset = new fakeRecordset(); response.recordset.push({ TABLE_SCHEMA: 'schema', TABLE_NAME: 'name' }) return response; } }) - let result = await driver.GetAllTables('schema') - let expectedResult = []; - let y = new EntityInfo(); + const result = await driver.GetAllTables('schema') + const expectedResult = [] as EntityInfo[]; + const y = new EntityInfo(); y.EntityName = 'name' y.Schema='schema' - y.Columns = []; - y.Indexes = []; + y.Columns = [] as ColumnInfo[]; + y.Indexes = [] as IndexInfo[]; expectedResult.push(y) expect(result).to.be.deep.equal(expectedResult) }) @@ -61,7 +61,7 @@ describe('MssqlDriver', function () { .returns( { query: (q) => { - let response = new fakeResponse(); + const response = new fakeResponse(); response.recordset = new fakeRecordset(); response.recordset.push({ TABLE_NAME: 'name', CHARACTER_MAXIMUM_LENGTH: 0, @@ -73,13 +73,13 @@ describe('MssqlDriver', function () { } }) - let entities = []; - let y = new EntityInfo(); + const entities = [] as EntityInfo[]; + const y = new EntityInfo(); y.EntityName = 'name' - y.Columns = []; - y.Indexes = []; + y.Columns = [] as ColumnInfo[]; + y.Indexes = [] as IndexInfo[]; entities.push(y) - var expected: EntityInfo[] = JSON.parse(JSON.stringify(entities)); + const expected: EntityInfo[] = JSON.parse(JSON.stringify(entities)); expected[0].Columns.push({ lenght: null, default: 'a', @@ -96,9 +96,9 @@ describe('MssqlDriver', function () { enumOptions: null, is_unique:false, is_array:false, - relations: [], + relations: [] as RelationInfo[], }) - let result = await driver.GetCoulmnsFromEntity(entities, 'schema'); + const result = await driver.GetCoulmnsFromEntity(entities, 'schema'); expect(result).to.be.deep.equal(expected) }) it('should find primary indexes') diff --git a/test/integration/entityTypes.test.ts b/test/integration/entityTypes.test.ts index e95fabc..aa3fc63 100644 --- a/test/integration/entityTypes.test.ts +++ b/test/integration/entityTypes.test.ts @@ -1,41 +1,41 @@ require('dotenv').config() -import "reflect-metadata"; +import { expect } from "chai"; import fs = require('fs-extra'); import path = require('path') -import { expect } from "chai"; +import "reflect-metadata"; import { EntityFileToJson } from "../utils/EntityFileToJson"; -var chai = require('chai'); -var chaiSubset = require('chai-subset'); +const chai = require('chai'); +const chaiSubset = require('chai-subset'); import * as ts from "typescript"; -import * as GTU from "../utils/GeneralTestUtils" import { Engine } from "../../src/Engine"; +import * as GTU from "../utils/GeneralTestUtils" chai.use(chaiSubset); describe("Platform specyfic types", async function () { this.timeout(30000) - this.slow(5000)//compiling created models takes time + this.slow(5000)// compiling created models takes time - let dbDrivers: string[] = [] - if (process.env.SQLITE_Skip == '0') dbDrivers.push('sqlite') - if (process.env.POSTGRES_Skip == '0') dbDrivers.push('postgres') - if (process.env.MYSQL_Skip == '0') dbDrivers.push('mysql') - if (process.env.MARIADB_Skip == '0') dbDrivers.push('mariadb') - if (process.env.MSSQL_Skip == '0') dbDrivers.push('mssql') - if (process.env.ORACLE_Skip == '0') dbDrivers.push('oracle') + const dbDrivers: string[] = [] + if (process.env.SQLITE_Skip == '0') { dbDrivers.push('sqlite') } + if (process.env.POSTGRES_Skip == '0') { dbDrivers.push('postgres') } + if (process.env.MYSQL_Skip == '0') { dbDrivers.push('mysql') } + if (process.env.MARIADB_Skip == '0') { dbDrivers.push('mariadb') } + if (process.env.MSSQL_Skip == '0') { dbDrivers.push('mssql') } + if (process.env.ORACLE_Skip == '0') { dbDrivers.push('oracle') } - let examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/entityTypes') - let examplesPathTS = path.resolve(process.cwd(), 'test/integration/entityTypes') - let files = fs.readdirSync(examplesPathTS) + const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/entityTypes') + const examplesPathTS = path.resolve(process.cwd(), 'test/integration/entityTypes') + const files = fs.readdirSync(examplesPathTS) - for (let dbDriver of dbDrivers) { - for (let folder of files) { + for (const dbDriver of dbDrivers) { + for (const folder of files) { if (dbDriver == folder) { it(dbDriver, async function () { - let filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity') - let filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity') - let resultsPath = path.resolve(process.cwd(), `output`) + const filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity') + const filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity') + const resultsPath = path.resolve(process.cwd(), `output`) fs.removeSync(resultsPath) let engine: Engine; @@ -60,27 +60,27 @@ describe("Platform specyfic types", async function () { break; default: console.log(`Unknown engine type`); - engine = {} + engine = {} as Engine break; } await engine.createModelFromDatabase() - let filesGenPath = path.resolve(resultsPath, 'entities') + const filesGenPath = path.resolve(resultsPath, 'entities') - let filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) - let filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) + const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) + const filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen) - for (let file of filesOrg) { - let entftj = new EntityFileToJson(); - let jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file))) - let jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file))) + for (const file of filesOrg) { + const entftj = new EntityFileToJson(); + const jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file))) + const jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file))) expect(jsonEntityGen, `Error in file ${file}`).to.containSubset(jsonEntityOrg) } const currentDirectoryFiles = fs.readdirSync(filesGenPath). filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v)) - let compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { + const compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { experimentalDecorators: true, sourceMap: false, emitDecoratorMetadata: true, diff --git a/test/integration/githubIssues.test.ts b/test/integration/githubIssues.test.ts index 03099e5..1b33c4b 100644 --- a/test/integration/githubIssues.test.ts +++ b/test/integration/githubIssues.test.ts @@ -1,14 +1,14 @@ require('dotenv').config() -import "reflect-metadata"; -import { createConnection, ConnectionOptions, Connection } from "typeorm"; +import { expect } from "chai"; import fs = require('fs-extra'); import path = require('path') -import { Engine } from "../../src/Engine"; -import { expect } from "chai"; +import "reflect-metadata"; import * as Sinon from 'sinon' +import { Connection, ConnectionOptions, createConnection } from "typeorm"; +import { Engine } from "../../src/Engine"; import { EntityFileToJson } from "../utils/EntityFileToJson"; -var chai = require('chai'); -var chaiSubset = require('chai-subset'); +const chai = require('chai'); +const chaiSubset = require('chai-subset'); import * as ts from "typescript"; import * as GTU from "../utils/GeneralTestUtils" @@ -17,29 +17,30 @@ chai.use(chaiSubset); describe("GitHub issues", async function () { this.timeout(30000) - this.slow(5000)//compiling created models takes time + this.slow(5000)// compiling created models takes time - let dbDrivers: string[] = [] - if (process.env.SQLITE_Skip == '0') dbDrivers.push('sqlite') - if (process.env.POSTGRES_Skip == '0') dbDrivers.push('postgres') - if (process.env.MYSQL_Skip == '0') dbDrivers.push('mysql') - if (process.env.MARIADB_Skip == '0') dbDrivers.push('mariadb') - if (process.env.MSSQL_Skip == '0') dbDrivers.push('mssql') - if (process.env.ORACLE_Skip == '0') dbDrivers.push('oracle') + const dbDrivers: string[] = [] + if (process.env.SQLITE_Skip == '0') { dbDrivers.push('sqlite') } + if (process.env.POSTGRES_Skip == '0') { dbDrivers.push('postgres') } + if (process.env.MYSQL_Skip == '0') { dbDrivers.push('mysql') } + if (process.env.MARIADB_Skip == '0') { dbDrivers.push('mariadb') } + if (process.env.MSSQL_Skip == '0') { dbDrivers.push('mssql') } + if (process.env.ORACLE_Skip == '0') { dbDrivers.push('oracle') } - let examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/github-issues') - let examplesPathTS = path.resolve(process.cwd(), 'test/integration/github-issues') - let files = fs.readdirSync(examplesPathTS) + const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/github-issues') + const examplesPathTS = path.resolve(process.cwd(), 'test/integration/github-issues') + const files = fs.readdirSync(examplesPathTS) - for (let folder of files) { + for (const folder of files) { describe(`#${folder}`, async function () { - for (let dbDriver of dbDrivers) { + for (const dbDriver of dbDrivers) { switch (folder) { case '39': - if (dbDriver == 'mysql' || dbDriver == 'mariadb' || dbDriver == 'oracle' || dbDriver == 'sqlite') + if (dbDriver == 'mysql' || dbDriver == 'mariadb' || dbDriver == 'oracle' || dbDriver == 'sqlite') { continue; + } break; default: break; @@ -47,9 +48,9 @@ describe("GitHub issues", async function () { it(dbDriver, async function () { - let filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity') - let filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity') - let resultsPath = path.resolve(process.cwd(), `output`) + const filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity') + const filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity') + const resultsPath = path.resolve(process.cwd(), `output`) fs.removeSync(resultsPath) let engine: Engine; @@ -74,7 +75,7 @@ describe("GitHub issues", async function () { break; default: console.log(`Unknown engine type`); - engine = {} + engine = {} as Engine break; } @@ -87,22 +88,22 @@ describe("GitHub issues", async function () { } await engine.createModelFromDatabase() - let filesGenPath = path.resolve(resultsPath, 'entities') + const filesGenPath = path.resolve(resultsPath, 'entities') - let filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) - let filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) + const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) + const filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen) - for (let file of filesOrg) { - let entftj = new EntityFileToJson(); - let jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file))) - let jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file))) + for (const file of filesOrg) { + const entftj = new EntityFileToJson(); + const jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file))) + const jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file))) expect(jsonEntityGen, `Error in file ${file}`).to.containSubset(jsonEntityOrg) } const currentDirectoryFiles = fs.readdirSync(filesGenPath). filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v)) - let compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { + const compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { experimentalDecorators: true, sourceMap: false, emitDecoratorMetadata: true, diff --git a/test/integration/integration.test.ts b/test/integration/integration.test.ts index 5c11403..516d88c 100644 --- a/test/integration/integration.test.ts +++ b/test/integration/integration.test.ts @@ -1,12 +1,12 @@ require('dotenv').config() -import "reflect-metadata"; +import { expect } from "chai"; import fs = require('fs-extra'); import path = require('path') +import "reflect-metadata"; import { Engine } from "../../src/Engine"; -import { expect } from "chai"; import { EntityFileToJson } from "../utils/EntityFileToJson"; -var chai = require('chai'); -var chaiSubset = require('chai-subset'); +const chai = require('chai'); +const chaiSubset = require('chai-subset'); import * as ts from "typescript"; import * as GTU from "../utils/GeneralTestUtils" @@ -14,27 +14,27 @@ chai.use(chaiSubset); describe("TypeOrm examples", async function () { this.timeout(30000) - this.slow(5000)//compiling created models takes time + this.slow(5000)// compiling created models takes time - let dbDrivers: string[] = [] - if (process.env.SQLITE_Skip == '0') dbDrivers.push('sqlite') - if (process.env.POSTGRES_Skip == '0') dbDrivers.push('postgres') - if (process.env.MYSQL_Skip == '0') dbDrivers.push('mysql') - if (process.env.MARIADB_Skip == '0') dbDrivers.push('mariadb') - if (process.env.MSSQL_Skip == '0') dbDrivers.push('mssql') - if (process.env.ORACLE_Skip == '0') dbDrivers.push('oracle') + const dbDrivers: string[] = [] + if (process.env.SQLITE_Skip == '0') { dbDrivers.push('sqlite') } + if (process.env.POSTGRES_Skip == '0') { dbDrivers.push('postgres') } + if (process.env.MYSQL_Skip == '0') { dbDrivers.push('mysql') } + if (process.env.MARIADB_Skip == '0') { dbDrivers.push('mariadb') } + if (process.env.MSSQL_Skip == '0') { dbDrivers.push('mssql') } + if (process.env.ORACLE_Skip == '0') { dbDrivers.push('oracle') } - let examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/examples') - let examplesPathTS = path.resolve(process.cwd(), 'test/integration/examples') - let files = fs.readdirSync(examplesPathTS) + const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/examples') + const examplesPathTS = path.resolve(process.cwd(), 'test/integration/examples') + const files = fs.readdirSync(examplesPathTS) - for (let folder of files) { + for (const folder of files) { describe(folder, async function () { - for (let dbDriver of dbDrivers) { + for (const dbDriver of dbDrivers) { it(dbDriver, async function () { - let filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity') - let filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity') - let resultsPath = path.resolve(process.cwd(), `output`) + const filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity') + const filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity') + const resultsPath = path.resolve(process.cwd(), `output`) fs.removeSync(resultsPath) let engine: Engine; @@ -59,7 +59,7 @@ describe("TypeOrm examples", async function () { break; default: console.log(`Unknown engine type`); - engine = {} + engine = {} as Engine break; } if (folder == 'sample18-lazy-relations') { @@ -67,22 +67,22 @@ describe("TypeOrm examples", async function () { } await engine.createModelFromDatabase() - let filesGenPath = path.resolve(resultsPath, 'entities') + const filesGenPath = path.resolve(resultsPath, 'entities') - let filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) - let filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) + const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) + const filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen) - for (let file of filesOrg) { - let entftj = new EntityFileToJson(); - let jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file))) - let jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file))) + for (const file of filesOrg) { + const entftj = new EntityFileToJson(); + const jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file))) + const jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file))) expect(jsonEntityGen, `Error in file ${file}`).to.containSubset(jsonEntityOrg) } const currentDirectoryFiles = fs.readdirSync(filesGenPath). filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v)) - let compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { + const compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { experimentalDecorators: true, sourceMap: false, emitDecoratorMetadata: true, diff --git a/test/utils/EntityFileToJson.ts b/test/utils/EntityFileToJson.ts index 0a1ac1f..1a88308 100644 --- a/test/utils/EntityFileToJson.ts +++ b/test/utils/EntityFileToJson.ts @@ -1,7 +1,7 @@ export class EntityFileToJson { - getEntityOptions(trimmedLine: string, ent: EntityJson) { - let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) + public getEntityOptions(trimmedLine: string, ent: EntityJson) { + const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) if (decoratorParameters.length > 0) { if (decoratorParameters[0] != '"' || !decoratorParameters.endsWith('"')) { let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim() @@ -12,9 +12,9 @@ export class EntityFileToJson { } } } - getColumnOptionsAndType(trimmedLine: string, col: EntityColumn) { - let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) - let primaryGeneratedColumn = trimmedLine.substring(0, trimmedLine.indexOf('('))=='@PrimaryGeneratedColumn' + public getColumnOptionsAndType(trimmedLine: string, col: EntityColumn) { + const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) + const primaryGeneratedColumn = trimmedLine.substring(0, trimmedLine.indexOf('('))=='@PrimaryGeneratedColumn' if (decoratorParameters.length > 0) { if (decoratorParameters.search(',') > 0 && !primaryGeneratedColumn) { col.columnTypes = decoratorParameters.substring(0, decoratorParameters.indexOf(',')).trim().split('|'); @@ -37,10 +37,10 @@ export class EntityFileToJson { } } } - getRelationOptions(trimmedLine:string, col:EntityColumn){ - let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) + public getRelationOptions(trimmedLine:string, col:EntityColumn){ + const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) if (decoratorParameters.length > 0) { - let params = decoratorParameters.match(/(,)(?!([^{]*}))/g) + const params = decoratorParameters.match(/(,)(?!([^{]*}))/g) if ( params && params.length == 2) { let badJSON = decoratorParameters.substring( decoratorParameters.lastIndexOf('{'),decoratorParameters.lastIndexOf('}')+1).trim() if (badJSON.lastIndexOf(',') == badJSON.length - 3) { @@ -50,18 +50,18 @@ export class EntityFileToJson { } } } - getIndexOptions(trimmedLine: string, ind: EntityIndex) { - let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) + public getIndexOptions(trimmedLine: string, ind: EntityIndex) { + const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) if (decoratorParameters.length > 0) { - let containsTables = decoratorParameters.search('\\[') > -1 - let containsOptions = decoratorParameters.search('{') > -1 - let containsName = decoratorParameters.search('"') > -1 + const containsTables = decoratorParameters.search('\\[') > -1 + const containsOptions = decoratorParameters.search('{') > -1 + const containsName = decoratorParameters.search('"') > -1 if (containsName) { ind.indexName = decoratorParameters.slice(decoratorParameters.indexOf('"') + 1, decoratorParameters.substr(decoratorParameters.indexOf('"') + 1).indexOf('"')) } if (containsTables) { - let columnsStr = decoratorParameters.slice(decoratorParameters.indexOf('[') + 1, decoratorParameters.indexOf(']')) + const columnsStr = decoratorParameters.slice(decoratorParameters.indexOf('[') + 1, decoratorParameters.indexOf(']')) ind.columnNames.push(...columnsStr.split(',').map((val) => { let colName = '' if (val.search('\\.') > -1) { @@ -73,7 +73,7 @@ export class EntityFileToJson { }).filter(v => v.length > 0)) } if (containsOptions) { - let optionsStr = decoratorParameters.slice(decoratorParameters.indexOf('{') + 1, decoratorParameters.indexOf('}')) + const optionsStr = decoratorParameters.slice(decoratorParameters.indexOf('{') + 1, decoratorParameters.indexOf('}')) optionsStr.split(',').forEach((v) => { if (v.split(':').length - 1 > 0) { switch (optionsStr.split(':')[0].trim()) { @@ -91,23 +91,25 @@ export class EntityFileToJson { } } - convert(entityFile: Buffer): EntityJson { - let retVal = new EntityJson(); + public convert(entityFile: Buffer): EntityJson { + const retVal = new EntityJson(); let isInClassBody = false; let isMultilineStatement = false; let priorPartOfMultilineStatement = ''; - let lines = entityFile.toString().replace('\r', '').split('\n'); - for (let line of lines) { + const lines = entityFile.toString().replace('\r', '').split('\n'); + for (const line of lines) { let trimmedLine = line.trim(); if (trimmedLine.startsWith('//')) { continue; } - if (isMultilineStatement) + if (isMultilineStatement) { trimmedLine = priorPartOfMultilineStatement + ' ' + trimmedLine - if (trimmedLine.length == 0) + } + if (trimmedLine.length == 0) { continue; + } else if (!isInClassBody) { if (trimmedLine.startsWith('import')) { continue; @@ -131,7 +133,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let ind = new EntityIndex() + const ind = new EntityIndex() this.getIndexOptions(trimmedLine, ind) retVal.indicies.push(ind); continue; @@ -145,7 +147,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let col = new EntityColumn() + const col = new EntityColumn() this.getColumnOptionsAndType(trimmedLine, col) retVal.columns.push(col); continue; @@ -157,9 +159,9 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let col = new EntityColumn() + const col = new EntityColumn() this.getColumnOptionsAndType(trimmedLine, col) - col.columnOptions['primary'] = true + col.columnOptions.primary = true retVal.columns.push(col); continue; } @@ -170,7 +172,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let col = new EntityColumn() + const col = new EntityColumn() this.getColumnOptionsAndType(trimmedLine, col) retVal.columns.push(col); continue; @@ -182,10 +184,10 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let col = new EntityColumn() + const col = new EntityColumn() this.getColumnOptionsAndType(trimmedLine, col) - col.columnOptions['primary'] = true - col.columnOptions['generated'] = true + col.columnOptions.primary = true + col.columnOptions.generated = true retVal.columns.push(col); continue; } @@ -196,7 +198,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let column = new EntityColumn() + const column = new EntityColumn() retVal.columns.push(column) column.relationType = "ManyToOne" column.isOwnerOfRelation = true; @@ -209,7 +211,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let column = new EntityColumn() + const column = new EntityColumn() retVal.columns.push(column) column.relationType = "OneToMany" continue; @@ -221,7 +223,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let column = new EntityColumn() + const column = new EntityColumn() retVal.columns.push(column) column.relationType = "ManyToMany" continue; @@ -233,7 +235,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let column = new EntityColumn() + const column = new EntityColumn() retVal.columns.push(column) column.relationType = "OneToOne" this.getRelationOptions(trimmedLine,column); @@ -266,7 +268,7 @@ export class EntityFileToJson { continue; } else { isMultilineStatement = false; - let ind = new EntityIndex() + const ind = new EntityIndex() this.getIndexOptions(trimmedLine, ind) retVal.indicies.push(ind); continue; @@ -282,7 +284,7 @@ export class EntityFileToJson { } } else if (trimmedLine.split(':').length - 1 > 0) { retVal.columns[retVal.columns.length - 1].columnName = trimmedLine.split(':')[0].trim(); - //TODO:Should check if null only column is nullable? + // TODO:Should check if null only column is nullable? let colTypes=trimmedLine.split(':')[1].split(';')[0].trim(); if (colTypes.startsWith('Promise<')) { colTypes=colTypes.substring(8,colTypes.length-1) @@ -290,14 +292,15 @@ export class EntityFileToJson { } retVal.columns[retVal.columns.length - 1].columnTypes = colTypes.split('|').map(function (x) { if (x == 'any') { - x = 'string' //for json columns + x = 'string' // for json columns } x = x.trim(); return x; }); - if (!retVal.columns[retVal.columns.length - 1].columnTypes.some( (val) => val == "null" ? true : false)) + if (!retVal.columns[retVal.columns.length - 1].columnTypes.some( (val) => val == "null" ? true : false)) { retVal.columns[retVal.columns.length - 1].columnTypes.push('null') + } if (retVal.indicies.length > 0 && retVal.indicies[retVal.indicies.length - 1].columnNames.length == 0) { retVal.indicies[retVal.indicies.length - 1].columnNames.push(retVal.columns[retVal.columns.length - 1].columnName) } @@ -316,41 +319,43 @@ export class EntityFileToJson { } retVal.columns = retVal.columns.map(col => { - if (col.columnName.endsWith('Id')) + if (col.columnName.endsWith('Id')) { col.columnName = col.columnName.substr(0, col.columnName.length - 2) + } return col; }) retVal.indicies = retVal.indicies.map(ind => { ind.columnNames = ind.columnNames.map(colName => { - if (colName.endsWith('Id')) + if (colName.endsWith('Id')) { colName = colName.substr(0, colName.length - 2) + } return colName; }) return ind; }) return retVal; } - isPartOfMultilineStatement(statement: string) { - let matchStarting = statement.split('(').length+statement.split('{').length - let matchEnding = statement.split(')').length+statement.split('}').length + public isPartOfMultilineStatement(statement: string) { + const matchStarting = statement.split('(').length+statement.split('{').length + const matchEnding = statement.split(')').length+statement.split('}').length return !(matchStarting == matchEnding) } } class EntityJson { - entityName: string - entityOptions: any = {} - columns: EntityColumn[] = []; - indicies: EntityIndex[] = []; + public entityName: string + public entityOptions: any = {} + public columns: EntityColumn[] = [] as EntityColumn[]; + public indicies: EntityIndex[] = [] as EntityIndex[]; } class EntityColumn { - columnName: string - columnTypes: string[] = [] - columnOptions: any = {} - relationType: "OneToOne" | "OneToMany" | "ManyToOne" | "ManyToMany" | "None" = "None" - isOwnerOfRelation: boolean = false; + public columnName: string + public columnTypes: string[] = [] + public columnOptions: any = {} + public relationType: "OneToOne" | "OneToMany" | "ManyToOne" | "ManyToMany" | "None" = "None" + public isOwnerOfRelation: boolean = false; } class EntityIndex { - indexName: string - columnNames: string[] = [] - isUnique: boolean = false + public indexName: string + public columnNames: string[] = [] + public isUnique: boolean = false } diff --git a/test/utils/GeneralTestUtils.ts b/test/utils/GeneralTestUtils.ts index f895b76..e3c3c47 100644 --- a/test/utils/GeneralTestUtils.ts +++ b/test/utils/GeneralTestUtils.ts @@ -1,16 +1,16 @@ +import path = require('path') +import { ConnectionOptions, createConnection } from "typeorm"; import * as ts from "typescript"; +import * as yn from "yn" +import { AbstractNamingStrategy } from "../../src/AbstractNamingStrategy"; import { AbstractDriver } from "../../src/drivers/AbstractDriver"; -import { MssqlDriver } from "../../src/drivers/MssqlDriver"; -import { PostgresDriver } from "../../src/drivers/PostgresDriver"; -import { MysqlDriver } from "../../src/drivers/MysqlDriver"; import { MariaDbDriver } from "../../src/drivers/MariaDbDriver"; +import { MssqlDriver } from "../../src/drivers/MssqlDriver"; +import { MysqlDriver } from "../../src/drivers/MysqlDriver"; import { OracleDriver } from "../../src/drivers/OracleDriver"; +import { PostgresDriver } from "../../src/drivers/PostgresDriver"; import { SqliteDriver } from "../../src/drivers/SqliteDriver"; 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"; export async function createMSSQLModels(filesOrgPath: string, resultsPath: string): Promise { @@ -19,12 +19,13 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin driver = new MssqlDriver(); await driver.ConnectToServer(`master`, String(process.env.MSSQL_Host), Number(process.env.MSSQL_Port), String(process.env.MSSQL_Username), String(process.env.MSSQL_Password), yn(process.env.MSSQL_SSL)); - if (await driver.CheckIfDBExists(String(process.env.MSSQL_Database))) + if (await driver.CheckIfDBExists(String(process.env.MSSQL_Database))) { await driver.DropDB(String(process.env.MSSQL_Database)); + } await driver.CreateDB(String(process.env.MSSQL_Database)); await driver.DisconnectFromServer(); - let connOpt: ConnectionOptions = { + const connOpt: ConnectionOptions = { database: String(process.env.MSSQL_Database), host: String(process.env.MSSQL_Host), password: String(process.env.MSSQL_Password), @@ -36,7 +37,7 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin entities: [path.resolve(filesOrgPath, '*.js')], } - let schemas = 'dbo,sch1,sch2' + const schemas = 'dbo,sch1,sch2' let conn = await createConnection(connOpt) let queryRunner = conn.createQueryRunner() for (const sch of schemas.split(',')) { @@ -44,13 +45,14 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin } await conn.synchronize(); - if (conn.isConnected) + if (conn.isConnected) { await conn.close() + } - let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + const namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new MssqlDriver(); - let engine = new Engine( + const engine = new Engine( driver, { host: String(process.env.MSSQL_Host), port: Number(process.env.MSSQL_Port), @@ -58,7 +60,7 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin user: String(process.env.MSSQL_Username), password: String(process.env.MSSQL_Password), databaseType: 'mssql', - resultsPath: resultsPath, + resultsPath, schemaName: 'dbo,sch1,sch2', ssl: yn(process.env.MSSQL_SSL), noConfigs: false, @@ -68,7 +70,7 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin propertyVisibility: 'none', lazy: false, constructor: false, - namingStrategy: namingStrategy, + namingStrategy, relationIds: false }); @@ -78,8 +80,9 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin await queryRunner.createSchema(sch, true); } await conn.synchronize(); - if (conn.isConnected) + if (conn.isConnected) { await conn.close() + } return engine; } @@ -89,12 +92,13 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st driver = new PostgresDriver(); await driver.ConnectToServer(`postgres`, String(process.env.POSTGRES_Host), Number(process.env.POSTGRES_Port), String(process.env.POSTGRES_Username), String(process.env.POSTGRES_Password), yn(process.env.POSTGRES_SSL)); - if (await driver.CheckIfDBExists(String(process.env.POSTGRES_Database))) + if (await driver.CheckIfDBExists(String(process.env.POSTGRES_Database))) { await driver.DropDB(String(process.env.POSTGRES_Database)); + } await driver.CreateDB(String(process.env.POSTGRES_Database)); await driver.DisconnectFromServer(); - let connOpt: ConnectionOptions = { + const connOpt: ConnectionOptions = { database: String(process.env.POSTGRES_Database), host: String(process.env.POSTGRES_Host), password: String(process.env.POSTGRES_Password), @@ -106,7 +110,7 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st entities: [path.resolve(filesOrgPath, '*.js')], } - let schemas = 'public,sch1,sch2' + const schemas = 'public,sch1,sch2' let conn = await createConnection(connOpt) let queryRunner = conn.createQueryRunner() for (const sch of schemas.split(',')) { @@ -114,12 +118,13 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st } await conn.synchronize(); - if (conn.isConnected) + if (conn.isConnected) { await conn.close() - let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + } + const namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new PostgresDriver(); - let engine = new Engine( + const engine = new Engine( driver, { host: String(process.env.POSTGRES_Host), port: Number(process.env.POSTGRES_Port), @@ -127,7 +132,7 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st user: String(process.env.POSTGRES_Username), password: String(process.env.POSTGRES_Password), databaseType: 'postgres', - resultsPath: resultsPath, + resultsPath, schemaName: 'public,sch1,sch2', ssl: yn(process.env.POSTGRES_SSL), noConfigs: false, @@ -137,7 +142,7 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st propertyVisibility: 'none', lazy: false, constructor: false, - namingStrategy: namingStrategy, + namingStrategy, relationIds: false }); @@ -147,8 +152,9 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st await queryRunner.createSchema(sch, true); } await conn.synchronize(); - if (conn.isConnected) + if (conn.isConnected) { await conn.close() + } return engine; } @@ -158,12 +164,13 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri driver = new SqliteDriver(); await driver.ConnectToServer(String(process.env.SQLITE_Database), '', 0, '', '', false); - if (await driver.CheckIfDBExists(String(process.env.SQLITE_Database))) + if (await driver.CheckIfDBExists(String(process.env.SQLITE_Database))) { await driver.DropDB(String(process.env.SQLITE_Database)); + } await driver.CreateDB(String(process.env.SQLITE_Database)); await driver.DisconnectFromServer(); - let connOpt: ConnectionOptions = { + const connOpt: ConnectionOptions = { database: String(process.env.SQLITE_Database), type: 'sqlite', dropSchema: true, @@ -175,12 +182,13 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri let queryRunner = conn.createQueryRunner() await conn.synchronize(); - if (conn.isConnected) + if (conn.isConnected) { await conn.close() - let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + } + const namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new SqliteDriver(); - let engine = new Engine( + const engine = new Engine( driver, { host: '', port: 0, @@ -188,7 +196,7 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri user: '', password: '', databaseType: 'sqlite', - resultsPath: resultsPath, + resultsPath, schemaName: '', ssl: false, noConfigs: false, @@ -198,15 +206,16 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri propertyVisibility: 'none', lazy: false, constructor: false, - namingStrategy: namingStrategy, + namingStrategy, relationIds: false }); conn = await createConnection(connOpt) queryRunner = conn.createQueryRunner() await conn.synchronize(); - if (conn.isConnected) + if (conn.isConnected) { await conn.close() + } return engine; } @@ -216,12 +225,13 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin driver = new MysqlDriver(); await driver.ConnectToServer(`mysql`, String(process.env.MYSQL_Host), Number(process.env.MYSQL_Port), String(process.env.MYSQL_Username), String(process.env.MYSQL_Password), yn(process.env.MYSQL_SSL)); - if (await driver.CheckIfDBExists(String(process.env.MYSQL_Database))) + if (await driver.CheckIfDBExists(String(process.env.MYSQL_Database))) { await driver.DropDB(String(process.env.MYSQL_Database)); + } await driver.CreateDB(String(process.env.MYSQL_Database)); await driver.DisconnectFromServer(); - let connOpt: ConnectionOptions = { + const connOpt: ConnectionOptions = { database: String(process.env.MYSQL_Database), host: String(process.env.MYSQL_Host), password: String(process.env.MYSQL_Password), @@ -232,14 +242,15 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin synchronize: true, entities: [path.resolve(filesOrgPath, '*.js')], } - let conn = await createConnection(connOpt) + const conn = await createConnection(connOpt) - if (conn.isConnected) + if (conn.isConnected) { await conn.close() - let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + } + const namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new MysqlDriver(); - let engine = new Engine( + const engine = new Engine( driver, { host: String(process.env.MYSQL_Host), port: Number(process.env.MYSQL_Port), @@ -247,7 +258,7 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin user: String(process.env.MYSQL_Username), password: String(process.env.MYSQL_Password), databaseType: 'mysql', - resultsPath: resultsPath, + resultsPath, schemaName: 'ignored', ssl: yn(process.env.MYSQL_SSL), noConfigs: false, @@ -257,7 +268,7 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin propertyVisibility: 'none', lazy: false, constructor: false, - namingStrategy: namingStrategy, + namingStrategy, relationIds: false }); @@ -268,12 +279,13 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str driver = new MariaDbDriver(); await driver.ConnectToServer(`mysql`, String(process.env.MARIADB_Host), Number(process.env.MARIADB_Port), String(process.env.MARIADB_Username), String(process.env.MARIADB_Password), yn(process.env.MARIADB_SSL)); - if (await driver.CheckIfDBExists(String(process.env.MARIADB_Database))) + if (await driver.CheckIfDBExists(String(process.env.MARIADB_Database))) { await driver.DropDB(String(process.env.MARIADB_Database)); + } await driver.CreateDB(String(process.env.MARIADB_Database)); await driver.DisconnectFromServer(); - let connOpt: ConnectionOptions = { + const connOpt: ConnectionOptions = { database: String(process.env.MARIADB_Database), host: String(process.env.MARIADB_Host), password: String(process.env.MARIADB_Password), @@ -284,14 +296,15 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str synchronize: true, entities: [path.resolve(filesOrgPath, '*.js')], } - let conn = await createConnection(connOpt) + const conn = await createConnection(connOpt) - if (conn.isConnected) + if (conn.isConnected) { await conn.close() - let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + } + const namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new MariaDbDriver(); - let engine = new Engine( + const engine = new Engine( driver, { host: String(process.env.MARIADB_Host), port: Number(process.env.MARIADB_Port), @@ -299,7 +312,7 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str user: String(process.env.MARIADB_Username), password: String(process.env.MARIADB_Password), databaseType: 'mariadb', - resultsPath: resultsPath, + resultsPath, schemaName: 'ignored', ssl: yn(process.env.MARIADB_SSL), noConfigs: false, @@ -309,7 +322,7 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str propertyVisibility: 'none', lazy: false, constructor: false, - namingStrategy: namingStrategy, + namingStrategy, relationIds: false }); @@ -323,12 +336,13 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st driver = new OracleDriver(); await driver.ConnectToServer(String(process.env.ORACLE_Database), String(process.env.ORACLE_Host), Number(process.env.ORACLE_Port), String(process.env.ORACLE_UsernameSys), String(process.env.ORACLE_PasswordSys), yn(process.env.ORACLE_SSL)); - if (await driver.CheckIfDBExists(String(process.env.ORACLE_Username))) + if (await driver.CheckIfDBExists(String(process.env.ORACLE_Username))) { await driver.DropDB(String(process.env.ORACLE_Username)); + } await driver.CreateDB(String(process.env.ORACLE_Username)); await driver.DisconnectFromServer(); - let connOpt: ConnectionOptions = { + const connOpt: ConnectionOptions = { database: String(process.env.ORACLE_Database), sid: String(process.env.ORACLE_Database), host: String(process.env.ORACLE_Host), @@ -339,14 +353,15 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st synchronize: true, entities: [path.resolve(filesOrgPath, '*.js')], } - let conn = await createConnection(connOpt) + const conn = await createConnection(connOpt) - if (conn.isConnected) + if (conn.isConnected) { await conn.close() - let namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + } + const namingStrategy: AbstractNamingStrategy = new NamingStrategy(); driver = new OracleDriver(); - let engine = new Engine( + const engine = new Engine( driver, { host: String(process.env.ORACLE_Host), port: Number(process.env.ORACLE_Port), @@ -354,7 +369,7 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st user: String(process.env.ORACLE_Username), password: String(process.env.ORACLE_Password), databaseType: 'oracle', - resultsPath: resultsPath, + resultsPath, schemaName: String(process.env.ORACLE_Username), ssl: yn(process.env.ORACLE_SSL), noConfigs: false, @@ -364,7 +379,7 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st propertyVisibility: 'none', lazy: false, constructor: false, - namingStrategy: namingStrategy, + namingStrategy, relationIds: false }); @@ -372,16 +387,16 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st } export function compileTsFiles(fileNames: string[], options: ts.CompilerOptions): boolean { - let program = ts.createProgram(fileNames, options); - let emitResult = program.emit(); + const program = ts.createProgram(fileNames, options); + const emitResult = program.emit(); let compileErrors = false; - let preDiagnostics = ts.getPreEmitDiagnostics(program); + const preDiagnostics = ts.getPreEmitDiagnostics(program); - let allDiagnostics = [...preDiagnostics, ...emitResult.diagnostics]; + const allDiagnostics = [...preDiagnostics, ...emitResult.diagnostics]; allDiagnostics.forEach(diagnostic => { - let lineAndCharacter = diagnostic.file!.getLineAndCharacterOfPosition(diagnostic.start!); - let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + const lineAndCharacter = diagnostic.file!.getLineAndCharacterOfPosition(diagnostic.start!); + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); console.log(`${diagnostic.file!.fileName} (${lineAndCharacter.line + 1},${lineAndCharacter.character + 1}): ${message}`); compileErrors = true; });