refactorings

This commit is contained in:
Kononnable 2019-01-21 21:32:42 +01:00
parent 3ba5ed6fb4
commit c62010c079
14 changed files with 448 additions and 552 deletions

View File

@ -4,29 +4,59 @@ import * as Handlebars from "handlebars";
import path = require("path");
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 { DatabaseModel } from "./models/DatabaseModel";
import { NamingStrategy } from "./NamingStrategy";
import * as TomgUtils from "./Utils";
export class Engine {
constructor(
private driver: AbstractDriver,
public Options: IEngineOptions
) {}
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.");
}
}
public async createModelFromDatabase(): Promise<boolean> {
const dbModel = await this.getEntitiesInfo(
this.Options.databaseName,
this.Options.host,
this.Options.port,
this.Options.user,
this.Options.password,
this.Options.schemaName,
this.Options.ssl,
this.Options.namingStrategy,
this.Options.relationIds
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.createModelFromMetadata(dbModel);
this.ApplyNamingStrategy(dbModel, generationOptions.namingStrategy);
this.createModelFromMetadata(
dbModel,
connectionOptions,
generationOptions
);
} else {
TomgUtils.LogError(
"Tables not found in selected database. Skipping creation of typeorm model.",
@ -35,41 +65,23 @@ export class Engine {
}
return true;
}
private async getEntitiesInfo(
database: string,
server: string,
port: number,
user: string,
password: string,
schemaName: string,
ssl: boolean,
namingStrategy: AbstractNamingStrategy,
relationIds: boolean
): Promise<DatabaseModel> {
return await this.driver.GetDataFromServer(
database,
server,
port,
user,
password,
schemaName,
ssl,
namingStrategy,
relationIds
);
}
private createModelFromMetadata(databaseModel: DatabaseModel) {
this.createHandlebarsHelpers();
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 = this.Options.resultsPath;
const resultPath = generationOptions.resultsPath;
if (!fs.existsSync(resultPath)) {
fs.mkdirSync(resultPath);
}
let entitesPath = resultPath;
if (!this.Options.noConfigs) {
if (!generationOptions.noConfigs) {
this.createTsConfigFile(resultPath);
this.createTypeOrmConfig(resultPath);
this.createTypeOrmConfig(resultPath, connectionOptions);
entitesPath = path.resolve(resultPath, "./entities");
if (!fs.existsSync(entitesPath)) {
fs.mkdirSync(entitesPath);
@ -87,13 +99,13 @@ export class Engine {
}
});
});
element.GenerateConstructor = this.Options.constructor;
element.IsActiveRecord = this.Options.activeRecord;
element.GenerateConstructor = generationOptions.constructor;
element.IsActiveRecord = generationOptions.activeRecord;
element.Imports.filter((elem, index, self) => {
return index === self.indexOf(elem);
});
let casedFileName = "";
switch (this.Options.convertCaseFile) {
switch (generationOptions.convertCaseFile) {
case "camel":
casedFileName = changeCase.camelCase(element.tsEntityName);
break;
@ -118,11 +130,13 @@ export class Engine {
});
});
}
private createHandlebarsHelpers() {
private static createHandlebarsHelpers(
generationOptions: IGenerationOptions
) {
Handlebars.registerHelper("curly", open => (open ? "{" : "}"));
Handlebars.registerHelper("toEntityName", str => {
let retStr = "";
switch (this.Options.convertCaseEntity) {
switch (generationOptions.convertCaseEntity) {
case "camel":
retStr = changeCase.camelCase(str);
break;
@ -140,7 +154,7 @@ export class Engine {
});
Handlebars.registerHelper("toFileName", str => {
let retStr = "";
switch (this.Options.convertCaseFile) {
switch (generationOptions.convertCaseFile) {
case "camel":
retStr = changeCase.camelCase(str);
break;
@ -159,13 +173,13 @@ export class Engine {
Handlebars.registerHelper(
"printPropertyVisibility",
() =>
this.Options.propertyVisibility !== "none"
? this.Options.propertyVisibility + " "
generationOptions.propertyVisibility !== "none"
? generationOptions.propertyVisibility + " "
: ""
);
Handlebars.registerHelper("toPropertyName", str => {
let retStr = "";
switch (this.Options.convertCaseProperty) {
switch (generationOptions.convertCaseProperty) {
case "camel":
retStr = changeCase.camelCase(str);
break;
@ -180,7 +194,7 @@ export class Engine {
});
Handlebars.registerHelper("toLowerCase", str => str.toLowerCase());
Handlebars.registerHelper("toLazy", str => {
if (this.Options.lazy) {
if (generationOptions.lazy) {
return `Promise<${str}>`;
} else {
return str;
@ -199,7 +213,7 @@ export class Engine {
}
// TODO:Move to mustache template file
private createTsConfigFile(resultPath) {
private static createTsConfigFile(resultPath) {
fs.writeFileSync(
path.resolve(resultPath, "tsconfig.json"),
`{"compilerOptions": {
@ -214,19 +228,22 @@ export class Engine {
{ encoding: "UTF-8", flag: "w" }
);
}
private createTypeOrmConfig(resultPath) {
if (this.Options.schemaName === "") {
private static createTypeOrmConfig(
resultPath: string,
connectionOptions: IConnectionOptions
) {
if (connectionOptions.schemaName === "") {
fs.writeFileSync(
path.resolve(resultPath, "ormconfig.json"),
`[
{
"name": "default",
"type": "${this.Options.databaseType}",
"host": "${this.Options.host}",
"port": ${this.Options.port},
"username": "${this.Options.user}",
"password": "${this.Options.password}",
"database": "${this.Options.databaseName}",
"type": "${connectionOptions.databaseType}",
"host": "${connectionOptions.host}",
"port": ${connectionOptions.port},
"username": "${connectionOptions.user}",
"password": "${connectionOptions.password}",
"database": "${connectionOptions.databaseName}",
"synchronize": false,
"entities": [
"entities/*.js"
@ -241,13 +258,13 @@ export class Engine {
`[
{
"name": "default",
"type": "${this.Options.databaseType}",
"host": "${this.Options.host}",
"port": ${this.Options.port},
"username": "${this.Options.user}",
"password": "${this.Options.password}",
"database": "${this.Options.databaseName}",
"schema": "${this.Options.schemaName}",
"type": "${connectionOptions.databaseType}",
"host": "${connectionOptions.host}",
"port": ${connectionOptions.port},
"username": "${connectionOptions.user}",
"password": "${connectionOptions.password}",
"database": "${connectionOptions.databaseName}",
"schema": "${connectionOptions.schemaName}",
"synchronize": false,
"entities": [
"entities/*.js"
@ -258,17 +275,135 @@ export class Engine {
);
}
}
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));
});
});
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 => {
entity.Columns.forEach(column => {
column.relations.forEach(relation => {
const newName = namingStrategy.relationName(
column.tsName,
relation,
dbModel
);
dbModel.entities.forEach(entity2 => {
entity2.Columns.forEach(column2 => {
column2.relations.forEach(relation2 => {
if (
relation2.relatedTable ===
entity.tsEntityName &&
relation2.ownerColumn === column.tsName
) {
relation2.ownerColumn = newName;
}
if (
relation2.relatedTable ===
entity.tsEntityName &&
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;
});
});
});
}
}
export interface IEngineOptions {
export interface IConnectionOptions {
host: string;
port: number;
databaseName: string;
user: string;
password: string;
resultsPath: string;
databaseType: string;
schemaName: string;
ssl: boolean;
}
export interface IGenerationOptions {
resultsPath: string;
noConfigs: boolean;
convertCaseFile: "pascal" | "param" | "camel" | "none";
convertCaseEntity: "pascal" | "camel" | "none";

View File

@ -11,6 +11,10 @@ import { RelationInfo } from "../models/RelationInfo";
import * as TomgUtils from "../Utils";
export abstract class AbstractDriver {
public abstract standardPort: number;
public abstract standardSchema: string;
public abstract standardUser: string;
public ColumnTypesWithWidth: WithWidthColumnType[] = [
"tinyint",
"smallint",
@ -53,7 +57,6 @@ export abstract class AbstractDriver {
"binary",
"varbinary"
];
public namingStrategy: AbstractNamingStrategy;
public generateRelationsIds: boolean;
public abstract GetAllTablesQuery: (
@ -64,104 +67,6 @@ export abstract class AbstractDriver {
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.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;
});
});
}
public changeEntityNames(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
const newName = this.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;
});
}
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.tsEntityName &&
relation2.ownerColumn === column.tsName
) {
relation2.ownerColumn = newName;
}
if (
relation2.relatedTable ===
entity.tsEntityName &&
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(
@ -242,12 +147,10 @@ export abstract class AbstractDriver {
password: string,
schema: string,
ssl: boolean,
namingStrategy: AbstractNamingStrategy,
relationIds: boolean
): Promise<DatabaseModel> {
this.generateRelationsIds = relationIds;
const dbModel = {} as DatabaseModel;
this.namingStrategy = namingStrategy;
await this.ConnectToServer(database, server, port, user, password, ssl);
const sqlEscapedSchema = "'" + schema.split(",").join("','") + "'";
dbModel.entities = await this.GetAllTables(sqlEscapedSchema);
@ -260,7 +163,6 @@ export abstract class AbstractDriver {
await this.DisconnectFromServer();
this.FindManyToManyRelations(dbModel);
this.FindPrimaryColumnsFromIndexes(dbModel);
this.ApplyNamingStrategy(dbModel);
return dbModel;
}
@ -478,10 +380,4 @@ export abstract class AbstractDriver {
public abstract async DropDB(dbName: string);
public abstract async UseDB(dbName: string);
public abstract async CheckIfDBExists(dbName: string): Promise<boolean>;
private ApplyNamingStrategy(dbModel: DatabaseModel) {
this.changeRelationNames(dbModel);
this.changeEntityNames(dbModel);
this.changeColumnNames(dbModel);
}
}

View File

@ -5,6 +5,10 @@ import * as TomgUtils from "../Utils";
import { AbstractDriver } from "./AbstractDriver";
export class MssqlDriver extends AbstractDriver {
public readonly standardPort = 1433;
public readonly standardSchema = "dbo";
public readonly standardUser = "sa";
private Connection: MSSQL.ConnectionPool;
public GetAllTablesQuery = async (schema: string) => {
const request = new MSSQL.Request(this.Connection);

View File

@ -6,6 +6,9 @@ import { AbstractDriver } from "./AbstractDriver";
export class MysqlDriver extends AbstractDriver {
public readonly EngineName: string = "MySQL";
public readonly standardPort = 3306;
public readonly standardUser = "root";
public readonly standardSchema = "";
private Connection: MYSQL.Connection;

View File

@ -4,6 +4,10 @@ import * as TomgUtils from "../Utils";
import { AbstractDriver } from "./AbstractDriver";
export class OracleDriver extends AbstractDriver {
public readonly standardPort = 1521;
public readonly standardUser = "SYS";
public readonly standardSchema = "";
public Oracle: any;
private Connection: any /*Oracle.IConnection*/;

View File

@ -5,6 +5,10 @@ import * as TomgUtils from "../Utils";
import { AbstractDriver } from "./AbstractDriver";
export class PostgresDriver extends AbstractDriver {
public readonly standardPort = 5432;
public readonly standardUser = "postgres";
public readonly standardSchema = "public";
private Connection: PG.Client;
public GetAllTablesQuery = async (schema: string) => {

View File

@ -4,6 +4,10 @@ import * as TomgUtils from "../Utils";
import { AbstractDriver } from "./AbstractDriver";
export class SqliteDriver extends AbstractDriver {
public readonly standardPort = 0;
public readonly standardUser = "";
public readonly standardSchema = "";
public sqlite = require("sqlite3").verbose();
public db: any;
public tablesWithGeneratedPrimaryKey: string[] = new Array<string>();

View File

@ -1,14 +1,7 @@
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 { Engine } from "./Engine";
import { Engine, IConnectionOptions, IGenerationOptions } from "./Engine";
import { NamingStrategy } from "./NamingStrategy";
import * as TomgUtils from "./Utils";
@ -112,46 +105,11 @@ const argv = Yargs.usage(
describe: "Generate constructor allowing partial initialization"
}).argv;
let driver: AbstractDriver;
let standardPort: number;
let standardSchema: string = "";
let standardUser: string = "";
switch (argv.e) {
case "mssql":
driver = new MssqlDriver();
standardPort = 1433;
standardSchema = "dbo";
standardUser = "sa";
break;
case "postgres":
driver = new PostgresDriver();
standardPort = 5432;
standardSchema = "public";
standardUser = "postgres";
break;
case "mysql":
driver = new MysqlDriver();
standardPort = 3306;
standardUser = "root";
break;
case "mariadb":
driver = new MariaDbDriver();
standardPort = 3306;
standardUser = "root";
break;
case "oracle":
driver = new OracleDriver();
standardPort = 1521;
standardUser = "SYS";
break;
case "sqlite":
driver = new SqliteDriver();
standardPort = 0;
break;
default:
TomgUtils.LogError("Database engine not recognized.", false);
throw new Error("Database engine not recognized.");
}
const driver = Engine.createDriver(argv.e);
const standardPort = driver.standardPort;
const standardSchema = driver.standardPort;
const standardUser = driver.standardPort;
let namingStrategy: AbstractNamingStrategy;
if (argv.namingStrategy && argv.namingStrategy !== "") {
// tslint:disable-next-line:no-var-requires
@ -160,34 +118,39 @@ if (argv.namingStrategy && argv.namingStrategy !== "") {
} else {
namingStrategy = new NamingStrategy();
}
const engine = new Engine(driver, {
const connectionOptions: IConnectionOptions = {
databaseName: argv.d ? argv.d.toString() : null,
databaseType: argv.e,
host: argv.h,
password: argv.x ? argv.x.toString() : null,
port: parseInt(argv.p, 10) || standardPort,
schemaName: argv.s ? argv.s.toString() : standardSchema,
ssl: argv.ssl,
user: argv.u ? argv.u.toString() : standardUser
};
const generationOptions: IGenerationOptions = {
activeRecord: argv.a,
constructor: argv.generateConstructor,
convertCaseEntity: argv.ce,
convertCaseFile: argv.cf,
convertCaseProperty: argv.cp,
databaseName: argv.d ? argv.d.toString() : null,
databaseType: argv.e,
host: argv.h,
lazy: argv.lazy,
activeRecord: argv.a,
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,
user: argv.u ? argv.u.toString() : standardUser
});
resultsPath: argv.o ? argv.o.toString() : null
};
console.log(TomgUtils.packageVersion());
console.log(
`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`
);
engine.createModelFromDatabase().then(() => {
Engine.createModelFromDatabase(
driver,
connectionOptions,
generationOptions
).then(() => {
console.info(
`[${new Date().toLocaleTimeString()}] Typeorm model classes created.`
);

View File

@ -28,7 +28,6 @@ describe('MssqlDriver', function () {
beforeEach(() => {
driver = new MssqlDriver();
driver.namingStrategy = new NamingStrategy();
})
afterEach(() => {

View File

@ -7,8 +7,10 @@ import { EntityFileToJson } from "../utils/EntityFileToJson";
const chai = require('chai');
const chaiSubset = require('chai-subset');
import * as ts from "typescript";
import { Engine } from "../../src/Engine";
import { Engine, IConnectionOptions, IGenerationOptions } from "../../src/Engine";
import * as GTU from "../utils/GeneralTestUtils"
import { AbstractDriver } from "../../src/drivers/AbstractDriver";
import { Exception } from "handlebars";
chai.use(chaiSubset);
@ -16,13 +18,7 @@ describe("Column default values", async function () {
this.timeout(30000)
this.slow(5000)// compiling created models takes time
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') }
const dbDrivers: string[] = GTU.getEnabledDbDrivers();
const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/defaultValues')
const examplesPathTS = path.resolve(process.cwd(), 'test/integration/defaultValues')
@ -38,33 +34,10 @@ describe("Column default values", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
let engine: Engine;
switch (dbDriver) {
case 'sqlite':
engine = await GTU.createSQLiteModels(filesOrgPathJS, resultsPath)
break;
case 'postgres':
engine = await GTU.createPostgresModels(filesOrgPathJS, resultsPath)
break;
case 'mysql':
engine = await GTU.createMysqlModels(filesOrgPathJS, resultsPath)
break;
case 'mariadb':
engine = await GTU.createMariaDBModels(filesOrgPathJS, resultsPath)
break;
case 'mssql':
engine = await GTU.createMSSQLModels(filesOrgPathJS, resultsPath)
break;
case 'oracle':
engine = await GTU.createOracleDBModels(filesOrgPathJS, resultsPath)
break;
default:
console.log(`Unknown engine type`);
engine = {} as Engine
break;
}
const driver = Engine.createDriver(dbDriver);
const [connectionOptions, generationOptions] = await GTU.getDriverAndOptions(dbDriver, filesOrgPathJS, resultsPath);
await engine.createModelFromDatabase()
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -7,8 +7,10 @@ import { EntityFileToJson } from "../utils/EntityFileToJson";
const chai = require('chai');
const chaiSubset = require('chai-subset');
import * as ts from "typescript";
import { Engine } from "../../src/Engine";
import { Engine, IConnectionOptions, IGenerationOptions } from "../../src/Engine";
import * as GTU from "../utils/GeneralTestUtils"
import { AbstractDriver } from "../../src/drivers/AbstractDriver";
import { Exception } from "handlebars";
chai.use(chaiSubset);
@ -16,13 +18,7 @@ describe("Platform specyfic types", async function () {
this.timeout(30000)
this.slow(5000)// compiling created models takes time
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') }
const dbDrivers: string[] = GTU.getEnabledDbDrivers();
const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/entityTypes')
const examplesPathTS = path.resolve(process.cwd(), 'test/integration/entityTypes')
@ -38,33 +34,10 @@ describe("Platform specyfic types", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
let engine: Engine;
switch (dbDriver) {
case 'sqlite':
engine = await GTU.createSQLiteModels(filesOrgPathJS, resultsPath)
break;
case 'postgres':
engine = await GTU.createPostgresModels(filesOrgPathJS, resultsPath)
break;
case 'mysql':
engine = await GTU.createMysqlModels(filesOrgPathJS, resultsPath)
break;
case 'mariadb':
engine = await GTU.createMariaDBModels(filesOrgPathJS, resultsPath)
break;
case 'mssql':
engine = await GTU.createMSSQLModels(filesOrgPathJS, resultsPath)
break;
case 'oracle':
engine = await GTU.createOracleDBModels(filesOrgPathJS, resultsPath)
break;
default:
console.log(`Unknown engine type`);
engine = {} as Engine
break;
}
const driver = Engine.createDriver(dbDriver);
const [connectionOptions, generationOptions] = await GTU.getDriverAndOptions(dbDriver, filesOrgPathJS, resultsPath);
await engine.createModelFromDatabase()
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -5,12 +5,13 @@ import path = require('path')
import "reflect-metadata";
import * as Sinon from 'sinon'
import { Connection, ConnectionOptions, createConnection } from "typeorm";
import { Engine } from "../../src/Engine";
import { Engine, IConnectionOptions, IGenerationOptions } from "../../src/Engine";
import { EntityFileToJson } from "../utils/EntityFileToJson";
const chai = require('chai');
const chaiSubset = require('chai-subset');
import * as ts from "typescript";
import * as GTU from "../utils/GeneralTestUtils"
import { AbstractDriver } from "../../src/drivers/AbstractDriver";
chai.use(chaiSubset);
@ -19,13 +20,7 @@ describe("GitHub issues", async function () {
this.timeout(30000)
this.slow(5000)// compiling created models takes time
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') }
const dbDrivers: string[] = GTU.getEnabledDbDrivers();
const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/github-issues')
const examplesPathTS = path.resolve(process.cwd(), 'test/integration/github-issues')
@ -53,41 +48,18 @@ describe("GitHub issues", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
let engine: Engine;
switch (dbDriver) {
case 'sqlite':
engine = await GTU.createSQLiteModels(filesOrgPathJS, resultsPath)
break;
case 'postgres':
engine = await GTU.createPostgresModels(filesOrgPathJS, resultsPath)
break;
case 'mysql':
engine = await GTU.createMysqlModels(filesOrgPathJS, resultsPath)
break;
case 'mariadb':
engine = await GTU.createMariaDBModels(filesOrgPathJS, resultsPath)
break;
case 'mssql':
engine = await GTU.createMSSQLModels(filesOrgPathJS, resultsPath)
break;
case 'oracle':
engine = await GTU.createOracleDBModels(filesOrgPathJS, resultsPath)
break;
default:
console.log(`Unknown engine type`);
engine = {} as Engine
break;
}
const driver = Engine.createDriver(dbDriver);
const [connectionOptions, generationOptions] = await GTU.getDriverAndOptions(dbDriver, filesOrgPathJS, resultsPath);
switch (folder) {
case '65':
engine.Options.relationIds = true;
generationOptions.relationIds = true;
break;
default:
break;
}
await engine.createModelFromDatabase()
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -3,12 +3,13 @@ import { expect } from "chai";
import fs = require('fs-extra');
import path = require('path')
import "reflect-metadata";
import { Engine } from "../../src/Engine";
import { Engine, IConnectionOptions, IGenerationOptions } from "../../src/Engine";
import { EntityFileToJson } from "../utils/EntityFileToJson";
const chai = require('chai');
const chaiSubset = require('chai-subset');
import * as ts from "typescript";
import * as GTU from "../utils/GeneralTestUtils"
import { AbstractDriver } from "../../src/drivers/AbstractDriver";
chai.use(chaiSubset);
@ -16,13 +17,8 @@ describe("TypeOrm examples", async function () {
this.timeout(30000)
this.slow(5000)// compiling created models takes time
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') }
const dbDrivers: string[] = GTU.getEnabledDbDrivers();
const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/examples')
const examplesPathTS = path.resolve(process.cwd(), 'test/integration/examples')
@ -37,36 +33,14 @@ describe("TypeOrm examples", async function () {
const resultsPath = path.resolve(process.cwd(), `output`)
fs.removeSync(resultsPath)
let engine: Engine;
switch (dbDriver) {
case 'sqlite':
engine = await GTU.createSQLiteModels(filesOrgPathJS, resultsPath)
break;
case 'postgres':
engine = await GTU.createPostgresModels(filesOrgPathJS, resultsPath)
break;
case 'mysql':
engine = await GTU.createMysqlModels(filesOrgPathJS, resultsPath)
break;
case 'mariadb':
engine = await GTU.createMariaDBModels(filesOrgPathJS, resultsPath)
break;
case 'mssql':
engine = await GTU.createMSSQLModels(filesOrgPathJS, resultsPath)
break;
case 'oracle':
engine = await GTU.createOracleDBModels(filesOrgPathJS, resultsPath)
break;
default:
console.log(`Unknown engine type`);
engine = {} as Engine
break;
}
const driver=Engine.createDriver(dbDriver);
const [connectionOptions, generationOptions] = await GTU.getDriverAndOptions(dbDriver, filesOrgPathJS, resultsPath);
if (folder == 'sample18-lazy-relations') {
engine.Options.lazy = true;
generationOptions.lazy = true;
}
await engine.createModelFromDatabase()
await Engine.createModelFromDatabase(driver,connectionOptions,generationOptions)
const filesGenPath = path.resolve(resultsPath, 'entities')
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))

View File

@ -10,10 +10,26 @@ 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 { Engine, IConnectionOptions, IGenerationOptions } from "../../src/Engine";
import { NamingStrategy } from "../../src/NamingStrategy";
export async function createMSSQLModels(filesOrgPath: string, resultsPath: string): Promise<Engine> {
export function getGenerationOptions():IGenerationOptions{
return {
resultsPath: "",
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy: new NamingStrategy(),
relationIds: false,
activeRecord: false
}
}
export async function createMSSQLModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new MssqlDriver();
@ -48,33 +64,6 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin
if (conn.isConnected) {
await conn.close()
}
const namingStrategy: AbstractNamingStrategy = new NamingStrategy();
driver = new MssqlDriver();
const engine = new Engine(
driver, {
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',
resultsPath,
schemaName: 'dbo,sch1,sch2',
ssl: yn(process.env.MSSQL_SSL),
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy,
relationIds: false,
activeRecord: false
});
conn = await createConnection(connOpt)
queryRunner = conn.createQueryRunner()
for (const sch of schemas.split(',')) {
@ -85,10 +74,22 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin
await conn.close()
}
return engine;
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, resultsPath: string): Promise<Engine> {
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));
@ -122,46 +123,34 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st
if (conn.isConnected) {
await conn.close()
}
const namingStrategy: AbstractNamingStrategy = new NamingStrategy();
driver = new PostgresDriver();
const engine = new Engine(
driver, {
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',
resultsPath,
schemaName: 'public,sch1,sch2',
ssl: yn(process.env.POSTGRES_SSL),
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy,
relationIds: false,
activeRecord: false
});
conn = await createConnection(connOpt)
queryRunner = conn.createQueryRunner()
for (const sch of schemas.split(',')) {
await queryRunner.createSchema(sch, true);
}
await conn.synchronize();
if (conn.isConnected) {
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),
conn = await createConnection(connOpt)
queryRunner = conn.createQueryRunner()
for (const sch of schemas.split(',')) {
await queryRunner.createSchema(sch, true);
}
await conn.synchronize();
if (conn.isConnected) {
await conn.close()
}
return engine;
return connectionOptions;
}
export async function createSQLiteModels(filesOrgPath: string, resultsPath: string): Promise<Engine> {
export async function createSQLiteModels(filesOrgPath: string): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new SqliteDriver();
await driver.ConnectToServer(String(process.env.SQLITE_Database), '', 0, '', '', false);
@ -187,32 +176,6 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri
if (conn.isConnected) {
await conn.close()
}
const namingStrategy: AbstractNamingStrategy = new NamingStrategy();
driver = new SqliteDriver();
const engine = new Engine(
driver, {
host: '',
port: 0,
databaseName: String(process.env.SQLITE_Database),
user: '',
password: '',
databaseType: 'sqlite',
resultsPath,
schemaName: '',
ssl: false,
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy,
relationIds: false,
activeRecord: false
});
conn = await createConnection(connOpt)
queryRunner = conn.createQueryRunner()
await conn.synchronize();
@ -220,10 +183,23 @@ export async function createSQLiteModels(filesOrgPath: string, resultsPath: stri
await conn.close()
}
return engine;
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, resultsPath: string): Promise<Engine> {
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));
@ -250,35 +226,23 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin
if (conn.isConnected) {
await conn.close()
}
const namingStrategy: AbstractNamingStrategy = new NamingStrategy();
driver = new MysqlDriver();
const engine = new Engine(
driver, {
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',
resultsPath,
schemaName: 'ignored',
ssl: yn(process.env.MYSQL_SSL),
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy,
relationIds: false,
activeRecord: false
});
return engine;
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, resultsPath: string): Promise<Engine> {
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));
@ -305,38 +269,24 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str
if (conn.isConnected) {
await conn.close()
}
const namingStrategy: AbstractNamingStrategy = new NamingStrategy();
driver = new MariaDbDriver();
const engine = new Engine(
driver, {
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',
resultsPath,
schemaName: 'ignored',
ssl: yn(process.env.MARIADB_SSL),
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy,
relationIds: false,
activeRecord: false
});
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 engine;
}
return connectionOptions;
}
export async function createOracleDBModels(filesOrgPath: string, resultsPath: string): Promise<Engine> {
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));
@ -363,33 +313,20 @@ export async function createOracleDBModels(filesOrgPath: string, resultsPath: st
if (conn.isConnected) {
await conn.close()
}
const namingStrategy: AbstractNamingStrategy = new NamingStrategy();
driver = new OracleDriver();
const engine = new Engine(
driver, {
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',
resultsPath,
schemaName: String(process.env.ORACLE_Username),
ssl: yn(process.env.ORACLE_SSL),
noConfigs: false,
convertCaseEntity: 'none',
convertCaseFile: 'none',
convertCaseProperty: 'none',
propertyVisibility: 'none',
lazy: false,
constructor: false,
namingStrategy,
relationIds: false,
activeRecord: false
});
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 engine;
}
return connectionOptions;
}
export function compileTsFiles(fileNames: string[], options: ts.CompilerOptions): boolean {
@ -409,3 +346,58 @@ export function compileTsFiles(fileNames: string[], options: ts.CompilerOptions)
return compileErrors;
}
export function getEnabledDbDrivers() {
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');
}
return dbDrivers;
}
export async function getDriverAndOptions(dbDriver: string, filesOrgPathJS: string, resultsPath: string): Promise<[IConnectionOptions,IGenerationOptions]> {
let connectionOptions: IConnectionOptions;
let generationOptions = getGenerationOptions();
switch (dbDriver) {
case 'sqlite':
connectionOptions = await createSQLiteModels(filesOrgPathJS);
break;
case 'postgres':
connectionOptions = await createPostgresModels(filesOrgPathJS);
break;
case 'mysql':
connectionOptions = await createMysqlModels(filesOrgPathJS);
break;
case 'mariadb':
connectionOptions = await createMariaDBModels(filesOrgPathJS);
break;
case 'mssql':
connectionOptions = await createMSSQLModels(filesOrgPathJS);
break;
case 'oracle':
connectionOptions = await createOracleDBModels(filesOrgPathJS);
break;
default:
console.log(`Unknown engine type`);
throw new Error("Unknown engine type");
}
generationOptions.resultsPath = resultsPath;
return [connectionOptions, generationOptions];
}