Skip to content

Commit 978aaa7

Browse files
committed
Adding support for Temporal
1 parent 008cbab commit 978aaa7

File tree

7 files changed

+39
-22
lines changed

7 files changed

+39
-22
lines changed

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"check": "deno check **/*.ts && deno lint && deno fmt --check",
2222
"lint": "deno lint src test",
2323
"release": "release",
24-
"test": "deno test -A --unstable-kv",
24+
"test": "deno test -A --unstable-kv --unstable-temporal",
2525
"test-mysql": "./test/test-mysql.sh",
2626
"test-postgres": "./test/test-postgres.sh"
2727
}

resources/tjs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ const program = TJS.getProgramFromFiles([ import.meta.dirname! + "/account.ts" ]
1212

1313
// We can either get the schema for one file and one type...
1414
const schema = DDL.cleanSchema(TJS.generateSchema(program, "Account", settings) as Schema);
15-
console.log(schema);
15+
console.info(schema);

src/db.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { blue, bold, white } from "@std/fmt/colors";
22
import { ConsoleHandler, getLogger, type LevelName, type Logger } from "@std/log";
33
import { DDL } from "./ddl.ts";
4-
import type { Class, Identifiable, Parameter, Row, Schema } from "./types.ts";
4+
import type { Class, Identifiable, Parameter, Row, Schema, Temporal } from "./types.ts";
55
import { Repository } from "./repository.ts";
66

77
// Import Driver Types
@@ -66,6 +66,10 @@ async function connect(config: ClientConfig): Promise<Client> {
6666
// Set the debug flag
6767
DB.debug = Deno.env.get("DEBUG")?.includes("dbx") || config.debug || false;
6868

69+
// Cleans parameters of temporal values
70+
const isTemporal = (p: unknown): p is Temporal => p instanceof Temporal.PlainDate || p instanceof Temporal.PlainDateTime || p instanceof Temporal.PlainTime;
71+
const cleanTemporals = (parameters: Parameter[] | undefined) => parameters?.map((p) => isTemporal(p) ? p.toString() : p);
72+
6973
// MySQL
7074
if (config.type === Provider.MYSQL) {
7175
const mysql = await import("npm:mysql2@^3/promise");
@@ -83,13 +87,13 @@ async function connect(config: ClientConfig): Promise<Client> {
8387
}
8488
async execute(sql: string, parameters?: Parameter[]) {
8589
// deno-lint-ignore no-explicit-any
86-
const [rsh] = await (nativeClient as any).execute(sql, parameters);
90+
const [rsh] = await (nativeClient as any).execute(sql, cleanTemporals(parameters));
8791
// deno-lint-ignore no-explicit-any
8892
return { affectedRows: (rsh as any).affectedRows, lastInsertId: (rsh as any).insertId };
8993
}
9094
async query(sql: string, parameters?: Parameter[]) {
9195
// deno-lint-ignore no-explicit-any
92-
const [rows] = await (nativeClient as any).query(sql, parameters);
96+
const [rows] = await (nativeClient as any).query(sql, cleanTemporals(parameters));
9397
return rows as Row[];
9498
}
9599
}();
@@ -106,11 +110,11 @@ async function connect(config: ClientConfig): Promise<Client> {
106110
return nativeClient.end();
107111
}
108112
async execute(sql: string, parameters?: Parameter[]) {
109-
const qar = await nativeClient.queryArray(sql, parameters);
113+
const qar = await nativeClient.queryArray(sql, cleanTemporals(parameters));
110114
return { affectedRows: qar.rowCount, lastInsertId: qar.rows[0]?.[0] as number ?? undefined };
111115
}
112116
async query(sql: string, parameters?: Parameter[]) {
113-
const qor = await nativeClient.queryObject(sql, parameters);
117+
const qor = await nativeClient.queryObject(sql, cleanTemporals(parameters));
114118
return qor.rows as Row[];
115119
}
116120
}();
@@ -130,11 +134,11 @@ async function connect(config: ClientConfig): Promise<Client> {
130134
return Promise.resolve(nativeClient.close());
131135
}
132136
execute(sql: string, parameters?: Parameter[]) {
133-
nativeClient.exec(sql, parameters);
137+
nativeClient.exec(sql, cleanTemporals(parameters));
134138
return Promise.resolve({ affectedRows: nativeClient.changes, lastInsertId: nativeClient.lastInsertRowId });
135139
}
136140
query(sql: string, parameters?: Parameter[]) {
137-
return Promise.resolve(nativeClient.prepare(sql).all(parameters));
141+
return Promise.resolve(nativeClient.prepare(sql).all(cleanTemporals(parameters)));
138142
}
139143
}();
140144
}

src/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copied from base util.ts which are copied from type-fest
2-
export type Primitive = bigint | boolean | Date | null | number | string | Uint8Array | undefined;
3-
export type Parameter = Primitive | bigint[] | boolean[] | Date[] | number[] | string[];
2+
export type Primitive = bigint | boolean | Date | null | number | string | Uint8Array;
3+
export type Temporal = Temporal.PlainDate | Temporal.PlainDateTime | Temporal.PlainTime;
4+
export type Parameter = Primitive | Primitive[] | Temporal;
45

56
export type Class<T> = { new (): T };
67
export type Row = { [key in string]?: unknown };

test/basic.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env -S deno test -A
1+
#!/usr/bin/env -S deno test -A --unstable-temporal
22

33
import { assert, assertEquals, assertExists, assertRejects } from "@std/assert";
44
import type { Schema } from "../src/types.ts";
@@ -72,9 +72,18 @@ Deno.test("Boolean Values", options, async function () {
7272
assertEquals(accounts.length, 0);
7373
});
7474

75-
Deno.test("DateTime Values", options, async function () {
76-
const account = await repo.findOne({});
75+
Deno.test("DateTime Values (including Temporal)", options, async function () {
76+
const account = await repo.findOne();
7777
assertEquals(account!.established!.getMilliseconds(), 123);
78+
79+
// Using actual dates
80+
assertEquals(await repo.count({ established: { lt: new Date("2000-01-01") } }), 0);
81+
assertEquals(await repo.count({ established: { lt: new Date("2100-01-01") } }), 1);
82+
83+
// Execute in a more raw form to test temporal parameters
84+
const sql = "SELECT COUNT(1) AS count FROM accounts WHERE established < ?";
85+
assertEquals(await DB.query(sql,[ Temporal.PlainDate.from("2000-01-01") ]), [ { count: 0 } ]);
86+
assertEquals(await DB.query(sql,[ "2100-01-01" ]), [ { count: 1 } ]);
7887
});
7988

8089
Deno.test("Full Text search", options, async function () {

test/ddl.test.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ CREATE INDEX accounts_updated ON accounts (updated);
5252

5353
Deno.test("Table Creation SQLite", function () {
5454
const sddl = DDL.createTable(staticSchema as Schema, "sqlite", "accounts");
55-
if (DEBUG) console.log(`\nSQLite\n${HR}\n${sddl}\n\n`);
55+
if (DEBUG) console.debug(`\nSQLite\n${HR}\n${sddl}\n\n`);
5656
assertEquals(sddl.trim(), SQLITE);
5757
const dddl = DDL.createTable(dynamicSchema as Schema, "sqlite", "accounts");
58-
console.log(`\nSQLite\n${HR}\n${dddl}\n\n`);
58+
if (DEBUG) console.debug(`\nSQLite\n${HR}\n${dddl}\n\n`);
5959
assertEquals(dddl.trim(), SQLITE);
6060
});
6161

@@ -89,10 +89,10 @@ CREATE FULLTEXT INDEX accounts_fulltext ON accounts (comments,country,phone,name
8989

9090
Deno.test("Table Creation MySQL", function () {
9191
const sddl = DDL.createTable(staticSchema as Schema, "mysql", "accounts");
92-
if (DEBUG) console.log(`\nMYSQL\n${HR}\n${sddl}\n\n`);
92+
if (DEBUG) console.debug(`\nMYSQL\n${HR}\n${sddl}\n\n`);
9393
assertEquals(sddl.trim(), MYSQL);
9494
const dddl = DDL.createTable(dynamicSchema as Schema, "mysql", "accounts");
95-
if (DEBUG) console.log(`\nMYSQL\n${HR}\n${dddl}\n\n`);
95+
if (DEBUG) console.debug(`\nMYSQL\n${HR}\n${dddl}\n\n`);
9696
assertEquals(dddl.trim(), MYSQL);
9797
});
9898

@@ -125,9 +125,12 @@ CREATE INDEX accounts_fulltext ON accounts USING GIN (TO_TSVECTOR('english', COA
125125
`.trim();
126126

127127
Deno.test("Table Creation Postgres", function () {
128-
const ddl = DDL.createTable(staticSchema as Schema, "postgres");
129-
if (DEBUG) console.log(`\nPostgres\n${HR}\n${ddl}\n\n`);
130-
assertEquals(ddl.trim(), POSTGRES);
128+
const sddl = DDL.createTable(staticSchema as Schema, "postgres");
129+
if (DEBUG) console.debug(`\nPostgres\n${HR}\n${sddl}\n\n`);
130+
assertEquals(sddl.trim(), POSTGRES);
131+
const dddl = DDL.createTable(dynamicSchema as Schema, "postgres");
132+
if (DEBUG) console.debug(`\nPostgres\n${HR}\n${dddl}\n\n`);
133+
assertEquals(dddl.trim(), POSTGRES);
131134
});
132135

133136
// Execute the table creation on the provided platform

test/test-mysql.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ docker exec -it "$NAME" mysql -u root -e "$SQL"
2727
# Run MySQL tests
2828
echo "🧪 Running Tests ..."
2929
echo "------------------------------------------------------------------------------"
30-
TEST_PROVIDER="$NAME" TEST_PORT="$PORT" deno test -A
30+
TEST_PROVIDER="$NAME" TEST_PORT="$PORT" deno test -A --unstable-kv --unstable-temporal
3131
echo "------------------------------------------------------------------------------"
3232

3333
# Stop and delete the container

0 commit comments

Comments
 (0)