From 5fbae57c6b8f807273851e915296611129c4260d Mon Sep 17 00:00:00 2001 From: Alberto Schiabel Date: Wed, 30 Aug 2023 20:12:04 +0200 Subject: [PATCH] fix(js-connectors): datetime with optional microseconds (#4180) --- .../mysql/commands/type_test/insert.sql | 2 +- .../smoke-test-js/prisma/mysql/schema.prisma | 13 ++++- .../postgres/commands/type_test/insert.sql | 2 +- .../prisma/postgres/schema.prisma | 11 +++- .../js/smoke-test-js/src/test.ts | 58 ++++++++++++++++++- query-engine/js-connectors/src/proxy.rs | 26 ++++++++- 6 files changed, 101 insertions(+), 11 deletions(-) diff --git a/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/commands/type_test/insert.sql b/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/commands/type_test/insert.sql index 95c0433bbc56..6641eff216b2 100644 --- a/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/commands/type_test/insert.sql +++ b/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/commands/type_test/insert.sql @@ -40,7 +40,7 @@ INSERT INTO type_test ( '2023-07-24', -- date '23:59:59', -- time 2023, -- year - '2023-07-24 23:59:59', -- datetime + '2023-07-24 23:59:59.415', -- datetime '2023-07-24 23:59:59', -- timestamp '{"key": "value"}', -- json 'value3', -- enum diff --git a/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/schema.prisma b/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/schema.prisma index 7b27422a6203..d1a3df2b50f3 100644 --- a/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/schema.prisma +++ b/query-engine/js-connectors/js/smoke-test-js/prisma/mysql/schema.prisma @@ -41,8 +41,8 @@ model type_test { time_column_null DateTime? @db.Time(0) year_column Int @db.Year year_column_null Int? @db.Year - datetime_column DateTime @db.DateTime(0) - datetime_column_null DateTime? @db.DateTime(0) + datetime_column DateTime @db.DateTime(3) + datetime_column_null DateTime? @db.DateTime(3) timestamp_column DateTime @db.Timestamp(0) timestamp_column_null DateTime? @db.Timestamp(0) json_column Json @@ -59,6 +59,13 @@ model type_test { set_column_null String? } +// This will eventually supersede type_test +model type_test_2 { + id String @id @default(cuid()) + datetime_column DateTime @default(now()) @db.DateTime(3) + datetime_column_null DateTime? @db.DateTime(3) +} + enum type_test_enum_column { value1 value2 @@ -93,7 +100,7 @@ model Parent { } model Author { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) firstName String lastName String age Int diff --git a/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/commands/type_test/insert.sql b/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/commands/type_test/insert.sql index 70f38a6a6ad7..170bafb9d810 100644 --- a/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/commands/type_test/insert.sql +++ b/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/commands/type_test/insert.sql @@ -28,7 +28,7 @@ INSERT INTO type_test ( 'This is a long text...', -- text '2023-07-24', -- date '23:59:59', -- time - '2023-07-24 23:59:59', -- datetime + '2023-07-24 23:59:59.415', -- datetime '2023-07-24 23:59:59', -- timestamp '{"key": "value"}', -- json 'value3' -- enum diff --git a/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/schema.prisma b/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/schema.prisma index 35c9805c3b31..620f78b3cffb 100644 --- a/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/schema.prisma +++ b/query-engine/js-connectors/js/smoke-test-js/prisma/postgres/schema.prisma @@ -33,8 +33,8 @@ model type_test { date_column_null DateTime? @db.Date time_column DateTime @db.Time(0) time_column_null DateTime? @db.Time(0) - datetime_column DateTime - datetime_column_null DateTime? + datetime_column DateTime @db.Timestamp(3) + datetime_column_null DateTime? @db.Timestamp(3) timestamp_column DateTime @db.Timestamp(0) timestamp_column_null DateTime? @db.Timestamp(0) json_column Json @@ -43,6 +43,13 @@ model type_test { enum_column_null type_test_enum_column_null? } +// This will eventually supersede type_test +model type_test_2 { + id String @id @default(cuid()) + datetime_column DateTime @default(now()) @db.Timestamp(3) + datetime_column_null DateTime? @db.Timestamp(3) +} + model Child { c String @unique c_1 String diff --git a/query-engine/js-connectors/js/smoke-test-js/src/test.ts b/query-engine/js-connectors/js/smoke-test-js/src/test.ts index 628b1e0bdd5e..f5ba493f25b6 100644 --- a/query-engine/js-connectors/js/smoke-test-js/src/test.ts +++ b/query-engine/js-connectors/js/smoke-test-js/src/test.ts @@ -3,8 +3,6 @@ import type { Connector } from '@jkomyno/prisma-js-connector-utils' import type { QueryEngineInstance } from './engines/types/Library' import { initQueryEngine } from './util' -type Flavor = Connector['flavour'] - export async function smokeTest(db: Connector, prismaSchemaRelativePath: string) { // wait for the database pool to be initialized await setImmediate(0) @@ -19,6 +17,7 @@ export async function smokeTest(db: Connector, prismaSchemaRelativePath: string) const test = new SmokeTest(engine, db.flavour) + await test.testTypeTest2() await test.testFindManyTypeTest() await test.createAutoIncrement() await test.testCreateAndDeleteChildParent() @@ -48,6 +47,61 @@ export async function smokeTest(db: Connector, prismaSchemaRelativePath: string) class SmokeTest { constructor(private readonly engine: QueryEngineInstance, readonly flavour: Connector['flavour']) {} + async testTypeTest2() { + const create = await this.engine.query(` + { + "action": "createOne", + "modelName": "type_test_2", + "query": { + "arguments": { + "data": {} + }, + "selection": { + "id": true, + "datetime_column": true, + "datetime_column_null": true + } + } + } + `, 'trace', undefined) + + console.log('[nodejs] create', JSON.stringify(JSON.parse(create), null, 2)) + + const findMany = await this.engine.query(` + { + "action": "findMany", + "modelName": "type_test_2", + "query": { + "selection": { + "id": true, + "datetime_column": true, + "datetime_column_null": true + }, + "arguments": { + "where": {} + } + } + } + `, 'trace', undefined) + + console.log('[nodejs] findMany', JSON.stringify(JSON.parse(findMany), null, 2)) + + await this.engine.query(` + { + "action": "deleteMany", + "modelName": "type_test_2", + "query": { + "arguments": { + "where": {} + }, + "selection": { + "count": true + } + } + } + `, 'trace', undefined) + } + async testFindManyTypeTest() { await this.testFindManyTypeTestMySQL() await this.testFindManyTypeTestPostgres() diff --git a/query-engine/js-connectors/src/proxy.rs b/query-engine/js-connectors/src/proxy.rs index 05dd1e00bd0f..7e9aadf52905 100644 --- a/query-engine/js-connectors/src/proxy.rs +++ b/query-engine/js-connectors/src/proxy.rs @@ -233,7 +233,7 @@ fn js_value_to_quaint(json_value: serde_json::Value, column_type: ColumnType) -> }, ColumnType::DateTime => match json_value { serde_json::Value::String(s) => { - let datetime = chrono::NaiveDateTime::parse_from_str(&s, "%Y-%m-%d %H:%M:%S") + let datetime = chrono::NaiveDateTime::parse_from_str(&s, "%Y-%m-%d %H:%M:%S%.f") .unwrap_or_else(|_| panic!("Expected a datetime string, found {:?}", &s)); let datetime: DateTime = DateTime::from_utc(datetime, Utc); QuaintValue::datetime(datetime) @@ -617,13 +617,35 @@ mod proxy_test { // null test_null(QuaintValue::DateTime(None), column_type); + let s = "2023-01-01 23:59:59.415"; + let json_value = serde_json::Value::String(s.to_string()); + let quaint_value = js_value_to_quaint(json_value, column_type); + + let datetime = NaiveDate::from_ymd_opt(2023, 1, 1) + .unwrap() + .and_hms_milli_opt(23, 59, 59, 415) + .unwrap(); + let datetime = DateTime::from_utc(datetime, Utc); + assert_eq!(quaint_value, QuaintValue::DateTime(Some(datetime))); + + let s = "2023-01-01 23:59:59.123456"; + let json_value = serde_json::Value::String(s.to_string()); + let quaint_value = js_value_to_quaint(json_value, column_type); + + let datetime = NaiveDate::from_ymd_opt(2023, 1, 1) + .unwrap() + .and_hms_micro_opt(23, 59, 59, 123_456) + .unwrap(); + let datetime = DateTime::from_utc(datetime, Utc); + assert_eq!(quaint_value, QuaintValue::DateTime(Some(datetime))); + let s = "2023-01-01 23:59:59"; let json_value = serde_json::Value::String(s.to_string()); let quaint_value = js_value_to_quaint(json_value, column_type); let datetime = NaiveDate::from_ymd_opt(2023, 1, 1) .unwrap() - .and_hms_opt(23, 59, 59) + .and_hms_milli_opt(23, 59, 59, 0) .unwrap(); let datetime = DateTime::from_utc(datetime, Utc); assert_eq!(quaint_value, QuaintValue::DateTime(Some(datetime)));