import { InStatement, ResultSet } from "https://esm.sh/@libsql/client";
import {
convertSqliteType,
DatabaseHeader,
DatabaseResultSet,
DatabaseRow,
SqliteLikeBaseDriver,
} from "https://esm.sh/@libsqlstudio/gui/driver";
export function transformRawResult(raw: ResultSet): DatabaseResultSet {
const headerSet = new Set();
const headers: DatabaseHeader[] = raw.columns.map((colName, colIdx) => {
const colType = raw.columnTypes[colIdx];
let renameColName = colName;
for (let i = 0; i < 20; i++) {
if (!headerSet.has(renameColName)) break;
renameColName = `__${colName}_${i}`;
}
headerSet.add(renameColName);
return {
name: renameColName,
displayName: colName,
originalType: colType,
type: convertSqliteType(colType),
};
});
const rows = raw.rows.map((r) =>
headers.reduce((a, b, idx) => {
a[b.name] = r[idx];
return a;
}, {} as DatabaseRow)
);
return {
rows,
stat: {
rowsAffected: raw.rowsAffected,
rowsRead: (raw as any).rowsRead ?? null,
rowsWritten: (raw as any).rowsWritten ?? null,
queryDurationMs: (raw as any).queryDurationMS ?? null,
},
headers,
lastInsertRowid: raw.lastInsertRowid === undefined
? undefined
: Number(raw.lastInsertRowid),
};
}
export default class ValtownDriver extends SqliteLikeBaseDriver {
constructor() {
super();
}
async transaction(stmts: InStatement[]): Promise<DatabaseResultSet[]> {
const r = await fetch(`/api/batch`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
statements: stmts,
mode: "write",
}),
});
const json = await r.json();
return json.map(transformRawResult);
}
supportBigInt(): boolean {
return false;
}
async query(stmt: InStatement): Promise<DatabaseResultSet> {
const r = await fetch(`/api/execute`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ statement: stmt }),
});
const json = await r.json();
return transformRawResult(json as ResultSet);
}
close(): void {
}
}