This commit is contained in:
udo
2026-06-13 15:10:42 +00:00
parent afaa4dd7c0
commit 5a56d4f39e
14 changed files with 531 additions and 83 deletions
+74 -7
View File
@@ -37,14 +37,81 @@ DValue MySQL::get_pending_result() { return(DValue()); }
String mysql_escape(String raw, char quote_char) { (void)quote_char; return(raw); }
bool SQLite::connect(String path) { this->path = path; connection = 0; set_error(1, WASM_DB_UNAVAILABLE); return(false); }
void SQLite::disconnect() { connection = 0; }
String SQLite::error() { return(error_code ? String(WASM_DB_UNAVAILABLE) : String("")); }
DValue SQLite::query(String q) { (void)q; set_error(1, WASM_DB_UNAVAILABLE); return(DValue()); }
DValue SQLite::query(String q, const StringMap& params) { (void)q; (void)params; set_error(1, WASM_DB_UNAVAILABLE); return(DValue()); }
// sqlite runs host-side (the host links libsqlite and owns the connections in
// a per-workspace handle table). One UCEB1-marshalled hostcall carries
// {op,handle,path,query,params} in and {handle,result,insert_id,affected,
// error_code,statement_info} out. `connection` holds the host handle (>0).
extern "C" size_t uce_host_sqlite(const char* in, size_t in_len, char* out, size_t cap);
static DValue wasm_sqlite_call(DValue request)
{
String encoded = ucb_encode(request);
size_t need = uce_host_sqlite(encoded.data(), encoded.size(), 0, 0);
if(need == 0)
return(DValue());
String buffer(need, 0);
size_t got = uce_host_sqlite(encoded.data(), encoded.size(), &buffer[0], need);
if(got == 0 || got > need)
return(DValue());
DValue response;
String error;
ucb_decode(String(buffer.data(), got), response, &error);
return(response);
}
void SQLite::set_error(s32 code, String info) { error_code = code; statement_info = info; }
bool SQLite::apply_default_pragmas() { return(false); }
bool SQLite::bind_params(void* statement, const StringMap& params) { (void)statement; (void)params; return(false); }
bool SQLite::connect(String path)
{
this->path = path;
DValue request;
request["op"] = "connect";
request["path"] = path;
DValue response = wasm_sqlite_call(request);
u64 handle = response["handle"].to_u64();
connection = (void*)(uintptr_t)handle;
error_code = (s32)response["error_code"].to_s64();
statement_info = response["statement_info"].to_string();
return(handle != 0 && error_code == 0);
}
void SQLite::disconnect()
{
if(connection)
{
DValue request;
request["op"] = "disconnect";
request["handle"] = (f64)(uintptr_t)connection;
wasm_sqlite_call(request);
connection = 0;
}
}
String SQLite::error()
{
return(statement_info);
}
DValue SQLite::query(String q, const StringMap& params)
{
DValue request;
request["op"] = "query";
request["handle"] = (f64)(uintptr_t)connection;
request["query"] = q;
for(auto& entry : params)
request["params"][entry.first] = entry.second;
DValue response = wasm_sqlite_call(request);
insert_id = response["insert_id"].to_u64();
affected_rows = (u32)response["affected"].to_u64();
error_code = (s32)response["error_code"].to_s64();
statement_info = response["statement_info"].to_string();
DValue* result = response.key("result");
return(result ? *result : DValue());
}
DValue SQLite::query(String q) { return(query(q, StringMap())); }
bool SQLite::apply_default_pragmas() { return(true); }
bool SQLite::bind_params(void* statement, const StringMap& params) { (void)statement; (void)params; return(true); }
DValue SQLite::collect_rows(void* statement) { (void)statement; return(DValue()); }
SQLite* sqlite_connect(String path)