import { TextDecoder } from 'util'; import * as native from '../sqlite3.pure'; import { EmscriptenType } from '../sqlite3.pure'; const NUMBER = 'number'; const STRING = 'string'; const NULL = 'null'; // change to `true` manually for some debugging const DEBUG_SQLITE = false; let cwrap = native.cwrap; if (DEBUG_SQLITE) { cwrap = (name: string, returnType: EmscriptenType, argTypes: EmscriptenType[]) => { const exportedFn = native.cwrap(name, returnType, argTypes); return (...args: any[]) => { console.log(name, ...args); return exportedFn(...args); }; }; } function storeString(string: string) { const len = native.lengthBytesUTF8(string); const ptr = native._malloc(len + 1); native.stringToUTF8(string, ptr, len + 1); return { len, ptr }; } const decoder = new TextDecoder(); function retrieveOutString() { const len = native.getValue(native.lengthOutPtr, 'i32'); const ptr = native.getValue(native.stringOutPtr, 'i32'); const view = new Uint8Array(native.HEAP8.buffer, ptr, len); return decoder.decode(view); } export const sqlite3_open_v2: (file: string, mode: number) => number = cwrap('sqlite3_open_v2_x', NUMBER, [ STRING, NUMBER, ]); export const sqlite3_close_v2: (db: number) => null = cwrap('sqlite3_close_v2_x', NULL, [NUMBER]); export const sqlite3_close: (db: number) => null = cwrap('sqlite3_close_x', NULL, [NUMBER]); export const sqlite3_prepare_v2: (db: number, sql: string) => number = cwrap('sqlite3_prepare_v2_x', NUMBER, [ NUMBER, STRING, ]); export const sqlite3_bind_parameter_index: (stmt: number, sql: string) => number = native.cwrap( 'sqlite3_bind_parameter_index_x', NUMBER, [NUMBER, STRING] ); export const sqlite3_bind_double: (stmt: number, db: number, param: number, value: number) => null = cwrap( 'sqlite3_bind_double_x', NULL, [NUMBER, NUMBER, NUMBER, NUMBER] ); export const sqlite3_bind_int: (stmt: number, db: number, param: number, value: number) => null = cwrap( 'sqlite3_bind_int_x', NULL, [NUMBER, NUMBER, NUMBER, NUMBER] ); const sqlite3_bind_text_x: (stmt: number, db: number, param: number, value: number, len: number) => null = cwrap( 'sqlite3_bind_text_x', NULL, [NUMBER, NUMBER, NUMBER, NUMBER, NUMBER] ); export const sqlite3_bind_text = (stmt: number, db: number, param: number, value: string) => { const { len, ptr } = storeString(value); try { sqlite3_bind_text_x(stmt, db, param, ptr, len); } finally { native._free(ptr); } }; export const sqlite3_bind_null: (stmt: number, db: number, param: number) => null = cwrap('sqlite3_bind_null_x', NULL, [ NUMBER, NUMBER, NUMBER, ]); export const sqlite3_step: (stmt: number, db: number) => boolean = cwrap('sqlite3_step_x', 'boolean', [NUMBER, NUMBER]); export const sqlite3_column_count: (stmt: number) => number = cwrap('sqlite3_column_count_x', NUMBER, [NUMBER]); export const sqlite3_column_type: (stmt: number, index: number) => number = cwrap('sqlite3_column_type_x', NUMBER, [ NUMBER, NUMBER, ]); export const sqlite3_column_name: (stmt: number, index: number) => string = cwrap('sqlite3_column_name_x', STRING, [ NUMBER, NUMBER, ]); export const sqlite3_column_int: (stmt: number, index: number) => number = cwrap('sqlite3_column_int_x', NUMBER, [ NUMBER, NUMBER, ]); export const sqlite3_column_double: (stmt: number, index: number) => number = cwrap('sqlite3_column_double_x', NUMBER, [ NUMBER, NUMBER, ]); const sqlite3_column_text_x: (stmt: number, index: number) => 'null' = cwrap('sqlite3_column_text_x', NULL, [ NUMBER, NUMBER, ]); export const sqlite3_column_text = (stmt: number, index: number) => { sqlite3_column_text_x(stmt, index); return retrieveOutString(); }; export const sqlite3_finalize: (stmt: number, db: number) => null = cwrap('sqlite3_finalize_x', NULL, [NUMBER, NUMBER]); export const sqlite3_finalize_silent: (stmt: number) => null = cwrap('sqlite3_finalize_silent_x', NULL, [NUMBER]); export const sqlite3_reset: (stmt: number, db: number) => null = cwrap('sqlite3_reset_x', NULL, [NUMBER, NUMBER]); export const sqlite3_clear_bindings: (stmt: number) => null = cwrap('sqlite3_clear_bindings_x', NULL, [NUMBER]); export const sqlite3_exec: (db: number, sql: string) => null = cwrap('sqlite3_exec_x', NULL, [NUMBER, STRING]); export const sqlite3_changes: (db: number) => number = cwrap('sqlite3_changes_x', NUMBER, [NUMBER]); export const sqlite3_last_insert_rowid: (db: number) => number = cwrap('sqlite3_last_insert_rowid_x', NUMBER, [NUMBER]);