Skip to content

Commit

Permalink
feat: export database instances (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandros94 authored Jan 24, 2025
1 parent 5e555fb commit 164c21c
Show file tree
Hide file tree
Showing 12 changed files with 45 additions and 14 deletions.
3 changes: 2 additions & 1 deletion src/connectors/better-sqlite3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ export default function sqliteConnector(opts: ConnectorOptions) {
return _db;
};

return <Connector>{
return <Connector<Database.Database>>{
name: "sqlite",
dialect: "sqlite",
getInstance: () => getDB(),
exec(sql: string) {
return getDB().exec(sql);
},
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/bun-sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ export default function bunSqliteConnector(opts: ConnectorOptions) {
return _db;
};

return <Connector>{
return <Connector<Database>>{
name: "sqlite",
dialect: "sqlite",
getInstance: () => getDB(),
exec(sql: string) {
return getDB().exec(sql);
},
Expand Down
1 change: 1 addition & 0 deletions src/connectors/cloudflare-d1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function cloudflareD1Connector(options: ConnectorOptions) {
return <Connector>{
name: "cloudflare-d1",
dialect: "sqlite",
getInstance: () => getDB(),
exec: (sql: string) => getDB().exec(sql),
prepare: (sql: string) => {
const _stmt = getDB().prepare(sql);
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/libsql/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ export default function libSqlCoreConnector(opts: ConnectorOptions) {
return client.execute(sql);
}

return <Connector>{
return <Connector<Client>>{
name: opts.name || "libsql-core",
dialect: "libsql",
getInstance: async () => opts.getClient(),
exec(sql: string) {
return query(sql);
},
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/mysql2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ export default function mysqlConnector(opts: ConnectorOptions) {
return _connection;
};

return <Connector>{
return <Connector<mysql.Connection>>{
name: "mysql",
dialect: "mysql",
getInstance: () => getConnection(),
exec(sql: string) {
return getConnection().then((c) => c.query(sql).then((res) => res[0]));
},
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/pglite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ export default function pgliteConnector(opts: ConnectorOptions = {}) {
return result;
}

return <Connector>{
return <Connector<PGlite>>{
name: "pglite",
dialect: "postgresql",
getInstance: () => getClient(),
exec(sql: string) {
return query(sql);
},
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/planetscale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ export default function planetscaleConnector(opts: ConnectorOptions) {
return client.execute(sql, params);
}

return <Connector>{
return <Connector<Client>>{
name: "planetscale",
dialect: "mysql",
getInstance: () => getClient(),
exec(sql: string) {
return query(sql);
},
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/postgresql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ export default function postgresqlConnector(opts: ConnectorOptions) {
return client.query(normalizeParams(sql), params);
}

return <Connector>{
return <Connector<pg.Client>>{
name: "postgresql",
dialect: "postgresql",
getInstance: () => getClient(),
exec(sql: string) {
return query(sql);
},
Expand Down
10 changes: 8 additions & 2 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ const SQL_WITH_RES_RE = /^select/i;
* @param {Connector} connector - The database connector used to execute and prepare SQL statements. See {@link Connector}.
* @returns {Database} The database interface that allows SQL operations. See {@link Database}.
*/
export function createDatabase(connector: Connector): Database {
return <Database>{
export function createDatabase<TConnector extends Connector = Connector>(
connector: TConnector,
): Database<TConnector> {
return <Database<TConnector>>{
get dialect() {
return connector.dialect;
},

getInstance() {
return connector.getInstance();
},

exec: (sql: string) => {
return Promise.resolve(connector.exec(sql));
},
Expand Down
15 changes: 13 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export type ExecResult = unknown;
/**
* Defines a database connector for executing SQL queries and preparing statements.
*/
export type Connector = {
export type Connector<TInstance = any> = {
/**
* The name of the connector.
*/
Expand All @@ -54,6 +54,11 @@ export type Connector = {
*/
dialect: SQLDialect;

/**
* The client instance used internally.
*/
getInstance: () => TInstance | Promise<TInstance>;

/**
* Executes an SQL query directly and returns the result.
* @param {string} sql - The SQL string to execute.
Expand All @@ -79,9 +84,15 @@ type DefaultSQLResult = {
rows?: { id?: string | number; [key: string]: unknown }[];
};

export interface Database {
export interface Database<TConnector extends Connector = Connector> {
readonly dialect: SQLDialect;

/**
* The client instance used internally.
* @returns {Promise<TInstance>} A promise that resolves with the client instance.
*/
getInstance: () => Promise<TConnector["getInstance"]>;

/**
* Executes a raw SQL string.
* @param {string} sql - The SQL string to execute.
Expand Down
10 changes: 8 additions & 2 deletions test/connectors/_tests.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { beforeAll, expect, it } from "vitest";
import { Connector, Database, createDatabase, type SQLDialect } from "../../src";

export function testConnector(opts: { connector: Connector, dialect: SQLDialect }) {
let db: Database;
export function testConnector<TConnector extends Connector = Connector>(opts: { connector: TConnector, dialect: SQLDialect }) {
let db: Database<TConnector>;
beforeAll(() => {
db = createDatabase(opts.connector);
});

const userId = "1001";

it("instance matches", async () => {
const instance = await db.getInstance();
expect(instance).toBeDefined();
expect(instance).toBe(await opts.connector.getInstance());
})

it("dialect matches", () => {
expect(db.dialect).toBe(opts.dialect);
})
Expand Down
2 changes: 1 addition & 1 deletion test/integrations/drizzle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe.runIf(process.env.POSTGRESQL_URL)("integrations: drizzle: postgres", ()
});

let drizzleDb: DrizzleDatabase;
let db: Database;
let db: Database<ReturnType<typeof pgConnector>>;

beforeAll(async () => {
db = createDatabase(pgConnector({
Expand Down

0 comments on commit 164c21c

Please sign in to comment.