fix for #122 - default values
This commit is contained in:
parent
e769696e58
commit
82f5ae43aa
@ -59,7 +59,9 @@ export class MssqlDriver extends AbstractDriver {
|
||||
colInfo.isNullable = resp.IS_NULLABLE === "YES";
|
||||
colInfo.isGenerated = resp.IsIdentity === 1;
|
||||
colInfo.isUnique = resp.IsUnique === 1;
|
||||
colInfo.default = resp.COLUMN_DEFAULT;
|
||||
colInfo.default = this.ReturnDefaultValueFunction(
|
||||
resp.COLUMN_DEFAULT
|
||||
);
|
||||
colInfo.sqlType = resp.DATA_TYPE;
|
||||
switch (resp.DATA_TYPE) {
|
||||
case "bigint":
|
||||
@ -404,4 +406,16 @@ order by
|
||||
);
|
||||
return resp.recordset.length > 0;
|
||||
}
|
||||
private ReturnDefaultValueFunction(defVal: string | null): string | null {
|
||||
if (!defVal) {
|
||||
return null;
|
||||
}
|
||||
if (defVal.startsWith("(") && defVal.endsWith(")")) {
|
||||
defVal = defVal.slice(1, -1);
|
||||
}
|
||||
if (defVal.startsWith(`'`)) {
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,9 @@ export class MysqlDriver extends AbstractDriver {
|
||||
colInfo.isNullable = resp.IS_NULLABLE === "YES";
|
||||
colInfo.isGenerated = resp.IsIdentity === 1;
|
||||
colInfo.isUnique = resp.column_key === "UNI";
|
||||
colInfo.default = resp.COLUMN_DEFAULT;
|
||||
colInfo.default = this.ReturnDefaultValueFunction(
|
||||
resp.COLUMN_DEFAULT
|
||||
);
|
||||
colInfo.sqlType = resp.DATA_TYPE;
|
||||
switch (resp.DATA_TYPE) {
|
||||
case "int":
|
||||
@ -409,4 +411,13 @@ export class MysqlDriver extends AbstractDriver {
|
||||
await promise;
|
||||
return ret;
|
||||
}
|
||||
private ReturnDefaultValueFunction(defVal: string | null): string | null {
|
||||
if (!defVal) {
|
||||
return null;
|
||||
}
|
||||
if (defVal === "CURRENT_TIMESTAMP" || defVal.startsWith(`'`)) {
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
return `() => "'${defVal}'"`;
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ export class OracleDriver extends AbstractDriver {
|
||||
colInfo.default =
|
||||
!resp.DATA_DEFAULT || resp.DATA_DEFAULT.includes('"')
|
||||
? null
|
||||
: resp.DATA_DEFAULT;
|
||||
: this.ReturnDefaultValueFunction(
|
||||
resp.DATA_DEFAULT
|
||||
);
|
||||
colInfo.isUnique = resp.IS_UNIQUE > 0;
|
||||
resp.DATA_TYPE = resp.DATA_TYPE.replace(/\([0-9]+\)/g, "");
|
||||
colInfo.sqlType = resp.DATA_TYPE.toLowerCase();
|
||||
@ -350,4 +352,16 @@ export class OracleDriver extends AbstractDriver {
|
||||
);
|
||||
return x.rows[0][0] > 0 || x.rows[0].CNT;
|
||||
}
|
||||
private ReturnDefaultValueFunction(defVal: string | null): string | null {
|
||||
if (!defVal) {
|
||||
return null;
|
||||
}
|
||||
if (defVal.endsWith(" ")) {
|
||||
defVal = defVal.slice(0, -1);
|
||||
}
|
||||
if (defVal.startsWith(`'`)) {
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
colInfo.isUnique = resp.isunique === "1";
|
||||
colInfo.default = colInfo.isGenerated
|
||||
? null
|
||||
: resp.column_default;
|
||||
: this.ReturnDefaultValueFunction(resp.column_default);
|
||||
|
||||
const columnTypes = this.MatchColumnTypes(
|
||||
resp.data_type,
|
||||
@ -577,4 +577,14 @@ export class PostgresDriver extends AbstractDriver {
|
||||
);
|
||||
return resp.rowCount > 0;
|
||||
}
|
||||
private ReturnDefaultValueFunction(defVal: string | null): string | null {
|
||||
if (!defVal) {
|
||||
return null;
|
||||
}
|
||||
defVal = defVal.replace(/'::[\w ]*/, "'");
|
||||
if (defVal.startsWith(`'`)) {
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,9 @@ export class SqliteDriver extends AbstractDriver {
|
||||
colInfo.sqlName = resp.name;
|
||||
colInfo.isNullable = resp.notnull === 0;
|
||||
colInfo.isPrimary = resp.pk > 0;
|
||||
colInfo.default = resp.dflt_value ? resp.dflt_value : null;
|
||||
colInfo.default = this.ReturnDefaultValueFunction(
|
||||
resp.dflt_value
|
||||
);
|
||||
colInfo.sqlType = resp.type
|
||||
.replace(/\([0-9 ,]+\)/g, "")
|
||||
.toLowerCase()
|
||||
@ -344,4 +346,13 @@ export class SqliteDriver extends AbstractDriver {
|
||||
await promise;
|
||||
return ret;
|
||||
}
|
||||
private ReturnDefaultValueFunction(defVal: string | null): string | null {
|
||||
if (!defVal) {
|
||||
return null;
|
||||
}
|
||||
if (defVal.startsWith(`'`)) {
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
return `() => "${defVal}"`;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import {BaseEntity,Column,Entity,Index,JoinColumn,JoinTable,ManyToMany,ManyToOne
|
||||
unique: true,{{/isUnique}}{{#lenght}}
|
||||
length:{{.}},{{/lenght}}{{#width}}
|
||||
width:{{.}},{{/width}}{{#default}}
|
||||
default:"{{.}}",{{/default}}{{#numericPrecision}}
|
||||
default: {{.}},{{/default}}{{#numericPrecision}}
|
||||
precision:{{.}},{{/numericPrecision}}{{#numericScale}}
|
||||
scale:{{.}},{{/numericScale}}{{#enumOptions}}
|
||||
enum:[{{.}}],{{/enumOptions}}{{#isArray}}
|
||||
|
@ -65,7 +65,7 @@ describe('MssqlDriver', function () {
|
||||
response.recordset = new fakeRecordset();
|
||||
response.recordset.push({
|
||||
TABLE_NAME: 'name', CHARACTER_MAXIMUM_LENGTH: 0,
|
||||
COLUMN_DEFAULT: 'a', COLUMN_NAME: 'name', DATA_TYPE: 'int',
|
||||
COLUMN_DEFAULT: "'a'", COLUMN_NAME: 'name', DATA_TYPE: 'int',
|
||||
IS_NULLABLE: 'YES', NUMERIC_PRECISION: 0, NUMERIC_SCALE: 0,
|
||||
IsIdentity: 1
|
||||
})
|
||||
@ -82,7 +82,7 @@ describe('MssqlDriver', function () {
|
||||
const expected: EntityInfo[] = JSON.parse(JSON.stringify(entities));
|
||||
expected[0].Columns.push({
|
||||
lenght: null,
|
||||
default: 'a',
|
||||
default: `() => "'a'"`,
|
||||
isNullable: true,
|
||||
isPrimary: false,
|
||||
isGenerated: true,
|
||||
|
96
test/integration/defaultValues.test.ts
Normal file
96
test/integration/defaultValues.test.ts
Normal file
@ -0,0 +1,96 @@
|
||||
require('dotenv').config()
|
||||
import { expect } from "chai";
|
||||
import fs = require('fs-extra');
|
||||
import path = require('path')
|
||||
import "reflect-metadata";
|
||||
import { EntityFileToJson } from "../utils/EntityFileToJson";
|
||||
const chai = require('chai');
|
||||
const chaiSubset = require('chai-subset');
|
||||
import * as ts from "typescript";
|
||||
import { Engine } from "../../src/Engine";
|
||||
import * as GTU from "../utils/GeneralTestUtils"
|
||||
|
||||
chai.use(chaiSubset);
|
||||
|
||||
describe("Column default values", async function () {
|
||||
this.timeout(30000)
|
||||
this.slow(5000)// compiling created models takes time
|
||||
|
||||
const dbDrivers: string[] = []
|
||||
if (process.env.SQLITE_Skip == '0') { dbDrivers.push('sqlite') }
|
||||
if (process.env.POSTGRES_Skip == '0') { dbDrivers.push('postgres') }
|
||||
if (process.env.MYSQL_Skip == '0') { dbDrivers.push('mysql') }
|
||||
if (process.env.MARIADB_Skip == '0') { dbDrivers.push('mariadb') }
|
||||
if (process.env.MSSQL_Skip == '0') { dbDrivers.push('mssql') }
|
||||
if (process.env.ORACLE_Skip == '0') { dbDrivers.push('oracle') }
|
||||
|
||||
const examplesPathJS = path.resolve(process.cwd(), 'dist/test/integration/defaultValues')
|
||||
const examplesPathTS = path.resolve(process.cwd(), 'test/integration/defaultValues')
|
||||
const files = fs.readdirSync(examplesPathTS)
|
||||
|
||||
for (const dbDriver of dbDrivers) {
|
||||
for (const folder of files) {
|
||||
if (dbDriver == folder) {
|
||||
it(dbDriver, async function () {
|
||||
|
||||
const filesOrgPathJS = path.resolve(examplesPathJS, folder, 'entity')
|
||||
const filesOrgPathTS = path.resolve(examplesPathTS, folder, 'entity')
|
||||
const resultsPath = path.resolve(process.cwd(), `output`)
|
||||
fs.removeSync(resultsPath)
|
||||
|
||||
let engine: Engine;
|
||||
switch (dbDriver) {
|
||||
case 'sqlite':
|
||||
engine = await GTU.createSQLiteModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
case 'postgres':
|
||||
engine = await GTU.createPostgresModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
case 'mysql':
|
||||
engine = await GTU.createMysqlModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
case 'mariadb':
|
||||
engine = await GTU.createMariaDBModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
case 'mssql':
|
||||
engine = await GTU.createMSSQLModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
case 'oracle':
|
||||
engine = await GTU.createOracleDBModels(filesOrgPathJS, resultsPath)
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown engine type`);
|
||||
engine = {} as Engine
|
||||
break;
|
||||
}
|
||||
|
||||
await engine.createModelFromDatabase()
|
||||
const filesGenPath = path.resolve(resultsPath, 'entities')
|
||||
|
||||
const filesOrg = fs.readdirSync(filesOrgPathTS).filter((val) => val.toString().endsWith('.ts'))
|
||||
const filesGen = fs.readdirSync(filesGenPath).filter((val) => val.toString().endsWith('.ts'))
|
||||
|
||||
expect(filesOrg, 'Errors detected in model comparision').to.be.deep.equal(filesGen)
|
||||
|
||||
for (const file of filesOrg) {
|
||||
const entftj = new EntityFileToJson();
|
||||
const jsonEntityOrg = entftj.convert(fs.readFileSync(path.resolve(filesOrgPathTS, file)))
|
||||
const jsonEntityGen = entftj.convert(fs.readFileSync(path.resolve(filesGenPath, file)))
|
||||
expect(jsonEntityGen, `Error in file ${file}`).to.containSubset(jsonEntityOrg)
|
||||
}
|
||||
const currentDirectoryFiles = fs.readdirSync(filesGenPath).
|
||||
filter(fileName => fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts").map(v => path.resolve(filesGenPath, v))
|
||||
const compileErrors = GTU.compileTsFiles(currentDirectoryFiles, {
|
||||
experimentalDecorators: true,
|
||||
sourceMap: false,
|
||||
emitDecoratorMetadata: true,
|
||||
target: ts.ScriptTarget.ES2016,
|
||||
moduleResolution: ts.ModuleResolutionKind.NodeJs,
|
||||
module: ts.ModuleKind.CommonJS
|
||||
});
|
||||
expect(compileErrors, 'Errors detected while compiling generated model').to.be.false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
21
test/integration/defaultValues/mariadb/entity/Post.ts
Normal file
21
test/integration/defaultValues/mariadb/entity/Post.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("timestamp",{
|
||||
default: () => "CURRENT_TIMESTAMP",
|
||||
})
|
||||
createdAt:Date;
|
||||
|
||||
|
||||
@Column("varchar",{
|
||||
length: 30,
|
||||
default: () => "'defVal'",
|
||||
})
|
||||
text:string;
|
||||
|
||||
}
|
21
test/integration/defaultValues/mssql/entity/Post.ts
Normal file
21
test/integration/defaultValues/mssql/entity/Post.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("datetime",{
|
||||
default: () => "getdate()",
|
||||
})
|
||||
createdAt:Date;
|
||||
|
||||
|
||||
@Column("varchar",{
|
||||
length: 30,
|
||||
default: () => "'defVal'",
|
||||
})
|
||||
text:string;
|
||||
|
||||
}
|
21
test/integration/defaultValues/mysql/entity/Post.ts
Normal file
21
test/integration/defaultValues/mysql/entity/Post.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("timestamp",{
|
||||
default: () => "CURRENT_TIMESTAMP",
|
||||
})
|
||||
createdAt:Date;
|
||||
|
||||
|
||||
@Column("varchar",{
|
||||
length: 30,
|
||||
default: () => "'defVal'",
|
||||
})
|
||||
text:string;
|
||||
|
||||
}
|
21
test/integration/defaultValues/oracle/entity/Post.ts
Normal file
21
test/integration/defaultValues/oracle/entity/Post.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("timestamp",{
|
||||
default: () => "CURRENT_TIMESTAMP",
|
||||
})
|
||||
createdAt:Date;
|
||||
|
||||
|
||||
@Column("varchar",{
|
||||
length: 30,
|
||||
default: () => "'defVal'",
|
||||
})
|
||||
text:string;
|
||||
|
||||
}
|
21
test/integration/defaultValues/postgres/entity/Post.ts
Normal file
21
test/integration/defaultValues/postgres/entity/Post.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("timestamp",{
|
||||
default: () => "now()",
|
||||
})
|
||||
createdAt:Date;
|
||||
|
||||
|
||||
@Column("varchar",{
|
||||
length: 30,
|
||||
default: () => "'defVal'",
|
||||
})
|
||||
text:string;
|
||||
|
||||
}
|
21
test/integration/defaultValues/sqlite/entity/Post.ts
Normal file
21
test/integration/defaultValues/sqlite/entity/Post.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
|
||||
|
||||
@Entity("Post")
|
||||
export class Post {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("datetime",{
|
||||
default: () => "CURRENT_TIMESTAMP",
|
||||
})
|
||||
createdAt:Date;
|
||||
|
||||
|
||||
@Column("varchar",{
|
||||
length: 30,
|
||||
default: () => "'defVal'",
|
||||
})
|
||||
text:string;
|
||||
|
||||
}
|
@ -22,6 +22,7 @@ export class EntityFileToJson {
|
||||
if (badJSON.lastIndexOf(',') == badJSON.length - 3) {
|
||||
badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1]
|
||||
}
|
||||
badJSON = badJSON.replace(/default: \(\) => (.*)/, `default: $1`)
|
||||
col.columnOptions = JSON.parse(badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '))
|
||||
} else {
|
||||
if (decoratorParameters[0] == '"' && decoratorParameters.endsWith('"')) {
|
||||
|
Loading…
Reference in New Issue
Block a user