Skip to content

Commit 9a1f861

Browse files
RihanArfanpi0
andauthored
feat: support dispose and using createDatabase() (#178)
Co-authored-by: Pooya Parsa <[email protected]>
1 parent d7b4db0 commit 9a1f861

File tree

13 files changed

+144
-2
lines changed

13 files changed

+144
-2
lines changed

docs/1.guide/1.index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ import sqlite from "db0/connectors/better-sqlite3";
3030
// Initiate database with SQLite connector
3131
const db = createDatabase(sqlite({}));
3232

33+
// Alternative:
34+
// `using` automatically closes the database connection
35+
// once the `db` variable goes out of scope (for example, the function execution ends)
36+
// await using db = createDatabase(sqlite({}));
37+
3338
// Create users table
3439
await db.sql`CREATE TABLE IF NOT EXISTS users ("id" TEXT PRIMARY KEY, "firstName" TEXT, "lastName" TEXT, "email" TEXT)`;
3540

src/connectors/better-sqlite3.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ export default function sqliteConnector(
3838
getInstance: () => getDB(),
3939
exec: (sql) => getDB().exec(sql),
4040
prepare: (sql) => new StatementWrapper(() => getDB().prepare(sql)),
41+
dispose: () => {
42+
_db?.close?.();
43+
_db = undefined as any;
44+
},
4145
};
4246
}
4347

src/connectors/bun-sqlite.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export default function bunSqliteConnector(
3737
getInstance: () => getDB(),
3838
exec: (sql) => getDB().exec(sql),
3939
prepare: (sql) => new StatementWrapper(getDB().prepare(sql)),
40+
dispose: () => {
41+
_db?.close?.();
42+
_db = undefined as any;
43+
},
4044
};
4145
}
4246

src/connectors/libsql/core.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ export default function libSqlCoreConnector(
2020
getInstance: async () => opts.getClient(),
2121
exec: (sql) => query(sql),
2222
prepare: (sql) => new StatementWrapper(sql, query),
23+
dispose: () => {
24+
opts.getClient()?.close?.();
25+
},
2326
};
2427
}
2528

src/connectors/mysql2.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ export default function mysqlConnector(
3636
getInstance: () => getConnection(),
3737
exec: (sql) => query(sql),
3838
prepare: (sql) => new StatementWrapper(sql, query),
39+
dispose: async () => {
40+
await _connection?.end?.();
41+
_connection = undefined;
42+
},
3943
};
4044
}
4145

src/connectors/node-sqlite.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ export default function nodeSqlite3Connector(
4747
return { success: true };
4848
},
4949
prepare: (sql) => new StatementWrapper(() => getDB().prepare(sql)),
50+
dispose: () => {
51+
_db?.close?.();
52+
_db = undefined;
53+
},
5054
};
5155
}
5256

src/connectors/pglite.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export default function pgliteConnector<TOptions extends ConnectorOptions>(
3939
getInstance: () => getClient(),
4040
exec: (sql) => query(sql),
4141
prepare: (sql) => new StatementWrapper(sql, query),
42+
dispose: async () => {
43+
await (await _client)?.close?.();
44+
_client = undefined;
45+
},
4246
};
4347
}
4448

src/connectors/planetscale.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export default function planetscaleConnector(
3535
getInstance: () => getClient(),
3636
exec: (sql) => query(sql),
3737
prepare: (sql) => new StatementWrapper(sql, query),
38+
dispose: () => {
39+
_client = undefined;
40+
},
3841
};
3942
}
4043

src/connectors/postgresql.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ export default function postgresqlConnector(
3838
getInstance: () => getClient(),
3939
exec: (sql) => query(sql),
4040
prepare: (sql) => new StatementWrapper(sql, query),
41+
dispose: async () => {
42+
await (await _client)?.end?.();
43+
_client = undefined;
44+
},
4145
};
4246
}
4347

src/connectors/sqlite3.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export default function nodeSqlite3Connector(
1515
opts: ConnectorOptions,
1616
): Connector<sqlite3.Database> {
1717
let _db: sqlite3.Database;
18+
const _activeStatements = new Set<StatementWrapper>();
19+
1820
const getDB = () => {
1921
if (_db) {
2022
return _db;
@@ -47,7 +49,25 @@ export default function nodeSqlite3Connector(
4749
dialect: "sqlite",
4850
getInstance: () => getDB(),
4951
exec: (sql: string) => query(sql),
50-
prepare: (sql) => new StatementWrapper(sql, getDB()),
52+
prepare: (sql) => {
53+
const stmt = new StatementWrapper(sql, getDB());
54+
_activeStatements.add(stmt);
55+
return stmt;
56+
},
57+
dispose: async () => {
58+
await Promise.all(
59+
[..._activeStatements].map((s) =>
60+
s.finalize().catch((error) => {
61+
console.warn("[db0] [sqlite3] failed to finalize statement", error);
62+
}),
63+
),
64+
);
65+
_activeStatements.clear();
66+
await new Promise<void>((resolve, reject) =>
67+
_db?.close?.((error) => (error ? reject(error) : resolve())),
68+
);
69+
_db = undefined as any;
70+
},
5171
};
5272
}
5373

@@ -90,4 +110,14 @@ class StatementWrapper extends BoundableStatement<sqlite3.Statement> {
90110
});
91111
return row;
92112
}
113+
114+
finalize() {
115+
try {
116+
// TODO: Can we await on finalize cb?
117+
this._statement.finalize();
118+
return Promise.resolve();
119+
} catch (error) {
120+
return Promise.reject(error);
121+
}
122+
}
93123
}

0 commit comments

Comments
 (0)