From 4d39b6c68c568e631b196f24be19adbeb5c7532c Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 24 Nov 2018 17:52:47 +0100 Subject: [PATCH 1/8] changing test coverage to remap also lcov report --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ebc14d..9737908 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "compile": "npm run clean && tsc", "precommit": "npm run prettier && git update-index --again", "test": "istanbul cover ./node_modules/mocha/bin/_mocha dist/test/**/*.test.js -- -R spec", - "posttest": "remap-istanbul -i ./coverage/coverage.json -o ./coverage/coverage-remapped.json && codecov --file=./coverage/coverage-remapped.json ", + "posttest": "remap-istanbul -i ./coverage/coverage.json -o ./coverage/lcov.info -t lcovonly && remap-istanbul -i ./coverage/coverage.json -o ./coverage/coverage.json && codecov --file=./coverage/coverage.json ", "clean": "rimraf dist coverage output", "prettier": "prettier --write ./src/*.ts ./src/**/*.ts", "prepack": "npm run compile" From b9f0ad54597bf04775df4372b9d625e7722d5633 Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 24 Nov 2018 18:21:34 +0100 Subject: [PATCH 2/8] adding npm cache to CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 732b4bd..55a040f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ node_js: - 10 - 8 - 6 +cache: npm sudo: required services: - docker From a9adc18b88ac460baf823ce9cc6dcc97b12c7d51 Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 24 Nov 2018 20:00:14 +0100 Subject: [PATCH 3/8] optimizing travis docker image download time --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 55a040f..a1bd34b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ before_install: - if [ -z "$DOCKER_USERNAME" ]; then echo "DOCKER_USERNAME is unset"; else echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin; fi - if [ -z "$DOCKER_USERNAME" ]; then mv docker-compose-without-login.yml docker-compose.yml; fi - if [ -z "$DOCKER_USERNAME" ]; then export ORACLE_Skip=1; fi +- docker-compose pull --parallel - docker-compose up -d - npm install -g npm@5 - npm install -g greenkeeper-lockfile@1 @@ -46,7 +47,6 @@ before_script: - npm link typescript - tsc - sleep 180 -- docker logs typeorm-mg-postgres after_script: - greenkeeper-lockfile-upload From 9b3be6a7a9c16644fb789f75e92a765818fe0915 Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 24 Nov 2018 20:36:10 +0100 Subject: [PATCH 4/8] fixing some errors while downloading docker images(retry) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a1bd34b..367ae48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ before_install: - if [ -z "$DOCKER_USERNAME" ]; then echo "DOCKER_USERNAME is unset"; else echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin; fi - if [ -z "$DOCKER_USERNAME" ]; then mv docker-compose-without-login.yml docker-compose.yml; fi - if [ -z "$DOCKER_USERNAME" ]; then export ORACLE_Skip=1; fi -- docker-compose pull --parallel +- docker-compose pull --parallel --ignore-pull-failures - docker-compose up -d - npm install -g npm@5 - npm install -g greenkeeper-lockfile@1 From 69a2362890084b25d3679976dada32cef8720c33 Mon Sep 17 00:00:00 2001 From: Kononnable Date: Thu, 6 Dec 2018 22:23:30 +0100 Subject: [PATCH 5/8] code cleanup --- src/Engine.ts | 40 ++---- src/NamingStrategy.ts | 9 +- src/Utils.ts | 1 - src/drivers/AbstractDriver.ts | 169 ++++++++++++-------------- src/drivers/MssqlDriver.ts | 12 +- src/drivers/MysqlDriver.ts | 26 ++-- src/drivers/OracleDriver.ts | 26 ++-- src/drivers/PostgresDriver.ts | 26 ++-- src/drivers/SqliteDriver.ts | 6 +- src/models/EntityInfo.ts | 8 +- test/integration/entityTypes.test.ts | 8 +- test/integration/githubIssues.test.ts | 8 +- test/integration/integration.test.ts | 8 +- test/utils/EntityFileToJson.ts | 26 ++-- 14 files changed, 150 insertions(+), 223 deletions(-) diff --git a/src/Engine.ts b/src/Engine.ts index fd80fda..cbd2727 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -112,9 +112,7 @@ export class Engine { }); } private createHandlebarsHelpers() { - Handlebars.registerHelper("curly", open => { - return open ? "{" : "}"; - }); + Handlebars.registerHelper("curly", open => (open ? "{" : "}")); Handlebars.registerHelper("toEntityName", str => { let retStr = ""; switch (this.Options.convertCaseEntity) { @@ -173,38 +171,20 @@ export class Engine { } return retStr; }); - Handlebars.registerHelper("toLowerCase", str => { - return str.toLowerCase(); - }); + Handlebars.registerHelper("toLowerCase", str => str.toLowerCase()); Handlebars.registerHelper("toLazy", str => { if (this.Options.lazy) return `Promise<${str}>`; else return str; }); Handlebars.registerHelper({ - eq: function(v1, v2) { - return v1 === v2; - }, - ne: function(v1, v2) { - return v1 !== v2; - }, - lt: function(v1, v2) { - return v1 < v2; - }, - gt: function(v1, v2) { - return v1 > v2; - }, - lte: function(v1, v2) { - return v1 <= v2; - }, - gte: function(v1, v2) { - return v1 >= v2; - }, - and: function(v1, v2) { - return v1 && v2; - }, - or: function(v1, v2) { - return v1 || v2; - } + eq: (v1, v2) => v1 === v2, + ne: (v1, v2) => v1 !== v2, + lt: (v1, v2) => v1 < v2, + gt: (v1, v2) => v1 > v2, + lte: (v1, v2) => v1 <= v2, + gte: (v1, v2) => v1 >= v2, + and: (v1, v2) => v1 && v2, + or: (v1, v2) => v1 || v2 }); } diff --git a/src/NamingStrategy.ts b/src/NamingStrategy.ts index 1cad9cb..33882ec 100644 --- a/src/NamingStrategy.ts +++ b/src/NamingStrategy.ts @@ -9,12 +9,9 @@ export class NamingStrategy extends AbstractNamingStrategy { dbModel: DatabaseModel ): string { let isRelationToMany = relation.isOneToMany || relation.isManyToMany; - let ownerEntity = dbModel.entities.filter(v => { - return v.EntityName == relation.ownerTable; - })[0]; - let referencedEntity = dbModel.entities.filter(v => { - return v.EntityName == relation.relatedTable; - })[0]; + let ownerEntity = dbModel.entities.find( + v => v.EntityName == relation.ownerTable + )!; let columnName = columnOldName[0].toLowerCase() + diff --git a/src/Utils.ts b/src/Utils.ts index d6ba713..8e34d49 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -14,7 +14,6 @@ export function LogError( ); if (isABug && !errObject) errObject = new Error().stack; if (!!errObject) console.error(errObject); - // process.abort(); } export function packageVersion() { return `${(packagejson).name}@${(packagejson).version}`; diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index c72895e..f84fb99 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -17,37 +17,27 @@ export abstract class AbstractDriver { let newName = this.namingStrategy.columnName(column.tsName); entity.Indexes.forEach(index => { index.columns - .filter(column2 => { - return column2.name == column.tsName; - }) - .forEach(column2 => { - column2.name = newName; - }); + .filter(column2 => column2.name == column.tsName) + .forEach(column2 => (column2.name = newName)); }); dbModel.entities.forEach(entity2 => { entity2.Columns.forEach(column2 => { column2.relations - .filter(relation => { - return ( + .filter( + relation => relation.relatedTable == entity.EntityName && relation.relatedColumn == column.tsName - ); - }) - .map(v => { - v.relatedColumn = newName; - }); + ) + .map(v => (v.relatedColumn = newName)); column2.relations - .filter(relation => { - return ( + .filter( + relation => relation.relatedTable == entity.EntityName && relation.ownerColumn == column.tsName - ); - }) - .map(v => { - v.ownerColumn = newName; - }); + ) + .map(v => (v.ownerColumn = newName)); }); }); @@ -75,43 +65,43 @@ export abstract class AbstractDriver { dbModel.entities.forEach(entity => { entity.Columns.forEach(column => { column.relations.forEach(relation => { - if (true || !relation.isOwner) { - 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.forEach(col => { - if (col.name == column.tsName) { - col.name = newName; - } - }); - }); - } - }); + 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; - } + }); + column.tsName = newName; }); }); }); @@ -162,8 +152,8 @@ export abstract class AbstractDriver { generateRelationsIds: boolean; FindManyToManyRelations(dbModel: DatabaseModel) { - let manyToManyEntities = dbModel.entities.filter(entity => { - return ( + let manyToManyEntities = dbModel.entities.filter( + entity => entity.Columns.filter(column => { return ( column.relations.length == 1 && @@ -171,29 +161,29 @@ export abstract class AbstractDriver { column.relations[0].isOwner ); }).length == entity.Columns.length - ); - }); + ); manyToManyEntities.map(entity => { let relations: RelationInfo[] = []; - relations = entity.Columns.reduce((prev: RelationInfo[], curr) => { - return prev.concat(curr.relations); - }, relations); + relations = entity.Columns.reduce( + (prev: RelationInfo[], curr) => prev.concat(curr.relations), + relations + ); let namesOfRelatedTables = relations .map(v => v.relatedTable) .filter((v, i, s) => s.indexOf(v) == i); if (namesOfRelatedTables.length == 2) { - let relatedTable1 = dbModel.entities.filter( + let relatedTable1 = dbModel.entities.find( v => v.EntityName == namesOfRelatedTables[0] - )[0]; + )!; relatedTable1.Columns = relatedTable1.Columns.filter( v => !v.tsName .toLowerCase() .startsWith(entity.EntityName.toLowerCase()) ); - let relatedTable2 = dbModel.entities.filter( + let relatedTable2 = dbModel.entities.find( v => v.EntityName == namesOfRelatedTables[1] - )[0]; + )!; relatedTable2.Columns = relatedTable2.Columns.filter( v => !v.tsName @@ -305,9 +295,9 @@ export abstract class AbstractDriver { entities: EntityInfo[] ) { relationsTemp.forEach(relationTmp => { - let ownerEntity = entities.find(entitity => { - return entitity.EntityName == relationTmp.ownerTable; - }); + let ownerEntity = entities.find( + entitity => entitity.EntityName == relationTmp.ownerTable + ); if (!ownerEntity) { TomgUtils.LogError( `Relation between tables ${relationTmp.ownerTable} and ${ @@ -316,9 +306,9 @@ export abstract class AbstractDriver { ); return; } - let referencedEntity = entities.find(entitity => { - return entitity.EntityName == relationTmp.referencedTable; - }); + let referencedEntity = entities.find( + entitity => entitity.EntityName == relationTmp.referencedTable + ); if (!referencedEntity) { TomgUtils.LogError( `Relation between tables ${relationTmp.ownerTable} and ${ @@ -332,12 +322,11 @@ export abstract class AbstractDriver { relationColumnIndex < relationTmp.ownerColumnsNames.length; relationColumnIndex++ ) { - let ownerColumn = ownerEntity.Columns.find(column => { - return ( + let ownerColumn = ownerEntity.Columns.find( + column => column.tsName == relationTmp.ownerColumnsNames[relationColumnIndex] - ); - }); + ); if (!ownerColumn) { TomgUtils.LogError( `Relation between tables ${ @@ -350,12 +339,11 @@ export abstract class AbstractDriver { ); return; } - let relatedColumn = referencedEntity.Columns.find(column => { - return ( + let relatedColumn = referencedEntity.Columns.find( + column => column.tsName == relationTmp.referencedColumnsNames[relationColumnIndex] - ); - }); + ); if (!relatedColumn) { TomgUtils.LogError( `Relation between tables ${ @@ -370,14 +358,13 @@ export abstract class AbstractDriver { } let isOneToMany: boolean; isOneToMany = false; - let index = ownerEntity.Indexes.find(index => { - return ( + let index = ownerEntity.Indexes.find( + index => index.isUnique && - index.columns.some(col => { - return col.name == ownerColumn!.tsName; - }) - ); - }); + index.columns.some( + col => col.name == ownerColumn!.tsName + ) + ); isOneToMany = !index; let ownerRelation = new RelationInfo(); @@ -467,15 +454,13 @@ export abstract class AbstractDriver { FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) { dbModel.entities.forEach(entity => { let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey); - entity.Columns.forEach(col => { - if ( + entity.Columns.filter( + col => primaryIndex && primaryIndex.columns.some( cIndex => cIndex.name == col.tsName ) - ) - col.isPrimary = true; - }); + ).forEach(col => (col.isPrimary = true)); if ( !entity.Columns.some(v => { return v.isPrimary; diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index ac64a13..7d3fe8c 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -228,9 +228,7 @@ ORDER BY t.name, ind.name, ind.index_id, ic.key_ordinal;`)).recordset; entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.TableName == ent.EntityName; - }) + .filter(filterVal => filterVal.TableName == ent.EntityName) .forEach(resp => { let indexInfo: IndexInfo = {}; let indexColumnInfo: IndexColumnInfo = {}; @@ -299,9 +297,9 @@ order by TableWithForeignKey, FK_PartNo`)).recordset; let relationsTemp: RelationTempInfo[] = []; response.forEach(resp => { - let rels = relationsTemp.find(val => { - return val.object_id == resp.object_id; - }); + let rels = relationsTemp.find( + val => val.object_id == resp.object_id + ); if (rels == undefined) { rels = {}; rels.ownerColumnsNames = []; @@ -315,7 +313,6 @@ order by break; default: rels.actionOnDelete = resp.onDelete; - break; } switch (resp.onUpdate) { @@ -327,7 +324,6 @@ order by break; default: rels.actionOnUpdate = resp.onUpdate; - break; } rels.object_id = resp.object_id; diff --git a/src/drivers/MysqlDriver.ts b/src/drivers/MysqlDriver.ts index b4ffe98..2fa3bf3 100644 --- a/src/drivers/MysqlDriver.ts +++ b/src/drivers/MysqlDriver.ts @@ -40,9 +40,7 @@ export class MysqlDriver extends AbstractDriver { FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA like DATABASE()`); entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.TABLE_NAME == ent.EntityName; - }) + .filter(filterVal => filterVal.TABLE_NAME == ent.EntityName) .forEach(resp => { let colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.COLUMN_NAME; @@ -226,20 +224,18 @@ export class MysqlDriver extends AbstractDriver { `); entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.TableName == ent.EntityName; - }) + .filter(filterVal => filterVal.TableName == ent.EntityName) .forEach(resp => { let indexInfo: IndexInfo = {}; let indexColumnInfo: IndexColumnInfo = {}; if ( - ent.Indexes.filter(filterVal => { - return filterVal.name == resp.IndexName; - }).length > 0 + ent.Indexes.filter( + filterVal => filterVal.name == resp.IndexName + ).length > 0 ) { - indexInfo = ent.Indexes.filter(filterVal => { - return filterVal.name == resp.IndexName; - })[0]; + indexInfo = ent.Indexes.find( + filterVal => filterVal.name == resp.IndexName + )!; } else { indexInfo.columns = []; indexInfo.name = resp.IndexName; @@ -286,9 +282,9 @@ export class MysqlDriver extends AbstractDriver { `); let relationsTemp: RelationTempInfo[] = []; response.forEach(resp => { - let rels = relationsTemp.find(val => { - return val.object_id == resp.object_id; - }); + let rels = relationsTemp.find( + val => val.object_id == resp.object_id + ); if (rels == undefined) { rels = {}; rels.ownerColumnsNames = []; diff --git a/src/drivers/OracleDriver.ts b/src/drivers/OracleDriver.ts index 751967c..4ac6580 100644 --- a/src/drivers/OracleDriver.ts +++ b/src/drivers/OracleDriver.ts @@ -51,9 +51,7 @@ export class OracleDriver extends AbstractDriver { entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.TABLE_NAME == ent.EntityName; - }) + .filter(filterVal => filterVal.TABLE_NAME == ent.EntityName) .forEach(resp => { let colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.COLUMN_NAME; @@ -202,20 +200,18 @@ export class OracleDriver extends AbstractDriver { entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.TABLE_NAME == ent.EntityName; - }) + .filter(filterVal => filterVal.TABLE_NAME == ent.EntityName) .forEach(resp => { let indexInfo: IndexInfo = {}; let indexColumnInfo: IndexColumnInfo = {}; if ( - ent.Indexes.filter(filterVal => { - return filterVal.name == resp.INDEX_NAME; - }).length > 0 + ent.Indexes.filter( + filterVal => filterVal.name == resp.INDEX_NAME + ).length > 0 ) { - indexInfo = ent.Indexes.filter(filterVal => { - return filterVal.name == resp.INDEX_NAME; - })[0]; + indexInfo = ent.Indexes.find( + filterVal => filterVal.name == resp.INDEX_NAME + )!; } else { indexInfo.columns = []; indexInfo.name = resp.INDEX_NAME; @@ -256,9 +252,9 @@ export class OracleDriver extends AbstractDriver { let relationsTemp: RelationTempInfo[] = []; response.forEach(resp => { - let rels = relationsTemp.find(val => { - return val.object_id == resp.CONSTRAINT_NAME; - }); + let rels = relationsTemp.find( + val => val.object_id == resp.CONSTRAINT_NAME + ); if (rels == undefined) { rels = {}; rels.ownerColumnsNames = []; diff --git a/src/drivers/PostgresDriver.ts b/src/drivers/PostgresDriver.ts index b117522..d91411d 100644 --- a/src/drivers/PostgresDriver.ts +++ b/src/drivers/PostgresDriver.ts @@ -50,9 +50,7 @@ export class PostgresDriver extends AbstractDriver { .rows; entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.table_name == ent.EntityName; - }) + .filter(filterVal => filterVal.table_name == ent.EntityName) .forEach(resp => { let colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.column_name; @@ -402,20 +400,18 @@ export class PostgresDriver extends AbstractDriver { ORDER BY c.relname,f.attname;`)).rows; entities.forEach(ent => { response - .filter(filterVal => { - return filterVal.tablename == ent.EntityName; - }) + .filter(filterVal => filterVal.tablename == ent.EntityName) .forEach(resp => { let indexInfo: IndexInfo = {}; let indexColumnInfo: IndexColumnInfo = {}; if ( - ent.Indexes.filter(filterVal => { - return filterVal.name == resp.indexname; - }).length > 0 + ent.Indexes.filter( + filterVal => filterVal.name == resp.indexname + ).length > 0 ) { - indexInfo = ent.Indexes.filter(filterVal => { - return filterVal.name == resp.indexname; - })[0]; + indexInfo = ent.Indexes.find( + filterVal => filterVal.name == resp.indexname + )!; } else { indexInfo.columns = []; indexInfo.name = resp.indexname; @@ -486,9 +482,9 @@ export class PostgresDriver extends AbstractDriver { and rc.constraint_name= con.conname`)).rows; let relationsTemp: RelationTempInfo[] = []; response.forEach(resp => { - let rels = relationsTemp.find(val => { - return val.object_id == resp.object_id; - }); + let rels = relationsTemp.find( + val => val.object_id == resp.object_id + ); if (rels == undefined) { rels = {}; rels.ownerColumnsNames = []; diff --git a/src/drivers/SqliteDriver.ts b/src/drivers/SqliteDriver.ts index 9768316..f9ac79d 100644 --- a/src/drivers/SqliteDriver.ts +++ b/src/drivers/SqliteDriver.ts @@ -217,9 +217,9 @@ export class SqliteDriver extends AbstractDriver { return filterVal.name == resp.name; }).length > 0 ) { - indexInfo = ent.Indexes.filter(filterVal => { - return filterVal.name == resp.name; - })[0]; + indexInfo = ent.Indexes.find( + filterVal => filterVal.name == resp.name + )!; } else { indexInfo.columns = []; indexInfo.name = resp.name; diff --git a/src/models/EntityInfo.ts b/src/models/EntityInfo.ts index 024a0e0..ecae01c 100644 --- a/src/models/EntityInfo.ts +++ b/src/models/EntityInfo.ts @@ -9,7 +9,7 @@ export class EntityInfo { Schema: string; GenerateConstructor: boolean; - relationImports(): any { + relationImports() { var imports: string[] = []; this.Columns.forEach(column => { column.relations.forEach(relation => { @@ -17,8 +17,8 @@ export class EntityInfo { imports.push(relation.relatedTable); }); }); - this.UniqueImports = imports.filter(function(elem, index, self) { - return index == self.indexOf(elem); - }); + this.UniqueImports = imports.filter( + (elem, index, self) => index == self.indexOf(elem) + ); } } diff --git a/test/integration/entityTypes.test.ts b/test/integration/entityTypes.test.ts index 10e570f..e95fabc 100644 --- a/test/integration/entityTypes.test.ts +++ b/test/integration/entityTypes.test.ts @@ -67,8 +67,8 @@ describe("Platform specyfic types", async function () { await engine.createModelFromDatabase() let filesGenPath = path.resolve(resultsPath, 'entities') - let filesOrg = fs.readdirSync(filesOrgPathTS).filter(function (this, val, ind, arr) { return val.toString().endsWith('.ts') }) - let filesGen = fs.readdirSync(filesGenPath).filter(function (this, val, ind, arr) { return val.toString().endsWith('.ts') }) + let filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) + let filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen) @@ -79,9 +79,7 @@ describe("Platform specyfic types", async function () { 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 => { - return path.resolve(filesGenPath, v) - }) + filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v)) let compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { experimentalDecorators: true, sourceMap: false, diff --git a/test/integration/githubIssues.test.ts b/test/integration/githubIssues.test.ts index 1c348ed..03099e5 100644 --- a/test/integration/githubIssues.test.ts +++ b/test/integration/githubIssues.test.ts @@ -89,8 +89,8 @@ describe("GitHub issues", async function () { await engine.createModelFromDatabase() let filesGenPath = path.resolve(resultsPath, 'entities') - let filesOrg = fs.readdirSync(filesOrgPathTS).filter(function (this, val) { return val.toString().endsWith('.ts') }) - let filesGen = fs.readdirSync(filesGenPath).filter(function (this, val) { return val.toString().endsWith('.ts') }) + let filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) + let filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen) @@ -101,9 +101,7 @@ describe("GitHub issues", async function () { 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 => { - return path.resolve(filesGenPath, v) - }) + filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v)) let compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { experimentalDecorators: true, sourceMap: false, diff --git a/test/integration/integration.test.ts b/test/integration/integration.test.ts index d75bb1a..5c11403 100644 --- a/test/integration/integration.test.ts +++ b/test/integration/integration.test.ts @@ -69,8 +69,8 @@ describe("TypeOrm examples", async function () { await engine.createModelFromDatabase() let filesGenPath = path.resolve(resultsPath, 'entities') - let filesOrg = fs.readdirSync(filesOrgPathTS).filter(function (this, val) { return val.toString().endsWith('.ts') }) - let filesGen = fs.readdirSync(filesGenPath).filter(function (this, val) { return val.toString().endsWith('.ts') }) + let filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts')) + let filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts')) expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen) @@ -81,9 +81,7 @@ describe("TypeOrm examples", async function () { 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 => { - return path.resolve(filesGenPath, v) - }) + filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v)) let compileErrors = GTU.compileTsFiles(currentDirectoryFiles, { experimentalDecorators: true, sourceMap: false, diff --git a/test/utils/EntityFileToJson.ts b/test/utils/EntityFileToJson.ts index 89c6d84..0a1ac1f 100644 --- a/test/utils/EntityFileToJson.ts +++ b/test/utils/EntityFileToJson.ts @@ -3,9 +3,7 @@ export class EntityFileToJson { getEntityOptions(trimmedLine: string, ent: EntityJson) { let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) if (decoratorParameters.length > 0) { - if (decoratorParameters[0] == '"' && decoratorParameters.endsWith('"')) { - - } else { + if (decoratorParameters[0] != '"' || !decoratorParameters.endsWith('"')) { let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim() if (badJSON.lastIndexOf(',') == badJSON.length - 3) { badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1] @@ -19,9 +17,7 @@ export class EntityFileToJson { let 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('|').map(function (x) { - return x; - }); + col.columnTypes = decoratorParameters.substring(0, decoratorParameters.indexOf(',')).trim().split('|'); let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim() if (badJSON.lastIndexOf(',') == badJSON.length - 3) { badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1] @@ -29,10 +25,7 @@ export class EntityFileToJson { col.columnOptions = JSON.parse(badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ')) } else { if (decoratorParameters[0] == '"' && decoratorParameters.endsWith('"')) { - col.columnTypes = decoratorParameters.split('|').map(function (x) { - x = x.trim(); - return x; - }); + col.columnTypes = decoratorParameters.split('|').map( x=>x.trim()) } else { let badJSON = !primaryGeneratedColumn ? decoratorParameters.substring(decoratorParameters.indexOf(',') + 1) : decoratorParameters badJSON = badJSON.trim() @@ -54,8 +47,6 @@ export class EntityFileToJson { badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1] } col.columnOptions = JSON.parse(badJSON.replace(/(')/g,`"`).replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ')) - } else { - } } } @@ -65,7 +56,7 @@ export class EntityFileToJson { if (decoratorParameters.length > 0) { let containsTables = decoratorParameters.search('\\[') > -1 let containsOptions = decoratorParameters.search('{') > -1 - let containsName = decoratorParameters.search('"') > -1//TODO:no name, but fields as string[] + let containsName = decoratorParameters.search('"') > -1 if (containsName) { ind.indexName = decoratorParameters.slice(decoratorParameters.indexOf('"') + 1, decoratorParameters.substr(decoratorParameters.indexOf('"') + 1).indexOf('"')) } @@ -79,9 +70,7 @@ export class EntityFileToJson { colName = val.slice(val.indexOf('"') + 1, val.lastIndexOf('"')) } return colName - }).filter(v => { - return v.length > 0 - })) + }).filter(v => v.length > 0)) } if (containsOptions) { let optionsStr = decoratorParameters.slice(decoratorParameters.indexOf('{') + 1, decoratorParameters.indexOf('}')) @@ -307,9 +296,8 @@ export class EntityFileToJson { return x; }); - if (!retVal.columns[retVal.columns.length - 1].columnTypes.some(function (this, val, ind, arr) { - return val == "null" ? true : false; - })) retVal.columns[retVal.columns.length - 1].columnTypes.push('null') + 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) } From a4592ffb4df6687e916d8e9233f7cb4875c009aa Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 8 Dec 2018 10:46:18 +0100 Subject: [PATCH 6/8] code cleanup, introducing tslint --- .npmignore | 1 + package-lock.json | 117 +++++++++ package.json | 4 +- src/AbstractNamingStrategy.ts | 8 +- src/Engine.ts | 43 +-- src/NamingStrategy.ts | 15 +- src/Utils.ts | 12 +- src/drivers/AbstractDriver.ts | 360 +++++++++++++------------- src/drivers/MariaDbDriver.ts | 2 +- src/drivers/MssqlDriver.ts | 28 +- src/drivers/MysqlDriver.ts | 126 ++++----- src/drivers/OracleDriver.ts | 106 ++++---- src/drivers/PostgresDriver.ts | 21 +- src/drivers/SqliteDriver.ts | 88 ++++--- src/index.ts | 22 +- src/models/ColumnInfo.ts | 32 +-- src/models/DatabaseModel.ts | 2 +- src/models/EntityInfo.ts | 21 +- src/models/RelationInfo.ts | 23 +- src/tslint.json | 9 + test/drivers/MssqlDriver.test.ts | 50 ++-- test/integration/entityTypes.test.ts | 60 ++--- test/integration/githubIssues.test.ts | 65 ++--- test/integration/integration.test.ts | 58 ++--- test/utils/EntityFileToJson.ts | 113 ++++---- test/utils/GeneralTestUtils.ts | 141 +++++----- 26 files changed, 857 insertions(+), 670 deletions(-) create mode 100644 src/tslint.json 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; }); From 721a85a0b9fabf4a91ddcd42f4adb103e7a76b33 Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 8 Dec 2018 12:49:57 +0100 Subject: [PATCH 7/8] more code cleaning --- src/Engine.ts | 20 ++-- src/NamingStrategy.ts | 16 ++-- src/drivers/AbstractDriver.ts | 8 +- src/drivers/MssqlDriver.ts | 157 ++++++++++++++++--------------- src/drivers/MysqlDriver.ts | 102 ++++++++++---------- src/drivers/OracleDriver.ts | 96 ++++++++++--------- src/drivers/PostgresDriver.ts | 105 ++++++++++----------- src/drivers/SqliteDriver.ts | 108 +++++++++++---------- src/entity.mst | 22 ++--- src/index.ts | 80 ++++++++-------- src/models/ColumnInfo.ts | 12 +-- src/models/EntityInfo.ts | 4 +- src/models/RelationInfo.ts | 8 +- src/models/RelationTempInfo.ts | 2 +- test/drivers/MssqlDriver.test.ts | 12 +-- 15 files changed, 379 insertions(+), 373 deletions(-) diff --git a/src/Engine.ts b/src/Engine.ts index fefef16..58a8d52 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -10,7 +10,7 @@ import * as TomgUtils from "./Utils"; export class Engine { constructor( private driver: AbstractDriver, - public Options: EngineOptions + public Options: IEngineOptions ) {} public async createModelFromDatabase(): Promise { @@ -88,7 +88,7 @@ export class Engine { }); }); element.GenerateConstructor = this.Options.constructor; - element.Imports.filter(function(elem, index, self) { + element.Imports.filter((elem, index, self) => { return index === self.indexOf(elem); }); let casedFileName = ""; @@ -186,13 +186,13 @@ export class Engine { } }); Handlebars.registerHelper({ - eq: (v1, v2) => v1 === v2, - ne: (v1, v2) => v1 !== v2, - lt: (v1, v2) => v1 < v2, - gt: (v1, v2) => v1 > v2, - lte: (v1, v2) => v1 <= v2, - gte: (v1, v2) => v1 >= v2, and: (v1, v2) => v1 && v2, + eq: (v1, v2) => v1 === v2, + gt: (v1, v2) => v1 > v2, + gte: (v1, v2) => v1 >= v2, + lt: (v1, v2) => v1 < v2, + lte: (v1, v2) => v1 <= v2, + ne: (v1, v2) => v1 !== v2, or: (v1, v2) => v1 || v2 }); } @@ -214,7 +214,7 @@ export class Engine { ); } private createTypeOrmConfig(resultPath) { - if (this.Options.schemaName == "") { + if (this.Options.schemaName === "") { fs.writeFileSync( path.resolve(resultPath, "ormconfig.json"), `[ @@ -258,7 +258,7 @@ export class Engine { } } } -export interface EngineOptions { +export interface IEngineOptions { host: string; port: number; databaseName: string; diff --git a/src/NamingStrategy.ts b/src/NamingStrategy.ts index f22c59a..698f5a6 100644 --- a/src/NamingStrategy.ts +++ b/src/NamingStrategy.ts @@ -10,7 +10,7 @@ export class NamingStrategy extends AbstractNamingStrategy { ): string { const isRelationToMany = relation.isOneToMany || relation.isManyToMany; const ownerEntity = dbModel.entities.find( - v => v.EntityName == relation.ownerTable + v => v.EntityName === relation.ownerTable )!; let columnName = @@ -25,19 +25,19 @@ export class NamingStrategy extends AbstractNamingStrategy { columnName.toLowerCase().lastIndexOf("id") ); } - if (!isNaN(parseInt(columnName[columnName.length - 1]))) { + if (!isNaN(parseInt(columnName[columnName.length - 1], 10))) { columnName = columnName.substring(0, columnName.length - 1); } - if (!isNaN(parseInt(columnName[columnName.length - 1]))) { + if (!isNaN(parseInt(columnName[columnName.length - 1], 10))) { columnName = columnName.substring(0, columnName.length - 1); } columnName += isRelationToMany ? "s" : ""; if ( - relation.relationType != "ManyToMany" && - columnOldName != columnName + relation.relationType !== "ManyToMany" && + columnOldName !== columnName ) { - if (ownerEntity.Columns.some(v => v.tsName == columnName)) { + if (ownerEntity.Columns.some(v => v.tsName === columnName)) { columnName = columnName + "_"; for (let i = 2; i <= ownerEntity.Columns.length; i++) { columnName = @@ -48,8 +48,8 @@ export class NamingStrategy extends AbstractNamingStrategy { if ( ownerEntity.Columns.every( v => - v.tsName != columnName || - columnName == columnOldName + v.tsName !== columnName || + columnName === columnOldName ) ) { break; diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index c47ff7d..1557341 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -288,7 +288,7 @@ export abstract class AbstractDriver { } public GetRelationsFromRelationTempInfo( - relationsTemp: RelationTempInfo[], + relationsTemp: IRelationTempInfo[], entities: EntityInfo[] ) { relationsTemp.forEach(relationTmp => { @@ -356,9 +356,9 @@ export abstract class AbstractDriver { let isOneToMany: boolean; isOneToMany = false; const index = ownerEntity.Indexes.find( - index => - index.isUnique && - index.columns.some( + ind => + ind.isUnique && + ind.columns.some( col => col.name === ownerColumn!.tsName ) ); diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index c8eb5ba..9bd6b2e 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -1,27 +1,28 @@ -import { AbstractDriver } from "./AbstractDriver"; import * as MSSQL from "mssql"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; +import { AbstractDriver } from "./AbstractDriver"; export class MssqlDriver extends AbstractDriver { - GetAllTablesQuery = async (schema: string) => { + private Connection: MSSQL.ConnectionPool; + public GetAllTablesQuery = async (schema: string) => { const request = new MSSQL.Request(this.Connection); - const response: { + const response: Array<{ TABLE_SCHEMA: string; TABLE_NAME: string; - }[] = (await request.query( + }> = (await request.query( `SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema})` )).recordset; return response; }; - async GetCoulmnsFromEntity( + public async GetCoulmnsFromEntity( entities: EntityInfo[], schema: string ): Promise { const request = new MSSQL.Request(this.Connection); - const response: { + const response: Array<{ TABLE_NAME: string; COLUMN_NAME: string; COLUMN_DEFAULT: string; @@ -32,7 +33,7 @@ export class MssqlDriver extends AbstractDriver { NUMERIC_SCALE: number; IsIdentity: number; IsUnique: number; - }[] = (await request.query(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE, + }> = (await request.query(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE, DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity, (SELECT count(*) @@ -52,113 +53,113 @@ export class MssqlDriver extends AbstractDriver { return 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.IsUnique == 1; + colInfo.isNullable = resp.IS_NULLABLE == "YES"; + colInfo.isGenerated = resp.IsIdentity == 1; + colInfo.isUnique = resp.IsUnique == 1; colInfo.default = resp.COLUMN_DEFAULT; - colInfo.sql_type = resp.DATA_TYPE; + colInfo.sqlType = resp.DATA_TYPE; switch (resp.DATA_TYPE) { case "bigint": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "bit": - colInfo.ts_type = "boolean"; + colInfo.tsType = "boolean"; break; case "decimal": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "int": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "money": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "numeric": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "smallint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "smallmoney": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "tinyint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "float": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "real": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "date": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "datetime2": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "datetime": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "datetimeoffset": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "smalldatetime": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "time": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "char": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "text": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "varchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "ntext": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nvarchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "binary": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "image": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "varbinary": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "hierarchyid": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "sql_variant": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "timestamp": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "uniqueidentifier": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "xml": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "geometry": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "geography": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; default: TomgUtils.LogError( @@ -173,7 +174,7 @@ export class MssqlDriver extends AbstractDriver { if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sql_type + v => v == colInfo.sqlType ) ) { colInfo.numericPrecision = resp.NUMERIC_PRECISION; @@ -181,7 +182,7 @@ export class MssqlDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sql_type + v => v == colInfo.sqlType ) ) { colInfo.lenght = @@ -190,23 +191,25 @@ export class MssqlDriver extends AbstractDriver { : null; } - if (colInfo.sql_type) ent.Columns.push(colInfo); + if (colInfo.sqlType) { + ent.Columns.push(colInfo); + } }); }); return entities; } - async GetIndexesFromEntity( + public async GetIndexesFromEntity( entities: EntityInfo[], schema: string ): Promise { const request = new MSSQL.Request(this.Connection); - const response: { + const response: Array<{ TableName: string; IndexName: string; ColumnName: string; is_unique: number; is_primary_key: number; - }[] = (await request.query(`SELECT + }> = (await request.query(`SELECT TableName = t.name, IndexName = ind.name, ColumnName = col.name, @@ -230,8 +233,8 @@ ORDER BY response .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 => { return filterVal.name == resp.IndexName; @@ -241,7 +244,7 @@ ORDER BY return filterVal.name == resp.IndexName; })[0]; } else { - indexInfo.columns = []; + indexInfo.columns = [] as IndexColumnInfo[]; indexInfo.name = resp.IndexName; indexInfo.isUnique = resp.is_unique == 1; indexInfo.isPrimaryKey = resp.is_primary_key == 1; @@ -254,12 +257,12 @@ ORDER BY return entities; } - async GetRelations( + public async GetRelations( entities: EntityInfo[], schema: string ): Promise { const request = new MSSQL.Request(this.Connection); - const response: { + const response: Array<{ TableWithForeignKey: string; FK_PartNo: number; ForeignKeyColumn: string; @@ -268,7 +271,7 @@ ORDER BY onDelete: "RESTRICT" | "CASCADE" | "SET_NULL" | "NO_ACTION"; onUpdate: "RESTRICT" | "CASCADE" | "SET_NULL" | "NO_ACTION"; object_id: number; - }[] = (await request.query(`select + }> = (await request.query(`select parentTable.name as TableWithForeignKey, fkc.constraint_column_id as FK_PartNo, parentColumn.name as ForeignKeyColumn, @@ -295,13 +298,13 @@ where fk.is_disabled=0 and fk.is_ms_shipped=0 and parentSchema.name in (${schema}) order by TableWithForeignKey, FK_PartNo`)).recordset; - let relationsTemp: RelationTempInfo[] = []; + const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( val => val.object_id == resp.object_id ); if (rels == undefined) { - rels = {}; + rels = {} as IRelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; switch (resp.onDelete) { @@ -340,12 +343,12 @@ order by ); return entities; } - async DisconnectFromServer() { - if (this.Connection) await this.Connection.close(); + public async DisconnectFromServer() { + if (this.Connection) { + await this.Connection.close(); + } } - - private Connection: MSSQL.ConnectionPool; - async ConnectToServer( + public async ConnectToServer( database: string, server: string, port: number, @@ -353,16 +356,16 @@ order by password: string, ssl: boolean ) { - let config: MSSQL.config = { - database: database, - server: server, - port: port, - user: user, - password: password, + const config: MSSQL.config = { + database, options: { - encrypt: ssl, - appName: "typeorm-model-generator" - } + appName: "typeorm-model-generator", + encrypt: ssl + }, + password, + port, + server, + user }; const promise = new Promise((resolve, reject) => { @@ -382,19 +385,19 @@ order by await promise; } - async CreateDB(dbName: string) { + public async CreateDB(dbName: string) { const request = new MSSQL.Request(this.Connection); await request.query(`CREATE DATABASE ${dbName}; `); } - async UseDB(dbName: string) { + public async UseDB(dbName: string) { const request = new MSSQL.Request(this.Connection); await request.query(`USE ${dbName}; `); } - async DropDB(dbName: string) { + public async DropDB(dbName: string) { const request = new MSSQL.Request(this.Connection); await request.query(`DROP DATABASE ${dbName}; `); } - async CheckIfDBExists(dbName: string): Promise { + public async CheckIfDBExists(dbName: string): Promise { const request = new MSSQL.Request(this.Connection); const resp = await request.query( `SELECT name FROM master.sys.databases WHERE name = N'${dbName}' ` diff --git a/src/drivers/MysqlDriver.ts b/src/drivers/MysqlDriver.ts index c0826c8..7ae30d2 100644 --- a/src/drivers/MysqlDriver.ts +++ b/src/drivers/MysqlDriver.ts @@ -47,121 +47,121 @@ export class MysqlDriver extends AbstractDriver { 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.isNullable = resp.IS_NULLABLE === "YES"; + colInfo.isGenerated = resp.IsIdentity === 1; + colInfo.isUnique = resp.column_key === "UNI"; colInfo.default = resp.COLUMN_DEFAULT; - colInfo.sql_type = resp.DATA_TYPE; + colInfo.sqlType = resp.DATA_TYPE; switch (resp.DATA_TYPE) { case "int": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "tinyint": if (resp.column_type === "tinyint(1)") { colInfo.width = 1; - colInfo.ts_type = "boolean"; + colInfo.tsType = "boolean"; } else { - colInfo.ts_type = "number"; + colInfo.tsType = "number"; } break; case "smallint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "mediumint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "bigint": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "float": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "double": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "decimal": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "date": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "datetime": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "timestamp": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "time": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "year": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "char": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "varchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "blob": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "text": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "tinyblob": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "tinytext": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "mediumblob": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "mediumtext": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "longblob": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "longtext": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "enum": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; colInfo.enumOptions = resp.column_type .substring(5, resp.column_type.length - 1) .replace(/\'/gi, '"'); break; case "json": - colInfo.ts_type = "Object"; + colInfo.tsType = "Object"; break; case "binary": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "geometry": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "point": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "linestring": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "polygon": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "multipoint": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "multilinestring": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "multipolygon": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "geometrycollection": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; default: TomgUtils.LogError( @@ -175,7 +175,7 @@ export class MysqlDriver extends AbstractDriver { } if ( this.ColumnTypesWithPrecision.some( - v => v === colInfo.sql_type + v => v === colInfo.sqlType ) ) { colInfo.numericPrecision = resp.NUMERIC_PRECISION; @@ -183,7 +183,7 @@ export class MysqlDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v === colInfo.sql_type + v => v === colInfo.sqlType ) ) { colInfo.lenght = @@ -194,8 +194,8 @@ export class MysqlDriver extends AbstractDriver { if ( this.ColumnTypesWithWidth.some( v => - v === colInfo.sql_type && - colInfo.ts_type !== "boolean" + v === colInfo.sqlType && + colInfo.tsType !== "boolean" ) ) { colInfo.width = @@ -204,7 +204,7 @@ export class MysqlDriver extends AbstractDriver { : null; } - if (colInfo.sql_type) { + if (colInfo.sqlType) { ent.Columns.push(colInfo); } }); @@ -284,13 +284,13 @@ export class MysqlDriver extends AbstractDriver { TABLE_SCHEMA = SCHEMA() AND CU.REFERENCED_TABLE_NAME IS NOT NULL; `); - const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[]; + const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( val => val.object_id === resp.object_id ); if (rels === undefined) { - rels = {} as RelationTempInfo; + rels = {} as IRelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = @@ -343,20 +343,20 @@ export class MysqlDriver extends AbstractDriver { config = { database, host: server, - port, - user, password, + port, ssl: { rejectUnauthorized: false - } + }, + user }; } else { config = { database, host: server, + password, port, - user, - password + user }; } diff --git a/src/drivers/OracleDriver.ts b/src/drivers/OracleDriver.ts index 6cda297..bf9d143 100644 --- a/src/drivers/OracleDriver.ts +++ b/src/drivers/OracleDriver.ts @@ -42,7 +42,7 @@ export class OracleDriver extends AbstractDriver { DATA_PRECISION: number; DATA_SCALE: number; IDENTITY_COLUMN: string; - IS_UNIQUE: Number; + IS_UNIQUE: number; }> = (await this.Connection .execute(`SELECT utc.TABLE_NAME, utc.COLUMN_NAME, DATA_DEFAULT, NULLABLE, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, IDENTITY_COLUMN, @@ -58,102 +58,102 @@ export class OracleDriver extends AbstractDriver { 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.isNullable = resp.NULLABLE === "Y"; + colInfo.isGenerated = resp.IDENTITY_COLUMN === "YES"; colInfo.default = !resp.DATA_DEFAULT || resp.DATA_DEFAULT.includes('"') ? null : resp.DATA_DEFAULT; - colInfo.is_unique = resp.IS_UNIQUE > 0; + colInfo.isUnique = resp.IS_UNIQUE > 0; resp.DATA_TYPE = resp.DATA_TYPE.replace(/\([0-9]+\)/g, ""); - colInfo.sql_type = resp.DATA_TYPE.toLowerCase(); + colInfo.sqlType = resp.DATA_TYPE.toLowerCase(); switch (resp.DATA_TYPE.toLowerCase()) { case "char": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nvarchar2": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "varchar2": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "long": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "raw": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "long raw": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "number": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "numeric": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "float": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "dec": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "decimal": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "integer": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "int": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "smallint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "real": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "double precision": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "date": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "timestamp": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "timestamp with time zone": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "timestamp with local time zone": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; case "interval year to month": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "interval day to second": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "bfile": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "blob": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "clob": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nclob": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "rowid": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "urowid": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; default: TomgUtils.LogError( @@ -163,7 +163,7 @@ export class OracleDriver extends AbstractDriver { } if ( this.ColumnTypesWithPrecision.some( - v => v === colInfo.sql_type + v => v === colInfo.sqlType ) ) { colInfo.numericPrecision = resp.DATA_PRECISION; @@ -171,14 +171,14 @@ export class OracleDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v === colInfo.sql_type + v => v === colInfo.sqlType ) ) { colInfo.lenght = resp.DATA_LENGTH > 0 ? resp.DATA_LENGTH : null; } - if (colInfo.sql_type) { + if (colInfo.sqlType) { ent.Columns.push(colInfo); } }); @@ -254,13 +254,13 @@ export class OracleDriver extends AbstractDriver { ORDER BY OWNER_TABLE_NAME ASC, owner.CONSTRAINT_NAME ASC, OWNER_POSITION ASC`)) .rows!; - const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[]; + const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( val => val.object_id === resp.CONSTRAINT_NAME ); if (rels === undefined) { - rels = {} as RelationTempInfo; + rels = {} as IRelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = @@ -296,23 +296,23 @@ export class OracleDriver extends AbstractDriver { let config: any; if (user === String(process.env.ORACLE_UsernameSys)) { config /*Oracle.IConnectionAttributes*/ = { - user, - password, connectString: `${server}:${port}/${database}`, externalAuth: ssl, - privilege: this.Oracle.SYSDBA + password, + privilege: this.Oracle.SYSDBA, + user }; } else { config /*Oracle.IConnectionAttributes*/ = { - user, - password, connectString: `${server}:${port}/${database}`, - externalAuth: ssl + externalAuth: ssl, + password, + user }; } const that = this; const promise = new Promise((resolve, reject) => { - this.Oracle.getConnection(config, function(err, connection) { + this.Oracle.getConnection(config, (err, connection) => { if (!err) { that.Connection = connection; resolve(true); @@ -338,7 +338,9 @@ export class OracleDriver extends AbstractDriver { ); await this.Connection.execute(`GRANT CONNECT TO ${dbName}`); } - public async UseDB(dbName: string) {} + public async UseDB(dbName: string) { + // not supported + } public async DropDB(dbName: string) { await this.Connection.execute(`DROP USER ${dbName} CASCADE`); } diff --git a/src/drivers/PostgresDriver.ts b/src/drivers/PostgresDriver.ts index 4db71f6..b192145 100644 --- a/src/drivers/PostgresDriver.ts +++ b/src/drivers/PostgresDriver.ts @@ -1,27 +1,27 @@ -import { AbstractDriver } from "./AbstractDriver"; import * as PG from "pg"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; +import { AbstractDriver } from "./AbstractDriver"; export class PostgresDriver extends AbstractDriver { private Connection: PG.Client; - GetAllTablesQuery = async (schema: string) => { - const response: { + public GetAllTablesQuery = async (schema: string) => { + const response: Array<{ TABLE_SCHEMA: string; TABLE_NAME: string; - }[] = (await this.Connection.query( + }> = (await this.Connection.query( `SELECT table_schema as "TABLE_SCHEMA",table_name as "TABLE_NAME" FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema in (${schema}) ` )).rows; return response; }; - async GetCoulmnsFromEntity( + public async GetCoulmnsFromEntity( entities: EntityInfo[], schema: string ): Promise { - const response: { + const response: Array<{ table_name: string; column_name: string; udt_name: string; @@ -33,7 +33,7 @@ export class PostgresDriver extends AbstractDriver { numeric_scale: number; isidentity: string; isunique: number; - }[] = (await this.Connection + }> = (await this.Connection .query(`SELECT table_name,column_name,udt_name,column_default,is_nullable, data_type,character_maximum_length,numeric_precision,numeric_scale, case when column_default LIKE 'nextval%' then 'YES' else 'NO' end isidentity, @@ -52,13 +52,13 @@ export class PostgresDriver extends AbstractDriver { response .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 == "YES"; - colInfo.is_unique = resp.isunique == 1; - colInfo.default = colInfo.is_generated + colInfo.isNullable = resp.is_nullable == "YES"; + colInfo.isGenerated = resp.isidentity == "YES"; + colInfo.isUnique = resp.isunique == 1; + colInfo.default = colInfo.isGenerated ? null : resp.column_default; @@ -89,19 +89,19 @@ export class PostgresDriver extends AbstractDriver { } return; } - colInfo.sql_type = columnTypes.sql_type; - colInfo.ts_type = columnTypes.ts_type; - colInfo.is_array = columnTypes.is_array; - if (colInfo.is_array) { - colInfo.ts_type = colInfo.ts_type + colInfo.sqlType = columnTypes.sql_type; + colInfo.tsType = columnTypes.ts_type; + colInfo.isArray = columnTypes.is_array; + if (colInfo.isArray) { + colInfo.tsType = colInfo.tsType .split("|") .map(x => x.replace("|", "").trim() + "[]") - .join(" | "); + .join(" | ") as any; } if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sql_type + v => v == colInfo.sqlType ) ) { colInfo.numericPrecision = resp.numeric_precision; @@ -109,7 +109,7 @@ export class PostgresDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sql_type + v => v == colInfo.sqlType ) ) { colInfo.lenght = @@ -119,7 +119,7 @@ export class PostgresDriver extends AbstractDriver { } if ( this.ColumnTypesWithWidth.some( - v => v == colInfo.sql_type + v => v == colInfo.sqlType ) ) { colInfo.width = @@ -127,7 +127,7 @@ export class PostgresDriver extends AbstractDriver { ? resp.character_maximum_length : null; } - if (colInfo.sql_type && colInfo.ts_type) { + if (colInfo.sqlType && colInfo.tsType) { ent.Columns.push(colInfo); } }); @@ -135,8 +135,8 @@ export class PostgresDriver extends AbstractDriver { return entities; } - MatchColumnTypes(data_type: string, udt_name: string) { - let ret: { + public MatchColumnTypes(dataType: string, udtName: string) { + const ret: { ts_type: | "number" | "string" @@ -151,8 +151,8 @@ export class PostgresDriver extends AbstractDriver { sql_type: string | null; is_array: boolean; } = { ts_type: null, sql_type: null, is_array: false }; - ret.sql_type = data_type; - switch (data_type) { + ret.sql_type = dataType; + switch (dataType) { case "int2": ret.ts_type = "number"; break; @@ -338,18 +338,15 @@ export class PostgresDriver extends AbstractDriver { ret.ts_type = "string"; break; case "ARRAY": - const z = this.MatchColumnTypes( - udt_name.substring(1), - udt_name - ); + const z = this.MatchColumnTypes(udtName.substring(1), udtName); ret.ts_type = z.ts_type; ret.sql_type = z.sql_type; ret.is_array = true; break; case "USER-DEFINED": - ret.sql_type = udt_name; + ret.sql_type = udtName; ret.ts_type = "string"; - switch (udt_name) { + switch (udtName) { case "citext": case "hstore": case "geometry": @@ -367,17 +364,17 @@ export class PostgresDriver extends AbstractDriver { } return ret; } - async GetIndexesFromEntity( + public async GetIndexesFromEntity( entities: EntityInfo[], schema: string ): Promise { - const response: { + const response: Array<{ tablename: string; indexname: string; columnname: string; is_unique: number; is_primary_key: number; - }[] = (await this.Connection.query(`SELECT + }> = (await this.Connection.query(`SELECT c.relname AS tablename, i.relname as indexname, f.attname AS columnname, @@ -405,8 +402,8 @@ export class PostgresDriver extends AbstractDriver { response .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 @@ -416,7 +413,7 @@ export class PostgresDriver extends AbstractDriver { 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; @@ -432,11 +429,11 @@ export class PostgresDriver extends AbstractDriver { return entities; } - async GetRelations( + public async GetRelations( entities: EntityInfo[], schema: string ): Promise { - const response: { + const response: Array<{ tablewithforeignkey: string; fk_partno: number; foreignkeycolumn: string; @@ -445,7 +442,7 @@ export class PostgresDriver extends AbstractDriver { ondelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"; onupdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"; object_id: string; - }[] = (await this.Connection.query(`SELECT + }> = (await this.Connection.query(`SELECT con.relname AS tablewithforeignkey, att.attnum as fk_partno, att2.attname AS foreignkeycolumn, @@ -483,13 +480,13 @@ export class PostgresDriver extends AbstractDriver { AND att2.attrelid = con.conrelid AND att2.attnum = con.parent and rc.constraint_name= con.conname`)).rows; - let relationsTemp: RelationTempInfo[] = []; + const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( val => val.object_id == resp.object_id ); if (rels == undefined) { - rels = {}; + rels = {} as IRelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = @@ -510,7 +507,7 @@ export class PostgresDriver extends AbstractDriver { ); return entities; } - async DisconnectFromServer() { + public async DisconnectFromServer() { if (this.Connection) { const promise = new Promise((resolve, reject) => { this.Connection.end(err => { @@ -530,7 +527,7 @@ export class PostgresDriver extends AbstractDriver { } } - async ConnectToServer( + public async ConnectToServer( database: string, server: string, port: number, @@ -539,12 +536,12 @@ export class PostgresDriver extends AbstractDriver { ssl: boolean ) { this.Connection = new PG.Client({ - database: database, + database, host: server, - port: port, - user: user, - password: password, - ssl: ssl + password, + port, + ssl, + user }); const promise = new Promise((resolve, reject) => { @@ -565,16 +562,16 @@ export class PostgresDriver extends AbstractDriver { await promise; } - async CreateDB(dbName: string) { + public async CreateDB(dbName: string) { await this.Connection.query(`CREATE DATABASE ${dbName}; `); } - async UseDB(dbName: string) { + public async UseDB(dbName: string) { await this.Connection.query(`USE ${dbName}; `); } - async DropDB(dbName: string) { + public async DropDB(dbName: string) { await this.Connection.query(`DROP DATABASE ${dbName}; `); } - async CheckIfDBExists(dbName: string): Promise { + public async CheckIfDBExists(dbName: string): Promise { const resp = await this.Connection.query( `SELECT datname FROM pg_database WHERE datname ='${dbName}' ` ); diff --git a/src/drivers/SqliteDriver.ts b/src/drivers/SqliteDriver.ts index ec64f3d..530c869 100644 --- a/src/drivers/SqliteDriver.ts +++ b/src/drivers/SqliteDriver.ts @@ -6,7 +6,7 @@ import { AbstractDriver } from "./AbstractDriver"; export class SqliteDriver extends AbstractDriver { public sqlite = require("sqlite3").verbose(); public db: any; - public tablesWithGeneratedPrimaryKey: String[] = new Array(); + public tablesWithGeneratedPrimaryKey: string[] = new Array(); public GetAllTablesQuery: any; public async GetAllTables(schema: string): Promise { @@ -43,103 +43,103 @@ export class SqliteDriver extends AbstractDriver { const colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.name; colInfo.sqlName = resp.name; - colInfo.is_nullable = resp.notnull == 0; + colInfo.isNullable = resp.notnull === 0; colInfo.isPrimary = resp.pk > 0; colInfo.default = resp.dflt_value ? resp.dflt_value : null; - colInfo.sql_type = resp.type + colInfo.sqlType = resp.type .replace(/\([0-9 ,]+\)/g, "") .toLowerCase() .trim(); - colInfo.is_generated = + colInfo.isGenerated = colInfo.isPrimary && this.tablesWithGeneratedPrimaryKey.includes(ent.EntityName); - switch (colInfo.sql_type) { + switch (colInfo.sqlType) { case "int": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "integer": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "int2": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "int8": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "tinyint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "smallint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "mediumint": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "bigint": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "unsigned big int": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "character": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "varchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "varying character": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "native character": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "nvarchar": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "text": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "blob": - colInfo.ts_type = "Buffer"; + colInfo.tsType = "Buffer"; break; case "clob": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "real": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "double": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "double precision": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "float": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "numeric": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "decimal": - colInfo.ts_type = "number"; + colInfo.tsType = "number"; break; case "boolean": - colInfo.ts_type = "boolean"; + colInfo.tsType = "boolean"; break; case "date": - colInfo.ts_type = "string"; + colInfo.tsType = "string"; break; case "datetime": - colInfo.ts_type = "Date"; + colInfo.tsType = "Date"; break; default: - console.log(colInfo.sql_type.toLowerCase().trim()); + console.log(colInfo.sqlType.toLowerCase().trim()); TomgUtils.LogError( `Unknown column type: ${ - colInfo.sql_type + colInfo.sqlType } table name: ${ent.EntityName} column name: ${ resp.name }` @@ -149,7 +149,7 @@ export class SqliteDriver extends AbstractDriver { const options = resp.type.match(/\([0-9 ,]+\)/g); if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sql_type + v => v === colInfo.sqlType ) && options ) { @@ -162,7 +162,7 @@ export class SqliteDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sql_type + v => v === colInfo.sqlType ) && options ) { @@ -174,8 +174,8 @@ export class SqliteDriver extends AbstractDriver { if ( this.ColumnTypesWithWidth.some( v => - v == colInfo.sql_type && - colInfo.ts_type != "boolean" + v === colInfo.sqlType && + colInfo.tsType !== "boolean" ) && options ) { @@ -185,7 +185,7 @@ export class SqliteDriver extends AbstractDriver { ) as any; } - if (colInfo.sql_type) { + if (colInfo.sqlType) { ent.Columns.push(colInfo); } }); @@ -216,26 +216,26 @@ export class SqliteDriver extends AbstractDriver { const indexColumnInfo: IndexColumnInfo = {} as IndexColumnInfo; if ( ent.Indexes.filter(filterVal => { - return filterVal.name == resp.name; + return filterVal.name === resp.name; }).length > 0 ) { indexInfo = ent.Indexes.find( - filterVal => filterVal.name == resp.name + filterVal => filterVal.name === resp.name )!; } else { indexInfo.columns = [] as IndexColumnInfo[]; indexInfo.name = resp.name; - indexInfo.isUnique = resp.unique == 1; + indexInfo.isUnique = resp.unique === 1; ent.Indexes.push(indexInfo); } indexColumnInfo.name = element.name; if ( - indexColumnsResponse.length == 1 && + indexColumnsResponse.length === 1 && indexInfo.isUnique ) { ent.Columns.filter( - v => v.tsName == indexColumnInfo.name - ).map(v => (v.is_unique = true)); + v => v.tsName === indexColumnInfo.name + ).map(v => (v.isUnique = true)); } indexInfo.columns.push(indexColumnInfo); }); @@ -259,15 +259,15 @@ export class SqliteDriver extends AbstractDriver { on_delete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION"; match: string; }>(`PRAGMA foreign_key_list('${entity.EntityName}');`); - const relationsTemp: RelationTempInfo[] = [] as RelationTempInfo[]; + const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { - const rels = {} as RelationTempInfo; + const rels = {} as IRelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; rels.actionOnDelete = - resp.on_delete == "NO ACTION" ? null : resp.on_delete; + resp.on_delete === "NO ACTION" ? null : resp.on_delete; rels.actionOnUpdate = - resp.on_update == "NO ACTION" ? null : resp.on_update; + resp.on_update === "NO ACTION" ? null : resp.on_update; rels.ownerTable = entity.EntityName; rels.referencedTable = resp.table; relationsTemp.push(rels); @@ -296,7 +296,9 @@ export class SqliteDriver extends AbstractDriver { await this.UseDB(database); } - public async CreateDB(dbName: string) {} + public async CreateDB(dbName: string) { + // not supported + } public async UseDB(dbName: string) { const promise = new Promise((resolve, reject) => { this.db = new this.sqlite.Database(dbName, err => { @@ -310,7 +312,9 @@ export class SqliteDriver extends AbstractDriver { }); return promise; } - public async DropDB(dbName: string) {} + public async DropDB(dbName: string) { + // not supported + } public async CheckIfDBExists(dbName: string): Promise { return true; } @@ -319,7 +323,7 @@ export class SqliteDriver extends AbstractDriver { let ret: any; const promise = new Promise((resolve, reject) => { this.db.serialize(() => { - this.db.all(sql, [], function(err, row) { + this.db.all(sql, [], (err, row) => { if (!err) { ret = row; resolve(true); diff --git a/src/entity.mst b/src/entity.mst index 6834464..0dd8ee7 100644 --- a/src/entity.mst +++ b/src/entity.mst @@ -8,24 +8,24 @@ import {Index,Entity, PrimaryColumn, PrimaryGeneratedColumn, Column, OneToOne, O {{/isPrimaryKey}}{{/Indexes}}export class {{toEntityName EntityName}} { {{#Columns}} - {{^relations}}{{#is_generated}} @PrimaryGeneratedColumn({ - type:"{{sql_type}}", {{/is_generated}}{{^is_generated}} @Column("{{sql_type}}",{ {{#is_nullable}} - nullable:true,{{/is_nullable}}{{^is_nullable}} - nullable:false,{{/is_nullable}}{{#isPrimary}} - primary:{{isPrimary}},{{/isPrimary}}{{/is_generated}}{{#is_unique}} - unique: true,{{/is_unique}}{{#lenght}} + {{^relations}}{{#isGenerated}} @PrimaryGeneratedColumn({ + type:"{{sqlType}}", {{/isGenerated}}{{^isGenerated}} @Column("{{sqlType}}",{ {{#isNullable}} + nullable:true,{{/isNullable}}{{^isNullable}} + nullable:false,{{/isNullable}}{{#isPrimary}} + primary:{{isPrimary}},{{/isPrimary}}{{/isGenerated}}{{#isUnique}} + unique: true,{{/isUnique}}{{#lenght}} length:{{.}},{{/lenght}}{{#width}} width:{{.}},{{/width}}{{#default}} default:"{{.}}",{{/default}}{{#numericPrecision}} precision:{{.}},{{/numericPrecision}}{{#numericScale}} scale:{{.}},{{/numericScale}}{{#enumOptions}} - enum:[{{.}}],{{/enumOptions}}{{#is_array}} - array:{{is_array}},{{/is_array}} + enum:[{{.}}],{{/enumOptions}}{{#isArray}} + array:{{isArray}},{{/isArray}} name:"{{sqlName}}" }) - {{printPropertyVisibility}}{{toPropertyName tsName}}:{{ts_type}}{{#is_nullable}} | null{{/is_nullable}}; + {{printPropertyVisibility}}{{toPropertyName tsName}}:{{tsType}}{{#isNullable}} | null{{/isNullable}}; {{/relations}}{{#relations}} - @{{relationType}}(type=>{{toEntityName relatedTable}}, {{toEntityName relatedTable}}=>{{toEntityName relatedTable}}.{{#if isOwner}}{{toPropertyName ownerColumn}},{ {{#../isPrimary}}primary:true,{{/../isPrimary}}{{^../is_nullable}} nullable:false,{{/../is_nullable}}{{#actionOnDelete}}onDelete: '{{.}}',{{/actionOnDelete}}{{#actionOnUpdate}}onUpdate: '{{.}}'{{/actionOnUpdate}} }{{else}}{{toPropertyName relatedColumn}}{{#if (or actionOnDelete actionOnUpdate ) }}{{#actionOnDelete}},{ onDelete: '{{.}}' ,{{/actionOnDelete}}{{#actionOnUpdate}}onUpdate: '{{.}}'{{/actionOnUpdate}} }{{/if}}{{/if}}){{#isOwner}} + @{{relationType}}(type=>{{toEntityName relatedTable}}, {{toEntityName relatedTable}}=>{{toEntityName relatedTable}}.{{#if isOwner}}{{toPropertyName ownerColumn}},{ {{#../isPrimary}}primary:true,{{/../isPrimary}}{{^../isNullable}} nullable:false,{{/../isNullable}}{{#actionOnDelete}}onDelete: '{{.}}',{{/actionOnDelete}}{{#actionOnUpdate}}onUpdate: '{{.}}'{{/actionOnUpdate}} }{{else}}{{toPropertyName relatedColumn}}{{#if (or actionOnDelete actionOnUpdate ) }}{{#actionOnDelete}},{ onDelete: '{{.}}' ,{{/actionOnDelete}}{{#actionOnUpdate}}onUpdate: '{{.}}'{{/actionOnUpdate}} }{{/if}}{{/if}}){{#isOwner}} {{#if isManyToMany}}@JoinTable(){{else}}@JoinColumn({ name:'{{ ../sqlName}}'}){{/if}}{{/isOwner}} {{#if (or isOneToMany isManyToMany)}}{{printPropertyVisibility}}{{toPropertyName ../tsName}}:{{toLazy (concat (toEntityName relatedTable) "[]")}}; {{else}}{{printPropertyVisibility}}{{toPropertyName ../tsName}}:{{toLazy (concat (toEntityName relatedTable) ' | null')}}; @@ -33,7 +33,7 @@ import {Index,Entity, PrimaryColumn, PrimaryGeneratedColumn, Column, OneToOne, O {{#if relationIdField }} @RelationId(({{../../EntityName}}: {{../../EntityName}}) => {{../../EntityName}}.{{toPropertyName ../tsName}}) - {{toPropertyName ../tsName}}Id: {{#if isOneToOne}}{{toLazy ../ts_type}}{{else}}{{toLazy (concat ../ts_type "[]")}}{{/if}};{{/if}}{{/relations}} + {{toPropertyName ../tsName}}Id: {{#if isOneToOne}}{{toLazy ../tsType}}{{else}}{{toLazy (concat ../tsType "[]")}}{{/if}};{{/if}}{{/relations}} {{/Columns}} {{#if GenerateConstructor}} constructor(init?: Partial<{{toEntityName EntityName}}>) { diff --git a/src/index.ts b/src/index.ts index a4a2a4e..dbad34a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,13 +17,13 @@ const argv = Yargs.usage( ) .option("h", { alias: "host", - describe: "IP adress/Hostname for database server", - default: "127.0.0.1" + default: "127.0.0.1", + describe: "IP adress/Hostname for database server" }) .option("d", { alias: "database", - describe: "Database name(or path for sqlite)", - demand: true + demand: true, + describe: "Database name(or path for sqlite)" }) .option("u", { alias: "user", @@ -31,8 +31,8 @@ const argv = Yargs.usage( }) .option("x", { alias: "pass", - describe: "Password for database server", - default: "" + default: "", + describe: "Password for database server" }) .option("p", { alias: "port", @@ -40,14 +40,14 @@ const argv = Yargs.usage( }) .option("e", { alias: "engine", - describe: "Database engine", choices: ["mssql", "postgres", "mysql", "mariadb", "oracle", "sqlite"], - default: "mssql" + default: "mssql", + describe: "Database engine" }) .option("o", { alias: "output", - describe: "Where to place generated models", - default: path.resolve(process.cwd(), "output") + default: path.resolve(process.cwd(), "output"), + describe: "Where to place generated models" }) .option("s", { alias: "schema", @@ -60,50 +60,50 @@ const argv = Yargs.usage( }) .option("noConfig", { boolean: true, - describe: `Doesn't create tsconfig.json and ormconfig.json`, - default: false + default: false, + describe: `Doesn't create tsconfig.json and ormconfig.json` }) .option("cf", { alias: "case-file", - describe: "Convert file names to specified case", choices: ["pascal", "param", "camel", "none"], - default: "none" + default: "none", + describe: "Convert file names to specified case" }) .option("ce", { alias: "case-entity", - describe: "Convert class names to specified case", choices: ["pascal", "camel", "none"], - default: "none" + default: "none", + describe: "Convert class names to specified case" }) .option("cp", { alias: "case-property", - describe: "Convert property names to specified case", choices: ["pascal", "camel", "none"], - default: "none" + default: "none", + describe: "Convert property names to specified case" }) .option("pv", { alias: "property-visibility", - describe: "Defines which visibility should have the generated property", choices: ["public", "protected", "private", "none"], - default: "none" + default: "none", + describe: "Defines which visibility should have the generated property" }) .option("lazy", { - describe: "Generate lazy relations", boolean: true, - default: false + default: false, + describe: "Generate lazy relations" }) .option("namingStrategy", { describe: "Use custom naming strategy" }) .option("relationIds", { - describe: "Generate RelationId fields", boolean: true, - default: false + default: false, + describe: "Generate RelationId fields" }) .option("generateConstructor", { - describe: "Generate constructor allowing partial initialization", boolean: true, - default: false + default: false, + describe: "Generate constructor allowing partial initialization" }).argv; let driver: AbstractDriver; @@ -147,7 +147,7 @@ switch (argv.e) { throw new Error("Database engine not recognized."); } let namingStrategy: AbstractNamingStrategy; -if (argv.namingStrategy && argv.namingStrategy != "") { +if (argv.namingStrategy && argv.namingStrategy !== "") { const req = require(argv.namingStrategy); namingStrategy = new req.NamingStrategy(); } else { @@ -155,24 +155,24 @@ if (argv.namingStrategy && argv.namingStrategy != "") { } const engine = new Engine(driver, { - host: argv.h, - port: parseInt(argv.p) || standardPort, + constructor: argv.generateConstructor, + convertCaseEntity: argv.ce, + convertCaseFile: argv.cf, + convertCaseProperty: argv.cp, databaseName: argv.d ? argv.d.toString() : null, - user: argv.u ? argv.u.toString() : standardUser, - password: argv.x ? argv.x.toString() : null, databaseType: argv.e, + host: argv.h, + lazy: argv.lazy, + namingStrategy, + noConfigs: argv.noConfig, + password: argv.x ? argv.x.toString() : null, + port: parseInt(argv.p, 10) || standardPort, + propertyVisibility: argv.pv, + relationIds: argv.relationIds, resultsPath: argv.o ? argv.o.toString() : null, schemaName: argv.s ? argv.s.toString() : standardSchema, ssl: argv.ssl, - noConfigs: argv.noConfig, - convertCaseFile: argv.cf, - convertCaseEntity: argv.ce, - convertCaseProperty: argv.cp, - propertyVisibility: argv.pv, - lazy: argv.lazy, - constructor: argv.generateConstructor, - relationIds: argv.relationIds, - namingStrategy + user: argv.u ? argv.u.toString() : standardUser }); console.log(TomgUtils.packageVersion()); diff --git a/src/models/ColumnInfo.ts b/src/models/ColumnInfo.ts index 44964bb..8cdaea3 100644 --- a/src/models/ColumnInfo.ts +++ b/src/models/ColumnInfo.ts @@ -4,9 +4,9 @@ export class ColumnInfo { public tsName: string = ""; public sqlName: string = ""; public default: string | null = null; - public is_nullable: boolean = false; - public is_unique: boolean = false; - public ts_type: + public isNullable: boolean = false; + public isUnique: boolean = false; + public tsType: | "number" | "string" | "boolean" @@ -16,12 +16,12 @@ export class ColumnInfo { | "string | Object" | "string | string[]" | "any"; - public sql_type: string; + public sqlType: 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 isGenerated: boolean = false; + public isArray: boolean = false; public numericPrecision: number | null = null; public numericScale: number | null = null; public enumOptions: string | null = null; diff --git a/src/models/EntityInfo.ts b/src/models/EntityInfo.ts index 286d107..82d90ed 100644 --- a/src/models/EntityInfo.ts +++ b/src/models/EntityInfo.ts @@ -13,13 +13,13 @@ export class EntityInfo { 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( - (elem, index, self) => index == self.indexOf(elem) + (elem, index, self) => index === self.indexOf(elem) ); } } diff --git a/src/models/RelationInfo.ts b/src/models/RelationInfo.ts index 5ec6336..6dd8b3c 100644 --- a/src/models/RelationInfo.ts +++ b/src/models/RelationInfo.ts @@ -21,15 +21,15 @@ export class RelationInfo { public relationIdField: boolean = false; get isOneToMany(): boolean { - return this.relationType == "OneToMany"; + return this.relationType === "OneToMany"; } get isManyToMany(): boolean { - return this.relationType == "ManyToMany"; + return this.relationType === "ManyToMany"; } get isOneToOne(): boolean { - return this.relationType == "OneToOne"; + return this.relationType === "OneToOne"; } get isManyToOne(): boolean { - return this.relationType == "ManyToOne"; + return this.relationType === "ManyToOne"; } } diff --git a/src/models/RelationTempInfo.ts b/src/models/RelationTempInfo.ts index 0081955..1c4f8d8 100644 --- a/src/models/RelationTempInfo.ts +++ b/src/models/RelationTempInfo.ts @@ -1,4 +1,4 @@ -interface RelationTempInfo { +interface IRelationTempInfo { ownerTable: string; ownerColumnsNames: string[]; referencedTable: string; diff --git a/test/drivers/MssqlDriver.test.ts b/test/drivers/MssqlDriver.test.ts index 20bd41b..8ddb9c1 100644 --- a/test/drivers/MssqlDriver.test.ts +++ b/test/drivers/MssqlDriver.test.ts @@ -83,19 +83,19 @@ describe('MssqlDriver', function () { expected[0].Columns.push({ lenght: null, default: 'a', - is_nullable: true, + isNullable: true, isPrimary: false, - is_generated: true, + isGenerated: true, tsName: 'name', sqlName: 'name', numericPrecision: null, numericScale: null, width: null, - sql_type: 'int', - ts_type: 'number', + sqlType: 'int', + tsType: 'number', enumOptions: null, - is_unique:false, - is_array:false, + isUnique:false, + isArray:false, relations: [] as RelationInfo[], }) const result = await driver.GetCoulmnsFromEntity(entities, 'schema'); From d5faa8b9c379d36c638c68ff96ccacfe7101d978 Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sat, 8 Dec 2018 18:58:16 +0100 Subject: [PATCH 8/8] more cleaning up --- src/drivers/MssqlDriver.ts | 30 +++++++++++----------- src/drivers/PostgresDriver.ts | 48 +++++++++++++++++------------------ src/drivers/SqliteDriver.ts | 7 +++-- src/index.ts | 1 + src/tslint.json | 4 ++- 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index 9bd6b2e..3b9b4fe 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -50,15 +50,15 @@ export class MssqlDriver extends AbstractDriver { entities.forEach(ent => { response .filter(filterVal => { - return filterVal.TABLE_NAME == ent.EntityName; + return filterVal.TABLE_NAME === ent.EntityName; }) .forEach(resp => { const colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.COLUMN_NAME; colInfo.sqlName = resp.COLUMN_NAME; - colInfo.isNullable = resp.IS_NULLABLE == "YES"; - colInfo.isGenerated = resp.IsIdentity == 1; - colInfo.isUnique = resp.IsUnique == 1; + colInfo.isNullable = resp.IS_NULLABLE === "YES"; + colInfo.isGenerated = resp.IsIdentity === 1; + colInfo.isUnique = resp.IsUnique === 1; colInfo.default = resp.COLUMN_DEFAULT; colInfo.sqlType = resp.DATA_TYPE; switch (resp.DATA_TYPE) { @@ -174,7 +174,7 @@ export class MssqlDriver extends AbstractDriver { if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sqlType + v => v === colInfo.sqlType ) ) { colInfo.numericPrecision = resp.NUMERIC_PRECISION; @@ -182,7 +182,7 @@ export class MssqlDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sqlType + v => v === colInfo.sqlType ) ) { colInfo.lenght = @@ -207,8 +207,8 @@ export class MssqlDriver extends AbstractDriver { TableName: string; IndexName: string; ColumnName: string; - is_unique: number; - is_primary_key: number; + is_unique: boolean; + is_primary_key: boolean; }> = (await request.query(`SELECT TableName = t.name, IndexName = ind.name, @@ -231,23 +231,23 @@ ORDER BY t.name, ind.name, ind.index_id, ic.key_ordinal;`)).recordset; entities.forEach(ent => { response - .filter(filterVal => filterVal.TableName == ent.EntityName) + .filter(filterVal => filterVal.TableName === ent.EntityName) .forEach(resp => { let indexInfo: IndexInfo = {} as IndexInfo; const indexColumnInfo: IndexColumnInfo = {} as IndexColumnInfo; if ( ent.Indexes.filter(filterVal => { - return filterVal.name == resp.IndexName; + return filterVal.name === resp.IndexName; }).length > 0 ) { indexInfo = ent.Indexes.filter(filterVal => { - return filterVal.name == resp.IndexName; + return filterVal.name === resp.IndexName; })[0]; } else { 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; + indexInfo.isPrimaryKey = resp.is_primary_key; ent.Indexes.push(indexInfo); } indexColumnInfo.name = resp.ColumnName; @@ -301,9 +301,9 @@ order by const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( - val => val.object_id == resp.object_id + val => val.object_id === resp.object_id ); - if (rels == undefined) { + if (rels === undefined) { rels = {} as IRelationTempInfo; rels.ownerColumnsNames = []; rels.referencedColumnsNames = []; diff --git a/src/drivers/PostgresDriver.ts b/src/drivers/PostgresDriver.ts index b192145..164d788 100644 --- a/src/drivers/PostgresDriver.ts +++ b/src/drivers/PostgresDriver.ts @@ -32,7 +32,7 @@ export class PostgresDriver extends AbstractDriver { numeric_precision: number; numeric_scale: number; isidentity: string; - isunique: number; + isunique: string; }> = (await this.Connection .query(`SELECT table_name,column_name,udt_name,column_default,is_nullable, data_type,character_maximum_length,numeric_precision,numeric_scale, @@ -50,14 +50,14 @@ export class PostgresDriver extends AbstractDriver { .rows; entities.forEach(ent => { response - .filter(filterVal => filterVal.table_name == ent.EntityName) + .filter(filterVal => filterVal.table_name === ent.EntityName) .forEach(resp => { const colInfo: ColumnInfo = new ColumnInfo(); colInfo.tsName = resp.column_name; colInfo.sqlName = resp.column_name; - colInfo.isNullable = resp.is_nullable == "YES"; - colInfo.isGenerated = resp.isidentity == "YES"; - colInfo.isUnique = resp.isunique == 1; + colInfo.isNullable = resp.is_nullable === "YES"; + colInfo.isGenerated = resp.isidentity === "YES"; + colInfo.isUnique = resp.isunique === "1"; colInfo.default = colInfo.isGenerated ? null : resp.column_default; @@ -68,8 +68,8 @@ export class PostgresDriver extends AbstractDriver { ); if (!columnTypes.sql_type || !columnTypes.ts_type) { if ( - resp.data_type == "USER-DEFINED" || - resp.data_type == "ARRAY" + resp.data_type === "USER-DEFINED" || + resp.data_type === "ARRAY" ) { TomgUtils.LogError( `Unknown ${resp.data_type} column type: ${ @@ -101,7 +101,7 @@ export class PostgresDriver extends AbstractDriver { if ( this.ColumnTypesWithPrecision.some( - v => v == colInfo.sqlType + v => v === colInfo.sqlType ) ) { colInfo.numericPrecision = resp.numeric_precision; @@ -109,7 +109,7 @@ export class PostgresDriver extends AbstractDriver { } if ( this.ColumnTypesWithLength.some( - v => v == colInfo.sqlType + v => v === colInfo.sqlType ) ) { colInfo.lenght = @@ -119,7 +119,7 @@ export class PostgresDriver extends AbstractDriver { } if ( this.ColumnTypesWithWidth.some( - v => v == colInfo.sqlType + v => v === colInfo.sqlType ) ) { colInfo.width = @@ -379,12 +379,12 @@ export class PostgresDriver extends AbstractDriver { i.relname as indexname, f.attname AS columnname, CASE - WHEN ix.indisunique = true THEN '1' - ELSE '0' + WHEN ix.indisunique = true THEN 1 + ELSE 0 END AS is_unique, CASE - WHEN ix.indisprimary='true' THEN '1' - ELSE '0' + WHEN ix.indisprimary='true' THEN 1 + ELSE 0 END AS is_primary_key FROM pg_attribute f JOIN pg_class c ON c.oid = f.attrelid @@ -400,27 +400,27 @@ export class PostgresDriver extends AbstractDriver { ORDER BY c.relname,f.attname;`)).rows; entities.forEach(ent => { response - .filter(filterVal => filterVal.tablename == ent.EntityName) + .filter(filterVal => filterVal.tablename === ent.EntityName) .forEach(resp => { 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 = [] 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; - if (resp.is_primary_key == 0) { + if (resp.is_primary_key === 0) { indexInfo.isPrimaryKey = false; } indexInfo.columns.push(indexColumnInfo); @@ -483,16 +483,16 @@ export class PostgresDriver extends AbstractDriver { const relationsTemp: IRelationTempInfo[] = [] as IRelationTempInfo[]; response.forEach(resp => { let rels = relationsTemp.find( - val => val.object_id == resp.object_id + val => val.object_id === resp.object_id ); - if (rels == undefined) { + if (rels === undefined) { rels = {} as IRelationTempInfo; 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; diff --git a/src/drivers/SqliteDriver.ts b/src/drivers/SqliteDriver.ts index 530c869..5e1cfc1 100644 --- a/src/drivers/SqliteDriver.ts +++ b/src/drivers/SqliteDriver.ts @@ -136,7 +136,6 @@ export class SqliteDriver extends AbstractDriver { colInfo.tsType = "Date"; break; default: - console.log(colInfo.sqlType.toLowerCase().trim()); TomgUtils.LogError( `Unknown column type: ${ colInfo.sqlType @@ -303,7 +302,11 @@ export class SqliteDriver extends AbstractDriver { const promise = new Promise((resolve, reject) => { this.db = new this.sqlite.Database(dbName, err => { if (err) { - console.error(err.message); + TomgUtils.LogError( + "Error connecting to SQLite database.", + false, + err.message + ); reject(err); return; } diff --git a/src/index.ts b/src/index.ts index dbad34a..6e36e54 100644 --- a/src/index.ts +++ b/src/index.ts @@ -148,6 +148,7 @@ switch (argv.e) { } let namingStrategy: AbstractNamingStrategy; if (argv.namingStrategy && argv.namingStrategy !== "") { + // tslint:disable-next-line:no-var-requires const req = require(argv.namingStrategy); namingStrategy = new req.NamingStrategy(); } else { diff --git a/src/tslint.json b/src/tslint.json index b48b355..bd2c46b 100644 --- a/src/tslint.json +++ b/src/tslint.json @@ -4,6 +4,8 @@ "tslint:recommended", "tslint-config-prettier" ], "jsRules": {}, - "rules": {}, + "rules": { + "no-console":false + }, "rulesDirectory": [] }