class SQLiteDatabaseClient {
constructor(buffer) {
Object.defineProperties(this, {
_db: {value: Promise.resolve(buffer).then(buffer => new SQLite(buffer))}
});
}
async query(sql, params) {
return (await this._db).exec(sql, params);
}
async queryRow(sql, params) {
return (await this.query(sql, params))[0];
}
async explain(sql, params) {
const rows = (await this.query(`EXPLAIN QUERY PLAN ${sql}`, params));
const text = rows.map(row => row.detail).join("\n");
const pre = document.createElement("PRE");
pre.className = "observablehq--inspect";
pre.appendChild(document.createTextNode(text));
return pre;
}
async describe(object) {
if (object !== undefined) {
const [row] = await this.query(`SELECT * FROM '${object}' LIMIT 1`);
const value = Object.entries(row).map(([column_name, value]) => ({
column_name,
data_type: typeof value === "string" ? "character varying"
: typeof value === "number" ? "integer"
: undefined,
column_default: null,
is_nullable: "YES"
}));
const table = html`
<table>
<thead>
<tr>
<th>column_name</th>
<th>data_type</th>
<th>column_default</th>
<th>is_nullable</th>
</tr>
</thead>
<tbody>
${value.map(({column_name, data_type, column_default, is_nullable}) => html`
<tr>
<td>${column_name}</td>
<td>${data_type}</td>
<td>${column_default}</td>
<td>${is_nullable}</td>
</tr>
`)}
</tbody>
</table>
`;
table.value = value;
return table;
} else {
const rows = await this.query(`SELECT name FROM sqlite_master WHERE type = 'table'`);
const table = html`
<table>
<thead>
<tr>
<th>name</th>
</tr>
</thead>
<tbody>
${rows.map(({name}) => html`
<tr>
<td>${name}</td>
</tr>
`)}
</tbody>
</table>
`;
table.value = [{table_schema: "public", table_name: "names"}];
return table;
}
}
}