|
1 | 1 | import type { PGlite } from '@electric-sql/pglite'; |
| 2 | +import type { SQLiteCloudRowset } from '@sqlitecloud/drivers'; |
2 | 3 | import type { AwsDataApiPgQueryResult, AwsDataApiSessionOptions } from 'drizzle-orm/aws-data-api/pg'; |
3 | 4 | import type { MigrationConfig, MigratorInitFailResponse } from 'drizzle-orm/migrator'; |
4 | 5 | import type { PreparedQueryConfig } from 'drizzle-orm/pg-core'; |
@@ -1128,7 +1129,7 @@ export const connectToSQLite = async ( |
1128 | 1129 | ): Promise< |
1129 | 1130 | & SQLiteDB |
1130 | 1131 | & { |
1131 | | - packageName: 'd1-http' | '@libsql/client' | 'better-sqlite3'; |
| 1132 | + packageName: 'd1-http' | '@libsql/client' | 'better-sqlite3' | '@sqlitecloud/drivers' | '@tursodatabase/database'; |
1132 | 1133 | migrate: (config: string | MigrationConfig) => Promise<void | MigratorInitFailResponse>; |
1133 | 1134 | proxy: Proxy; |
1134 | 1135 | transactionProxy: TransactionProxy; |
@@ -1269,6 +1270,90 @@ export const connectToSQLite = async ( |
1269 | 1270 | return result.rows; |
1270 | 1271 | }; |
1271 | 1272 | return { ...db, packageName: 'd1-http', proxy, transactionProxy, migrate: migrateFn }; |
| 1273 | + } else if (driver === 'sqlite-cloud') { |
| 1274 | + assertPackages('@sqlitecloud/drivers'); |
| 1275 | + const { Database } = await import('@sqlitecloud/drivers'); |
| 1276 | + const { drizzle } = await import('drizzle-orm/sqlite-cloud'); |
| 1277 | + const { migrate } = await import('drizzle-orm/sqlite-cloud/migrator'); |
| 1278 | + |
| 1279 | + const client = new Database(credentials.url); |
| 1280 | + const drzl = drizzle({ client }); |
| 1281 | + const migrateFn = async (config: MigrationConfig) => { |
| 1282 | + return migrate(drzl, config); |
| 1283 | + }; |
| 1284 | + |
| 1285 | + const query = async <T>(sql: string, params?: any[]) => { |
| 1286 | + const stmt = client.prepare(sql).bind(params || []); |
| 1287 | + return await new Promise<T[]>((resolve, reject) => { |
| 1288 | + stmt.all((e: Error | null, d: SQLiteCloudRowset) => { |
| 1289 | + if (e) return reject(e); |
| 1290 | + |
| 1291 | + return resolve(d.map((v) => Object.fromEntries(Object.entries(v)))); |
| 1292 | + }); |
| 1293 | + }); |
| 1294 | + }; |
| 1295 | + const run = async (query: string) => { |
| 1296 | + return await new Promise<void>((resolve, reject) => { |
| 1297 | + client.exec(query, (e: Error | null) => { |
| 1298 | + if (e) return reject(e); |
| 1299 | + return resolve(); |
| 1300 | + }); |
| 1301 | + }); |
| 1302 | + }; |
| 1303 | + |
| 1304 | + const proxy = async (params: ProxyParams) => { |
| 1305 | + const preparedParams = prepareSqliteParams(params.params || []); |
| 1306 | + const stmt = client.prepare(params.sql).bind(preparedParams); |
| 1307 | + return await new Promise<any[]>((resolve, reject) => { |
| 1308 | + stmt.all((e: Error | null, d: SQLiteCloudRowset | undefined) => { |
| 1309 | + if (e) return reject(e); |
| 1310 | + |
| 1311 | + if (params.mode === 'array') { |
| 1312 | + return resolve((d || []).map((v) => v.getData())); |
| 1313 | + } else { |
| 1314 | + return resolve((d || []).map((v) => Object.fromEntries(Object.entries(v)))); |
| 1315 | + } |
| 1316 | + }); |
| 1317 | + }); |
| 1318 | + }; |
| 1319 | + |
| 1320 | + const transactionProxy: TransactionProxy = async (queries) => { |
| 1321 | + const results: (any[] | Error)[] = []; |
| 1322 | + try { |
| 1323 | + await new Promise<void>((resolve, reject) => { |
| 1324 | + client.exec('BEGIN', (e: Error | null) => { |
| 1325 | + if (e) return reject(e); |
| 1326 | + return resolve(); |
| 1327 | + }); |
| 1328 | + }); |
| 1329 | + for (const query of queries) { |
| 1330 | + const result = await new Promise<any[]>((resolve, reject) => { |
| 1331 | + client.all(query.sql, (e: Error | null, d: SQLiteCloudRowset | undefined) => { |
| 1332 | + if (e) return reject(e); |
| 1333 | + return resolve((d || []).map((v) => Object.fromEntries(Object.entries(v)))); |
| 1334 | + }); |
| 1335 | + }); |
| 1336 | + results.push(result); |
| 1337 | + } |
| 1338 | + await new Promise<void>((resolve, reject) => { |
| 1339 | + client.exec('COMMIT', (e: Error | null) => { |
| 1340 | + if (e) return reject(e); |
| 1341 | + return resolve(); |
| 1342 | + }); |
| 1343 | + }); |
| 1344 | + } catch (error) { |
| 1345 | + results.push(error as Error); |
| 1346 | + await new Promise<void>((resolve, reject) => { |
| 1347 | + client.exec('ROLLBACK', (e: Error | null) => { |
| 1348 | + if (e) return reject(e); |
| 1349 | + return resolve(); |
| 1350 | + }); |
| 1351 | + }); |
| 1352 | + } |
| 1353 | + return results; |
| 1354 | + }; |
| 1355 | + |
| 1356 | + return { query, run, packageName: '@sqlitecloud/drivers', proxy, transactionProxy, migrate: migrateFn }; |
1272 | 1357 | } else { |
1273 | 1358 | assertUnreachable(driver); |
1274 | 1359 | } |
@@ -1341,6 +1426,61 @@ export const connectToSQLite = async ( |
1341 | 1426 | return { ...db, packageName: '@libsql/client', proxy, transactionProxy, migrate: migrateFn }; |
1342 | 1427 | } |
1343 | 1428 |
|
| 1429 | + if (await checkPackage('@tursodatabase/database')) { |
| 1430 | + console.log(withStyle.info(`Using '@tursodatabase/database' driver for database querying`)); |
| 1431 | + const { Database } = await import('@tursodatabase/database'); |
| 1432 | + const { drizzle } = await import('drizzle-orm/tursodatabase/database'); |
| 1433 | + const { migrate } = await import('drizzle-orm/tursodatabase/migrator'); |
| 1434 | + |
| 1435 | + const client = new Database(normaliseSQLiteUrl(credentials.url, '@tursodatabase/database')); |
| 1436 | + const drzl = drizzle({ client }); |
| 1437 | + const migrateFn = async (config: MigrationConfig) => { |
| 1438 | + return migrate(drzl, config); |
| 1439 | + }; |
| 1440 | + |
| 1441 | + const query = async <T>(sql: string, params?: any[]) => { |
| 1442 | + const stmt = client.prepare(sql).bind(preparePGliteParams(params || [])); |
| 1443 | + const res = await stmt.all(); |
| 1444 | + return res as T[]; |
| 1445 | + }; |
| 1446 | + |
| 1447 | + const proxy = async (params: ProxyParams) => { |
| 1448 | + const preparedParams = prepareSqliteParams(params.params || []); |
| 1449 | + const stmt = client.prepare(params.sql).bind(preparedParams); |
| 1450 | + |
| 1451 | + return stmt.raw(params.mode === 'array').all(); |
| 1452 | + }; |
| 1453 | + |
| 1454 | + const transactionProxy: TransactionProxy = async (queries) => { |
| 1455 | + const results: (any[] | Error)[] = []; |
| 1456 | + try { |
| 1457 | + const tx = client.transaction(async () => { |
| 1458 | + for (const query of queries) { |
| 1459 | + const result = await client.prepare(query.sql).all(); |
| 1460 | + results.push(result); |
| 1461 | + } |
| 1462 | + }); |
| 1463 | + await tx(); |
| 1464 | + } catch (error) { |
| 1465 | + results.push(error as Error); |
| 1466 | + } |
| 1467 | + return results; |
| 1468 | + }; |
| 1469 | + |
| 1470 | + return { |
| 1471 | + query, |
| 1472 | + packageName: '@tursodatabase/database', |
| 1473 | + proxy, |
| 1474 | + transactionProxy, |
| 1475 | + migrate: migrateFn, |
| 1476 | + run: async (query: string) => { |
| 1477 | + await client.exec(query).catch((e) => { |
| 1478 | + throw new QueryError(e, query, []); |
| 1479 | + }); |
| 1480 | + }, |
| 1481 | + }; |
| 1482 | + } |
| 1483 | + |
1344 | 1484 | if (await checkPackage('better-sqlite3')) { |
1345 | 1485 | const { default: Database } = await import('better-sqlite3'); |
1346 | 1486 | const { drizzle } = await import('drizzle-orm/better-sqlite3'); |
|
0 commit comments