Skip to content

Commit

Permalink
fix(schema): support empty string in @Property({ default: '' })
Browse files Browse the repository at this point in the history
Closes #534
  • Loading branch information
B4nan committed May 2, 2020
1 parent 0811b6c commit 4ec19c7
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 18 deletions.
13 changes: 11 additions & 2 deletions lib/schema/SchemaGenerator.ts
@@ -1,4 +1,4 @@
import { ColumnBuilder, SchemaBuilder, TableBuilder } from 'knex';
import { ColumnBuilder, Raw, SchemaBuilder, TableBuilder } from 'knex';
import { AbstractSqlDriver, Cascade, Configuration, DatabaseSchema, IsSame, ReferenceType } from '..';
import { EntityMetadata, EntityProperty } from '../typings';
import { Utils } from '../utils';
Expand Down Expand Up @@ -374,14 +374,15 @@ export class SchemaGenerator {
const uniqueName = this.getIndexName(meta, prop, true, columnName);
const hasDefault = typeof prop.default !== 'undefined'; // support falsy default values like `0`, `false` or empty string
const sameDefault = alter && 'sameDefault' in alter ? alter.sameDefault : !hasDefault;
const defaultValue = this.getDefaultValue(prop, hasDefault);

Utils.runIfNotEmpty(() => col.nullable(), !sameNullable && nullable);
Utils.runIfNotEmpty(() => col.notNullable(), !sameNullable && !nullable);
Utils.runIfNotEmpty(() => col.primary(), prop.primary && !meta.compositePK);
Utils.runIfNotEmpty(() => col.unsigned(), pkProp.unsigned);
Utils.runIfNotEmpty(() => col.index(indexName), index);
Utils.runIfNotEmpty(() => col.unique(uniqueName), prop.unique);
Utils.runIfNotEmpty(() => col.defaultTo(hasDefault ? this.knex.raw('' + prop.default) : null), !sameDefault);
Utils.runIfNotEmpty(() => col.defaultTo(defaultValue), !sameDefault);

return col;
}
Expand All @@ -397,6 +398,14 @@ export class SchemaGenerator {
return this.helper.getIndexName(meta.collection, [columnName], unique);
}

private getDefaultValue<T>(prop: EntityProperty<T>, hasDefault: boolean): Raw | null {
if (!hasDefault) {
return null;
}

return this.knex.raw(prop.default === '' ? this.helper.getDefaultEmptyString() : '' + prop.default);
}

private createForeignKeys(table: TableBuilder, meta: EntityMetadata, props?: EntityProperty[]): void {
Object.values(meta.properties)
.filter(prop => !props || props.includes(prop))
Expand Down
8 changes: 8 additions & 0 deletions lib/schema/SchemaHelper.ts
Expand Up @@ -167,6 +167,10 @@ export abstract class SchemaHelper {
return 'information_schema';
}

getDefaultEmptyString(): string {
return "''";
}

async databaseExists(connection: Connection, name: string): Promise<boolean> {
try {
const res = await connection.execute(this.getDatabaseExistsSQL(name));
Expand Down Expand Up @@ -218,6 +222,10 @@ export abstract class SchemaHelper {
return defaultValue === !!prop.default;
}

if (['', this.getDefaultEmptyString()].includes(prop.default)) {
return info.defaultValue.toString() === '' || info.defaultValue.toString() === this.getDefaultEmptyString();
}

// tslint:disable-next-line:triple-equals
return info.defaultValue == prop.default; // == intentionally
}
Expand Down
4 changes: 2 additions & 2 deletions tests/__snapshots__/EntityGenerator.test.ts.snap
Expand Up @@ -518,7 +518,7 @@ export class Book2 {
@Property({ length: 3, default: \`current_timestamp(3)\` })
createdAt!: Date;
@Property({ length: 255, nullable: true })
@Property({ length: 255, nullable: true, default: \`''\` })
title?: string;
@Property({ columnType: 'text', nullable: true })
Expand Down Expand Up @@ -813,7 +813,7 @@ export class Book3 {
@Property({ nullable: true })
updatedAt?: Date;
@Property()
@Property({ default: \`''\` })
title!: string;
@Property({ nullable: true })
Expand Down
18 changes: 9 additions & 9 deletions tests/__snapshots__/SchemaGenerator.test.ts.snap
Expand Up @@ -21,7 +21,7 @@ alter table \`address2\` add primary key \`address2_pkey\`(\`author_id\`);
alter table \`address2\` add index \`address2_author_id_index\`(\`author_id\`);
alter table \`address2\` add unique \`address2_author_id_unique\`(\`author_id\`);
create table \`book2\` (\`uuid_pk\` varchar(36) not null, \`created_at\` datetime(3) not null default current_timestamp(3), \`title\` varchar(255) null, \`perex\` text null, \`price\` float null, \`double\` double null, \`meta\` json null, \`author_id\` int(11) unsigned not null, \`publisher_id\` int(11) unsigned null) default character set utf8mb4 engine = InnoDB;
create table \`book2\` (\`uuid_pk\` varchar(36) not null, \`created_at\` datetime(3) not null default current_timestamp(3), \`title\` varchar(255) null default '', \`perex\` text null, \`price\` float null, \`double\` double null, \`meta\` json null, \`author_id\` int(11) unsigned not null, \`publisher_id\` int(11) unsigned null) default character set utf8mb4 engine = InnoDB;
alter table \`book2\` add primary key \`book2_pkey\`(\`uuid_pk\`);
alter table \`book2\` add index \`book2_author_id_index\`(\`author_id\`);
alter table \`book2\` add index \`book2_publisher_id_index\`(\`publisher_id\`);
Expand Down Expand Up @@ -207,7 +207,7 @@ alter table \`address2\` add primary key \`address2_pkey\`(\`author_id\`);
alter table \`address2\` add index \`address2_author_id_index\`(\`author_id\`);
alter table \`address2\` add unique \`address2_author_id_unique\`(\`author_id\`);
create table \`book2\` (\`uuid_pk\` varchar(36) not null, \`created_at\` datetime(3) not null default current_timestamp(3), \`title\` varchar(255) null, \`perex\` text null, \`price\` float null, \`double\` double null, \`meta\` json null, \`author_id\` int(11) unsigned not null, \`publisher_id\` int(11) unsigned null) default character set utf8mb4 engine = InnoDB;
create table \`book2\` (\`uuid_pk\` varchar(36) not null, \`created_at\` datetime(3) not null default current_timestamp(3), \`title\` varchar(255) null default '', \`perex\` text null, \`price\` float null, \`double\` double null, \`meta\` json null, \`author_id\` int(11) unsigned not null, \`publisher_id\` int(11) unsigned null) default character set utf8mb4 engine = InnoDB;
alter table \`book2\` add primary key \`book2_pkey\`(\`uuid_pk\`);
alter table \`book2\` add index \`book2_author_id_index\`(\`author_id\`);
alter table \`book2\` add index \`book2_publisher_id_index\`(\`publisher_id\`);
Expand Down Expand Up @@ -358,7 +358,7 @@ create table \\"address2\\" (\\"author_id\\" int4 not null, \\"value\\" varchar(
alter table \\"address2\\" add constraint \\"address2_pkey\\" primary key (\\"author_id\\");
alter table \\"address2\\" add constraint \\"address2_author_id_unique\\" unique (\\"author_id\\");
create table \\"book2\\" (\\"uuid_pk\\" varchar(36) not null, \\"created_at\\" timestamptz(3) not null default current_timestamp(3), \\"title\\" varchar(255) null, \\"perex\\" text null, \\"price\\" float null, \\"double\\" double precision null, \\"meta\\" json null, \\"author_id\\" int4 not null, \\"publisher_id\\" int4 null);
create table \\"book2\\" (\\"uuid_pk\\" varchar(36) not null, \\"created_at\\" timestamptz(3) not null default current_timestamp(3), \\"title\\" varchar(255) null default '', \\"perex\\" text null, \\"price\\" float null, \\"double\\" double precision null, \\"meta\\" json null, \\"author_id\\" int4 not null, \\"publisher_id\\" int4 null);
alter table \\"book2\\" add constraint \\"book2_pkey\\" primary key (\\"uuid_pk\\");
create table \\"book_tag2\\" (\\"id\\" bigserial primary key, \\"name\\" varchar(50) not null);
Expand Down Expand Up @@ -497,7 +497,7 @@ create table \\"address2\\" (\\"author_id\\" int4 not null, \\"value\\" varchar(
alter table \\"address2\\" add constraint \\"address2_pkey\\" primary key (\\"author_id\\");
alter table \\"address2\\" add constraint \\"address2_author_id_unique\\" unique (\\"author_id\\");
create table \\"book2\\" (\\"uuid_pk\\" varchar(36) not null, \\"created_at\\" timestamptz(3) not null default current_timestamp(3), \\"title\\" varchar(255) null, \\"perex\\" text null, \\"price\\" float null, \\"double\\" double precision null, \\"meta\\" json null, \\"author_id\\" int4 not null, \\"publisher_id\\" int4 null);
create table \\"book2\\" (\\"uuid_pk\\" varchar(36) not null, \\"created_at\\" timestamptz(3) not null default current_timestamp(3), \\"title\\" varchar(255) null default '', \\"perex\\" text null, \\"price\\" float null, \\"double\\" double precision null, \\"meta\\" json null, \\"author_id\\" int4 not null, \\"publisher_id\\" int4 null);
alter table \\"book2\\" add constraint \\"book2_pkey\\" primary key (\\"uuid_pk\\");
create table \\"book_tag2\\" (\\"id\\" bigserial primary key, \\"name\\" varchar(50) not null);
Expand Down Expand Up @@ -594,7 +594,7 @@ exports[`SchemaGenerator generate schema from metadata [sqlite]: sqlite-create-s
create table \`author3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`name\` varchar not null, \`email\` varchar not null, \`age\` integer null, \`terms_accepted\` integer not null default 0, \`identities\` varchar null, \`born\` date(3) null, \`born_time\` time(3) null);
create unique index \`author3_email_unique\` on \`author3\` (\`email\`);
create table \`book3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`title\` varchar not null);
create table \`book3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`title\` varchar not null default '');
create table \`book_tag3\` (\`id\` integer not null primary key autoincrement, \`name\` varchar not null, \`version\` datetime not null default current_timestamp);
Expand Down Expand Up @@ -664,7 +664,7 @@ drop table if exists \`publisher3_to_test3\`;
create table \`author3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`name\` varchar not null, \`email\` varchar not null, \`age\` integer null, \`terms_accepted\` integer not null default 0, \`identities\` varchar null, \`born\` date(3) null, \`born_time\` time(3) null);
create unique index \`author3_email_unique\` on \`author3\` (\`email\`);
create table \`book3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`title\` varchar not null);
create table \`book3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`title\` varchar not null default '');
create table \`book_tag3\` (\`id\` integer not null primary key autoincrement, \`name\` varchar not null, \`version\` datetime not null default current_timestamp);
Expand Down Expand Up @@ -870,7 +870,7 @@ alter table \`address2\` add primary key \`address2_pkey\`(\`author_id\`);
alter table \`address2\` add index \`address2_author_id_index\`(\`author_id\`);
alter table \`address2\` add unique \`address2_author_id_unique\`(\`author_id\`);
create table \`book2\` (\`uuid_pk\` varchar(36) not null, \`created_at\` datetime(3) not null default current_timestamp(3), \`title\` varchar(255) null, \`perex\` text null, \`price\` float null, \`double\` double null, \`meta\` json null, \`author_id\` int(11) unsigned not null, \`publisher_id\` int(11) unsigned null) default character set utf8mb4 engine = InnoDB;
create table \`book2\` (\`uuid_pk\` varchar(36) not null, \`created_at\` datetime(3) not null default current_timestamp(3), \`title\` varchar(255) null default '', \`perex\` text null, \`price\` float null, \`double\` double null, \`meta\` json null, \`author_id\` int(11) unsigned not null, \`publisher_id\` int(11) unsigned null) default character set utf8mb4 engine = InnoDB;
alter table \`book2\` add primary key \`book2_pkey\`(\`uuid_pk\`);
alter table \`book2\` add index \`book2_author_id_index\`(\`author_id\`);
alter table \`book2\` add index \`book2_publisher_id_index\`(\`publisher_id\`);
Expand Down Expand Up @@ -1005,7 +1005,7 @@ create table \\"address2\\" (\\"author_id\\" int4 not null, \\"value\\" varchar(
alter table \\"address2\\" add constraint \\"address2_pkey\\" primary key (\\"author_id\\");
alter table \\"address2\\" add constraint \\"address2_author_id_unique\\" unique (\\"author_id\\");
create table \\"book2\\" (\\"uuid_pk\\" varchar(36) not null, \\"created_at\\" timestamptz(3) not null default current_timestamp(3), \\"title\\" varchar(255) null, \\"perex\\" text null, \\"price\\" float null, \\"double\\" double precision null, \\"meta\\" json null, \\"author_id\\" int4 not null, \\"publisher_id\\" int4 null);
create table \\"book2\\" (\\"uuid_pk\\" varchar(36) not null, \\"created_at\\" timestamptz(3) not null default current_timestamp(3), \\"title\\" varchar(255) null default '', \\"perex\\" text null, \\"price\\" float null, \\"double\\" double precision null, \\"meta\\" json null, \\"author_id\\" int4 not null, \\"publisher_id\\" int4 null);
alter table \\"book2\\" add constraint \\"book2_pkey\\" primary key (\\"uuid_pk\\");
create table \\"book_tag2\\" (\\"id\\" bigserial primary key, \\"name\\" varchar(50) not null);
Expand Down Expand Up @@ -1090,7 +1090,7 @@ exports[`SchemaGenerator update empty schema from metadata [sqlite]: sqlite-upda
create table \`author3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`name\` varchar not null, \`email\` varchar not null, \`age\` integer null, \`terms_accepted\` integer not null default 0, \`identities\` varchar null, \`born\` date(3) null, \`born_time\` time(3) null);
create unique index \`author3_email_unique\` on \`author3\` (\`email\`);
create table \`book3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`title\` varchar not null);
create table \`book3\` (\`id\` integer not null primary key autoincrement, \`created_at\` datetime null, \`updated_at\` datetime null, \`title\` varchar not null default '');
create table \`book_tag3\` (\`id\` integer not null primary key autoincrement, \`name\` varchar not null, \`version\` datetime not null default current_timestamp);
Expand Down
5 changes: 4 additions & 1 deletion tests/entities-js/Book3.js
Expand Up @@ -40,7 +40,10 @@ const schema = {
nullable: true,
onUpdate: () => new Date(),
},
title: 'string',
title: {
type: 'string',
default: '',
},
author: {
reference: 'm:1',
type: 'Author3',
Expand Down
2 changes: 1 addition & 1 deletion tests/entities-sql/Book2.ts
Expand Up @@ -14,7 +14,7 @@ export class Book2 {
@Property({ default: 'current_timestamp(3)', length: 3 })
createdAt: Date = new Date();

@Property({ nullable: true })
@Property({ nullable: true, default: '' })
title?: string;

@Property({ type: 'text', nullable: true })
Expand Down
2 changes: 1 addition & 1 deletion tests/mysql-schema.sql
Expand Up @@ -39,7 +39,7 @@ alter table `address2` add primary key `address2_pkey`(`author_id`);
alter table `address2` add index `address2_author_id_index`(`author_id`);
alter table `address2` add unique `address2_author_id_unique`(`author_id`);

create table `book2` (`uuid_pk` varchar(36) not null, `created_at` datetime(3) not null default current_timestamp(3), `title` varchar(255) null, `perex` text null, `price` float null, `double` double null, `meta` json null, `author_id` int(11) unsigned not null, `publisher_id` int(11) unsigned null, `foo` varchar(255) null) default character set utf8mb4 engine = InnoDB;
create table `book2` (`uuid_pk` varchar(36) not null, `created_at` datetime(3) not null default current_timestamp(3), `title` varchar(255) null default '', `perex` text null, `price` float null, `double` double null, `meta` json null, `author_id` int(11) unsigned not null, `publisher_id` int(11) unsigned null, `foo` varchar(255) null) default character set utf8mb4 engine = InnoDB;
alter table `book2` add primary key `book2_pkey`(`uuid_pk`);
alter table `book2` add index `book2_author_id_index`(`author_id`);
alter table `book2` add index `book2_publisher_id_index`(`publisher_id`);
Expand Down
2 changes: 1 addition & 1 deletion tests/postgre-schema.sql
Expand Up @@ -33,7 +33,7 @@ create table "address2" ("author_id" int4 not null check ("author_id" > 0), "val
alter table "address2" add constraint "address2_pkey" primary key ("author_id");
alter table "address2" add constraint "address2_author_id_unique" unique ("author_id");

create table "book2" ("uuid_pk" varchar(36) not null, "created_at" timestamptz(3) not null default current_timestamp(3), "title" varchar(255) null, "perex" text null, "price" float null, "double" numeric null, "meta" json null, "author_id" int4 not null, "publisher_id" int4 null, "foo" varchar(255) null);
create table "book2" ("uuid_pk" varchar(36) not null, "created_at" timestamptz(3) not null default current_timestamp(3), "title" varchar(255) null default '', "perex" text null, "price" float null, "double" numeric null, "meta" json null, "author_id" int4 not null, "publisher_id" int4 null, "foo" varchar(255) null);
alter table "book2" add constraint "book2_pkey" primary key ("uuid_pk");

create table "book_tag2" ("id" bigserial primary key, "name" varchar(50) not null);
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlite-schema.sql
Expand Up @@ -11,7 +11,7 @@ drop table if exists `publisher3_to_test3`;
create table `author3` (`id` integer not null primary key autoincrement, `created_at` datetime null, `updated_at` datetime null, `name` varchar not null, `email` varchar not null, `age` integer null, `terms_accepted` integer not null default 0, `identities` varchar null, `born` date null, `born_time` time null);
create unique index `author3_email_unique` on `author3` (`email`);

create table `book3` (`id` integer not null primary key autoincrement, `created_at` datetime null, `updated_at` datetime null, `title` varchar not null, `foo` varchar null);
create table `book3` (`id` integer not null primary key autoincrement, `created_at` datetime null, `updated_at` datetime null, `title` varchar not null default '', `foo` varchar null);

create table `book_tag3` (`id` integer not null primary key autoincrement, `name` varchar not null, `version` datetime not null default current_timestamp);

Expand Down

0 comments on commit 4ec19c7

Please sign in to comment.