Update to latest emscripten, add new methods

This commit is contained in:
Jérôme Laban 2018-09-19 16:40:31 -04:00
Родитель 1948f8873c
Коммит 24f88259dd
10 изменённых файлов: 164 добавлений и 59 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -4,3 +4,4 @@ temp/
debug/
dist/
node_modules/
/package-lock.json

Просмотреть файл

@ -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,10 +30,14 @@ 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 \
--post-js temp/api.js \
-s MODULARIZE=1 \
-s EXPORT_NAME="'SQLite'" \
--memory-init-file 0 \
--post-js temp/api.js \
EMFLAGS_DEBUG = \
-s INLINING_LIMIT=10 \
@ -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) }
if (code) {
throw new SQLiteError(code)
}
this.pDb = pDb as ptr<sqlite3>
this.databaseHandle = databaseHandle as ptr<sqlite3>
}
"close"(): void {
const code = sqlite3_close_v2(this.pDb)
if (code) { throw new SQLiteError(code) }
delete this.pDb
public get id(): number {
return this.databaseHandle as number;
}
"exec"<T>(
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"])

38
src/ts/statement.ts Normal file
Просмотреть файл

@ -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",