parent
3eeb7be881
commit
a19d82609c
@ -15,10 +15,11 @@ export abstract class AbstractDriver {
|
||||
): Promise<DatabaseModel> {
|
||||
let dbModel = <DatabaseModel>{};
|
||||
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);
|
||||
let sqlEscapedSchema='\''+ schema.split(',').join('\',\'')+'\''
|
||||
dbModel.entities = await this.GetAllTables(sqlEscapedSchema);
|
||||
await this.GetCoulmnsFromEntity(dbModel.entities, sqlEscapedSchema);
|
||||
await this.GetIndexesFromEntity(dbModel.entities, sqlEscapedSchema);
|
||||
dbModel.entities = await this.GetRelations(dbModel.entities, sqlEscapedSchema);
|
||||
await this.DisconnectFromServer();
|
||||
this.FindPrimaryColumnsFromIndexes(dbModel);
|
||||
return dbModel;
|
||||
|
@ -37,12 +37,13 @@ export class MssqlDriver extends AbstractDriver {
|
||||
TABLE_SCHEMA: string;
|
||||
TABLE_NAME: string;
|
||||
}[] = (await request.query(
|
||||
`SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA='${schema}'`
|
||||
`SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema})`
|
||||
)).recordset;
|
||||
let ret: EntityInfo[] = <EntityInfo[]>[];
|
||||
response.forEach(val => {
|
||||
let ent: EntityInfo = new EntityInfo();
|
||||
ent.EntityName = val.TABLE_NAME;
|
||||
ent.Schema=val.TABLE_SCHEMA;
|
||||
ent.Columns = <ColumnInfo[]>[];
|
||||
ent.Indexes = <IndexInfo[]>[];
|
||||
ret.push(ent);
|
||||
@ -66,7 +67,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
IsIdentity: number;
|
||||
}[] = (await request.query(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,
|
||||
DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE,
|
||||
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='${schema}'`))
|
||||
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA in (${schema})`))
|
||||
.recordset;
|
||||
entities.forEach(ent => {
|
||||
response
|
||||
@ -278,7 +279,7 @@ INNER JOIN
|
||||
INNER JOIN
|
||||
sys.schemas s on s.schema_id=t.schema_id
|
||||
WHERE
|
||||
t.is_ms_shipped = 0 and s.name='${schema}'
|
||||
t.is_ms_shipped = 0 and s.name in (${schema})
|
||||
ORDER BY
|
||||
t.name, ind.name, ind.index_id, ic.key_ordinal;`)).recordset;
|
||||
entities.forEach(ent => {
|
||||
@ -352,7 +353,7 @@ inner join
|
||||
inner join
|
||||
sys.schemas as parentSchema on parentSchema.schema_id=parentTable.schema_id
|
||||
where
|
||||
fk.is_disabled=0 and fk.is_ms_shipped=0 and parentSchema.name='${schema}'
|
||||
fk.is_disabled=0 and fk.is_ms_shipped=0 and parentSchema.name in (${schema})
|
||||
order by
|
||||
TableWithForeignKey, FK_PartNo`)).recordset;
|
||||
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
|
||||
|
@ -37,13 +37,14 @@ export class PostgresDriver extends AbstractDriver {
|
||||
table_schema: string;
|
||||
table_name: string;
|
||||
}[] = (await this.Connection.query(
|
||||
`SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema = '${schema}' `
|
||||
`SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema in (${schema}) `
|
||||
)).rows;
|
||||
|
||||
let ret: EntityInfo[] = <EntityInfo[]>[];
|
||||
response.forEach(val => {
|
||||
let ent: EntityInfo = new EntityInfo();
|
||||
ent.EntityName = val.table_name;
|
||||
ent.Schema=val.table_schema;
|
||||
ent.Columns = <ColumnInfo[]>[];
|
||||
ent.Indexes = <IndexInfo[]>[];
|
||||
ret.push(ent);
|
||||
@ -69,7 +70,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
data_type,character_maximum_length,numeric_precision,numeric_scale
|
||||
--,COLUMNPROPERTY(object_id(table_name), column_name, 'isidentity') isidentity
|
||||
, case when column_default LIKE 'nextval%' then 'YES' else 'NO' end isidentity
|
||||
FROM INFORMATION_SCHEMA.COLUMNS where table_schema ='${schema}'`))
|
||||
FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (${schema})`))
|
||||
.rows;
|
||||
entities.forEach(ent => {
|
||||
response
|
||||
@ -84,7 +85,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
colInfo.is_generated =
|
||||
resp.isidentity == "YES" ? true : false;
|
||||
colInfo.default = colInfo.is_generated
|
||||
? ""
|
||||
? null
|
||||
: resp.column_default;
|
||||
colInfo.sql_type = resp.data_type;
|
||||
switch (resp.data_type) {
|
||||
@ -252,7 +253,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
LEFT JOIN pg_class AS i ON ix.indexrelid = i.oid
|
||||
|
||||
WHERE c.relkind = 'r'::char
|
||||
AND n.nspname = '${schema}'
|
||||
AND n.nspname in (${schema})
|
||||
--AND c.relname = 'nodes' -- Replace with table name, or Comment this for get all tables
|
||||
AND f.attnum > 0
|
||||
AND i.oid<>0
|
||||
@ -331,7 +332,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
con1.contype = 'f'::"char"
|
||||
AND cl_1.relnamespace = ns.oid
|
||||
AND con1.conrelid = cl_1.oid
|
||||
and nspname='${schema}'
|
||||
and nspname in (${schema})
|
||||
) con,
|
||||
pg_attribute att,
|
||||
pg_class cl,
|
||||
|
@ -3,7 +3,7 @@ import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, Joi
|
||||
{{/each}}
|
||||
|
||||
|
||||
@Entity("{{EntityName}}")
|
||||
@Entity("{{EntityName}}"{{#Schema}},{schema:"{{.}}"}{{/Schema}})
|
||||
{{#Indexes}}{{^isPrimaryKey}}@Index("{{name}}",[{{#columns}}"{{name}}",{{/columns}}]{{#isUnique}},{unique:true}{{/isUnique}})
|
||||
{{/isPrimaryKey}}{{/Indexes}}export class {{toEntityName EntityName}} {
|
||||
{{#Columns}}
|
||||
|
@ -10,6 +10,7 @@ export class EntityInfo {
|
||||
Imports: string[];
|
||||
UniqueImports: string[];
|
||||
Indexes: IndexInfo[];
|
||||
Schema:string;
|
||||
|
||||
relationImports(): any {
|
||||
var returnString = "";
|
||||
|
@ -61,6 +61,7 @@ describe('MssqlDriver', function () {
|
||||
let expectedResult = <EntityInfo[]>[];
|
||||
let y = new EntityInfo();
|
||||
y.EntityName = 'name'
|
||||
y.Schema='schema'
|
||||
y.Columns = <ColumnInfo[]>[];
|
||||
y.Indexes = <IndexInfo[]>[];
|
||||
expectedResult.push(y)
|
||||
|
28
test/integration/github-issues/39/entity/Post.ts
Normal file
28
test/integration/github-issues/39/entity/Post.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, JoinColumn} from "typeorm";
|
||||
import {User} from "./User";
|
||||
|
||||
|
||||
@Entity("Post",{schema:"sch1"})
|
||||
export class Post {
|
||||
|
||||
@Column("integer",{
|
||||
nullable:false,
|
||||
primary:true,
|
||||
name:"id"
|
||||
})
|
||||
id:number;
|
||||
|
||||
|
||||
|
||||
@ManyToOne(type=>User, userId=>userId.posts)
|
||||
@JoinColumn({ name:"userId"})
|
||||
userId:User;
|
||||
|
||||
|
||||
@Column("text",{
|
||||
nullable:true,
|
||||
name:"body"
|
||||
})
|
||||
body:string;
|
||||
|
||||
}
|
27
test/integration/github-issues/39/entity/User.ts
Normal file
27
test/integration/github-issues/39/entity/User.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, JoinColumn} from "typeorm";
|
||||
import {Post} from "./Post";
|
||||
|
||||
|
||||
@Entity("User",{schema:"sch2"})
|
||||
export class User {
|
||||
|
||||
@Column("integer",{
|
||||
nullable:false,
|
||||
primary:true,
|
||||
name:"id"
|
||||
})
|
||||
id:number;
|
||||
|
||||
|
||||
@Column("text",{
|
||||
nullable:true,
|
||||
name:"name"
|
||||
})
|
||||
name:string;
|
||||
|
||||
|
||||
|
||||
@OneToMany(type=>Post, posts=>posts.userId)
|
||||
posts:Post[];
|
||||
|
||||
}
|
@ -34,6 +34,16 @@ describe("GitHub issues", async function () {
|
||||
|
||||
describe(`#${folder}`, async function () {
|
||||
for (let dbDriver of dbDrivers) {
|
||||
|
||||
switch (folder) {
|
||||
case '39':
|
||||
if (dbDriver =='mysql' || dbDriver=='mariadb')
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
it(dbDriver, async function () {
|
||||
|
||||
let filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity')
|
||||
|
@ -1,4 +1,21 @@
|
||||
import { debug } from "util";
|
||||
|
||||
export class EntityFileToJson {
|
||||
getEntityOptions(trimmedLine: string, ent: EntityJson) {
|
||||
let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')'))
|
||||
|
||||
if (decoratorParameters.length > 0) {
|
||||
if (decoratorParameters[0] == '"' && decoratorParameters.endsWith('"')) {
|
||||
|
||||
} else {
|
||||
let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim()
|
||||
if (badJSON.lastIndexOf(',') == badJSON.length - 3) {
|
||||
badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1]
|
||||
}
|
||||
ent.entityOptions = JSON.parse(badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '))
|
||||
}
|
||||
}
|
||||
}
|
||||
getColumnOptionsAndType(trimmedLine: string, col: EntityColumn) {
|
||||
let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')'))
|
||||
|
||||
@ -104,7 +121,15 @@ export class EntityFileToJson {
|
||||
if (trimmedLine.startsWith('import')) {
|
||||
continue; //import statement is not part of entity definition
|
||||
} else if (trimmedLine.startsWith('@Entity')) {
|
||||
continue; //TODO:entity options
|
||||
if (this.isPartOfMultilineStatement(trimmedLine)) {
|
||||
isMultilineStatement = true;
|
||||
priorPartOfMultilineStatement = trimmedLine;
|
||||
continue;
|
||||
} else {
|
||||
let options = trimmedLine.substring(trimmedLine.lastIndexOf('{'), trimmedLine.lastIndexOf('}')+1).trim().toLowerCase()
|
||||
this.getEntityOptions(trimmedLine,retVal);
|
||||
continue;
|
||||
}
|
||||
} else if (trimmedLine.startsWith('export class')) {
|
||||
retVal.entityName = trimmedLine.substring(trimmedLine.indexOf('class') + 5, trimmedLine.lastIndexOf('{')).trim().toLowerCase()
|
||||
isInClassBody = true;
|
||||
|
@ -17,8 +17,9 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin
|
||||
driver = new MssqlDriver();
|
||||
await driver.ConnectToServer(`master`, String(process.env.MSSQL_Host), Number(process.env.MSSQL_Port), String(process.env.MSSQL_Username), String(process.env.MSSQL_Password), yn(process.env.MSSQL_SSL));
|
||||
|
||||
if (! await driver.CheckIfDBExists(String(process.env.MSSQL_Database)))
|
||||
await driver.CreateDB(String(process.env.MSSQL_Database));
|
||||
if (await driver.CheckIfDBExists(String(process.env.MSSQL_Database)))
|
||||
await driver.DropDB(String(process.env.MSSQL_Database));
|
||||
await driver.CreateDB(String(process.env.MSSQL_Database));
|
||||
await driver.DisconnectFromServer();
|
||||
|
||||
let connOpt: ConnectionOptions = {
|
||||
@ -49,7 +50,7 @@ export async function createMSSQLModels(filesOrgPath: string, resultsPath: strin
|
||||
password: String(process.env.MSSQL_Password),
|
||||
databaseType: 'mssql',
|
||||
resultsPath: resultsPath,
|
||||
schemaName: 'dbo',
|
||||
schemaName: 'dbo,sch1,sch2',
|
||||
ssl: yn(process.env.MSSQL_SSL),
|
||||
noConfigs: false,
|
||||
convertCaseEntity: 'none',
|
||||
@ -66,8 +67,9 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st
|
||||
driver = new PostgresDriver();
|
||||
await driver.ConnectToServer(`postgres`, String(process.env.POSTGRES_Host), Number(process.env.POSTGRES_Port), String(process.env.POSTGRES_Username), String(process.env.POSTGRES_Password), yn(process.env.POSTGRES_SSL));
|
||||
|
||||
if (! await driver.CheckIfDBExists(String(process.env.POSTGRES_Database)))
|
||||
await driver.CreateDB(String(process.env.POSTGRES_Database));
|
||||
if (await driver.CheckIfDBExists(String(process.env.POSTGRES_Database)))
|
||||
await driver.DropDB(String(process.env.POSTGRES_Database));
|
||||
await driver.CreateDB(String(process.env.POSTGRES_Database));
|
||||
await driver.DisconnectFromServer();
|
||||
|
||||
let connOpt: ConnectionOptions = {
|
||||
@ -96,7 +98,7 @@ export async function createPostgresModels(filesOrgPath: string, resultsPath: st
|
||||
password: String(process.env.POSTGRES_Password),
|
||||
databaseType: 'postgres',
|
||||
resultsPath: resultsPath,
|
||||
schemaName: 'public',
|
||||
schemaName: 'public,sch1,sch2',
|
||||
ssl: yn(process.env.POSTGRES_SSL),
|
||||
noConfigs: false,
|
||||
convertCaseEntity: 'none',
|
||||
@ -114,8 +116,9 @@ export async function createMysqlModels(filesOrgPath: string, resultsPath: strin
|
||||
driver = new MysqlDriver();
|
||||
await driver.ConnectToServer(`mysql`, String(process.env.MYSQL_Host), Number(process.env.MYSQL_Port), String(process.env.MYSQL_Username), String(process.env.MYSQL_Password), yn(process.env.MYSQL_SSL));
|
||||
|
||||
if (! await driver.CheckIfDBExists(String(process.env.MYSQL_Database)))
|
||||
await driver.CreateDB(String(process.env.MYSQL_Database));
|
||||
if (await driver.CheckIfDBExists(String(process.env.MYSQL_Database)))
|
||||
await driver.DropDB(String(process.env.MYSQL_Database));
|
||||
await driver.CreateDB(String(process.env.MYSQL_Database));
|
||||
await driver.DisconnectFromServer();
|
||||
|
||||
let connOpt: ConnectionOptions = {
|
||||
@ -161,8 +164,9 @@ export async function createMariaDBModels(filesOrgPath: string, resultsPath: str
|
||||
driver = new MariaDbDriver();
|
||||
await driver.ConnectToServer(`mysql`, String(process.env.MARIADB_Host), Number(process.env.MARIADB_Port), String(process.env.MARIADB_Username), String(process.env.MARIADB_Password), yn(process.env.MARIADB_SSL));
|
||||
|
||||
if (! await driver.CheckIfDBExists(String(process.env.MARIADB_Database)))
|
||||
await driver.CreateDB(String(process.env.MARIADB_Database));
|
||||
if (await driver.CheckIfDBExists(String(process.env.MARIADB_Database)))
|
||||
await driver.DropDB(String(process.env.MARIADB_Database));
|
||||
await driver.CreateDB(String(process.env.MARIADB_Database));
|
||||
await driver.DisconnectFromServer();
|
||||
|
||||
let connOpt: ConnectionOptions = {
|
||||
|
Loading…
Reference in New Issue
Block a user