From c5760c17fd37cafa0196ab7b4aae9d2ebb0601d5 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 | 15 +++------------ packages/mysql/tests/mysql.spec.ts | 8 +++++--- packages/sql/src/platform/default-platform.ts | 17 ++++++----------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/packages/mysql/src/mysql-platform.ts b/packages/mysql/src/mysql-platform.ts index 7fc200564..0edf608f8 100644 --- a/packages/mysql/src/mysql-platform.ts +++ b/packages/mysql/src/mysql-platform.ts @@ -10,17 +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, @@ -30,6 +20,7 @@ import { PreparedAdapter, typeResolvesToBigInt, typeResolvesToBoolean, + typeResolvesToDate, typeResolvesToInteger, typeResolvesToNumber, typeResolvesToString, @@ -78,7 +69,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 ad9615584..dd08967e2 100644 --- a/packages/sql/src/platform/default-platform.ts +++ b/packages/sql/src/platform/default-platform.ts @@ -24,17 +24,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'; import { PreparedAdapter } from '../prepare.js'; @@ -98,6 +88,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; }