From 88dd4a90390611e75ce4984d1586103e8ddf10da Mon Sep 17 00:00:00 2001 From: Sean Ferguson Date: Sat, 10 Feb 2024 20:31:36 -0500 Subject: [PATCH] fix(sql): dates should be nullable without casting as JSON --- packages/mysql/src/mysql-platform.ts | 5 +++-- packages/mysql/tests/mysql.spec.ts | 8 +++++--- packages/sql/src/platform/default-platform.ts | 7 ++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/mysql/src/mysql-platform.ts b/packages/mysql/src/mysql-platform.ts index 74e7a71b2..801dba6c5 100644 --- a/packages/mysql/src/mysql-platform.ts +++ b/packages/mysql/src/mysql-platform.ts @@ -10,7 +10,7 @@ import { Pool } from 'mariadb'; import { mySqlSerializer } from './mysql-serializer.js'; -import { isDateType, isReferenceType, isUUIDType, ReflectionClass, ReflectionKind, ReflectionProperty, Serializer, Type, TypeNumberBrand } from '@deepkit/type'; +import { isReferenceType, isUUIDType, ReflectionClass, ReflectionKind, ReflectionProperty, Serializer, Type, TypeNumberBrand } from '@deepkit/type'; import { Column, DefaultPlatform, @@ -19,6 +19,7 @@ import { noopSqlTypeCaster, typeResolvesToBigInt, typeResolvesToBoolean, + typeResolvesToDate, typeResolvesToInteger, typeResolvesToNumber, typeResolvesToString, @@ -66,7 +67,7 @@ export class MySQLPlatform extends DefaultPlatform { this.addType(type => type.kind === ReflectionKind.number && type.brand === TypeNumberBrand.float64, 'double'); this.addType(type => type.kind === ReflectionKind.number && type.brand === TypeNumberBrand.float, 'double'); - this.addType(isDateType, 'datetime'); + this.addType(typeResolvesToDate, 'datetime'); this.addType(isUUIDType, 'binary', 16); this.addBinaryType('longblob'); diff --git a/packages/mysql/tests/mysql.spec.ts b/packages/mysql/tests/mysql.spec.ts index f7d73e50d..69635665b 100644 --- a/packages/mysql/tests/mysql.spec.ts +++ b/packages/mysql/tests/mysql.spec.ts @@ -324,21 +324,23 @@ test('unique constraint 1', async () => { } }); -test('string/null unions should not render as JSON', async () => { +test('non-object null unions should not render as JSON', async () => { @entity.name('model6') class Model { id: number & PrimaryKey & AutoIncrement = 0; - constructor(public name: string, public nickName: string | null = null) {} + constructor(public name: string, public nickName: string | null = null, public birthdate: Date | null = null) {} } const database = await databaseFactory([Model]); await database.persist(new Model('Peter')); await database.persist(new Model('Christopher', 'Chris')); + await database.persist(new Model('Thomas', 'Tom', new Date('1960-02-10T00:00:00Z'))); const result = await database.query(Model).orderBy('id', 'asc').find(); expect(result).toMatchObject([ {name: 'Peter', nickName: null}, - {name: 'Christopher', nickName: 'Chris'} + {name: 'Christopher', nickName: 'Chris'}, + {name: 'Thomas', nickName: 'Tom', birthdate: new Date('1960-02-10T00:00:00Z')}, ]); }); diff --git a/packages/sql/src/platform/default-platform.ts b/packages/sql/src/platform/default-platform.ts index fb4b95fe8..44ec5c049 100644 --- a/packages/sql/src/platform/default-platform.ts +++ b/packages/sql/src/platform/default-platform.ts @@ -15,7 +15,7 @@ import { sqlSerializer } from '../serializer/sql-serializer.js'; import { parseType, SchemaParser } from '../reverse/schema-parser.js'; import { SQLFilterBuilder } from '../sql-filter-builder.js'; import { Sql } from '../sql-builder.js'; -import { binaryTypes, databaseAnnotation, isCustomTypeClass, isIntegerType, ReflectionClass, ReflectionKind, ReflectionProperty, Serializer, Type } from '@deepkit/type'; +import { binaryTypes, databaseAnnotation, isCustomTypeClass, isDateType, isIntegerType, ReflectionClass, ReflectionKind, ReflectionProperty, Serializer, Type } from '@deepkit/type'; import { DatabaseEntityRegistry, MigrateOptions } from '@deepkit/orm'; import { splitDotPath } from '../sql-adapter.js'; @@ -78,6 +78,11 @@ export function typeResolvesToBoolean(type: Type): boolean { return false; } +export function typeResolvesToDate(type: Type): boolean { + if (type.kind === ReflectionKind.union) return type.types.filter(isNonUndefined).every(isDateType); + return isDateType(type); +} + export function noopSqlTypeCaster(placeholder: string): string { return placeholder; }