Skip to content

Commit

Permalink
Updated interfaces according to stdext/sql
Browse files Browse the repository at this point in the history
  • Loading branch information
halvardssm committed Jun 21, 2024
1 parent 3966391 commit e5f2ac6
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 210 deletions.
2 changes: 1 addition & 1 deletion bench/bench_deno_sqlx.js → bench/bench_deno_std_sql.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SqliteClient } from "../sqlx.ts";
import { SqliteClient } from "../std_sql.ts";

const db = new SqliteClient(":memory:", { unsafeConcurrency: true });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SqliteClient } from "../../sqlx.ts";
import { SqliteClient } from "../../std_sql.ts";

const db = new SqliteClient("./bench/northwind.sqlite", {
unsafeConcurrency: true,
Expand Down
6 changes: 3 additions & 3 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"lock": false,
"exports": {
".": "./mod.ts",
"./sqlx": "./sqlx.ts"
"./std_sql": "./std_sql.ts"
},
"exclude": [
"sqlite",
Expand Down Expand Up @@ -50,9 +50,9 @@
},
"imports": {
"@denosaurs/plug": "jsr:@denosaurs/plug@^1.0.5",
"@halvardm/sqlx": "jsr:@halvardm/sqlx@0.0.0-13",
"@std/assert": "jsr:@std/assert@^0.221.0",
"@std/log": "jsr:@std/log@^0.223.0",
"@std/path": "jsr:@std/path@^0.217.0"
"@std/path": "jsr:@std/path@^0.217.0",
"@stdext/sql": "jsr:@stdext/sql@0.0.0-4"
}
}
35 changes: 26 additions & 9 deletions src/connection.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
import { SqliteConnection } from "./connection.ts";
import { connectionConstructorTest } from "@halvardm/sqlx/testing";
import { assert, assertEquals } from "@std/assert";
import { SqliteConnectable, SqliteConnection } from "./connection.ts";
import { _testSqlConnectable, testSqlConnection } from "@stdext/sql/testing";

Deno.test("Connection", async (t) => {
await connectionConstructorTest({
t,
Connection: SqliteConnection,
connectionUrl: ":memory:",
connectionOptions: {},
});
Deno.test("connection and connectable contstructs", () => {
const connection = new SqliteConnection(":memory:");
testSqlConnection(connection, { connectionUrl: ":memory:" });
const connectable = new SqliteConnectable(connection);
_testSqlConnectable(connectable, connection);
});

Deno.test("connection can connect and query", async () => {
await using connection = new SqliteConnection(":memory:");
await connection.connect();
assert(connection.connected, "connection should be connected");
const executeResult = await connection.execute(`select 1 as one`);
assertEquals(executeResult, 0);
const queryManyResult = connection.queryMany(`select 1 as one`);
const queryManyResultNext1 = await queryManyResult.next();
assertEquals(queryManyResultNext1, { done: false, value: { one: 1 } });
const queryManyResultNext2 = await queryManyResult.next();
assertEquals(queryManyResultNext2, { done: true, value: undefined });
const queryManyArrayResult = connection.queryManyArray(`select 1 as one`);
const queryManyArrayResultNext1 = await queryManyArrayResult.next();
assertEquals(queryManyArrayResultNext1, { done: false, value: [1] });
const queryManyArrayResultNext2 = await queryManyArrayResult.next();
assertEquals(queryManyArrayResultNext2, { done: true, value: undefined });
});
83 changes: 68 additions & 15 deletions src/connection.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
// deno-lint-ignore-file require-await
import {
SqlxBase,
type SqlxConnection,
type SqlxConnectionOptions,
} from "@halvardm/sqlx";
import type {
ArrayRow,
Row,
SqlConnectable,
SqlConnection,
SqlConnectionOptions,
} from "@stdext/sql";
import { fromFileUrl } from "@std/path";
import ffi from "./ffi.ts";
import { Database, type DatabaseOpenOptions } from "../mod.ts";
import type { SqliteParameterType, SqliteQueryOptions } from "./core.ts";
import { transformToAsyncGenerator } from "./util.ts";

/** Various options that can be configured when opening Database connection. */
export interface SqliteConnectionOptions
extends SqlxConnectionOptions, DatabaseOpenOptions {
extends SqlConnectionOptions, DatabaseOpenOptions {
}

/**
Expand All @@ -31,12 +35,14 @@ export interface SqliteConnectionOptions
* const db = new SqliteClient(new URL("./myfile.db", import.meta.url));
* ```
*/
export class SqliteConnection extends SqlxBase implements
SqlxConnection<
SqliteConnectionOptions
export class SqliteConnection implements
SqlConnection<
SqliteConnectionOptions,
SqliteParameterType,
SqliteQueryOptions
> {
connectionUrl: string;
connectionOptions: SqliteConnectionOptions;
readonly connectionUrl: string;
readonly options: SqliteConnectionOptions;

/**
* The FFI SQLite methods.
Expand Down Expand Up @@ -64,23 +70,47 @@ export class SqliteConnection extends SqlxBase implements
connectionUrl: string | URL,
options: SqliteConnectionOptions = {},
) {
super();

this.connectionUrl = connectionUrl instanceof URL
? fromFileUrl(connectionUrl)
: connectionUrl;
this.connectionOptions = options;
this.options = options;
}

async connect(): Promise<void> {
this.db = new Database(this.connectionUrl, this.connectionOptions);
this.db = new Database(this.connectionUrl, this.options);
}

async close(): Promise<void> {
this._db?.close();
this._db = null;
}

execute(
sql: string,
params?: SqliteParameterType[],
_options?: SqliteQueryOptions,
): Promise<number | undefined> {
return Promise.resolve(this.db.exec(sql, ...(params || [])));
}
queryMany<T extends Row<any> = Row<any>>(
sql: string,
params?: SqliteParameterType[],
options?: SqliteQueryOptions,
): AsyncGenerator<T, any, unknown> {
return transformToAsyncGenerator(
this.db.prepare(sql).getMany<T>(params, options),
);
}
queryManyArray<T extends ArrayRow<any> = ArrayRow<any>>(
sql: string,
params?: SqliteParameterType[],
options?: SqliteQueryOptions,
): AsyncGenerator<T, any, unknown> {
return transformToAsyncGenerator(
this.db.prepare(sql).valueMany<T>(params, options),
);
}

async [Symbol.asyncDispose](): Promise<void> {
await this.close();
}
Expand All @@ -89,3 +119,26 @@ export class SqliteConnection extends SqlxBase implements
return `SQLite3.SqliteConnection { path: ${this.connectionUrl} }`;
}
}

export class SqliteConnectable implements
SqlConnectable<
SqliteConnectionOptions,
SqliteConnection
> {
readonly connection: SqliteConnection;
readonly options: SqliteConnectionOptions;
get connected(): boolean {
return this.connection.connected;
}

constructor(
connection: SqliteConnectable["connection"],
options: SqliteConnectable["options"] = {},
) {
this.connection = connection;
this.options = options;
}
[Symbol.asyncDispose](): Promise<void> {
return this.connection.close();
}
}
67 changes: 43 additions & 24 deletions src/sqlx.test.ts → src/core.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { assertEquals, assertRejects } from "@std/assert";
import { SQLITE_VERSION } from "./ffi.ts";
import { SqliteClient, type SqliteParameterType } from "./sqlx.ts";
import { clientTest } from "@halvardm/sqlx/testing";
import {
SqliteClient,
type SqliteParameterType,
SqlitePreparedStatement,
SqliteTransaction,
} from "./core.ts";
import { sqlIntegrationTestSuite, sqlUnitTestSuite } from "@stdext/sql/testing";
import { SqliteError } from "./util.ts";
import { SqliteConnection } from "./connection.ts";
import { SqliteEventTarget } from "./events.ts";

Deno.test("sqlite sqlx", async (t) => {
const DB_URL = new URL("./test.db", import.meta.url);
Expand Down Expand Up @@ -232,26 +239,38 @@ Deno.test("sqlite sqlx", async (t) => {
});
});

Deno.test("SQLx Test", async (t) => {
await clientTest({
t,
Client: SqliteClient,
connectionUrl: ":memory:",
connectionOptions: {},
queries: {
createTable: "CREATE TABLE IF NOT EXISTS sqlxtesttable (testcol TEXT)",
dropTable: "DROP TABLE IF EXISTS sqlxtesttable",
insertOneToTable: "INSERT INTO sqlxtesttable (testcol) VALUES (?)",
insertManyToTable:
"INSERT INTO sqlxtesttable (testcol) VALUES (?),(?),(?)",
selectOneFromTable:
"SELECT * FROM sqlxtesttable WHERE testcol = ? LIMIT 1",
selectByMatchFromTable: "SELECT * FROM sqlxtesttable WHERE testcol = ?",
selectManyFromTable: "SELECT * FROM sqlxtesttable",
select1AsString: "SELECT '1' as result",
select1Plus1AsNumber: "SELECT 1+1 as result",
deleteByMatchFromTable: "DELETE FROM sqlxtesttable WHERE testcol = ?",
deleteAllFromTable: "DELETE FROM sqlxtesttable",
},
});
const connectionUrl = ":memory:";
const options: SqliteTransaction["options"] = {};
const sql = "SELECT 1 as one;";

const connection = new SqliteConnection(connectionUrl, options);
await connection.connect();
const preparedStatement = new SqlitePreparedStatement(
connection,
sql,
options,
);
const transaction = new SqliteTransaction(connection, options);
const eventTarget = new SqliteEventTarget();
const client = new SqliteClient(connectionUrl, options);

sqlUnitTestSuite({
testPrefix: "sql",
connectionClass: connection,
preparedStatementClass: preparedStatement,
transactionClass: transaction,
eventTargetClass: eventTarget,
clientClass: client,
checks: {
connectionUrl,
options,
clientPoolOptions: options,
sql,
},
});

sqlIntegrationTestSuite({
testPrefix: "sql",
Client: SqliteClient,
clientArguments: [connectionUrl, options],
});
Loading

0 comments on commit e5f2ac6

Please sign in to comment.