Merge branch 'next'
This commit is contained in:
commit
f1eb918526
8
.editorconfig
Normal file
8
.editorconfig
Normal file
@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
50
.travis.yml
50
.travis.yml
@ -1,30 +1,36 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- stable
|
||||
- 8
|
||||
- 6
|
||||
- stable
|
||||
- 8
|
||||
- 6
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
- docker
|
||||
env:
|
||||
matrix:
|
||||
- POSTGRES_Skip=0 POSTGRES_Host=localhost POSTGRES_Port=5432 POSTGRES_Username=postgres
|
||||
POSTGRES_Password=!Passw0rd POSTGRES_Database=typeorm_mg POSTGRES_SSL=0 MYSQL_Skip=0
|
||||
MYSQL_Host=localhost MYSQL_Port=3306 MYSQL_Username=root MYSQL_Password=!Passw0rd
|
||||
MYSQL_Database=typeorm_mg MYSQL_SSL=1 MARIADB_Skip=0 MARIADB_Host=localhost MARIADB_Port=3307
|
||||
MARIADB_Username=root MARIADB_Password=!Passw0rd MARIADB_Database=typeorm_mg MARIADB_SSL=0
|
||||
global:
|
||||
secure: Xj6wO8aghAhi6nvBI/HTtW9mIq9xfigIQfCC7ZkgAcqS4Oe3ba+7A5pCJq6Fxndadc6Bg1bZ3BGCH3Upf/Yv3zCFybsk43LwwXPJoG9gCrva/me7Sd+ws30EcD2dsKbvjZqNYai/XdrhzJY+KlxWvS/g3N/puBNffcU5hteo1zllxakQIAiavJ64D4g+Th8LSytmb2qDDToSsCxXkzNSutaKgZSf6T8QCWzcl0NCZkl69s9kX7L5335HVBD9lR/EKFC4wqHQjryCDRAyNRvItZRNlTPqgOI8lvcTsH9zKozDwEz7h/zcLebbY/+YTsLB5pb2sa62tkQE0x24TG7bLxujQShEQZU8itkRSV+w6+0JpBHQPlSUppkQJBNGKao7GaO/Eix4mSyvHkeECmTWDtEpBGWERYLqCKGe2Nj3BfcA2Ue6pjz9CX8wnrCbx53j6be3M/g/gcx7fbJbX3P95yc1CWAaR+tJKlP38rTcyo+o+Db1Ft0pzRJyZGmkGGPnCj6LxWYSmVqumLYDyqAMBDcQYuVwaKaTsJtU/2OBb3+zjKmWivV+19SXBqILvFbLv9IYLavpMr9OAwDGcJu0+mF+VCjGkZTlBxWJ53PmCoIJ6Qx/5o67LsCYL4L/hugNETlOEEKwe/k1mBraYWB0jI3mBUCV0d8J5P+ZQhwIZo4=
|
||||
matrix:
|
||||
- >-
|
||||
POSTGRES_Skip=0 POSTGRES_Host=localhost POSTGRES_Port=5432
|
||||
POSTGRES_Username=postgres POSTGRES_Password=!Passw0rd
|
||||
POSTGRES_Database=typeorm_mg POSTGRES_SSL=0 MYSQL_Skip=0
|
||||
MYSQL_Host=localhost MYSQL_Port=3306 MYSQL_Username=root
|
||||
MYSQL_Password=!Passw0rd MYSQL_Database=typeorm_mg MYSQL_SSL=1
|
||||
MARIADB_Skip=0 MARIADB_Host=localhost MARIADB_Port=3307
|
||||
MARIADB_Username=root MARIADB_Password=!Passw0rd
|
||||
MARIADB_Database=typeorm_mg MARIADB_SSL=0
|
||||
global:
|
||||
secure: >-
|
||||
Xj6wO8aghAhi6nvBI/HTtW9mIq9xfigIQfCC7ZkgAcqS4Oe3ba+7A5pCJq6Fxndadc6Bg1bZ3BGCH3Upf/Yv3zCFybsk43LwwXPJoG9gCrva/me7Sd+ws30EcD2dsKbvjZqNYai/XdrhzJY+KlxWvS/g3N/puBNffcU5hteo1zllxakQIAiavJ64D4g+Th8LSytmb2qDDToSsCxXkzNSutaKgZSf6T8QCWzcl0NCZkl69s9kX7L5335HVBD9lR/EKFC4wqHQjryCDRAyNRvItZRNlTPqgOI8lvcTsH9zKozDwEz7h/zcLebbY/+YTsLB5pb2sa62tkQE0x24TG7bLxujQShEQZU8itkRSV+w6+0JpBHQPlSUppkQJBNGKao7GaO/Eix4mSyvHkeECmTWDtEpBGWERYLqCKGe2Nj3BfcA2Ue6pjz9CX8wnrCbx53j6be3M/g/gcx7fbJbX3P95yc1CWAaR+tJKlP38rTcyo+o+Db1Ft0pzRJyZGmkGGPnCj6LxWYSmVqumLYDyqAMBDcQYuVwaKaTsJtU/2OBb3+zjKmWivV+19SXBqILvFbLv9IYLavpMr9OAwDGcJu0+mF+VCjGkZTlBxWJ53PmCoIJ6Qx/5o67LsCYL4L/hugNETlOEEKwe/k1mBraYWB0jI3mBUCV0d8J5P+ZQhwIZo4=
|
||||
before_install:
|
||||
- sudo service mysql stop
|
||||
- sudo service postgresql stop
|
||||
- docker-compose up -d
|
||||
- npm install -g npm@5
|
||||
- npm install -g greenkeeper-lockfile@1
|
||||
- sudo service mysql stop
|
||||
- sudo service postgresql stop
|
||||
- docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"
|
||||
- docker-compose up -d
|
||||
- npm install -g npm@5
|
||||
- npm install -g greenkeeper-lockfile@1
|
||||
before_script:
|
||||
- greenkeeper-lockfile-update
|
||||
- npm run typings-install
|
||||
- npm link typescript
|
||||
- tsc
|
||||
- greenkeeper-lockfile-update
|
||||
- npm run typings-install
|
||||
- npm link typescript
|
||||
- tsc
|
||||
after_script:
|
||||
- greenkeeper-lockfile-upload
|
||||
- greenkeeper-lockfile-upload
|
||||
|
16
README.md
16
README.md
@ -5,7 +5,7 @@
|
||||
[![npm version](https://badge.fury.io/js/typeorm-model-generator.svg)](https://badge.fury.io/js/typeorm-model-generator)
|
||||
[![codecov](https://codecov.io/gh/Kononnable/typeorm-model-generator/branch/master/graph/badge.svg)](https://codecov.io/gh/Kononnable/typeorm-model-generator)
|
||||
|
||||
Generates models for TypeORM from existing databases.
|
||||
Generates models for TypeORM from existing databases.
|
||||
Suported db engines:
|
||||
* Microsoft SQL Server
|
||||
* PostgreSQL
|
||||
@ -19,7 +19,7 @@ Suported db engines:
|
||||
To install module globally simply type `npm i -g typeorm-model-generator` in your console.
|
||||
### Npx way
|
||||
Thanks to npx you can use npm modules without polluting global installs. So nothing to do here :)
|
||||
>To use `npx` you need to use npm at version at least 5.2.0. Try updating your npm by `npm i -g npm`
|
||||
>To use `npx` you need to use npm at version at least 5.2.0. Try updating your npm by `npm i -g npm`
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
@ -37,24 +37,26 @@ Options:
|
||||
-o, --output Where to place generated models.
|
||||
-s, --schema Schema name to create model from. Only for mssql and postgres.
|
||||
--ssl [boolean] [default: false]
|
||||
--noConfig Doesn't create tsconfig.json and ormconfig.json
|
||||
[boolean] [default: false]
|
||||
```
|
||||
### Examples
|
||||
|
||||
* Creating model from local MSSQL database
|
||||
* Global module
|
||||
* Global module
|
||||
```
|
||||
typeorm-model-generator -h localhost -d tempdb -u sa -x !Passw0rd -e mssql -o .\
|
||||
````
|
||||
* Npx Way
|
||||
* Npx Way
|
||||
```
|
||||
npx typeorm-model-generator -h localhost -d tempdb -u sa -x !Passw0rd -e mssql -o .\
|
||||
````
|
||||
* Creating model from local Postgres database, public schema with ssl connection
|
||||
* Global module
|
||||
* Global module
|
||||
```
|
||||
typeorm-model-generator -h localhost -d postgres -u postgres -x !Passw0rd -e postgres -o .\ -s public --ssl
|
||||
````
|
||||
* Npx Way
|
||||
* Npx Way
|
||||
```
|
||||
npx typeorm-model-generator -h localhost -d postgres -u postgres -x !Passw0rd -e postgres -o .\ -s public --ssl
|
||||
````
|
||||
````
|
||||
|
15
codecov.yml
15
codecov.yml
@ -1,3 +1,14 @@
|
||||
parsers:
|
||||
javascript:
|
||||
enable_partials: yes
|
||||
javascript:
|
||||
enable_partials: yes
|
||||
comment:
|
||||
layout: diff
|
||||
behavior: default
|
||||
codecov:
|
||||
notify:
|
||||
require_ci_to_pass: no
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 5%
|
||||
|
@ -28,7 +28,7 @@ services:
|
||||
environment:
|
||||
POSTGRES_PASSWORD: "!Passw0rd"
|
||||
|
||||
# # mssql
|
||||
# mssql
|
||||
# mssql:
|
||||
# image: "microsoft/mssql-server-linux:2017-GA"
|
||||
# container_name: "typeorm-mg-mssql"
|
||||
@ -37,4 +37,13 @@ services:
|
||||
# environment:
|
||||
# ACCEPT_EULA: "Y"
|
||||
# SA_PASSWORD: "!Passw0rd"
|
||||
|
||||
|
||||
# oracle
|
||||
# oracle:
|
||||
# image: "store/oracle/database-enterprise:12.2.0.1-slim"
|
||||
# container_name: "typeorm-mg-oracle"
|
||||
# ports:
|
||||
# - "1521:1521"
|
||||
# environment:
|
||||
# DB_SID: "ORCLCDB"
|
||||
# SYS_PASSWORD: "Oradoc_db1"
|
||||
|
2049
package-lock.json
generated
2049
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -27,9 +27,10 @@
|
||||
"handlebars": "^4.0.11",
|
||||
"mssql": "^4.0.4",
|
||||
"mysql": "^2.15.0",
|
||||
"oracledb": "^2.0.15",
|
||||
"pg": "^7.4.0",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"typeorm": "^0.1.3",
|
||||
"typeorm": "^0.2.0-alpha.13",
|
||||
"typescript": "^2.6.1",
|
||||
"yargs": "^10.0.3",
|
||||
"yn": "^2.0.0"
|
||||
@ -43,6 +44,7 @@
|
||||
"@types/mocha": "^2.2.44",
|
||||
"@types/mssql": "^4.0.4",
|
||||
"@types/mysql": "2.15.2",
|
||||
"@types/oracledb": "^1.11.34",
|
||||
"@types/node": "^9.3.0",
|
||||
"@types/pg": "^7.4.1",
|
||||
"@types/sinon": "^4.1.2",
|
||||
@ -54,7 +56,7 @@
|
||||
"fs-extra": "^5.0.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"mocha": "^4.0.1",
|
||||
"remap-istanbul": "^0.9.5",
|
||||
"remap-istanbul": "^0.10.0",
|
||||
"sinon": "^4.1.2",
|
||||
"sinon-chai": "^2.14.0",
|
||||
"typings": "^2.1.1"
|
||||
|
@ -3,6 +3,7 @@ import { DatabaseModel } from './models/DatabaseModel'
|
||||
import * as Handlebars from 'handlebars'
|
||||
import fs = require('fs');
|
||||
import path = require('path')
|
||||
import * as TomgUtils from './Utils'
|
||||
/**
|
||||
* Engine
|
||||
*/
|
||||
@ -15,12 +16,12 @@ export class Engine {
|
||||
if (dbModel.entities.length > 0) {
|
||||
this.createModelFromMetadata(dbModel);
|
||||
} else {
|
||||
console.error('Tables not found in selected database. Skipping creation of typeorm model.');
|
||||
TomgUtils.LogFatalError('Tables not found in selected database. Skipping creation of typeorm model.', false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string, schemaName:string, ssl:boolean): Promise<DatabaseModel> {
|
||||
return await this.driver.GetDataFromServer(database, server, port, user, password,schemaName,ssl)
|
||||
private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string, schemaName: string, ssl: boolean): Promise<DatabaseModel> {
|
||||
return await this.driver.GetDataFromServer(database, server, port, user, password, schemaName, ssl)
|
||||
|
||||
}
|
||||
private createModelFromMetadata(databaseModel: DatabaseModel) {
|
||||
@ -29,21 +30,25 @@ export class Engine {
|
||||
let resultPath = this.Options.resultsPath
|
||||
if (!fs.existsSync(resultPath))
|
||||
fs.mkdirSync(resultPath);
|
||||
this.createTsConfigFile(resultPath)
|
||||
this.createTypeOrm(resultPath)
|
||||
let entitesPath = path.resolve(resultPath, './entities')
|
||||
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);
|
||||
}
|
||||
Handlebars.registerHelper('toLowerCase', function (str) {
|
||||
return str.toLowerCase();
|
||||
});
|
||||
if (!fs.existsSync(entitesPath))
|
||||
fs.mkdirSync(entitesPath);
|
||||
let compliedTemplate = Handlebars.compile(template,{noEscape:true})
|
||||
let compliedTemplate = Handlebars.compile(template, { noEscape: true })
|
||||
databaseModel.entities.forEach(element => {
|
||||
let resultFilePath = path.resolve(entitesPath, element.EntityName + '.ts');
|
||||
let rendered =compliedTemplate(element)
|
||||
let rendered = compliedTemplate(element)
|
||||
fs.writeFileSync(resultFilePath, rendered, { encoding: 'UTF-8', flag: 'w' })
|
||||
});
|
||||
}
|
||||
//TODO:Move to mustache template file
|
||||
private createTsConfigFile(resultPath) {
|
||||
fs.writeFileSync(path.resolve(resultPath, 'tsconfig.json'), `{"compilerOptions": {
|
||||
"lib": ["es5", "es6"],
|
||||
@ -55,8 +60,9 @@ export class Engine {
|
||||
"sourceMap": true
|
||||
}}`, { encoding: 'UTF-8', flag: 'w' });
|
||||
}
|
||||
private createTypeOrm(resultPath) {
|
||||
fs.writeFileSync(path.resolve(resultPath, 'ormconfig.json'), `[
|
||||
private createTypeOrmConfig(resultPath) {
|
||||
if (this.Options.schemaName == '') {
|
||||
fs.writeFileSync(path.resolve(resultPath, 'ormconfig.json'), `[
|
||||
{
|
||||
"name": "default",
|
||||
"driver": {
|
||||
@ -72,7 +78,28 @@ export class Engine {
|
||||
]
|
||||
}
|
||||
]`, { encoding: 'UTF-8', flag: 'w' });
|
||||
}
|
||||
else {
|
||||
fs.writeFileSync(path.resolve(resultPath, 'ormconfig.json'), `[
|
||||
{
|
||||
"name": "default",
|
||||
"driver": {
|
||||
"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}"
|
||||
},
|
||||
"entities": [
|
||||
"entities/*.js"
|
||||
]
|
||||
}
|
||||
]`, { encoding: 'UTF-8', flag: 'w' });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
export interface EngineOptions {
|
||||
host: string,
|
||||
@ -82,6 +109,7 @@ export interface EngineOptions {
|
||||
password: string,
|
||||
resultsPath: string,
|
||||
databaseType: string,
|
||||
schemaName:string,
|
||||
ssl:boolean
|
||||
}
|
||||
schemaName: string,
|
||||
ssl: boolean,
|
||||
noConfigs: boolean
|
||||
}
|
||||
|
12
src/Utils.ts
Normal file
12
src/Utils.ts
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
import * as data from './../../package.json'
|
||||
export function LogFatalError(errText: string, isABug: boolean = true, errObject?: any) {
|
||||
let x = <any>data;
|
||||
console.error(`Fatal error occured.`)
|
||||
console.error(`${x.name}@${x.version} node@${process.version}`)
|
||||
console.error(`Fatal error occured in typeorm-model-generator.`)
|
||||
console.error(`If this is a bug please open an issue including this log on ${x.bugs.url}`)
|
||||
if (isABug && !errObject) errObject = new Error().stack
|
||||
if (!!errObject) console.error(errObject)
|
||||
process.abort()
|
||||
}
|
@ -4,22 +4,22 @@ import { DatabaseModel } from './../models/DatabaseModel'
|
||||
* AbstractDriver
|
||||
*/
|
||||
export abstract class AbstractDriver {
|
||||
async GetDataFromServer(database: string, server: string, port: number, user: string, password: string, schema:string, ssl:boolean): Promise<DatabaseModel> {
|
||||
async GetDataFromServer(database: string, server: string, port: number, user: string, password: string, schema: string, ssl: boolean): Promise<DatabaseModel> {
|
||||
let dbModel = <DatabaseModel>{};
|
||||
await this.ConnectToServer(database, server, port, user, password,ssl);
|
||||
await this.ConnectToServer(database, server, port, user, password, ssl);
|
||||
dbModel.entities = await this.GetAllTables(schema);
|
||||
await this.GetCoulmnsFromEntity(dbModel.entities,schema);
|
||||
await this.GetIndexesFromEntity(dbModel.entities,schema);
|
||||
dbModel.entities = await this.GetRelations(dbModel.entities,schema);
|
||||
await this.GetCoulmnsFromEntity(dbModel.entities, schema);
|
||||
await this.GetIndexesFromEntity(dbModel.entities, schema);
|
||||
dbModel.entities = await this.GetRelations(dbModel.entities, schema);
|
||||
await this.DisconnectFromServer();
|
||||
this.FindPrimaryColumnsFromIndexes(dbModel)
|
||||
return dbModel;
|
||||
}
|
||||
abstract async ConnectToServer(database: string, server: string, port: number, user: string, password: string,ssl:boolean);
|
||||
abstract async GetAllTables(schema:string): Promise<EntityInfo[]>
|
||||
abstract async GetCoulmnsFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]>;
|
||||
abstract async GetIndexesFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]>;
|
||||
abstract async GetRelations(entities: EntityInfo[],schema:string): Promise<EntityInfo[]>;
|
||||
abstract async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean);
|
||||
abstract async GetAllTables(schema: string): Promise<EntityInfo[]>
|
||||
abstract async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]>;
|
||||
abstract async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]>;
|
||||
abstract async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]>;
|
||||
abstract async FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel);
|
||||
abstract async DisconnectFromServer();
|
||||
|
||||
@ -27,4 +27,4 @@ export abstract class AbstractDriver {
|
||||
abstract async DropDB(dbName: string);
|
||||
abstract async UseDB(dbName: string);
|
||||
abstract async CheckIfDBExists(dbName: string): Promise<boolean>;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ import { MysqlDriver } from './MysqlDriver';
|
||||
* MariaDb
|
||||
*/
|
||||
export class MariaDbDriver extends MysqlDriver {
|
||||
readonly EngineName:string = 'MariaDb'
|
||||
|
||||
}
|
||||
readonly EngineName: string = 'MariaDb'
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import { ColumnInfo } from './../models/ColumnInfo'
|
||||
import { EntityInfo } from './../models/EntityInfo'
|
||||
import { RelationInfo } from './../models/RelationInfo'
|
||||
import { DatabaseModel } from './../models/DatabaseModel'
|
||||
import * as TomgUtils from './../Utils'
|
||||
|
||||
/**
|
||||
* MssqlDriver
|
||||
*/
|
||||
@ -12,7 +14,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
dbModel.entities.forEach(entity => {
|
||||
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
|
||||
if (!primaryIndex) {
|
||||
console.error(`Table ${entity.EntityName} has no PK.`)
|
||||
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
|
||||
return;
|
||||
}
|
||||
entity.Columns.forEach(col => {
|
||||
@ -194,7 +196,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
colInfo.sql_type = "text"
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown column type:" + resp.DATA_TYPE);
|
||||
TomgUtils.LogFatalError("Unknown column type:" + resp.DATA_TYPE);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -209,7 +211,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
|
||||
is_primary_key: number//, is_descending_key: number//, is_included_column: number
|
||||
}[]
|
||||
= (await request.query(`SELECT
|
||||
= (await request.query(`SELECT
|
||||
TableName = t.name,
|
||||
IndexName = ind.name,
|
||||
ColumnName = col.name,
|
||||
@ -217,19 +219,19 @@ export class MssqlDriver extends AbstractDriver {
|
||||
ind.is_primary_key
|
||||
-- ,ic.is_descending_key,
|
||||
-- ic.is_included_column
|
||||
FROM
|
||||
sys.indexes ind
|
||||
INNER JOIN
|
||||
sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id
|
||||
INNER JOIN
|
||||
sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
|
||||
INNER JOIN
|
||||
sys.tables t ON ind.object_id = t.object_id
|
||||
FROM
|
||||
sys.indexes ind
|
||||
INNER JOIN
|
||||
sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id
|
||||
INNER JOIN
|
||||
sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
|
||||
INNER JOIN
|
||||
sys.tables t ON ind.object_id = t.object_id
|
||||
INNER JOIN
|
||||
sys.schemas s on s.schema_id=t.schema_id
|
||||
WHERE
|
||||
WHERE
|
||||
t.is_ms_shipped = 0 and s.name='${schema}'
|
||||
ORDER BY
|
||||
ORDER BY
|
||||
t.name, ind.name, ind.index_id, ic.key_ordinal;`)).recordset;
|
||||
entities.forEach((ent) => {
|
||||
response.filter((filterVal) => {
|
||||
@ -268,32 +270,32 @@ ORDER BY
|
||||
onDelete: "RESTRICT" | "CASCADE" | "SET NULL",
|
||||
onUpdate: "RESTRICT" | "CASCADE" | "SET NULL", object_id: number
|
||||
}[]
|
||||
= (await request.query(`select
|
||||
parentTable.name as TableWithForeignKey,
|
||||
= (await request.query(`select
|
||||
parentTable.name as TableWithForeignKey,
|
||||
fkc.constraint_column_id as FK_PartNo,
|
||||
parentColumn.name as ForeignKeyColumn,
|
||||
referencedTable.name as TableReferenced,
|
||||
referencedTable.name as TableReferenced,
|
||||
referencedColumn.name as ForeignKeyColumnReferenced,
|
||||
fk.delete_referential_action_desc as onDelete,
|
||||
fk.update_referential_action_desc as onUpdate,
|
||||
fk.object_id
|
||||
from
|
||||
sys.foreign_keys fk
|
||||
inner join
|
||||
from
|
||||
sys.foreign_keys fk
|
||||
inner join
|
||||
sys.foreign_key_columns as fkc on fkc.constraint_object_id=fk.object_id
|
||||
inner join
|
||||
inner join
|
||||
sys.tables as parentTable on fkc.parent_object_id = parentTable.object_id
|
||||
inner join
|
||||
inner join
|
||||
sys.columns as parentColumn on fkc.parent_object_id = parentColumn.object_id and fkc.parent_column_id = parentColumn.column_id
|
||||
inner join
|
||||
inner join
|
||||
sys.tables as referencedTable on fkc.referenced_object_id = referencedTable.object_id
|
||||
inner join
|
||||
inner join
|
||||
sys.columns as referencedColumn on fkc.referenced_object_id = referencedColumn.object_id and fkc.referenced_column_id = referencedColumn.column_id
|
||||
inner join
|
||||
sys.schemas as parentSchema on parentSchema.schema_id=parentTable.schema_id
|
||||
where
|
||||
where
|
||||
fk.is_disabled=0 and fk.is_ms_shipped=0 and parentSchema.name='${schema}'
|
||||
order by
|
||||
order by
|
||||
TableWithForeignKey, FK_PartNo`)).recordset;
|
||||
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
|
||||
response.forEach((resp) => {
|
||||
@ -319,28 +321,28 @@ order by
|
||||
return entitity.EntityName == relationTmp.ownerTable;
|
||||
})
|
||||
if (!ownerEntity) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
return;
|
||||
}
|
||||
let referencedEntity = entities.find((entitity) => {
|
||||
return entitity.EntityName == relationTmp.referencedTable;
|
||||
})
|
||||
if (!referencedEntity) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
return;
|
||||
}
|
||||
let ownerColumn = ownerEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.ownerColumnsNames[0];
|
||||
})
|
||||
if (!ownerColumn) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
return;
|
||||
}
|
||||
let relatedColumn = referencedEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.referencedColumnsNames[0];
|
||||
})
|
||||
if (!relatedColumn) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
return;
|
||||
}
|
||||
let ownColumn: ColumnInfo = ownerColumn;
|
||||
@ -359,15 +361,15 @@ order by
|
||||
isOneToMany = false;
|
||||
}
|
||||
let ownerRelation = new RelationInfo()
|
||||
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
|
||||
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length>0){
|
||||
for (let i=2;i<=ownerEntity.Columns.length;i++){
|
||||
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')+i.toString();
|
||||
}).length > 0) {
|
||||
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
|
||||
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length==0) break;
|
||||
}).length == 0) break;
|
||||
}
|
||||
}
|
||||
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
|
||||
@ -440,9 +442,7 @@ order by
|
||||
resolve(true)
|
||||
}
|
||||
else {
|
||||
console.error('Error connecting to MSSQL Server.')
|
||||
console.error(err.message)
|
||||
process.abort()
|
||||
TomgUtils.LogFatalError('Error connecting to MSSQL Server.', false, err.message)
|
||||
reject(err)
|
||||
}
|
||||
});
|
||||
@ -468,4 +468,4 @@ order by
|
||||
let resp = await request.query(`SELECT name FROM master.sys.databases WHERE name = N'${dbName}' `)
|
||||
return resp.recordset.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { ColumnInfo } from './../models/ColumnInfo'
|
||||
import { EntityInfo } from './../models/EntityInfo'
|
||||
import { RelationInfo } from './../models/RelationInfo'
|
||||
import { DatabaseModel } from './../models/DatabaseModel'
|
||||
import * as TomgUtils from './../Utils'
|
||||
/**
|
||||
* MysqlDriver
|
||||
*/
|
||||
@ -14,7 +15,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
dbModel.entities.forEach(entity => {
|
||||
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
|
||||
if (!primaryIndex) {
|
||||
console.error(`Table ${entity.EntityName} has no PK.`)
|
||||
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
|
||||
return;
|
||||
}
|
||||
entity.Columns.forEach(col => {
|
||||
@ -196,7 +197,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
colInfo.sql_type = "json"
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown column type:" + resp.DATA_TYPE);
|
||||
TomgUtils.LogFatalError("Unknown column type:" + resp.DATA_TYPE);
|
||||
break;
|
||||
}
|
||||
if (colInfo.sql_type) ent.Columns.push(colInfo);
|
||||
@ -208,7 +209,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
let response = await this.ExecQuery<{
|
||||
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
|
||||
is_primary_key: number//, is_descending_key: number//, is_included_column: number
|
||||
}>(`SELECT TABLE_NAME TableName,INDEX_NAME IndexName,COLUMN_NAME ColumnName,CASE WHEN NON_UNIQUE=0 THEN 1 ELSE 0 END is_unique,
|
||||
}>(`SELECT TABLE_NAME TableName,INDEX_NAME IndexName,COLUMN_NAME ColumnName,CASE WHEN NON_UNIQUE=0 THEN 1 ELSE 0 END is_unique,
|
||||
CASE WHEN INDEX_NAME='PRIMARY' THEN 1 ELSE 0 END is_primary_key
|
||||
FROM information_schema.statistics sta
|
||||
WHERE table_schema like DATABASE();
|
||||
@ -248,22 +249,22 @@ export class MysqlDriver extends AbstractDriver {
|
||||
TableReferenced: string, ForeignKeyColumnReferenced: string,
|
||||
onDelete: "RESTRICT" | "CASCADE" | "SET NULL",
|
||||
onUpdate: "RESTRICT" | "CASCADE" | "SET NULL", object_id: string
|
||||
}>(`SELECT
|
||||
CU.TABLE_NAME TableWithForeignKey,
|
||||
}>(`SELECT
|
||||
CU.TABLE_NAME TableWithForeignKey,
|
||||
CU.ORDINAL_POSITION FK_PartNo,
|
||||
CU.COLUMN_NAME ForeignKeyColumn,
|
||||
CU.REFERENCED_TABLE_NAME TableReferenced,
|
||||
CU.COLUMN_NAME ForeignKeyColumn,
|
||||
CU.REFERENCED_TABLE_NAME TableReferenced,
|
||||
CU.REFERENCED_COLUMN_NAME ForeignKeyColumnReferenced,
|
||||
RC.DELETE_RULE onDelete,
|
||||
RC.UPDATE_RULE onUpdate,
|
||||
CU.CONSTRAINT_NAME object_id
|
||||
FROM
|
||||
INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
|
||||
JOIN
|
||||
JOIN
|
||||
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC ON CU.CONSTRAINT_NAME=RC.CONSTRAINT_NAME
|
||||
WHERE
|
||||
TABLE_SCHEMA = SCHEMA()
|
||||
AND CU.REFERENCED_TABLE_NAME IS NOT NULL;
|
||||
TABLE_SCHEMA = SCHEMA()
|
||||
AND CU.REFERENCED_TABLE_NAME IS NOT NULL;
|
||||
`);
|
||||
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
|
||||
response.forEach((resp) => {
|
||||
@ -289,28 +290,28 @@ export class MysqlDriver extends AbstractDriver {
|
||||
return entitity.EntityName == relationTmp.ownerTable;
|
||||
})
|
||||
if (!ownerEntity) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
return;
|
||||
}
|
||||
let referencedEntity = entities.find((entitity) => {
|
||||
return entitity.EntityName == relationTmp.referencedTable;
|
||||
})
|
||||
if (!referencedEntity) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
return;
|
||||
}
|
||||
let ownerColumn = ownerEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.ownerColumnsNames[0];
|
||||
})
|
||||
if (!ownerColumn) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
return;
|
||||
}
|
||||
let relatedColumn = referencedEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.referencedColumnsNames[0];
|
||||
})
|
||||
if (!relatedColumn) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
return;
|
||||
}
|
||||
let ownColumn: ColumnInfo = ownerColumn;
|
||||
@ -333,7 +334,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length > 0) {
|
||||
for (let i=2;i<=ownerEntity.Columns.length;i++){
|
||||
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
|
||||
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
@ -391,9 +392,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
resolve(true)
|
||||
}
|
||||
else {
|
||||
console.error(`Error disconnecting to ${this.EngineName} Server.`)
|
||||
console.error(err.message)
|
||||
process.abort()
|
||||
TomgUtils.LogFatalError(`Error disconnecting to ${this.EngineName} Server.`, false, err.message)
|
||||
reject(err)
|
||||
}
|
||||
});
|
||||
@ -440,9 +439,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
resolve(true)
|
||||
}
|
||||
else {
|
||||
console.error(`Error connecting to ${this.EngineName} Server.`)
|
||||
console.error(err.message)
|
||||
process.abort()
|
||||
TomgUtils.LogFatalError(`Error connecting to ${this.EngineName} Server.`, false, err.message)
|
||||
reject(err)
|
||||
}
|
||||
});
|
||||
@ -480,4 +477,4 @@ export class MysqlDriver extends AbstractDriver {
|
||||
await promise;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
306
src/drivers/OracleDriver.ts
Normal file
306
src/drivers/OracleDriver.ts
Normal file
@ -0,0 +1,306 @@
|
||||
import { AbstractDriver } from './AbstractDriver'
|
||||
import { ColumnInfo } from './../models/ColumnInfo'
|
||||
import { EntityInfo } from './../models/EntityInfo'
|
||||
import { RelationInfo } from './../models/RelationInfo'
|
||||
import { DatabaseModel } from './../models/DatabaseModel'
|
||||
import { promisify } from 'util'
|
||||
import { request } from 'https';
|
||||
import * as TomgUtils from './../Utils'
|
||||
|
||||
|
||||
/**
|
||||
* OracleDriver
|
||||
*/
|
||||
export class OracleDriver extends AbstractDriver {
|
||||
Oracle: any;
|
||||
constructor() {
|
||||
super();
|
||||
try {
|
||||
this.Oracle = require('oracledb')
|
||||
} catch (error) {
|
||||
TomgUtils.LogFatalError('', false, error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel) {
|
||||
dbModel.entities.forEach(entity => {
|
||||
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
|
||||
if (!primaryIndex) {
|
||||
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
|
||||
return;
|
||||
}
|
||||
entity.Columns.forEach(col => {
|
||||
if (primaryIndex!.columns.some(cIndex => cIndex.name == col.name)) col.isPrimary = true
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async GetAllTables(schema: string): Promise<EntityInfo[]> {
|
||||
|
||||
let response: any[][] = (await this.Connection.execute(` SELECT TABLE_NAME FROM all_tables WHERE owner = (select user from dual)`)).rows!;
|
||||
let ret: EntityInfo[] = <EntityInfo[]>[];
|
||||
response.forEach((val) => {
|
||||
let ent: EntityInfo = new EntityInfo();
|
||||
ent.EntityName = val[0];
|
||||
ent.Columns = <ColumnInfo[]>[];
|
||||
ent.Indexes = <IndexInfo[]>[];
|
||||
ret.push(ent);
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
|
||||
let response: any[][] = (await this.Connection.execute(`SELECT TABLE_NAME, COLUMN_NAME, DATA_DEFAULT, NULLABLE, DATA_TYPE, DATA_LENGTH,
|
||||
DATA_PRECISION, DATA_SCALE, IDENTITY_COLUMN
|
||||
FROM USER_TAB_COLUMNS`)).rows!;
|
||||
|
||||
entities.forEach((ent) => {
|
||||
response.filter((filterVal) => {
|
||||
return filterVal[0] == ent.EntityName;
|
||||
}).forEach((resp) => {
|
||||
let colInfo: ColumnInfo = new ColumnInfo();
|
||||
colInfo.name = resp[1];
|
||||
colInfo.is_nullable = resp[3] == 'Y' ? true : false;
|
||||
colInfo.is_generated = resp[8] == 'YES' ? true : false;
|
||||
colInfo.default = resp[2];
|
||||
switch (resp[4].toLowerCase()) {
|
||||
case "number":
|
||||
colInfo.ts_type = "number"
|
||||
colInfo.sql_type = "int"
|
||||
colInfo.char_max_lenght = resp[5] > 0 ? resp[5] : null;
|
||||
break;
|
||||
case "varchar2":
|
||||
colInfo.ts_type = "number"
|
||||
colInfo.sql_type = "smallint"
|
||||
colInfo.char_max_lenght = resp[5] > 0 ? resp[5] : null;
|
||||
break;
|
||||
default:
|
||||
TomgUtils.LogFatalError("Unknown column type:" + resp[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (colInfo.sql_type) ent.Columns.push(colInfo);
|
||||
})
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetIndexesFromEntity(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
|
||||
let response: any[][] = (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
|
||||
FROM USER_INDEXES ind
|
||||
JOIN USER_IND_COLUMNS col ON ind.INDEX_NAME=col.INDEX_NAME
|
||||
LEFT JOIN USER_CONSTRAINTS uc ON uc.INDEX_NAME = ind.INDEX_NAME
|
||||
ORDER BY col.INDEX_NAME ASC ,col.COLUMN_POSITION ASC`)).rows!;
|
||||
|
||||
entities.forEach((ent) => {
|
||||
response.filter((filterVal) => {
|
||||
return filterVal[0] == ent.EntityName;
|
||||
}).forEach((resp) => {
|
||||
let indexInfo: IndexInfo = <IndexInfo>{};
|
||||
let indexColumnInfo: IndexColumnInfo = <IndexColumnInfo>{};
|
||||
if (ent.Indexes.filter((filterVal) => {
|
||||
return filterVal.name == resp[1]
|
||||
}).length > 0) {
|
||||
indexInfo = ent.Indexes.filter((filterVal) => {
|
||||
return filterVal.name == resp[1]
|
||||
})[0];
|
||||
} else {
|
||||
indexInfo.columns = <IndexColumnInfo[]>[];
|
||||
indexInfo.name = resp[1];
|
||||
indexInfo.isUnique = resp[3] == 'UNIQUE' ? true : false;
|
||||
indexInfo.isPrimaryKey = resp[4] == 1 ? true : false;
|
||||
ent.Indexes.push(indexInfo);
|
||||
}
|
||||
indexColumnInfo.name = resp[2];
|
||||
// indexColumnInfo.isIncludedColumn = resp.is_included_column == 1 ? true : false;
|
||||
// indexColumnInfo.isDescending = resp.is_descending_key == 1 ? true : false;
|
||||
indexInfo.columns.push(indexColumnInfo);
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
return entities;
|
||||
}
|
||||
async GetRelations(entities: EntityInfo[], schema: string): Promise<EntityInfo[]> {
|
||||
let response: any[][] = (await this.Connection.execute(`select owner.TABLE_NAME ownTbl,ownCol.POSITION,ownCol.COLUMN_NAME,
|
||||
child.TABLE_NAME,childCol.COLUMN_NAME,
|
||||
owner.DELETE_RULE,
|
||||
4,owner.CONSTRAINT_NAME
|
||||
from user_constraints owner
|
||||
join user_constraints child on owner.r_constraint_name=child.CONSTRAINT_NAME and child.constraint_type in ('P','U')
|
||||
JOIN USER_CONS_COLUMNS ownCol ON owner.CONSTRAINT_NAME = ownCol.CONSTRAINT_NAME
|
||||
JOIN USER_CONS_COLUMNS childCol ON child.CONSTRAINT_NAME = childCol.CONSTRAINT_NAME AND ownCol.POSITION=childCol.POSITION
|
||||
ORDER BY ownTbl ASC, owner.CONSTRAINT_NAME ASC, ownCol.POSITION ASC`)).rows!;
|
||||
|
||||
|
||||
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
|
||||
response.forEach((resp) => {
|
||||
let rels = relationsTemp.find((val) => {
|
||||
return val.object_id == resp[6];
|
||||
})
|
||||
if (rels == undefined) {
|
||||
rels = <RelationTempInfo>{};
|
||||
rels.ownerColumnsNames = [];
|
||||
rels.referencedColumnsNames = [];
|
||||
rels.actionOnDelete = resp[5];
|
||||
rels.actionOnUpdate = "NO ACTION";
|
||||
rels.object_id = resp[6];
|
||||
rels.ownerTable = resp[0];
|
||||
rels.referencedTable = resp[3];
|
||||
relationsTemp.push(rels);
|
||||
}
|
||||
rels.ownerColumnsNames.push(resp[2]);
|
||||
rels.referencedColumnsNames.push(resp[4]);
|
||||
})
|
||||
relationsTemp.forEach((relationTmp) => {
|
||||
let ownerEntity = entities.find((entitity) => {
|
||||
return entitity.EntityName == relationTmp.ownerTable;
|
||||
})
|
||||
if (!ownerEntity) {
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
return;
|
||||
}
|
||||
let referencedEntity = entities.find((entitity) => {
|
||||
return entitity.EntityName == relationTmp.referencedTable;
|
||||
})
|
||||
if (!referencedEntity) {
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
return;
|
||||
}
|
||||
let ownerColumn = ownerEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.ownerColumnsNames[0];
|
||||
})
|
||||
if (!ownerColumn) {
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
return;
|
||||
}
|
||||
let relatedColumn = referencedEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.referencedColumnsNames[0];
|
||||
})
|
||||
if (!relatedColumn) {
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
return;
|
||||
}
|
||||
let ownColumn: ColumnInfo = ownerColumn;
|
||||
let isOneToMany: boolean;
|
||||
isOneToMany = false;
|
||||
let index = ownerEntity.Indexes.find(
|
||||
(index) => {
|
||||
return index.isUnique && index.columns.some(col => {
|
||||
return col.name == ownerColumn!.name
|
||||
})
|
||||
}
|
||||
)
|
||||
if (!index) {
|
||||
isOneToMany = true;
|
||||
} else {
|
||||
isOneToMany = false;
|
||||
}
|
||||
let ownerRelation = new RelationInfo()
|
||||
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length > 0) {
|
||||
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
|
||||
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length == 0) break;
|
||||
}
|
||||
}
|
||||
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
|
||||
ownerRelation.actionOnUpdate = relationTmp.actionOnUpdate
|
||||
ownerRelation.isOwner = true
|
||||
ownerRelation.relatedColumn = relatedColumn.name.toLowerCase()
|
||||
ownerRelation.relatedTable = relationTmp.referencedTable
|
||||
ownerRelation.ownerTable = relationTmp.ownerTable
|
||||
ownerRelation.ownerColumn = columnName
|
||||
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne"
|
||||
ownerColumn.relations.push(ownerRelation)
|
||||
if (isOneToMany) {
|
||||
let col = new ColumnInfo()
|
||||
col.name = columnName
|
||||
let referencedRelation = new RelationInfo();
|
||||
col.relations.push(referencedRelation)
|
||||
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
|
||||
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
|
||||
referencedRelation.isOwner = false
|
||||
referencedRelation.relatedColumn = ownerColumn.name
|
||||
referencedRelation.relatedTable = relationTmp.ownerTable
|
||||
referencedRelation.ownerTable = relationTmp.referencedTable
|
||||
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
|
||||
referencedRelation.relationType = "OneToMany"
|
||||
referencedEntity.Columns.push(col)
|
||||
} else {
|
||||
let col = new ColumnInfo()
|
||||
col.name = columnName
|
||||
let referencedRelation = new RelationInfo();
|
||||
col.relations.push(referencedRelation)
|
||||
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
|
||||
referencedRelation.actionOnUpdate = relationTmp.actionOnUpdate
|
||||
referencedRelation.isOwner = false
|
||||
referencedRelation.relatedColumn = ownerColumn.name
|
||||
referencedRelation.relatedTable = relationTmp.ownerTable
|
||||
referencedRelation.ownerTable = relationTmp.referencedTable
|
||||
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
|
||||
referencedRelation.relationType = "OneToOne"
|
||||
|
||||
referencedEntity.Columns.push(col)
|
||||
}
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async DisconnectFromServer() {
|
||||
if (this.Connection)
|
||||
await this.Connection.close();
|
||||
}
|
||||
|
||||
private Connection: any/*Oracle.IConnection*/;
|
||||
async ConnectToServer(database: string, server: string, port: number, user: string, password: string, ssl: boolean) {
|
||||
let config: any/*Oracle.IConnectionAttributes*/ = {
|
||||
user: user,
|
||||
password: password,
|
||||
// connectString: `${server}:${port}/ORCLCDB.localdomain/${database}`,
|
||||
connectString: `${server}:${port}/${database}`,
|
||||
externalAuth: ssl
|
||||
}
|
||||
|
||||
|
||||
let that = this;
|
||||
let promise = new Promise<boolean>(
|
||||
(resolve, reject) => {
|
||||
this.Oracle.getConnection(
|
||||
config,
|
||||
function (err, connection) {
|
||||
if (!err) {
|
||||
//Connection successfull
|
||||
that.Connection = connection
|
||||
resolve(true)
|
||||
}
|
||||
else {
|
||||
TomgUtils.LogFatalError('Error connecting to Oracle Server.', false, err.message)
|
||||
reject(err)
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
)
|
||||
|
||||
await promise;
|
||||
}
|
||||
|
||||
|
||||
async CreateDB(dbName: string) {
|
||||
}
|
||||
async UseDB(dbName: string) {
|
||||
}
|
||||
async DropDB(dbName: string) {
|
||||
}
|
||||
async CheckIfDBExists(dbName: string): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import { ColumnInfo } from './../models/ColumnInfo'
|
||||
import { EntityInfo } from './../models/EntityInfo'
|
||||
import { RelationInfo } from './../models/RelationInfo'
|
||||
import { DatabaseModel } from './../models/DatabaseModel'
|
||||
import * as TomgUtils from './../Utils'
|
||||
/**
|
||||
* PostgresDriver
|
||||
*/
|
||||
@ -14,7 +15,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
dbModel.entities.forEach(entity => {
|
||||
let primaryIndex = entity.Indexes.find(v => v.isPrimaryKey);
|
||||
if (!primaryIndex) {
|
||||
console.error(`Table ${entity.EntityName} has no PK.`)
|
||||
TomgUtils.LogFatalError(`Table ${entity.EntityName} has no PK.`, false)
|
||||
return;
|
||||
}
|
||||
entity.Columns.forEach(col => {
|
||||
@ -116,7 +117,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
break;
|
||||
case "timestamp without time zone":
|
||||
colInfo.ts_type = "Date"
|
||||
colInfo.sql_type = "datetime"
|
||||
colInfo.sql_type = "timestamp"
|
||||
break;
|
||||
case "timestamp with time zone":
|
||||
colInfo.ts_type = "Date"
|
||||
@ -205,7 +206,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error("Unknown column type:" + resp.data_type);
|
||||
TomgUtils.LogFatalError("Unknown column type:" + resp.data_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -348,28 +349,28 @@ export class PostgresDriver extends AbstractDriver {
|
||||
return entitity.EntityName == relationTmp.ownerTable;
|
||||
})
|
||||
if (!ownerEntity) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
return;
|
||||
}
|
||||
let referencedEntity = entities.find((entitity) => {
|
||||
return entitity.EntityName == relationTmp.referencedTable;
|
||||
})
|
||||
if (!referencedEntity) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
return;
|
||||
}
|
||||
let ownerColumn = ownerEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.ownerColumnsNames[0];
|
||||
})
|
||||
if (!ownerColumn) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
return;
|
||||
}
|
||||
let relatedColumn = referencedEntity.Columns.find((column) => {
|
||||
return column.name == relationTmp.referencedColumnsNames[0];
|
||||
})
|
||||
if (!relatedColumn) {
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
TomgUtils.LogFatalError(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
return;
|
||||
}
|
||||
let ownColumn: ColumnInfo = ownerColumn;
|
||||
@ -388,15 +389,15 @@ export class PostgresDriver extends AbstractDriver {
|
||||
isOneToMany = false;
|
||||
}
|
||||
let ownerRelation = new RelationInfo()
|
||||
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
|
||||
let columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length>0){
|
||||
for (let i=2;i<=ownerEntity.Columns.length;i++){
|
||||
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '')+i.toString();
|
||||
}).length > 0) {
|
||||
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
|
||||
columnName = ownerEntity.EntityName.toLowerCase() + (isOneToMany ? 's' : '') + i.toString();
|
||||
if (referencedEntity.Columns.filter((filterVal) => {
|
||||
return filterVal.name == columnName;
|
||||
}).length==0) break;
|
||||
}).length == 0) break;
|
||||
}
|
||||
}
|
||||
ownerRelation.actionOnDelete = relationTmp.actionOnDelete
|
||||
@ -451,9 +452,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
resolve(true)
|
||||
}
|
||||
else {
|
||||
console.error('Error connecting to Postgres Server.')
|
||||
console.error(err.message)
|
||||
process.abort()
|
||||
TomgUtils.LogFatalError('Error connecting to Postgres Server.', false, err.message)
|
||||
reject(err)
|
||||
}
|
||||
});
|
||||
@ -481,9 +480,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
resolve(true)
|
||||
}
|
||||
else {
|
||||
console.error('Error connecting to Postgres Server.')
|
||||
console.error(err.message)
|
||||
process.abort()
|
||||
TomgUtils.LogFatalError('Error connecting to Postgres Server.', false, err.message)
|
||||
reject(err)
|
||||
}
|
||||
});
|
||||
@ -507,4 +504,4 @@ export class PostgresDriver extends AbstractDriver {
|
||||
let resp = await this.Connection.query(`SELECT datname FROM pg_database WHERE datname ='${dbName}' `)
|
||||
return resp.rowCount > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,14 +15,14 @@ import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, Joi
|
||||
default:"{{.}}",{{/default}}{{#numericPrecision}}
|
||||
precision:{{.}},{{/numericPrecision}}{{#numericScale}}
|
||||
scale:{{.}},{{/numericScale}}{{#isPrimary}}
|
||||
primary:{{isPrimary}},{{/isPrimary}}
|
||||
primary:{{isPrimary}},{{/isPrimary}}
|
||||
})
|
||||
{{name}}:{{ts_type}};
|
||||
{{/relations}}{{#relations}}
|
||||
@{{relationType}}(type=>{{relatedTable}}, {{../name}}=>{{../name}}.{{#if isOwner}}{{ownerColumn}}{{else}}{{relatedColumn}}{{/if}}){{#isOwner}}
|
||||
@JoinColumn(){{/isOwner}}
|
||||
@JoinColumn({name:'{{../name}}'}){{/isOwner}}
|
||||
{{#if isOneToMany}}{{../name}}:{{relatedTable}}[];
|
||||
{{else}}{{../name}}:{{relatedTable}};
|
||||
{{/if}}{{/relations}}
|
||||
{{/Columns}}
|
||||
}
|
||||
}
|
||||
|
24
src/index.ts
24
src/index.ts
@ -3,8 +3,10 @@ import { MssqlDriver } from './drivers/MssqlDriver';
|
||||
import { PostgresDriver } from "./drivers/PostgresDriver";
|
||||
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')
|
||||
|
||||
|
||||
@ -50,9 +52,14 @@ var argv = Yargs
|
||||
alias: 'schema',
|
||||
describe: 'Schema name to create model from. Only for mssql and postgres.'
|
||||
})
|
||||
.option('ssl',{
|
||||
boolean:true,
|
||||
default:false
|
||||
.option('ssl', {
|
||||
boolean: true,
|
||||
default: false
|
||||
})
|
||||
.option('noConfig', {
|
||||
boolean: true,
|
||||
describe: `Doesn't create tsconfig.json and ormconfig.json`,
|
||||
default: false
|
||||
})
|
||||
.argv;
|
||||
|
||||
@ -79,9 +86,12 @@ switch (argv.e) {
|
||||
driver = new MysqlDriver();
|
||||
standardPort = 3306;
|
||||
break;
|
||||
case 'oracle':
|
||||
driver = new OracleDriver();
|
||||
standardPort = 1521;
|
||||
break;
|
||||
default:
|
||||
console.error('Database engine not recognized.')
|
||||
process.abort();
|
||||
TomgUtils.LogFatalError('Database engine not recognized.', false)
|
||||
throw new Error('Database engine not recognized.');
|
||||
}
|
||||
|
||||
@ -95,11 +105,11 @@ let engine = new Engine(
|
||||
databaseType: argv.e,
|
||||
resultsPath: argv.o,
|
||||
schemaName: argv.s || standardSchema,
|
||||
ssl:argv.ssl
|
||||
ssl: argv.ssl,
|
||||
noConfigs: argv.noConfig
|
||||
});
|
||||
|
||||
console.log(`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`);
|
||||
engine.createModelFromDatabase().then(() => {
|
||||
console.info(`[${new Date().toLocaleTimeString()}] Typeorm model classes created.`)
|
||||
})
|
||||
|
||||
|
@ -22,5 +22,3 @@ export class ColumnInfo {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {EntityInfo} from './EntityInfo'
|
||||
import { EntityInfo } from './EntityInfo'
|
||||
export class DatabaseModel {
|
||||
entities: EntityInfo[];
|
||||
config: {
|
||||
@ -6,11 +6,11 @@ export class DatabaseModel {
|
||||
cascadeUpdate: boolean,
|
||||
cascadeRemove: boolean,
|
||||
}
|
||||
relationImports():any{
|
||||
let that=this;
|
||||
return function(text, render) {
|
||||
if ('l'!=render(text)) return `import {${render(text)}} from "./${render(text)}"`
|
||||
else return '';
|
||||
relationImports(): any {
|
||||
let that = this;
|
||||
return function (text, render) {
|
||||
if ('l' != render(text)) return `import {${render(text)}} from "./${render(text)}"`
|
||||
else return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,23 +8,23 @@ export class EntityInfo {
|
||||
Indexes: IndexInfo[];
|
||||
|
||||
relationImports(): any {
|
||||
var returnString = "";
|
||||
var imports: string[] = [];
|
||||
this.Columns.forEach((column) => {
|
||||
column.relations.forEach(
|
||||
(relation) => {
|
||||
if (this.EntityName!=relation.relatedTable)
|
||||
var returnString = "";
|
||||
var imports: string[] = [];
|
||||
this.Columns.forEach((column) => {
|
||||
column.relations.forEach(
|
||||
(relation) => {
|
||||
if (this.EntityName != relation.relatedTable)
|
||||
imports.push(relation.relatedTable);
|
||||
}
|
||||
)
|
||||
});
|
||||
imports.filter(function (elem, index, self) {
|
||||
return index == self.indexOf(elem);
|
||||
}).forEach((imp)=>{
|
||||
returnString+=`import {${imp}} from './${imp}'\n`
|
||||
})
|
||||
}
|
||||
)
|
||||
});
|
||||
imports.filter(function (elem, index, self) {
|
||||
return index == self.indexOf(elem);
|
||||
}).forEach((imp) => {
|
||||
returnString += `import {${imp}} from './${imp}'\n`
|
||||
})
|
||||
|
||||
return returnString;
|
||||
return returnString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
interface IndexColumnInfo{
|
||||
name:string,
|
||||
interface IndexColumnInfo {
|
||||
name: string,
|
||||
//isDescending:boolean,
|
||||
// isIncludedColumn:boolean
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
* IndexInfo
|
||||
*/
|
||||
interface IndexInfo {
|
||||
name:string,
|
||||
columns:IndexColumnInfo[],
|
||||
isUnique:boolean,
|
||||
isPrimaryKey:boolean,
|
||||
name: string,
|
||||
columns: IndexColumnInfo[],
|
||||
isUnique: boolean,
|
||||
isPrimaryKey: boolean,
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export class RelationInfo { [x: string]: any;
|
||||
export class RelationInfo {
|
||||
[x: string]: any;
|
||||
|
||||
isOwner: boolean
|
||||
relationType: "OneToOne" | "OneToMany" | "ManyToOne"
|
||||
@ -13,4 +14,4 @@ export class RelationInfo { [x: string]: any;
|
||||
return this.relationType == "OneToMany"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
interface RelationTempInfo{
|
||||
ownerTable:string,
|
||||
ownerColumnsNames:string[],
|
||||
referencedTable:string,
|
||||
referencedColumnsNames:string[],
|
||||
actionOnDelete:"RESTRICT"|"CASCADE"|"SET NULL"|"NO ACTION",
|
||||
actionOnUpdate:"RESTRICT"|"CASCADE"|"SET NULL"|"NO ACTION",
|
||||
object_id:number|string
|
||||
}
|
||||
interface RelationTempInfo {
|
||||
ownerTable: string,
|
||||
ownerColumnsNames: string[],
|
||||
referencedTable: string,
|
||||
referencedColumnsNames: string[],
|
||||
actionOnDelete: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION",
|
||||
actionOnUpdate: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION",
|
||||
object_id: number | string
|
||||
}
|
||||
|
4
src/typings.d.ts
vendored
Normal file
4
src/typings.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
declare module "*.json" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
@ -7,19 +7,19 @@ import { ColumnInfo } from './../../src/models/ColumnInfo'
|
||||
import { RelationInfo } from './../../src/models/RelationInfo'
|
||||
import { Table, IColumnMetadata } from "mssql";
|
||||
|
||||
class fakeResponse implements MSSQL.IResult<any> {
|
||||
recordsets: MSSQL.IRecordSet<any>[];
|
||||
recordset: MSSQL.IRecordSet<any>;
|
||||
rowsAffected: number[];
|
||||
output: { [key: string]: any; };
|
||||
|
||||
}
|
||||
class fakeRecordset extends Array<any> implements MSSQL.IRecordSet<any>{
|
||||
class fakeResponse implements MSSQL.IResult<any> {
|
||||
recordsets: MSSQL.IRecordSet<any>[];
|
||||
recordset: MSSQL.IRecordSet<any>;
|
||||
rowsAffected: number[];
|
||||
output: { [key: string]: any; };
|
||||
|
||||
}
|
||||
class fakeRecordset extends Array<any> implements MSSQL.IRecordSet<any>{
|
||||
columns: IColumnMetadata;
|
||||
toTable(): Table{
|
||||
toTable(): Table {
|
||||
return new Table();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe('MssqlDriver', function () {
|
||||
let driver: MssqlDriver
|
||||
@ -48,10 +48,10 @@ describe('MssqlDriver', function () {
|
||||
.returns(
|
||||
{
|
||||
query: (q) => {
|
||||
|
||||
let response=new fakeResponse();
|
||||
|
||||
response.recordset=new fakeRecordset();
|
||||
|
||||
let response = new fakeResponse();
|
||||
|
||||
response.recordset = new fakeRecordset();
|
||||
response.recordset.push({ TABLE_SCHEMA: 'schema', TABLE_NAME: 'name' })
|
||||
return response;
|
||||
}
|
||||
@ -71,13 +71,13 @@ describe('MssqlDriver', function () {
|
||||
.returns(
|
||||
{
|
||||
query: (q) => {
|
||||
let response=new fakeResponse();
|
||||
response.recordset=new fakeRecordset();
|
||||
let response = new fakeResponse();
|
||||
response.recordset = new fakeRecordset();
|
||||
response.recordset.push({
|
||||
TABLE_NAME: 'name', CHARACTER_MAXIMUM_LENGTH: 0,
|
||||
COLUMN_DEFAULT: 'a', COLUMN_NAME: 'name', DATA_TYPE: 'int',
|
||||
IS_NULLABLE: 'YES', NUMERIC_PRECISION: 0, NUMERIC_SCALE: 0,
|
||||
IsIdentity:1
|
||||
IsIdentity: 1
|
||||
})
|
||||
return response;
|
||||
}
|
||||
@ -97,7 +97,7 @@ describe('MssqlDriver', function () {
|
||||
default: 'a',
|
||||
is_nullable: true,
|
||||
isPrimary: false,
|
||||
is_generated:true,
|
||||
is_generated: true,
|
||||
name: 'name',
|
||||
numericPrecision: null,
|
||||
numericScale: null,
|
||||
@ -105,10 +105,10 @@ describe('MssqlDriver', function () {
|
||||
ts_type: 'number',
|
||||
relations: <RelationInfo[]>[]
|
||||
})
|
||||
let result = await driver.GetCoulmnsFromEntity(entities,'schema');
|
||||
let result = await driver.GetCoulmnsFromEntity(entities, 'schema');
|
||||
expect(result).to.be.deep.equal(expected)
|
||||
})
|
||||
it('should find primary indexes')
|
||||
it('should get indexes info')
|
||||
it('should get relations info')
|
||||
})
|
||||
})
|
||||
|
@ -30,9 +30,9 @@ describe("Platform specyfic types", async function () {
|
||||
let examplesPathTS = path.resolve(process.cwd(), 'test/integration/entityTypes')
|
||||
let files = fs.readdirSync(examplesPathTS)
|
||||
|
||||
for (let folder of files) {
|
||||
for (let dbDriver of dbDrivers) {
|
||||
|
||||
for (let dbDriver of dbDrivers) {
|
||||
for (let folder of files) {
|
||||
if (dbDriver == folder) {
|
||||
it(dbDriver, async function () {
|
||||
|
||||
|
@ -91,4 +91,4 @@ export class Post {
|
||||
// @Column("simple-array")
|
||||
// simpleArray: string[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -118,4 +118,4 @@ export class Post {
|
||||
// @Column("simple-array")
|
||||
// simpleArray: string[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -90,4 +90,4 @@ export class Post {
|
||||
// @Column("simple-array")
|
||||
// simpleArray: string[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -237,4 +237,4 @@ export class Post {
|
||||
// @Column("simple-array")
|
||||
// simpleArray: string[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Column, Entity,PrimaryGeneratedColumn,Index,Generated} from "typeorm";
|
||||
import { Column, Entity, PrimaryGeneratedColumn, Index, Generated } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
@ -17,4 +17,4 @@ export class Post {
|
||||
})
|
||||
likesCount: number;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn, Index } f
|
||||
|
||||
@Entity("EverythingEntity")
|
||||
export class EverythingEntity {
|
||||
//TODO: change to check column types per database engine
|
||||
//TODO: change to check column types per database engine
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@ -69,4 +69,4 @@ export class EverythingEntity {
|
||||
// @UpdateDateColumn()
|
||||
// updatedDate: Date;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from "typeorm"
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from "typeorm"
|
||||
|
||||
@Entity("Post")
|
||||
@Index("my_index_with_id_and_text", ["id", "text"], {unique:true})
|
||||
@Index("my_index_with_id_and_title", (post: Post) => [post.id, post.title], {unique:true})
|
||||
@Index("my_index_with_id_and_text", ["id", "text"], { unique: true })
|
||||
@Index("my_index_with_id_and_title", (post: Post) => [post.id, post.title], { unique: true })
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
@ -23,4 +23,4 @@ export class Post {
|
||||
@Index()
|
||||
likesCount: number;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn, VersionColumn } from "typeorm"
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn, VersionColumn } from "typeorm"
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
@ -14,5 +14,5 @@ export class Post {
|
||||
|
||||
@VersionColumn()
|
||||
version: number;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn,Index} from "typeorm";
|
||||
import {PostDetails} from "./PostDetails";
|
||||
import {PostCategory} from "./PostCategory";
|
||||
import {PostAuthor} from "./PostAuthor";
|
||||
import {PostInformation} from "./PostInformation";
|
||||
import {PostImage} from "./PostImage";
|
||||
import {PostMetadata} from "./PostMetadata";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn, Index } from "typeorm";
|
||||
import { PostDetails } from "./PostDetails";
|
||||
import { PostCategory } from "./PostCategory";
|
||||
import { PostAuthor } from "./PostAuthor";
|
||||
import { PostInformation } from "./PostInformation";
|
||||
import { PostImage } from "./PostImage";
|
||||
import { PostMetadata } from "./PostMetadata";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
@ -20,18 +20,17 @@ export class Post {
|
||||
|
||||
// post has relation with category, however inverse relation is not set (category does not have relation with post set)
|
||||
@OneToOne(type => PostCategory, {
|
||||
cascadeInsert: true,
|
||||
cascadeUpdate: true,
|
||||
cascadeRemove: true
|
||||
cascade: true,
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
@JoinColumn()
|
||||
@Index({ unique: true })
|
||||
category: PostCategory;
|
||||
|
||||
// post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
|
||||
// post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
|
||||
// relation it will be inserted automatically to the db when you save this Post entity
|
||||
@OneToOne(type => PostDetails, details => details.post, {
|
||||
cascadeInsert: true
|
||||
cascade: true
|
||||
})
|
||||
@JoinColumn()
|
||||
@Index({ unique: true })
|
||||
@ -40,7 +39,7 @@ export class Post {
|
||||
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
|
||||
// it will be inserted automatically to the db when you save this Post entity
|
||||
@OneToOne(type => PostImage, image => image.post, {
|
||||
cascadeUpdate: true
|
||||
cascade: true,
|
||||
})
|
||||
@JoinColumn()
|
||||
@Index({ unique: true })
|
||||
@ -49,17 +48,16 @@ export class Post {
|
||||
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
|
||||
// it will be inserted automatically to the db when you save this Post entity
|
||||
@OneToOne(type => PostMetadata, metadata => metadata.post, {
|
||||
cascadeRemove: true
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
@JoinColumn()
|
||||
@Index({ unique: true })
|
||||
metadata: PostMetadata|null;
|
||||
metadata: PostMetadata | null;
|
||||
|
||||
// post has relation with details. full cascades here
|
||||
@OneToOne(type => PostInformation, information => information.post, {
|
||||
cascadeInsert: true,
|
||||
cascadeUpdate: true,
|
||||
cascadeRemove: true
|
||||
cascade: true,
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
@JoinColumn()
|
||||
@Index({ unique: true })
|
||||
@ -71,4 +69,4 @@ export class Post {
|
||||
@Index({ unique: true })
|
||||
author: PostAuthor;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn } from "typeorm";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostAuthor")
|
||||
export class PostAuthor {
|
||||
@ -13,4 +13,4 @@ export class PostAuthor {
|
||||
@OneToOne(type => Post, post => post.author)
|
||||
post: Post;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("PostCategory")
|
||||
export class PostCategory {
|
||||
@ -9,4 +9,4 @@ export class PostCategory {
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn } from "typeorm";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostDetails")
|
||||
export class PostDetails {
|
||||
@ -15,12 +15,11 @@ export class PostDetails {
|
||||
|
||||
@Column()
|
||||
metadata: string;
|
||||
|
||||
|
||||
@OneToOne(type => Post, post => post.details, {
|
||||
cascadeInsert: true,
|
||||
cascadeUpdate: true,
|
||||
cascadeRemove: true
|
||||
// cascade: true,
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
post: Post;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn } from "typeorm";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostImage")
|
||||
export class PostImage {
|
||||
@ -13,4 +13,4 @@ export class PostImage {
|
||||
@OneToOne(type => Post, post => post.image)
|
||||
post: Post;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn } from "typeorm";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostInformation")
|
||||
export class PostInformation {
|
||||
@ -9,10 +9,8 @@ export class PostInformation {
|
||||
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@OneToOne(type => Post, post => post.information, {
|
||||
cascadeUpdate: true,
|
||||
})
|
||||
|
||||
@OneToOne(type => Post, post => post.information)
|
||||
post: Post;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, JoinColumn } from "typeorm";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostMetadata")
|
||||
export class PostMetadata {
|
||||
@ -13,4 +13,4 @@ export class PostMetadata {
|
||||
@OneToOne(type => Post, post => post.metadata)
|
||||
post: Post;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Column, Entity, PrimaryColumn} from "typeorm";
|
||||
import { Column, Entity, PrimaryColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
@ -12,4 +12,4 @@ export class Post {
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
import {PostDetails} from "./PostDetails";
|
||||
import {PostCategory} from "./PostCategory";
|
||||
import {PostAuthor} from "./PostAuthor";
|
||||
import {PostInformation} from "./PostInformation";
|
||||
import {PostImage} from "./PostImage";
|
||||
import {PostMetadata} from "./PostMetadata";
|
||||
import { PostDetails } from "./PostDetails";
|
||||
import { PostCategory } from "./PostCategory";
|
||||
import { PostAuthor } from "./PostAuthor";
|
||||
import { PostInformation } from "./PostInformation";
|
||||
import { PostImage } from "./PostImage";
|
||||
import { PostMetadata } from "./PostMetadata";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
@ -20,38 +20,36 @@ export class Post {
|
||||
|
||||
// post has relation with category, however inverse relation is not set (category does not have relation with post set)
|
||||
@ManyToOne(type => PostCategory, {
|
||||
cascadeInsert: true,
|
||||
cascadeUpdate: true,
|
||||
cascadeRemove: true
|
||||
cascade: true,
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
category: PostCategory;
|
||||
|
||||
// post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
|
||||
// post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
|
||||
// relation it will be inserted automatically to the db when you save this Post entity
|
||||
@ManyToOne(type => PostDetails, details => details.posts, {
|
||||
cascadeInsert: true
|
||||
cascade: true,
|
||||
})
|
||||
details: PostDetails;
|
||||
|
||||
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
|
||||
// it will be inserted automatically to the db when you save this Post entity
|
||||
@ManyToOne(type => PostImage, image => image.posts, {
|
||||
cascadeUpdate: true
|
||||
cascade: true,
|
||||
})
|
||||
image: PostImage;
|
||||
|
||||
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
|
||||
// it will be inserted automatically to the db when you save this Post entity
|
||||
@ManyToOne(type => PostMetadata, metadata => metadata.posts, {
|
||||
cascadeRemove: true
|
||||
cascade: true,
|
||||
})
|
||||
metadata: PostMetadata|null;
|
||||
metadata: PostMetadata | null;
|
||||
|
||||
// post has relation with details. full cascades here
|
||||
@ManyToOne(type => PostInformation, information => information.posts, {
|
||||
cascadeInsert: true,
|
||||
cascadeUpdate: true,
|
||||
cascadeRemove: true
|
||||
cascade: true,
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
information: PostInformation;
|
||||
|
||||
@ -59,4 +57,4 @@ export class Post {
|
||||
@ManyToOne(type => PostAuthor, author => author.posts)
|
||||
author: PostAuthor;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostAuthor")
|
||||
export class PostAuthor {
|
||||
@ -13,4 +13,4 @@ export class PostAuthor {
|
||||
@OneToMany(type => Post, post => post.author)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,4 @@ export class PostCategory {
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostDetails")
|
||||
export class PostDetails {
|
||||
@ -21,11 +21,8 @@ export class PostDetails {
|
||||
nullable: true
|
||||
})
|
||||
metadata: string;
|
||||
|
||||
@OneToMany(type => Post, post => post.details, {
|
||||
cascadeInsert: true,
|
||||
cascadeUpdate: true
|
||||
})
|
||||
|
||||
@OneToMany(type => Post, post => post.details)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,4 +13,4 @@ export class PostImage {
|
||||
@OneToMany(type => Post, post => post.image)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostInformation")
|
||||
export class PostInformation {
|
||||
@ -9,10 +9,8 @@ export class PostInformation {
|
||||
|
||||
@Column()
|
||||
text: string;
|
||||
|
||||
@OneToMany(type => Post, post => post.information, {
|
||||
cascadeUpdate: true,
|
||||
})
|
||||
|
||||
@OneToMany(type => Post, post => post.information)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
import { Post } from "./Post";
|
||||
|
||||
@Entity("PostMetadata")
|
||||
export class PostMetadata {
|
||||
@ -13,4 +13,4 @@ export class PostMetadata {
|
||||
@OneToMany(type => Post, post => post.metadata)
|
||||
posts: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,4 +13,4 @@ export class Post {
|
||||
@ManyToOne(type => PostAuthor, author => author.posts2)
|
||||
author2: PostAuthor;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,4 +13,4 @@ export class PostAuthor {
|
||||
@OneToMany(type => Post, post => post.author2)
|
||||
posts2: Post[];
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ describe("TypeOrm examples", async function () {
|
||||
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')
|
||||
@ -55,6 +56,9 @@ describe("TypeOrm examples", async function () {
|
||||
case 'mariadb':
|
||||
engine = await GTU.createMariaDBModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
case 'oracle':
|
||||
engine = await GTU.createOracleDBModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log(`Unknown engine type`);
|
||||
|
@ -21,6 +21,7 @@ export class EntityFileToJson {
|
||||
// if (!x.endsWith('[]')) {
|
||||
// x = x + '[]'// can't distinguish OneTwoMany from OneToOne without indexes
|
||||
// }
|
||||
x = x.trim();
|
||||
return x;
|
||||
});
|
||||
} else {
|
||||
@ -92,7 +93,7 @@ export class EntityFileToJson {
|
||||
for (let line of lines) {
|
||||
let trimmedLine = line.trim();
|
||||
if (trimmedLine.startsWith('//')) {
|
||||
continue; //commented line
|
||||
continue; //commented line
|
||||
}
|
||||
if (isMultilineStatement)
|
||||
trimmedLine = priorPartOfMultilineStatement + ' ' + trimmedLine
|
||||
@ -101,7 +102,7 @@ export class EntityFileToJson {
|
||||
|
||||
else if (!isInClassBody) {
|
||||
if (trimmedLine.startsWith('import')) {
|
||||
continue; //import statement is not part of entity definition
|
||||
continue; //import statement is not part of entity definition
|
||||
} else if (trimmedLine.startsWith('@Entity')) {
|
||||
continue; //TODO:entity options
|
||||
} else if (trimmedLine.startsWith('export class')) {
|
||||
@ -243,6 +244,7 @@ export class EntityFileToJson {
|
||||
// if (!x.endsWith('[]')) {
|
||||
// x = x + '[]'// can't distinguish OneTwoMany from OneToOne without indexes
|
||||
// }
|
||||
x = x.trim();
|
||||
return x;
|
||||
});
|
||||
|
||||
@ -272,15 +274,15 @@ export class EntityFileToJson {
|
||||
console.log(`${trimmedLine}`)
|
||||
}
|
||||
|
||||
retVal.columns=retVal.columns.map(col=>{
|
||||
retVal.columns = retVal.columns.map(col => {
|
||||
if (col.columnName.endsWith('Id'))
|
||||
col.columnName=col.columnName.substr(0,col.columnName.length-2)
|
||||
col.columnName = col.columnName.substr(0, col.columnName.length - 2)
|
||||
return col;
|
||||
})
|
||||
retVal.indicies=retVal.indicies.map(ind=>{
|
||||
ind.columnNames=ind.columnNames.map(colName=>{
|
||||
retVal.indicies = retVal.indicies.map(ind => {
|
||||
ind.columnNames = ind.columnNames.map(colName => {
|
||||
if (colName.endsWith('Id'))
|
||||
colName=colName.substr(0,colName.length-2)
|
||||
colName = colName.substr(0, colName.length - 2)
|
||||
return colName;
|
||||
})
|
||||
return ind;
|
||||
@ -312,4 +314,4 @@ class EntityIndex {
|
||||
indexName: string
|
||||
columnNames: string[] = []
|
||||
isUnique: boolean = false
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ 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 { OracleDriver } from "../../src/drivers/OracleDriver";
|
||||
import { Engine } from "../../src/Engine";
|
||||
import { createConnection, ConnectionOptions, Connection } from "typeorm";
|
||||
import * as yn from "yn"
|
||||
@ -48,7 +49,8 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin
|
||||
databaseType: 'mssql',
|
||||
resultsPath: resultsPath,
|
||||
schemaName: 'dbo',
|
||||
ssl: yn(process.env.MSSQL_SSL)
|
||||
ssl: yn(process.env.MSSQL_SSL),
|
||||
noConfigs: false
|
||||
});
|
||||
|
||||
|
||||
@ -91,7 +93,8 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st
|
||||
databaseType: 'postgres',
|
||||
resultsPath: resultsPath,
|
||||
schemaName: 'public',
|
||||
ssl: yn(process.env.POSTGRES_SSL)
|
||||
ssl: yn(process.env.POSTGRES_SSL),
|
||||
noConfigs: false
|
||||
});
|
||||
|
||||
|
||||
@ -135,7 +138,8 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin
|
||||
databaseType: 'mysql',
|
||||
resultsPath: resultsPath,
|
||||
schemaName: 'ignored',
|
||||
ssl: yn(process.env.MYSQL_SSL)
|
||||
ssl: yn(process.env.MYSQL_SSL),
|
||||
noConfigs: false
|
||||
});
|
||||
|
||||
|
||||
@ -179,7 +183,55 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str
|
||||
databaseType: 'mariadb',
|
||||
resultsPath: resultsPath,
|
||||
schemaName: 'ignored',
|
||||
ssl: yn(process.env.MARIADB_SSL)
|
||||
ssl: yn(process.env.MARIADB_SSL),
|
||||
noConfigs: false
|
||||
});
|
||||
|
||||
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
export async function createOracleDBModels(filesOrgPath: string, resultsPath: string): Promise<Engine> {
|
||||
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_Username), String(process.env.ORACLE_Password), yn(process.env.ORACLE_SSL));
|
||||
|
||||
if (! await driver.CheckIfDBExists(String(process.env.ORACLE_Database)))
|
||||
await driver.CreateDB(String(process.env.ORACLE_Database));
|
||||
await driver.DisconnectFromServer();
|
||||
|
||||
let connOpt: ConnectionOptions = {
|
||||
|
||||
database: String(process.env.ORACLE_Database),
|
||||
sid: String(process.env.ORACLE_Database),
|
||||
host: String(process.env.ORACLE_Host),
|
||||
password: String(process.env.ORACLE_Password),
|
||||
type: 'oracle',
|
||||
username: String(process.env.ORACLE_Username),
|
||||
port: Number(process.env.ORACLE_Port),
|
||||
// dropSchema: true,
|
||||
synchronize: true,
|
||||
entities: [path.resolve(filesOrgPath, '*.js')],
|
||||
}
|
||||
let conn = await createConnection(connOpt)
|
||||
|
||||
if (conn.isConnected)
|
||||
await conn.close()
|
||||
|
||||
driver = new OracleDriver();
|
||||
let 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: resultsPath,
|
||||
schemaName: String(process.env.ORACLE_Username),
|
||||
ssl: yn(process.env.ORACLE_SSL),
|
||||
noConfigs: false
|
||||
});
|
||||
|
||||
|
||||
@ -203,4 +255,4 @@ export function compileTsFiles(fileNames: string[], options: ts.CompilerOptions)
|
||||
});
|
||||
|
||||
return compileErrors;
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,9 @@
|
||||
"moduleResolution": "node",
|
||||
"outDir": "dist",
|
||||
"newLine": "LF"
|
||||
}, "include": [
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
16
typings.json
16
typings.json
@ -1,10 +1,10 @@
|
||||
{
|
||||
"globalDevDependencies": {
|
||||
"mustache": "registry:dt/mustache#0.8.2+20160510002910"
|
||||
},
|
||||
"dependencies": {
|
||||
"mssql": "registry:dt/mssql#3.3.0+20170311011547",
|
||||
"yargs": "registry:npm/yargs#5.0.0+20160907000723",
|
||||
"yn": "registry:npm/yn#1.3.0+20170508185912"
|
||||
}
|
||||
"globalDevDependencies": {
|
||||
"mustache": "registry:dt/mustache#0.8.2+20160510002910"
|
||||
},
|
||||
"dependencies": {
|
||||
"mssql": "registry:dt/mssql#3.3.0+20170311011547",
|
||||
"yargs": "registry:npm/yargs#5.0.0+20160907000723",
|
||||
"yn": "registry:npm/yn#1.3.0+20170508185912"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user