Update to latest emscripten, add new methods
This commit is contained in:
Родитель
1948f8873c
Коммит
24f88259dd
|
@ -4,3 +4,4 @@ temp/
|
|||
debug/
|
||||
dist/
|
||||
node_modules/
|
||||
/package-lock.json
|
||||
|
|
10
Makefile
10
Makefile
|
@ -6,7 +6,7 @@ SQLITE_AMALGAMATION_ZIP_SHA1 = e9dc46fc55a512b5d2ef97fd548b7ab4beb2d3e3
|
|||
|
||||
EXTENSION_FUNCTIONS = extension-functions.c
|
||||
EXTENSION_FUNCTIONS_URL = http://www.sqlite.org/contrib/download/extension-functions.c?get=25
|
||||
EXTENSION_FUNCTIONS_SHA1 = c68fa706d6d9ff98608044c00212473f9c14892f
|
||||
EXTENSION_FUNCTIONS_SHA1 = da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||
|
||||
# source files
|
||||
|
||||
|
@ -30,9 +30,13 @@ CFLAGS = \
|
|||
|
||||
EMFLAGS = \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s EXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS_JSON) \
|
||||
-s EXPORTED_FUNCTIONS="`cat $(EXPORTED_FUNCTIONS_JSON) | tr '\n' ' '`" \
|
||||
-s RESERVED_FUNCTION_POINTERS=64 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS="[\"cwrap\", \"getValue\", \"setValue\", \"addFunction\", \"removeFunction\", \"UTF8ToString\", \"print\"]" \
|
||||
-s WASM=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s EXPORT_NAME="'SQLite'" \
|
||||
--memory-init-file 0 \
|
||||
--post-js temp/api.js \
|
||||
|
||||
EMFLAGS_DEBUG = \
|
||||
|
@ -41,7 +45,7 @@ EMFLAGS_DEBUG = \
|
|||
|
||||
EMFLAGS_DIST = \
|
||||
-s INLINING_LIMIT=50 \
|
||||
--closure 1 \
|
||||
-s IGNORE_CLOSURE_COMPILER_ERRORS=1 \
|
||||
-O3
|
||||
|
||||
# directories
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/emscripten": "0.0.30",
|
||||
"@types/emscripten": "0.0.31",
|
||||
"typescript": "^2.5.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
"_sqlite3_bind_int",
|
||||
"_sqlite3_bind_parameter_index",
|
||||
"_sqlite3_step",
|
||||
"_sqlite3_last_insert_rowid",
|
||||
"_sqlite3_bind_text16",
|
||||
"_sqlite3_data_count",
|
||||
"_sqlite3_column_double",
|
||||
"_sqlite3_column_text",
|
||||
|
@ -20,6 +22,8 @@
|
|||
"_sqlite3_column_bytes",
|
||||
"_sqlite3_column_type",
|
||||
"_sqlite3_column_name",
|
||||
"_sqlite3_column_count",
|
||||
"_sqlite3_step",
|
||||
"_sqlite3_reset",
|
||||
"_sqlite3_clear_bindings",
|
||||
"_sqlite3_finalize",
|
||||
|
|
|
@ -9,43 +9,64 @@ namespace Module {
|
|||
}
|
||||
|
||||
export class Connection {
|
||||
private pDb: ptr<sqlite3>
|
||||
public readonly "uri": string
|
||||
constructor(public readonly filename: string, options: ConnectionOptions = {}) {
|
||||
const opts = []
|
||||
const vfs = options["vfs"]
|
||||
if (vfs != null) { opts.push(`vfs=${encodeURIComponent(vfs)}`) }
|
||||
const mode = options["mode"]
|
||||
if (mode != null) { opts.push(`mode=${encodeURIComponent(mode)}`) }
|
||||
const cache = options["cache"]
|
||||
if (cache != null) { opts.push(`cache=${encodeURIComponent(cache)}`) }
|
||||
const psow = options["psow"]
|
||||
if (psow != null) { opts.push(`psow=${Number(psow)}`) }
|
||||
const nolock = options["nolock"]
|
||||
if (nolock != null) { opts.push(`nolock=${Number(nolock)}`) }
|
||||
const immutable = options["immutable"]
|
||||
if (immutable != null) { opts.push(`nolock=${Number(immutable)}`) }
|
||||
const q = opts.join("&")
|
||||
const uri = this["uri"] = `file:${encodeURI(filename)}${q ? "?" + q : ""}`
|
||||
private databaseHandle: ptr<sqlite3>
|
||||
|
||||
public readonly uri: string
|
||||
|
||||
constructor(public readonly data: Uint8Array, options: ConnectionOptions = {}) {
|
||||
|
||||
const opts = this.buildOptions(options);
|
||||
const filename = 'dbfile_' + (0xffffffff * Math.random() >>> 0);
|
||||
const uri = this.uri = `file:${encodeURI(filename)}${opts ? "?" + opts : ""}`
|
||||
|
||||
const stack = stackSave()
|
||||
const ppDb = stackAlloc<ptr<sqlite3>>(4)
|
||||
const code = sqlite3_open(uri, ppDb)
|
||||
const pDb = Module["getValue"](ppDb, "*")
|
||||
const databaseHandle = Module["getValue"](ppDb, "*")
|
||||
stackRestore(stack)
|
||||
|
||||
if (code) { throw new SQLiteError(code) }
|
||||
|
||||
this.pDb = pDb as ptr<sqlite3>
|
||||
if (code) {
|
||||
throw new SQLiteError(code)
|
||||
}
|
||||
|
||||
"close"(): void {
|
||||
const code = sqlite3_close_v2(this.pDb)
|
||||
if (code) { throw new SQLiteError(code) }
|
||||
delete this.pDb
|
||||
this.databaseHandle = databaseHandle as ptr<sqlite3>
|
||||
}
|
||||
|
||||
"exec"<T>(
|
||||
public get id(): number {
|
||||
return this.databaseHandle as number;
|
||||
}
|
||||
|
||||
close(): void {
|
||||
const code = sqlite3_close_v2(this.databaseHandle)
|
||||
if (code) { throw new SQLiteError(code) }
|
||||
delete this.databaseHandle
|
||||
}
|
||||
|
||||
preparev2(sql: string) : Statement {
|
||||
|
||||
const stack = stackSave()
|
||||
const ppStatement = stackAlloc<ptr<sqlite3>>(4)
|
||||
const code = sqlite3_prepare2(this.databaseHandle, sql, -1, ppStatement, <ptr<sqlite3>>0);
|
||||
|
||||
const statementHandle = Module["getValue"](ppStatement, "*")
|
||||
stackRestore(stack)
|
||||
|
||||
if (code) {
|
||||
throw new SQLiteError(code)
|
||||
}
|
||||
|
||||
return new Statement(statementHandle as ptr<sqlite3>);
|
||||
}
|
||||
|
||||
getChanges(): number {
|
||||
return sqlite3_changes(this.databaseHandle);
|
||||
}
|
||||
|
||||
getLastInsertRowId(): number {
|
||||
return sqlite3_last_insert_rowid(this.databaseHandle);
|
||||
}
|
||||
|
||||
exec<T>(
|
||||
sql: string,
|
||||
callback?: ((columns: {[k in string]: string}) => T | undefined),
|
||||
): T | undefined {
|
||||
|
@ -74,7 +95,7 @@ namespace Module {
|
|||
|
||||
const stack = stackSave()
|
||||
const ppErrmsg = stackAlloc(4) as ptr<sqlite3_ptr<string>>
|
||||
const code = sqlite3_exec(this.pDb, sql, pCallback, 0, ppErrmsg)
|
||||
const code = sqlite3_exec(this.databaseHandle, sql, pCallback, 0, ppErrmsg)
|
||||
const pErrmsg = Module["getValue"](ppErrmsg, "*")
|
||||
stackRestore(stack)
|
||||
|
||||
|
@ -88,5 +109,23 @@ namespace Module {
|
|||
if (code) { throw new SQLiteError(code, errmsg) }
|
||||
return result
|
||||
}
|
||||
|
||||
private buildOptions(options: ConnectionOptions): string {
|
||||
const opts = []
|
||||
const vfs = options["vfs"]
|
||||
if (vfs != null) { opts.push(`vfs=${encodeURIComponent(vfs)}`) }
|
||||
const mode = options["mode"]
|
||||
if (mode != null) { opts.push(`mode=${encodeURIComponent(mode)}`) }
|
||||
const cache = options["cache"]
|
||||
if (cache != null) { opts.push(`cache=${encodeURIComponent(cache)}`) }
|
||||
const psow = options["psow"]
|
||||
if (psow != null) { opts.push(`psow=${Number(psow)}`) }
|
||||
const nolock = options["nolock"]
|
||||
if (nolock != null) { opts.push(`nolock=${Number(nolock)}`) }
|
||||
const immutable = options["immutable"]
|
||||
if (immutable != null) { opts.push(`nolock=${Number(immutable)}`) }
|
||||
|
||||
return opts.join("&")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
namespace Module {
|
||||
export declare var onRuntimeInitialized: () => void
|
||||
Module["onRuntimeInitialized"] = function () {
|
||||
const conn1 = new Connection("db", { mode: "memory", cache: "shared" })
|
||||
const conn2 = new Connection("db", { mode: "memory", cache: "shared" })
|
||||
Module["print"](conn1.uri)
|
||||
conn1.exec(`create table t (x, y); insert into t values (1, 2), (3, 4);`)
|
||||
conn2.exec(`select * from t;`, (columns) => {
|
||||
Module["print"](JSON.stringify(columns))
|
||||
})
|
||||
|
||||
conn1.close()
|
||||
conn2.close()
|
||||
}
|
||||
}
|
|
@ -13,19 +13,9 @@ namespace Module {
|
|||
export declare function UTF8ToString(ptr: ptr<string>): string
|
||||
export declare function stringToUTF8(str: string, outPtr: ptr<string>, maxBytesToWrite: number): void
|
||||
|
||||
export const stackSave
|
||||
: () => stack
|
||||
= Module["Runtime"].stackSave
|
||||
export const stackRestore
|
||||
: (stack: stack) => void
|
||||
= Module["Runtime"].stackRestore
|
||||
export const stackAlloc
|
||||
: <T extends sized>(size: number & T["__size__"]) => ptr<T>
|
||||
= Module["Runtime"].stackAlloc
|
||||
export const addFunction
|
||||
: <T extends Function>(func: T) => ptr<T>
|
||||
= Module["Runtime"].addFunction
|
||||
export const removeFunction
|
||||
: <T extends Function>(ptr: ptr<T>) => void
|
||||
= Module["Runtime"].removeFunction
|
||||
export declare function stackSave(): stack;
|
||||
export declare function stackRestore(stack: stack): void;
|
||||
export declare function stackAlloc<T extends sized>(size: number & T["__size__"]): ptr<T>;
|
||||
export declare function addFunction<T extends Function>(func: T): ptr<T>;
|
||||
export declare function removeFunction<T extends Function>(ptr: ptr<T>): void;
|
||||
}
|
|
@ -2,9 +2,47 @@ namespace Module {
|
|||
export const sqlite3_open
|
||||
: (filename: string, ppDb: ptr<ptr<sqlite3>>) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_open", "number", ["string", "number"])
|
||||
|
||||
export const sqlite3_last_insert_rowid
|
||||
: (pDb: ptr<sqlite3>) => number
|
||||
= Module["cwrap"]("sqlite3_last_insert_rowid", "number", ["number"])
|
||||
|
||||
export const sqlite3_prepare2
|
||||
: (pDb: ptr<sqlite3>, sql: string, numBytes: number, pStatement: ptr<ptr<sqlite3>>, pzTail: ptr<sqlite3>) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_prepare_v2", "number", ["number", "string", "number", "number", "number"])
|
||||
|
||||
export const sqlite3_column_count
|
||||
: (pStatement: ptr<sqlite3>) => number
|
||||
= Module["cwrap"]("sqlite3_column_count", "number", ["number"])
|
||||
|
||||
export const sqlite3_step
|
||||
: (pStatement: ptr<sqlite3>) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_step", "number", ["number"])
|
||||
|
||||
export const sqlite3_finalize
|
||||
: (pStatement: ptr<sqlite3>) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_finalize", "number", ["number"])
|
||||
|
||||
export const sqlite3_reset
|
||||
: (pStatement: ptr<sqlite3>) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_reset", "number", ["number"])
|
||||
|
||||
export const sqlite3_column_name
|
||||
: (pStatement: ptr<sqlite3>, index: number) => string
|
||||
= Module["cwrap"]("sqlite3_column_name", "number", ["number", "number"])
|
||||
|
||||
export const sqlite3_bind_text16
|
||||
: (pStatement: ptr<sqlite3>, index: number, val: string, n: number, pFree: ptr<sqlite3>) => number
|
||||
= Module["cwrap"]("sqlite3_bind_text16", "number", ["number", "number", "string", "number", "number"])
|
||||
|
||||
export const sqlite3_changes
|
||||
: (pStatement: ptr<sqlite3>) => number
|
||||
= Module["cwrap"]("sqlite3_changes", "number", ["number"])
|
||||
|
||||
export const sqlite3_close_v2
|
||||
: (pDb: ptr<sqlite3>) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_close_v2", "number", ["number"])
|
||||
|
||||
export const sqlite3_exec
|
||||
: <T extends number>(
|
||||
pDb: ptr<sqlite3>,
|
||||
|
@ -14,6 +52,7 @@ namespace Module {
|
|||
errmsg: ptr<sqlite3_ptr<string>> | null
|
||||
) => SQLiteResult
|
||||
= Module["cwrap"]("sqlite3_exec", "number", ["number", "string", "number", "number", "number"])
|
||||
|
||||
export const sqlite3_free
|
||||
: (ptr: sqlite3_ptr<any> | 0) => void
|
||||
= Module["cwrap"]("sqlite3_free", "", ["number"])
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
namespace Module {
|
||||
|
||||
export class Statement {
|
||||
private statementHandle: ptr<sqlite3>
|
||||
|
||||
constructor(statementHandle: ptr<sqlite3>) {
|
||||
this.statementHandle = statementHandle;
|
||||
}
|
||||
|
||||
public get id(): number {
|
||||
return this.statementHandle as number;
|
||||
}
|
||||
|
||||
getColumnCount(): number {
|
||||
return sqlite3_column_count(this.statementHandle);
|
||||
}
|
||||
|
||||
step(): SQLiteResult {
|
||||
return sqlite3_step(this.statementHandle);
|
||||
}
|
||||
|
||||
finalize(): SQLiteResult {
|
||||
return sqlite3_finalize(this.statementHandle);
|
||||
}
|
||||
|
||||
reset(): SQLiteResult {
|
||||
return sqlite3_reset(this.statementHandle);
|
||||
}
|
||||
|
||||
getColumnName(index: number): string {
|
||||
return sqlite3_column_name(this.statementHandle, index);
|
||||
}
|
||||
|
||||
bindText(index: number, value: string): number {
|
||||
return sqlite3_bind_text16(this.statementHandle, index, value, -1, <ptr<sqlite3>>0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"alwaysStrict": false,
|
||||
"target": "es5",
|
||||
"target": "es6",
|
||||
"module": "none",
|
||||
"strict": true,
|
||||
"outFile": "temp/api.js",
|
||||
|
|
Загрузка…
Ссылка в новой задаче