summaryrefslogtreecommitdiff
path: root/packages/db/src/runtime/db-client.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/db/src/runtime/db-client.ts')
-rw-r--r--packages/db/src/runtime/db-client.ts142
1 files changed, 99 insertions, 43 deletions
diff --git a/packages/db/src/runtime/db-client.ts b/packages/db/src/runtime/db-client.ts
index bd892a4dd..db8535e15 100644
--- a/packages/db/src/runtime/db-client.ts
+++ b/packages/db/src/runtime/db-client.ts
@@ -15,58 +15,114 @@ export function createLocalDatabaseClient({ dbUrl }: { dbUrl: string }): LibSQLD
return db;
}
+const remoteResultSchema = z.object({
+ columns: z.array(z.string()),
+ columnTypes: z.array(z.string()),
+ rows: z.array(z.array(z.unknown())),
+ rowsAffected: z.number(),
+ lastInsertRowid: z.unknown().optional(),
+});
+
export function createRemoteDatabaseClient(appToken: string, remoteDbURL: string) {
const url = new URL('/db/query', remoteDbURL);
- const db = drizzleProxy(async (sql, parameters, method) => {
- const requestBody: InStatement = { sql, args: parameters };
- const res = await fetch(url, {
- method: 'POST',
- headers: {
- Authorization: `Bearer ${appToken}`,
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(requestBody),
- });
- if (!res.ok) {
- throw new Error(
- `Failed to execute query.\nQuery: ${sql}\nFull error: ${res.status} ${await res.text()}}`
- );
- }
+ const db = drizzleProxy(
+ async (sql, parameters, method) => {
+ const requestBody: InStatement = { sql, args: parameters };
+ const res = await fetch(url, {
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${appToken}`,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(requestBody),
+ });
+ if (!res.ok) {
+ throw new Error(
+ `Failed to execute query.\nQuery: ${sql}\nFull error: ${res.status} ${await res.text()}}`
+ );
+ }
- const queryResultSchema = z.object({
- rows: z.array(z.unknown()),
- });
- let rows: unknown[];
- try {
- const json = await res.json();
- rows = queryResultSchema.parse(json).rows;
- } catch (e) {
- throw new Error(
- `Failed to execute query.\nQuery: ${sql}\nFull error: Unexpected JSON response. ${
- e instanceof Error ? e.message : String(e)
- }`
- );
- }
+ let remoteResult: z.infer<typeof remoteResultSchema>;
+ try {
+ const json = await res.json();
+ remoteResult = remoteResultSchema.parse(json);
+ } catch (e) {
+ throw new Error(
+ `Failed to execute query.\nQuery: ${sql}\nFull error: Unexpected JSON response. ${
+ e instanceof Error ? e.message : String(e)
+ }`
+ );
+ }
- // Drizzle expects each row as an array of its values
- const rowValues: unknown[][] = [];
+ if (method === 'run') return remoteResult;
- for (const row of rows) {
- if (row != null && typeof row === 'object') {
- rowValues.push(Object.values(row));
+ // Drizzle expects each row as an array of its values
+ const rowValues: unknown[][] = [];
+
+ for (const row of remoteResult.rows) {
+ if (row != null && typeof row === 'object') {
+ rowValues.push(Object.values(row));
+ }
}
- }
- if (method === 'get') {
- return { rows: rowValues[0] };
- }
+ if (method === 'get') {
+ return { rows: rowValues[0] };
+ }
- return { rows: rowValues };
- });
+ return { rows: rowValues };
+ },
+ async (queries) => {
+ const stmts: InStatement[] = queries.map(({ sql, params }) => ({ sql, args: params }));
+ const res = await fetch(url, {
+ method: 'POST',
+ headers: {
+ Authorization: `Bearer ${appToken}`,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(stmts),
+ });
+ if (!res.ok) {
+ throw new Error(
+ `Failed to execute batch queries.\nFull error: ${res.status} ${await res.text()}}`
+ );
+ }
+
+ let remoteResults: z.infer<typeof remoteResultSchema>[];
+ try {
+ const json = await res.json();
+ remoteResults = z.array(remoteResultSchema).parse(json);
+ } catch (e) {
+ throw new Error(
+ `Failed to execute batch queries.\nFull error: Unexpected JSON response. ${
+ e instanceof Error ? e.message : String(e)
+ }`
+ );
+ }
+ let results: any[] = [];
+ for (const [idx, rawResult] of remoteResults.entries()) {
+ if (queries[idx]?.method === 'run') {
+ results.push(rawResult);
+ continue;
+ }
+
+ // Drizzle expects each row as an array of its values
+ const rowValues: unknown[][] = [];
- (db as any).batch = (_drizzleQueries: Array<Promise<unknown>>) => {
- throw new Error('db.batch() is not currently supported.');
- };
+ for (const row of rawResult.rows) {
+ if (row != null && typeof row === 'object') {
+ rowValues.push(Object.values(row));
+ }
+ }
+
+ if (queries[idx]?.method === 'get') {
+ results.push({ rows: rowValues[0] });
+ }
+
+ results.push({ rows: rowValues });
+ }
+ return results;
+ }
+ );
return db;
}