Skip to content

Commit 36ad677

Browse files
committed
Enable SQLite usage via Bun SQL
1 parent c445637 commit 36ad677

File tree

10 files changed

+4088
-33
lines changed

10 files changed

+4088
-33
lines changed

drizzle-orm/src/bun-sql/index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1-
export * from './driver.ts';
2-
export * from './session.ts';
1+
export { BunSQLPGDatabase as BunSQLDatabase, drizzle } from './pg/driver.ts';
2+
export {
3+
BunSQLPGPreparedQuery as BunSQLPreparedQuery,
4+
type BunSQLPGQueryResultHKT as BunSQLQueryResultHKT,
5+
BunSQLPGSession as BunSQLSession,
6+
type BunSQLPGSessionOptions as BunSQLSessionOptions,
7+
BunSQLPGTransaction as BunSQLTransaction,
8+
} from './pg/session.ts';

drizzle-orm/src/bun-sql/migrator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { MigrationConfig } from '~/migrator.ts';
22
import { readMigrationFiles } from '~/migrator.ts';
3-
import type { BunSQLDatabase } from './driver.ts';
3+
import type { BunSQLPGDatabase } from './pg/driver.ts';
44

55
export async function migrate<TSchema extends Record<string, unknown>>(
6-
db: BunSQLDatabase<TSchema>,
6+
db: BunSQLPGDatabase<TSchema>,
77
config: MigrationConfig,
88
) {
99
const migrations = readMigrationFiles(config);

drizzle-orm/src/bun-sql/driver.ts renamed to drizzle-orm/src/bun-sql/pg/driver.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ import {
1313
type TablesRelationalConfig,
1414
} from '~/relations.ts';
1515
import { type DrizzleConfig, isConfig } from '~/utils.ts';
16-
import type { BunSQLQueryResultHKT } from './session.ts';
17-
import { BunSQLSession } from './session.ts';
16+
import type { BunSQLPGQueryResultHKT } from './session.ts';
17+
import { BunSQLPGSession } from './session.ts';
1818

19-
export class BunSQLDatabase<
19+
export class BunSQLPGDatabase<
2020
TSchema extends Record<string, unknown> = Record<string, never>,
21-
> extends PgDatabase<BunSQLQueryResultHKT, TSchema> {
22-
static override readonly [entityKind]: string = 'BunSQLDatabase';
21+
> extends PgDatabase<BunSQLPGQueryResultHKT, TSchema> {
22+
static override readonly [entityKind]: string = 'BunSQLPGDatabase';
2323
}
2424

2525
function construct<TSchema extends Record<string, unknown> = Record<string, never>>(
2626
client: SQL,
2727
config: DrizzleConfig<TSchema> = {},
28-
): BunSQLDatabase<TSchema> & {
28+
): BunSQLPGDatabase<TSchema> & {
2929
$client: SQL;
3030
} {
3131
const dialect = new PgDialect({ casing: config.casing });
@@ -49,8 +49,8 @@ function construct<TSchema extends Record<string, unknown> = Record<string, neve
4949
};
5050
}
5151

52-
const session = new BunSQLSession(client, dialect, schema, { logger, cache: config.cache });
53-
const db = new BunSQLDatabase(dialect, session, schema as any) as BunSQLDatabase<TSchema>;
52+
const session = new BunSQLPGSession(client, dialect, schema, { logger, cache: config.cache });
53+
const db = new BunSQLPGDatabase(dialect, session, schema as any) as BunSQLPGDatabase<TSchema>;
5454
(<any> db).$client = client;
5555
(<any> db).$cache = config.cache;
5656
if ((<any> db).$cache) {
@@ -79,7 +79,7 @@ export function drizzle<
7979
})
8080
),
8181
]
82-
): BunSQLDatabase<TSchema> & {
82+
): BunSQLPGDatabase<TSchema> & {
8383
$client: TClient;
8484
} {
8585
if (typeof params[0] === 'string') {
@@ -113,7 +113,7 @@ export function drizzle<
113113
export namespace drizzle {
114114
export function mock<TSchema extends Record<string, unknown> = Record<string, never>>(
115115
config?: DrizzleConfig<TSchema>,
116-
): BunSQLDatabase<TSchema> & {
116+
): BunSQLPGDatabase<TSchema> & {
117117
$client: '$client is not available on drizzle.mock()';
118118
} {
119119
return construct({
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './driver.ts';
2+
export * from './session.ts';

drizzle-orm/src/bun-sql/session.ts renamed to drizzle-orm/src/bun-sql/pg/session.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import { fillPlaceholders, type Query } from '~/sql/sql.ts';
1616
import { tracer } from '~/tracing.ts';
1717
import { type Assume, mapResultRow } from '~/utils.ts';
1818

19-
export class BunSQLPreparedQuery<T extends PreparedQueryConfig> extends PgPreparedQuery<T> {
20-
static override readonly [entityKind]: string = 'BunSQLPreparedQuery';
19+
export class BunSQLPGPreparedQuery<T extends PreparedQueryConfig> extends PgPreparedQuery<T> {
20+
static override readonly [entityKind]: string = 'BunSQLPGPreparedQuery';
2121

2222
constructor(
2323
private client: SQL,
@@ -102,17 +102,17 @@ export class BunSQLPreparedQuery<T extends PreparedQueryConfig> extends PgPrepar
102102
}
103103
}
104104

105-
export interface BunSQLSessionOptions {
105+
export interface BunSQLPGSessionOptions {
106106
logger?: Logger;
107107
cache?: Cache;
108108
}
109109

110-
export class BunSQLSession<
110+
export class BunSQLPGSession<
111111
TSQL extends SQL,
112112
TFullSchema extends Record<string, unknown>,
113113
TSchema extends TablesRelationalConfig,
114-
> extends PgSession<BunSQLQueryResultHKT, TFullSchema, TSchema> {
115-
static override readonly [entityKind]: string = 'BunSQLSession';
114+
> extends PgSession<BunSQLPGQueryResultHKT, TFullSchema, TSchema> {
115+
static override readonly [entityKind]: string = 'BunSQLPGSession';
116116

117117
logger: Logger;
118118
private cache: Cache;
@@ -122,7 +122,7 @@ export class BunSQLSession<
122122
dialect: PgDialect,
123123
private schema: RelationalSchemaConfig<TSchema> | undefined,
124124
/** @internal */
125-
readonly options: BunSQLSessionOptions = {},
125+
readonly options: BunSQLPGSessionOptions = {},
126126
) {
127127
super(dialect);
128128
this.logger = options.logger ?? new NoopLogger();
@@ -141,7 +141,7 @@ export class BunSQLSession<
141141
},
142142
cacheConfig?: WithCacheConfig,
143143
): PgPreparedQuery<T> {
144-
return new BunSQLPreparedQuery(
144+
return new BunSQLPGPreparedQuery(
145145
this.client,
146146
query.sql,
147147
query.params,
@@ -168,17 +168,17 @@ export class BunSQLSession<
168168
}
169169

170170
override transaction<T>(
171-
transaction: (tx: BunSQLTransaction<TFullSchema, TSchema>) => Promise<T>,
171+
transaction: (tx: BunSQLPGTransaction<TFullSchema, TSchema>) => Promise<T>,
172172
config?: PgTransactionConfig,
173173
): Promise<T> {
174174
return this.client.begin(async (client) => {
175-
const session = new BunSQLSession<TransactionSQL, TFullSchema, TSchema>(
175+
const session = new BunSQLPGSession<TransactionSQL, TFullSchema, TSchema>(
176176
client,
177177
this.dialect,
178178
this.schema,
179179
this.options,
180180
);
181-
const tx = new BunSQLTransaction(this.dialect, session, this.schema);
181+
const tx = new BunSQLPGTransaction(this.dialect, session, this.schema);
182182
if (config) {
183183
await tx.setTransaction(config);
184184
}
@@ -187,38 +187,38 @@ export class BunSQLSession<
187187
}
188188
}
189189

190-
export class BunSQLTransaction<
190+
export class BunSQLPGTransaction<
191191
TFullSchema extends Record<string, unknown>,
192192
TSchema extends TablesRelationalConfig,
193-
> extends PgTransaction<BunSQLQueryResultHKT, TFullSchema, TSchema> {
194-
static override readonly [entityKind]: string = 'BunSQLTransaction';
193+
> extends PgTransaction<BunSQLPGQueryResultHKT, TFullSchema, TSchema> {
194+
static override readonly [entityKind]: string = 'BunSQLPGTransaction';
195195

196196
constructor(
197197
dialect: PgDialect,
198198
/** @internal */
199-
override readonly session: BunSQLSession<TransactionSQL | SavepointSQL, TFullSchema, TSchema>,
199+
override readonly session: BunSQLPGSession<TransactionSQL | SavepointSQL, TFullSchema, TSchema>,
200200
schema: RelationalSchemaConfig<TSchema> | undefined,
201201
nestedIndex = 0,
202202
) {
203203
super(dialect, session, schema, nestedIndex);
204204
}
205205

206206
override transaction<T>(
207-
transaction: (tx: BunSQLTransaction<TFullSchema, TSchema>) => Promise<T>,
207+
transaction: (tx: BunSQLPGTransaction<TFullSchema, TSchema>) => Promise<T>,
208208
): Promise<T> {
209209
return (this.session.client as TransactionSQL).savepoint((client) => {
210-
const session = new BunSQLSession<SavepointSQL, TFullSchema, TSchema>(
210+
const session = new BunSQLPGSession<SavepointSQL, TFullSchema, TSchema>(
211211
client,
212212
this.dialect,
213213
this.schema,
214214
this.session.options,
215215
);
216-
const tx = new BunSQLTransaction<TFullSchema, TSchema>(this.dialect, session, this.schema);
216+
const tx = new BunSQLPGTransaction<TFullSchema, TSchema>(this.dialect, session, this.schema);
217217
return transaction(tx);
218218
}) as Promise<T>;
219219
}
220220
}
221221

222-
export interface BunSQLQueryResultHKT extends PgQueryResultHKT {
222+
export interface BunSQLPGQueryResultHKT extends PgQueryResultHKT {
223223
type: Assume<this['row'], Record<string, any>[]>;
224224
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/// <reference types="bun-types" />
2+
3+
import type { SQLOptions } from 'bun';
4+
import { SQL } from 'bun';
5+
import { entityKind } from '~/entity.ts';
6+
import { DefaultLogger } from '~/logger.ts';
7+
import {
8+
createTableRelationsHelpers,
9+
extractTablesRelationalConfig,
10+
type RelationalSchemaConfig,
11+
type TablesRelationalConfig,
12+
} from '~/relations.ts';
13+
import { BaseSQLiteDatabase } from '~/sqlite-core/db.ts';
14+
import { SQLiteAsyncDialect } from '~/sqlite-core/dialect.ts';
15+
import { type DrizzleConfig, isConfig } from '~/utils.ts';
16+
import { BunSQLSQLiteSession } from './session.ts';
17+
18+
export class BunSQLSQLiteDatabase<
19+
TSchema extends Record<string, unknown> = Record<string, never>,
20+
> extends BaseSQLiteDatabase<'async', void, TSchema> {
21+
static override readonly [entityKind]: string = 'BunSQLSQLiteDatabase';
22+
}
23+
24+
function construct<TSchema extends Record<string, unknown> = Record<string, never>>(
25+
client: SQL,
26+
config: DrizzleConfig<TSchema> = {},
27+
): BunSQLSQLiteDatabase<TSchema> & {
28+
$client: SQL;
29+
} {
30+
const dialect = new SQLiteAsyncDialect({ casing: config.casing });
31+
let logger;
32+
if (config.logger === true) {
33+
logger = new DefaultLogger();
34+
} else if (config.logger !== false) {
35+
logger = config.logger;
36+
}
37+
38+
let schema: RelationalSchemaConfig<TablesRelationalConfig> | undefined;
39+
if (config.schema) {
40+
const tablesConfig = extractTablesRelationalConfig(
41+
config.schema,
42+
createTableRelationsHelpers,
43+
);
44+
schema = {
45+
fullSchema: config.schema,
46+
schema: tablesConfig.tables,
47+
tableNamesMap: tablesConfig.tableNamesMap,
48+
};
49+
}
50+
51+
const session = new BunSQLSQLiteSession(client, dialect, schema, { logger });
52+
const db = new BunSQLSQLiteDatabase('async', dialect, session, schema as any) as BunSQLSQLiteDatabase<TSchema>;
53+
(<any> db).$client = client;
54+
(<any> db).$cache = config.cache;
55+
if ((<any> db).$cache) {
56+
(<any> db).$cache['invalidate'] = config.cache?.onMutate;
57+
}
58+
59+
return db as any;
60+
}
61+
62+
export function drizzle<
63+
TSchema extends Record<string, unknown> = Record<string, never>,
64+
TClient extends SQL = SQL,
65+
>(
66+
...params: [
67+
TClient | string,
68+
] | [
69+
TClient | string,
70+
DrizzleConfig<TSchema>,
71+
] | [
72+
(
73+
& DrizzleConfig<TSchema>
74+
& ({
75+
connection: string | ({ url?: string } & SQLOptions);
76+
} | {
77+
client: TClient;
78+
})
79+
),
80+
]
81+
): BunSQLSQLiteDatabase<TSchema> & {
82+
$client: TClient;
83+
} {
84+
if (typeof params[0] === 'string') {
85+
const instance = new SQL(params[0]);
86+
87+
return construct(instance, params[1]) as any;
88+
}
89+
90+
if (isConfig(params[0])) {
91+
const { connection, client, ...drizzleConfig } = params[0] as {
92+
connection?: { url?: string } & SQLOptions;
93+
client?: TClient;
94+
} & DrizzleConfig<TSchema>;
95+
96+
if (client) return construct(client, drizzleConfig) as any;
97+
98+
if (typeof connection === 'object' && connection.url !== undefined) {
99+
const { url, ...config } = connection;
100+
101+
const instance = new SQL({ url, ...config });
102+
return construct(instance, drizzleConfig) as any;
103+
}
104+
105+
const instance = new SQL(connection);
106+
return construct(instance, drizzleConfig) as any;
107+
}
108+
109+
return construct(params[0] as TClient, params[1] as DrizzleConfig<TSchema> | undefined) as any;
110+
}
111+
112+
export namespace drizzle {
113+
export function mock<TSchema extends Record<string, unknown> = Record<string, never>>(
114+
config?: DrizzleConfig<TSchema>,
115+
): BunSQLSQLiteDatabase<TSchema> & {
116+
$client: '$client is not available on drizzle.mock()';
117+
} {
118+
return construct({
119+
options: {
120+
parsers: {},
121+
serializers: {},
122+
},
123+
} as any, config) as any;
124+
}
125+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './driver.ts';
2+
export * from './session.ts';

0 commit comments

Comments
 (0)