more refactorings

This commit is contained in:
Kononnable 2019-01-22 15:58:57 +01:00
parent c34f2912e0
commit dd59fd3eca
16 changed files with 450 additions and 506 deletions

View File

@ -1,11 +1,11 @@
import { DatabaseModel } from "./models/DatabaseModel";
import { EntityInfo } from "./models/EntityInfo";
import { RelationInfo } from "./models/RelationInfo";
export abstract class AbstractNamingStrategy {
public abstract relationName(
columnName: string,
relation: RelationInfo,
dbModel: DatabaseModel
dbModel: EntityInfo[]
): string;
public abstract entityName(entityName: string): string;

View File

@ -10,213 +10,207 @@ import { MysqlDriver } from "./drivers/MysqlDriver";
import { OracleDriver } from "./drivers/OracleDriver";
import { PostgresDriver } from "./drivers/PostgresDriver";
import { SqliteDriver } from "./drivers/SqliteDriver";
import { DatabaseModel } from "./models/DatabaseModel";
import { EntityInfo } from "./models/EntityInfo";
import { NamingStrategy } from "./NamingStrategy";
import * as TomgUtils from "./Utils";
export class Engine {
public static createDriver(driverName: string): AbstractDriver {
switch (driverName) {
case "mssql":
return new MssqlDriver();
case "postgres":
return new PostgresDriver();
case "mysql":
return new MysqlDriver();
case "mariadb":
return new MariaDbDriver();
case "oracle":
return new OracleDriver();
case "sqlite":
return new SqliteDriver();
default:
TomgUtils.LogError("Database engine not recognized.", false);
throw new Error("Database engine not recognized.");
}
export function createDriver(driverName: string): AbstractDriver {
switch (driverName) {
case "mssql":
return new MssqlDriver();
case "postgres":
return new PostgresDriver();
case "mysql":
return new MysqlDriver();
case "mariadb":
return new MariaDbDriver();
case "oracle":
return new OracleDriver();
case "sqlite":
return new SqliteDriver();
default:
TomgUtils.LogError("Database engine not recognized.", false);
throw new Error("Database engine not recognized.");
}
}
public static async createModelFromDatabase(
driver: AbstractDriver,
connectionOptions: IConnectionOptions,
generationOptions: IGenerationOptions
): Promise<boolean> {
const dbModel = await driver.GetDataFromServer(
connectionOptions.databaseName,
connectionOptions.host,
connectionOptions.port,
connectionOptions.user,
connectionOptions.password,
connectionOptions.schemaName,
connectionOptions.ssl,
generationOptions.relationIds
);
if (dbModel.entities.length > 0) {
this.ApplyNamingStrategy(dbModel, generationOptions.namingStrategy);
this.createModelFromMetadata(
dbModel,
connectionOptions,
generationOptions
);
} else {
TomgUtils.LogError(
"Tables not found in selected database. Skipping creation of typeorm model.",
false
);
}
return true;
}
private static createModelFromMetadata(
databaseModel: DatabaseModel,
connectionOptions: IConnectionOptions,
generationOptions: IGenerationOptions
) {
this.createHandlebarsHelpers(generationOptions);
const templatePath = path.resolve(__dirname, "../../src/entity.mst");
const template = fs.readFileSync(templatePath, "UTF-8");
const resultPath = generationOptions.resultsPath;
if (!fs.existsSync(resultPath)) {
fs.mkdirSync(resultPath);
}
let entitesPath = resultPath;
if (!generationOptions.noConfigs) {
this.createTsConfigFile(resultPath);
this.createTypeOrmConfig(resultPath, connectionOptions);
entitesPath = path.resolve(resultPath, "./entities");
if (!fs.existsSync(entitesPath)) {
fs.mkdirSync(entitesPath);
}
}
const compliedTemplate = Handlebars.compile(template, {
noEscape: true
});
databaseModel.entities.forEach(element => {
element.Imports = [];
element.Columns.forEach(column => {
column.relations.forEach(relation => {
if (element.tsEntityName !== relation.relatedTable) {
element.Imports.push(relation.relatedTable);
}
export async function createModelFromDatabase(
driver: AbstractDriver,
connectionOptions: IConnectionOptions,
generationOptions: IGenerationOptions
) {
function setRelationId(model: EntityInfo[]) {
if (generationOptions.relationIds) {
model.forEach(ent => {
ent.Columns.forEach(col => {
col.relations.map(rel => {
rel.relationIdField = rel.isOwner;
});
});
});
element.GenerateConstructor = generationOptions.constructor;
element.IsActiveRecord = generationOptions.activeRecord;
element.Imports.filter((elem, index, self) => {
return index === self.indexOf(elem);
});
let casedFileName = "";
switch (generationOptions.convertCaseFile) {
case "camel":
casedFileName = changeCase.camelCase(element.tsEntityName);
break;
case "param":
casedFileName = changeCase.paramCase(element.tsEntityName);
break;
case "pascal":
casedFileName = changeCase.pascalCase(element.tsEntityName);
break;
case "none":
casedFileName = element.tsEntityName;
break;
}
const resultFilePath = path.resolve(
entitesPath,
casedFileName + ".ts"
);
const rendered = compliedTemplate(element);
fs.writeFileSync(resultFilePath, rendered, {
encoding: "UTF-8",
flag: "w"
});
});
}
private static createHandlebarsHelpers(
generationOptions: IGenerationOptions
) {
Handlebars.registerHelper("curly", open => (open ? "{" : "}"));
Handlebars.registerHelper("toEntityName", str => {
let retStr = "";
switch (generationOptions.convertCaseEntity) {
case "camel":
retStr = changeCase.camelCase(str);
break;
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper("concat", (stra, strb) => {
return stra + strb;
});
Handlebars.registerHelper("toFileName", str => {
let retStr = "";
switch (generationOptions.convertCaseFile) {
case "camel":
retStr = changeCase.camelCase(str);
break;
case "param":
retStr = changeCase.paramCase(str);
break;
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper(
"printPropertyVisibility",
() =>
generationOptions.propertyVisibility !== "none"
? generationOptions.propertyVisibility + " "
: ""
);
Handlebars.registerHelper("toPropertyName", str => {
let retStr = "";
switch (generationOptions.convertCaseProperty) {
case "camel":
retStr = changeCase.camelCase(str);
break;
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper("toLowerCase", str => str.toLowerCase());
Handlebars.registerHelper("toLazy", str => {
if (generationOptions.lazy) {
return `Promise<${str}>`;
} else {
return str;
}
});
Handlebars.registerHelper({
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
});
}
return model;
}
// TODO:Move to mustache template file
private static createTsConfigFile(resultPath) {
fs.writeFileSync(
path.resolve(resultPath, "tsconfig.json"),
`{"compilerOptions": {
let dbModel = await driver.GetDataFromServer(connectionOptions);
if (dbModel.length === 0) {
TomgUtils.LogError(
"Tables not found in selected database. Skipping creation of typeorm model.",
false
);
return;
}
dbModel = setRelationId(dbModel);
dbModel = ApplyNamingStrategy(generationOptions.namingStrategy, dbModel);
createModelFromMetadata(connectionOptions, generationOptions, dbModel);
}
function createModelFromMetadata(
connectionOptions: IConnectionOptions,
generationOptions: IGenerationOptions,
databaseModel: EntityInfo[]
) {
createHandlebarsHelpers(generationOptions);
const templatePath = path.resolve(__dirname, "../../src/entity.mst");
const template = fs.readFileSync(templatePath, "UTF-8");
const resultPath = generationOptions.resultsPath;
if (!fs.existsSync(resultPath)) {
fs.mkdirSync(resultPath);
}
let entitesPath = resultPath;
if (!generationOptions.noConfigs) {
createTsConfigFile(resultPath);
createTypeOrmConfig(resultPath, connectionOptions);
entitesPath = path.resolve(resultPath, "./entities");
if (!fs.existsSync(entitesPath)) {
fs.mkdirSync(entitesPath);
}
}
const compliedTemplate = Handlebars.compile(template, {
noEscape: true
});
databaseModel.forEach(element => {
element.Imports = [];
element.Columns.forEach(column => {
column.relations.forEach(relation => {
if (element.tsEntityName !== relation.relatedTable) {
element.Imports.push(relation.relatedTable);
}
});
});
element.GenerateConstructor = generationOptions.constructor;
element.IsActiveRecord = generationOptions.activeRecord;
element.Imports.filter((elem, index, self) => {
return index === self.indexOf(elem);
});
let casedFileName = "";
switch (generationOptions.convertCaseFile) {
case "camel":
casedFileName = changeCase.camelCase(element.tsEntityName);
break;
case "param":
casedFileName = changeCase.paramCase(element.tsEntityName);
break;
case "pascal":
casedFileName = changeCase.pascalCase(element.tsEntityName);
break;
case "none":
casedFileName = element.tsEntityName;
break;
}
const resultFilePath = path.resolve(entitesPath, casedFileName + ".ts");
const rendered = compliedTemplate(element);
fs.writeFileSync(resultFilePath, rendered, {
encoding: "UTF-8",
flag: "w"
});
});
}
function createHandlebarsHelpers(generationOptions: IGenerationOptions) {
Handlebars.registerHelper("curly", open => (open ? "{" : "}"));
Handlebars.registerHelper("toEntityName", str => {
let retStr = "";
switch (generationOptions.convertCaseEntity) {
case "camel":
retStr = changeCase.camelCase(str);
break;
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper("concat", (stra, strb) => {
return stra + strb;
});
Handlebars.registerHelper("toFileName", str => {
let retStr = "";
switch (generationOptions.convertCaseFile) {
case "camel":
retStr = changeCase.camelCase(str);
break;
case "param":
retStr = changeCase.paramCase(str);
break;
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper(
"printPropertyVisibility",
() =>
generationOptions.propertyVisibility !== "none"
? generationOptions.propertyVisibility + " "
: ""
);
Handlebars.registerHelper("toPropertyName", str => {
let retStr = "";
switch (generationOptions.convertCaseProperty) {
case "camel":
retStr = changeCase.camelCase(str);
break;
case "pascal":
retStr = changeCase.pascalCase(str);
break;
case "none":
retStr = str;
break;
}
return retStr;
});
Handlebars.registerHelper("toLowerCase", str => str.toLowerCase());
Handlebars.registerHelper("toLazy", str => {
if (generationOptions.lazy) {
return `Promise<${str}>`;
} else {
return str;
}
});
Handlebars.registerHelper({
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
});
}
// TODO:Move to mustache template file
function createTsConfigFile(resultPath) {
fs.writeFileSync(
path.resolve(resultPath, "tsconfig.json"),
`{"compilerOptions": {
"lib": ["es5", "es6"],
"target": "es6",
"module": "commonjs",
@ -225,17 +219,17 @@ export class Engine {
"experimentalDecorators": true,
"sourceMap": true
}}`,
{ encoding: "UTF-8", flag: "w" }
);
}
private static createTypeOrmConfig(
resultPath: string,
connectionOptions: IConnectionOptions
) {
if (connectionOptions.schemaName === "") {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{ encoding: "UTF-8", flag: "w" }
);
}
function createTypeOrmConfig(
resultPath: string,
connectionOptions: IConnectionOptions
) {
if (connectionOptions.schemaName === "") {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{
"name": "default",
"type": "${connectionOptions.databaseType}",
@ -250,12 +244,12 @@ export class Engine {
]
}
]`,
{ encoding: "UTF-8", flag: "w" }
);
} else {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{ encoding: "UTF-8", flag: "w" }
);
} else {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{
"name": "default",
"type": "${connectionOptions.databaseType}",
@ -271,89 +265,29 @@ export class Engine {
]
}
]`,
{ encoding: "UTF-8", flag: "w" }
);
}
{ encoding: "UTF-8", flag: "w" }
);
}
private static ApplyNamingStrategy(
dbModel: DatabaseModel,
namingStrategy: NamingStrategy
) {
this.changeRelationNames(dbModel, namingStrategy);
this.changeEntityNames(dbModel, namingStrategy);
this.changeColumnNames(dbModel, namingStrategy);
}
private static changeColumnNames(
dbModel: DatabaseModel,
namingStrategy: NamingStrategy
) {
dbModel.entities.forEach(entity => {
entity.Columns.forEach(column => {
const newName = 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.tsEntityName &&
relation.relatedColumn === column.tsName
)
.map(v => (v.relatedColumn = newName));
column2.relations
.filter(
relation =>
relation.relatedTable ===
entity.tsEntityName &&
relation.ownerColumn === column.tsName
)
.map(v => (v.ownerColumn = newName));
});
});
}
function ApplyNamingStrategy(
namingStrategy: NamingStrategy,
dbModel: EntityInfo[]
) {
dbModel = changeRelationNames(dbModel);
dbModel = changeEntityNames(dbModel);
dbModel = changeColumnNames(dbModel);
return dbModel;
column.tsName = newName;
});
});
}
private static changeEntityNames(
dbModel: DatabaseModel,
namingStrategy: NamingStrategy
) {
dbModel.entities.forEach(entity => {
const newName = namingStrategy.entityName(entity.tsEntityName);
dbModel.entities.forEach(entity2 => {
entity2.Columns.forEach(column => {
column.relations.forEach(relation => {
if (relation.ownerTable === entity.tsEntityName) {
relation.ownerTable = newName;
}
if (relation.relatedTable === entity.tsEntityName) {
relation.relatedTable = newName;
}
});
});
});
entity.tsEntityName = newName;
});
}
private static changeRelationNames(
dbModel: DatabaseModel,
namingStrategy: NamingStrategy
) {
dbModel.entities.forEach(entity => {
function changeRelationNames(model: EntityInfo[]) {
model.forEach(entity => {
entity.Columns.forEach(column => {
column.relations.forEach(relation => {
const newName = namingStrategy.relationName(
column.tsName,
relation,
dbModel
model
);
dbModel.entities.forEach(entity2 => {
model.forEach(entity2 => {
entity2.Columns.forEach(column2 => {
column2.relations.forEach(relation2 => {
if (
@ -389,6 +323,62 @@ export class Engine {
});
});
});
return dbModel;
}
function changeColumnNames(model: EntityInfo[]) {
model.forEach(entity => {
entity.Columns.forEach(column => {
const newName = namingStrategy.columnName(column.tsName);
entity.Indexes.forEach(index => {
index.columns
.filter(column2 => column2.name === column.tsName)
.forEach(column2 => (column2.name = newName));
});
model.forEach(entity2 => {
entity2.Columns.forEach(column2 => {
column2.relations
.filter(
relation =>
relation.relatedTable ===
entity.tsEntityName &&
relation.relatedColumn === column.tsName
)
.map(v => (v.relatedColumn = newName));
column2.relations
.filter(
relation =>
relation.relatedTable ===
entity.tsEntityName &&
relation.ownerColumn === column.tsName
)
.map(v => (v.ownerColumn = newName));
});
});
column.tsName = newName;
});
});
return model;
}
function changeEntityNames(entities: EntityInfo[]) {
entities.forEach(entity => {
const newName = namingStrategy.entityName(entity.tsEntityName);
entities.forEach(entity2 => {
entity2.Columns.forEach(column => {
column.relations.forEach(relation => {
if (relation.ownerTable === entity.tsEntityName) {
relation.ownerTable = newName;
}
if (relation.relatedTable === entity.tsEntityName) {
relation.relatedTable = newName;
}
});
});
});
entity.tsEntityName = newName;
});
return entities;
}
}

View File

@ -1,15 +1,15 @@
import { AbstractNamingStrategy } from "./AbstractNamingStrategy";
import { DatabaseModel } from "./models/DatabaseModel";
import { EntityInfo } from "./models/EntityInfo";
import { RelationInfo } from "./models/RelationInfo";
export class NamingStrategy extends AbstractNamingStrategy {
public relationName(
columnOldName: string,
relation: RelationInfo,
dbModel: DatabaseModel
dbModel: EntityInfo[]
): string {
const isRelationToMany = relation.isOneToMany || relation.isManyToMany;
const ownerEntity = dbModel.entities.find(
const ownerEntity = dbModel.find(
v => v.tsEntityName === relation.ownerTable
)!;

View File

@ -3,8 +3,8 @@ import {
WithPrecisionColumnType,
WithWidthColumnType
} from "typeorm/driver/types/ColumnTypes";
import { IConnectionOptions } from "../Engine";
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";
@ -56,7 +56,6 @@ export abstract class AbstractDriver {
"binary",
"varbinary"
];
public generateRelationsIds: boolean;
public abstract GetAllTablesQuery: (
schema: string
@ -67,8 +66,8 @@ export abstract class AbstractDriver {
}>
>;
public FindManyToManyRelations(dbModel: DatabaseModel) {
const manyToManyEntities = dbModel.entities.filter(
public FindManyToManyRelations(dbModel: EntityInfo[]) {
const manyToManyEntities = dbModel.filter(
entity =>
entity.Columns.filter(column => {
return (
@ -88,7 +87,7 @@ export abstract class AbstractDriver {
.map(v => v.relatedTable)
.filter((v, i, s) => s.indexOf(v) === i);
if (namesOfRelatedTables.length === 2) {
const relatedTable1 = dbModel.entities.find(
const relatedTable1 = dbModel.find(
v => v.tsEntityName === namesOfRelatedTables[0]
)!;
relatedTable1.Columns = relatedTable1.Columns.filter(
@ -97,7 +96,7 @@ export abstract class AbstractDriver {
.toLowerCase()
.startsWith(entity.tsEntityName.toLowerCase())
);
const relatedTable2 = dbModel.entities.find(
const relatedTable2 = dbModel.find(
v => v.tsEntityName === namesOfRelatedTables[1]
)!;
relatedTable2.Columns = relatedTable2.Columns.filter(
@ -106,7 +105,7 @@ export abstract class AbstractDriver {
.toLowerCase()
.startsWith(entity.tsEntityName.toLowerCase())
);
dbModel.entities = dbModel.entities.filter(ent => {
dbModel = dbModel.filter(ent => {
return ent.tsEntityName !== entity.tsEntityName;
});
@ -137,42 +136,26 @@ export abstract class AbstractDriver {
relatedTable2.Columns.push(column2);
}
});
return dbModel;
}
public async GetDataFromServer(
database: string,
server: string,
port: number,
user: string,
password: string,
schema: string,
ssl: boolean,
relationIds: boolean
): Promise<DatabaseModel> {
this.generateRelationsIds = relationIds;
const dbModel = {} as DatabaseModel;
await this.ConnectToServer(database, server, port, user, password, ssl);
const sqlEscapedSchema = "'" + schema.split(",").join("','") + "'";
dbModel.entities = await this.GetAllTables(sqlEscapedSchema);
await this.GetCoulmnsFromEntity(dbModel.entities, sqlEscapedSchema);
await this.GetIndexesFromEntity(dbModel.entities, sqlEscapedSchema);
dbModel.entities = await this.GetRelations(
dbModel.entities,
sqlEscapedSchema
);
connectionOptons: IConnectionOptions
): Promise<EntityInfo[]> {
let dbModel = [] as EntityInfo[];
await this.ConnectToServer(connectionOptons);
const sqlEscapedSchema =
"'" + connectionOptons.schemaName.split(",").join("','") + "'";
dbModel = await this.GetAllTables(sqlEscapedSchema);
await this.GetCoulmnsFromEntity(dbModel, sqlEscapedSchema);
await this.GetIndexesFromEntity(dbModel, sqlEscapedSchema);
dbModel = await this.GetRelations(dbModel, sqlEscapedSchema);
await this.DisconnectFromServer();
this.FindManyToManyRelations(dbModel);
dbModel = this.FindManyToManyRelations(dbModel);
this.FindPrimaryColumnsFromIndexes(dbModel);
return dbModel;
}
public abstract async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
);
public abstract async ConnectToServer(connectionOptons: IConnectionOptions);
public async GetAllTables(schema: string): Promise<EntityInfo[]> {
const response = await this.GetAllTablesQuery(schema);
@ -276,7 +259,6 @@ export abstract class AbstractDriver {
ownerRelation.relationType = isOneToMany
? "ManyToOne"
: "OneToOne";
ownerRelation.relationIdField = this.generateRelationsIds;
let columnName = ownerEntity.tsEntityName;
if (
@ -351,8 +333,8 @@ export abstract class AbstractDriver {
schema: string
): Promise<EntityInfo[]>;
public FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
public FindPrimaryColumnsFromIndexes(dbModel: EntityInfo[]) {
dbModel.forEach(entity => {
const primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
entity.Columns.filter(
col =>

View File

@ -1,4 +1,5 @@
import * as MSSQL from "mssql";
import { IConnectionOptions } from "../Engine";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
@ -354,24 +355,17 @@ order by
await this.Connection.close();
}
}
public async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
public async ConnectToServer(connectionOptons: IConnectionOptions) {
const config: MSSQL.config = {
database,
database: connectionOptons.databaseName,
options: {
appName: "typeorm-model-generator",
encrypt: ssl
encrypt: connectionOptons.ssl
},
password,
port,
server,
user
password: connectionOptons.password,
port: connectionOptons.port,
server: connectionOptons.host,
user: connectionOptons.user
};
const promise = new Promise<boolean>((resolve, reject) => {

View File

@ -1,4 +1,5 @@
import * as MYSQL from "mysql";
import { IConnectionOptions } from "../Engine";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
@ -339,33 +340,26 @@ export class MysqlDriver extends AbstractDriver {
await promise;
}
}
public async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
public async ConnectToServer(connectionOptons: IConnectionOptions) {
let config: MYSQL.ConnectionConfig;
if (ssl) {
if (connectionOptons.ssl) {
config = {
database,
host: server,
password,
port,
database: connectionOptons.databaseName,
host: connectionOptons.host,
password: connectionOptons.password,
port: connectionOptons.port,
ssl: {
rejectUnauthorized: false
},
user
user: connectionOptons.user
};
} else {
config = {
database,
host: server,
password,
port,
user
database: connectionOptons.databaseName,
host: connectionOptons.host,
password: connectionOptons.password,
port: connectionOptons.port,
user: connectionOptons.user
};
}

View File

@ -1,3 +1,4 @@
import { IConnectionOptions } from "../Engine";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
@ -291,29 +292,26 @@ export class OracleDriver extends AbstractDriver {
await this.Connection.close();
}
}
public async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
public async ConnectToServer(connectionOptons: IConnectionOptions) {
let config: any;
if (user === String(process.env.ORACLE_UsernameSys)) {
if (connectionOptons.user === String(process.env.ORACLE_UsernameSys)) {
config /*Oracle.IConnectionAttributes*/ = {
connectString: `${server}:${port}/${database}`,
externalAuth: ssl,
password,
connectString: `${connectionOptons.host}:${
connectionOptons.port
}/${connectionOptons.databaseName}`,
externalAuth: connectionOptons.ssl,
password: connectionOptons.password,
privilege: this.Oracle.SYSDBA,
user
user: connectionOptons.user
};
} else {
config /*Oracle.IConnectionAttributes*/ = {
connectString: `${server}:${port}/${database}`,
externalAuth: ssl,
password,
user
connectString: `${connectionOptons.host}:${
connectionOptons.port
}/${connectionOptons.databaseName}`,
externalAuth: connectionOptons.ssl,
password: connectionOptons.password,
user: connectionOptons.user
};
}
const that = this;

View File

@ -1,4 +1,5 @@
import * as PG from "pg";
import { IConnectionOptions } from "../Engine";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
@ -531,21 +532,14 @@ export class PostgresDriver extends AbstractDriver {
}
}
public async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
public async ConnectToServer(connectionOptons: IConnectionOptions) {
this.Connection = new PG.Client({
database,
host: server,
password,
port,
ssl,
user
database: connectionOptons.databaseName,
host: connectionOptons.host,
password: connectionOptons.password,
port: connectionOptons.port,
ssl: connectionOptons.ssl,
user: connectionOptons.user
});
const promise = new Promise<boolean>((resolve, reject) => {

View File

@ -1,3 +1,4 @@
import { IConnectionOptions } from "../Engine";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
@ -292,15 +293,8 @@ export class SqliteDriver extends AbstractDriver {
this.db.close();
}
public async ConnectToServer(
database: string,
server: string,
port: number,
user: string,
password: string,
ssl: boolean
) {
await this.UseDB(database);
public async ConnectToServer(connectionOptons: IConnectionOptions) {
await this.UseDB(connectionOptons.databaseName);
}
public async CreateDB(dbName: string) {

View File

@ -1,7 +1,12 @@
import path = require("path");
import * as Yargs from "yargs";
import { AbstractNamingStrategy } from "./AbstractNamingStrategy";
import { Engine, IConnectionOptions, IGenerationOptions } from "./Engine";
import {
createDriver,
createModelFromDatabase,
IConnectionOptions,
IGenerationOptions
} from "./Engine";
import { NamingStrategy } from "./NamingStrategy";
import * as TomgUtils from "./Utils";
@ -105,7 +110,7 @@ const argv = Yargs.usage(
describe: "Generate constructor allowing partial initialization"
}).argv;
const driver = Engine.createDriver(argv.e);
const driver = createDriver(argv.e);
const standardPort = driver.standardPort;
const standardSchema = driver.standardPort;
const standardUser = driver.standardPort;
@ -146,12 +151,10 @@ console.log(TomgUtils.packageVersion());
console.log(
`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`
);
Engine.createModelFromDatabase(
driver,
connectionOptions,
generationOptions
).then(() => {
console.info(
`[${new Date().toLocaleTimeString()}] Typeorm model classes created.`
);
});
createModelFromDatabase(driver, connectionOptions, generationOptions).then(
() => {
console.info(
`[${new Date().toLocaleTimeString()}] Typeorm model classes created.`
);
}
);

View File

@ -1,4 +0,0 @@
import { EntityInfo } from "./EntityInfo";
export class DatabaseModel {
public entities: EntityInfo[];
}

View File

@ -7,7 +7,7 @@ import { EntityFileToJson } from "../utils/EntityFileToJson";
import chai = require('chai');
import chaiSubset = require('chai-subset');
import * as ts from "typescript";
import { Engine } from "../../src/Engine";
import { createDriver, createModelFromDatabase } from "../../src/Engine";
import * as GTU from "../utils/GeneralTestUtils"
chai.use(chaiSubset);
@ -32,11 +32,11 @@ describe("Column default values", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
const driver = Engine.createDriver(dbDriver);
const driver = createDriver(dbDriver);
const connectionOptions = await GTU.createModelsInDb(dbDriver, filesOrgPathJS);
const generationOptions = GTU.getGenerationOptions(resultsPath);
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
await createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -7,7 +7,7 @@ import { EntityFileToJson } from "../utils/EntityFileToJson";
import chai = require('chai');
import chaiSubset = require('chai-subset');
import * as ts from "typescript";
import { Engine } from "../../src/Engine";
import { createDriver, createModelFromDatabase } from "../../src/Engine";
import * as GTU from "../utils/GeneralTestUtils"
chai.use(chaiSubset);
@ -32,11 +32,11 @@ describe("Platform specyfic types", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
const driver = Engine.createDriver(dbDriver);
const driver = createDriver(dbDriver);
const connectionOptions = await GTU.createModelsInDb(dbDriver, filesOrgPathJS);
const generationOptions = GTU.getGenerationOptions(resultsPath);
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
await createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -3,7 +3,7 @@ import { expect } from "chai";
import fs = require('fs-extra');
import path = require('path')
import "reflect-metadata";
import { Engine } from "../../src/Engine";
import { createModelFromDatabase, createDriver } from "../../src/Engine";
import { EntityFileToJson } from "../utils/EntityFileToJson";
import chai = require('chai');
import chaiSubset = require('chai-subset');
@ -45,7 +45,7 @@ describe("GitHub issues", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
const driver = Engine.createDriver(dbDriver);
const driver = createDriver(dbDriver);
const connectionOptions = await GTU.createModelsInDb(dbDriver, filesOrgPathJS);
const generationOptions = GTU.getGenerationOptions(resultsPath);
@ -57,7 +57,7 @@ describe("GitHub issues", async function () {
break;
}
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
await createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -3,7 +3,7 @@ import { expect } from "chai";
import fs = require('fs-extra');
import path = require('path')
import "reflect-metadata";
import { Engine } from "../../src/Engine";
import { createModelFromDatabase, createDriver } from "../../src/Engine";
import { EntityFileToJson } from "../utils/EntityFileToJson";
import chai = require('chai');
import chaiSubset = require('chai-subset');
@ -31,7 +31,7 @@ describe("TypeOrm examples", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
const driver=Engine.createDriver(dbDriver);
const driver=createDriver(dbDriver);
const connectionOptions = await GTU.createModelsInDb(dbDriver, filesOrgPathJS);
const generationOptions = GTU.getGenerationOptions(resultsPath);
@ -39,7 +39,7 @@ describe("TypeOrm examples", async function () {
generationOptions.lazy = true;
}
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
await createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -32,7 +32,18 @@ export async function createMSSQLModels(filesOrgPath: string): Promise<IConnecti
let driver: AbstractDriver;
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));
const connectionOptions: IConnectionOptions = {
host: String(process.env.MSSQL_Host),
port: Number(process.env.MSSQL_Port),
databaseName: `master`,
user: String(process.env.MSSQL_Username),
password: String(process.env.MSSQL_Password),
databaseType: 'mssql',
schemaName: 'dbo,sch1,sch2',
ssl: yn(process.env.MSSQL_SSL),
}
await driver.ConnectToServer(connectionOptions);
connectionOptions.databaseName = String(process.env.MSSQL_Database);
if (await driver.CheckIfDBExists(String(process.env.MSSQL_Database))) {
await driver.DropDB(String(process.env.MSSQL_Database));
@ -64,24 +75,24 @@ export async function createMSSQLModels(filesOrgPath: string): Promise<IConnecti
await conn.close()
}
const connectionOptions: IConnectionOptions = {
host: String(process.env.MSSQL_Host),
port: Number(process.env.MSSQL_Port),
databaseName: String(process.env.MSSQL_Database),
user: String(process.env.MSSQL_Username),
password: String(process.env.MSSQL_Password),
databaseType: 'mssql',
schemaName: 'dbo,sch1,sch2',
ssl: yn(process.env.MSSQL_SSL),
}
return connectionOptions;
}
export async function createPostgresModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
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));
const connectionOptions: IConnectionOptions = {
host: String(process.env.POSTGRES_Host),
port: Number(process.env.POSTGRES_Port),
databaseName: `postgres`,
user: String(process.env.POSTGRES_Username),
password: String(process.env.POSTGRES_Password),
databaseType: 'postgres',
schemaName: 'public,sch1,sch2',
ssl: yn(process.env.POSTGRES_SSL),
}
await driver.ConnectToServer(connectionOptions);
connectionOptions.databaseName = String(process.env.POSTGRES_Database);
if (await driver.CheckIfDBExists(String(process.env.POSTGRES_Database))) {
await driver.DropDB(String(process.env.POSTGRES_Database));
@ -113,24 +124,23 @@ export async function createPostgresModels(filesOrgPath: string): Promise<IConne
await conn.close()
}
const connectionOptions: IConnectionOptions = {
host: String(process.env.POSTGRES_Host),
port: Number(process.env.POSTGRES_Port),
databaseName: String(process.env.POSTGRES_Database),
user: String(process.env.POSTGRES_Username),
password: String(process.env.POSTGRES_Password),
databaseType: 'postgres',
schemaName: 'public,sch1,sch2',
ssl: yn(process.env.POSTGRES_SSL),
}
return connectionOptions;
}
export async function createSQLiteModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new SqliteDriver();
await driver.ConnectToServer(String(process.env.SQLITE_Database), '', 0, '', '', false);
const connectionOptions: IConnectionOptions = {
host: '',
port: 0,
databaseName: String(process.env.SQLITE_Database),
user: '',
password: '',
databaseType: 'sqlite',
schemaName: '',
ssl: false,
}
await driver.ConnectToServer(connectionOptions);
if (await driver.CheckIfDBExists(String(process.env.SQLITE_Database))) {
await driver.DropDB(String(process.env.SQLITE_Database));
@ -153,24 +163,23 @@ export async function createSQLiteModels(filesOrgPath: string): Promise<IConnect
await conn.close()
}
const connectionOptions: IConnectionOptions = {
host: '',
port: 0,
databaseName: String(process.env.SQLITE_Database),
user: '',
password: '',
databaseType: 'sqlite',
schemaName: '',
ssl: false,
}
return connectionOptions;
}
export async function createMysqlModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new MysqlDriver();
await driver.ConnectToServer(String(process.env.MYSQL_Database), 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));
const connectionOptions: IConnectionOptions = {
host: String(process.env.MYSQL_Host),
port: Number(process.env.MYSQL_Port),
databaseName: String(process.env.MYSQL_Database),
user: String(process.env.MYSQL_Username),
password: String(process.env.MYSQL_Password),
databaseType: 'mysql',
schemaName: 'ignored',
ssl: yn(process.env.MYSQL_SSL),
}
await driver.ConnectToServer(connectionOptions);
if (await driver.CheckIfDBExists(String(process.env.MYSQL_Database))) {
await driver.DropDB(String(process.env.MYSQL_Database));
@ -195,23 +204,22 @@ export async function createMysqlModels(filesOrgPath: string): Promise<IConnecti
await conn.close()
}
const connectionOptions: IConnectionOptions = {
host: String(process.env.MYSQL_Host),
port: Number(process.env.MYSQL_Port),
databaseName: String(process.env.MYSQL_Database),
user: String(process.env.MYSQL_Username),
password: String(process.env.MYSQL_Password),
databaseType: 'mysql',
schemaName: 'ignored',
ssl: yn(process.env.MYSQL_SSL),
}
return connectionOptions;
}
export async function createMariaDBModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new MariaDbDriver();
await driver.ConnectToServer(String(process.env.MARIADB_Database), 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));
const connectionOptions: IConnectionOptions = {
host: String(process.env.MARIADB_Host),
port: Number(process.env.MARIADB_Port),
databaseName: String(process.env.MARIADB_Database),
user: String(process.env.MARIADB_Username),
password: String(process.env.MARIADB_Password),
databaseType: 'mariadb',
schemaName: 'ignored',
ssl: yn(process.env.MARIADB_SSL),
}
await driver.ConnectToServer(connectionOptions);
if (await driver.CheckIfDBExists(String(process.env.MARIADB_Database))) {
await driver.DropDB(String(process.env.MARIADB_Database));
@ -236,24 +244,26 @@ export async function createMariaDBModels(filesOrgPath: string): Promise<IConnec
await conn.close()
}
const connectionOptions: IConnectionOptions = {
host: String(process.env.MARIADB_Host),
port: Number(process.env.MARIADB_Port),
databaseName: String(process.env.MARIADB_Database),
user: String(process.env.MARIADB_Username),
password: String(process.env.MARIADB_Password),
databaseType: 'mariadb',
schemaName: 'ignored',
ssl: yn(process.env.MARIADB_SSL),
}
return connectionOptions;
}
export async function createOracleDBModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
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));
const connectionOptions: IConnectionOptions = {
host: String(process.env.ORACLE_Host),
port: Number(process.env.ORACLE_Port),
databaseName: String(process.env.ORACLE_Database),
user: String(process.env.ORACLE_UsernameSys),
password: String(process.env.ORACLE_PasswordSys),
databaseType: 'oracle',
schemaName: String(process.env.ORACLE_Username),
ssl: yn(process.env.ORACLE_SSL),
}
await driver.ConnectToServer(connectionOptions);
connectionOptions.user = String(process.env.ORACLE_Username)
connectionOptions.password = String(process.env.ORACLE_Password)
if (await driver.CheckIfDBExists(String(process.env.ORACLE_Username))) {
await driver.DropDB(String(process.env.ORACLE_Username));
@ -278,17 +288,6 @@ export async function createOracleDBModels(filesOrgPath: string): Promise<IConne
await conn.close()
}
const connectionOptions: IConnectionOptions = {
host: String(process.env.ORACLE_Host),
port: Number(process.env.ORACLE_Port),
databaseName: String(process.env.ORACLE_Database),
user: String(process.env.ORACLE_Username),
password: String(process.env.ORACLE_Password),
databaseType: 'oracle',
schemaName: String(process.env.ORACLE_Username),
ssl: yn(process.env.ORACLE_SSL),
}
return connectionOptions;
}