michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * This file defines an Sqlite object containing js-ctypes bindings for michael@0: * sqlite3. It should be included from a worker thread using require. michael@0: * michael@0: * It serves the following purposes: michael@0: * - opens libxul; michael@0: * - defines sqlite3 API functions; michael@0: * - defines the necessary sqlite3 types. michael@0: */ michael@0: michael@0: "use strict"; michael@0: michael@0: importScripts("resource://gre/modules/workers/require.js"); michael@0: michael@0: let SharedAll = require( michael@0: "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"); michael@0: michael@0: // Open the sqlite3 library. michael@0: let path; michael@0: if (SharedAll.Constants.Sys.Name === "Android") { michael@0: path = ctypes.libraryName("sqlite3"); michael@0: } else if (SharedAll.Constants.Win) { michael@0: path = ctypes.libraryName("nss3"); michael@0: } else { michael@0: path = SharedAll.Constants.Path.libxul; michael@0: } michael@0: michael@0: let lib; michael@0: try { michael@0: lib = ctypes.open(path); michael@0: } catch (ex) { michael@0: throw new Error("Could not open system library: " + ex.message); michael@0: } michael@0: michael@0: let declareLazyFFI = SharedAll.declareLazyFFI; michael@0: michael@0: let Type = Object.create(SharedAll.Type); michael@0: michael@0: /** michael@0: * Opaque Structure |sqlite3_ptr|. michael@0: * |sqlite3_ptr| is equivalent to a void*. michael@0: */ michael@0: Type.sqlite3_ptr = Type.voidptr_t.withName("sqlite3_ptr"); michael@0: michael@0: /** michael@0: * |sqlite3_stmt_ptr| an instance of an object representing a single SQL michael@0: * statement. michael@0: * |sqlite3_stmt_ptr| is equivalent to a void*. michael@0: */ michael@0: Type.sqlite3_stmt_ptr = Type.voidptr_t.withName("sqlite3_stmt_ptr"); michael@0: michael@0: /** michael@0: * |sqlite3_destructor_ptr| a constant defining a special destructor behaviour. michael@0: * |sqlite3_destructor_ptr| is equivalent to a void*. michael@0: */ michael@0: Type.sqlite3_destructor_ptr = Type.voidptr_t.withName( michael@0: "sqlite3_destructor_ptr"); michael@0: michael@0: /** michael@0: * A C double. michael@0: */ michael@0: Type.double = new SharedAll.Type("double", ctypes.double); michael@0: michael@0: /** michael@0: * |sqlite3_int64| typedef for 64-bit integer. michael@0: */ michael@0: Type.sqlite3_int64 = Type.int64_t.withName("sqlite3_int64"); michael@0: michael@0: /** michael@0: * Sqlite3 constants. michael@0: */ michael@0: let Constants = {}; michael@0: michael@0: /** michael@0: * |SQLITE_STATIC| a special value for the destructor that is passed as an michael@0: * argument to routines like bind_blob, bind_text and bind_text16. It means that michael@0: * the content pointer is constant and will never change and does need to be michael@0: * destroyed. michael@0: */ michael@0: Constants.SQLITE_STATIC = Type.sqlite3_destructor_ptr.implementation(0); michael@0: michael@0: /** michael@0: * |SQLITE_TRANSIENT| a special value for the destructor that is passed as an michael@0: * argument to routines like bind_blob, bind_text and bind_text16. It means that michael@0: * the content will likely change in the near future and that SQLite should make michael@0: * its own private copy of the content before returning. michael@0: */ michael@0: Constants.SQLITE_TRANSIENT = Type.sqlite3_destructor_ptr.implementation(-1); michael@0: michael@0: /** michael@0: * |SQLITE_OK| michael@0: * Successful result. michael@0: */ michael@0: Constants.SQLITE_OK = 0; michael@0: michael@0: /** michael@0: * |SQLITE_ROW| michael@0: * sqlite3_step() has another row ready. michael@0: */ michael@0: Constants.SQLITE_ROW = 100; michael@0: michael@0: /** michael@0: * |SQLITE_DONE| michael@0: * sqlite3_step() has finished executing. michael@0: */ michael@0: Constants.SQLITE_DONE = 101; michael@0: michael@0: let Sqlite3 = { michael@0: Constants: Constants, michael@0: Type: Type michael@0: }; michael@0: michael@0: declareLazyFFI(Sqlite3, "open", lib, "sqlite3_open", null, michael@0: /*return*/ Type.int, michael@0: /*path*/ Type.char.in_ptr, michael@0: /*db handle*/ Type.sqlite3_ptr.out_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "open_v2", lib, "sqlite3_open_v2", null, michael@0: /*return*/ Type.int, michael@0: /*path*/ Type.char.in_ptr, michael@0: /*db handle*/ Type.sqlite3_ptr.out_ptr, michael@0: /*flags*/ Type.int, michael@0: /*VFS*/ Type.char.in_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "close", lib, "sqlite3_close", null, michael@0: /*return*/ Type.int, michael@0: /*db handle*/ Type.sqlite3_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "prepare_v2", lib, "sqlite3_prepare_v2", null, michael@0: /*return*/ Type.int, michael@0: /*db handle*/ Type.sqlite3_ptr, michael@0: /*zSql*/ Type.char.in_ptr, michael@0: /*nByte*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr.out_ptr, michael@0: /*unused*/ Type.cstring.out_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "step", lib, "sqlite3_step", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "finalize", lib, "sqlite3_finalize", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "reset", lib, "sqlite3_reset", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_int", lib, "sqlite3_column_int", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_blob", lib, "sqlite3_column_blob", null, michael@0: /*return*/ Type.voidptr_t, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_bytes", lib, "sqlite3_column_bytes", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_bytes16", lib, "sqlite3_column_bytes16", michael@0: null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_double", lib, "sqlite3_column_double", null, michael@0: /*return*/ Type.double, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_int64", lib, "sqlite3_column_int64", null, michael@0: /*return*/ Type.sqlite3_int64, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_text", lib, "sqlite3_column_text", null, michael@0: /*return*/ Type.cstring, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "column_text16", lib, "sqlite3_column_text16", null, michael@0: /*return*/ Type.wstring, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*col*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_int", lib, "sqlite3_bind_int", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*value*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_int64", lib, "sqlite3_bind_int64", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*value*/ Type.sqlite3_int64); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_double", lib, "sqlite3_bind_double", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*value*/ Type.double); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_null", lib, "sqlite3_bind_null", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_zeroblob", lib, "sqlite3_bind_zeroblob", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*nBytes*/ Type.int); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_text", lib, "sqlite3_bind_text", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*value*/ Type.cstring, michael@0: /*nBytes*/ Type.int, michael@0: /*destructor*/ Type.sqlite3_destructor_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_text16", lib, "sqlite3_bind_text16", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*value*/ Type.wstring, michael@0: /*nBytes*/ Type.int, michael@0: /*destructor*/ Type.sqlite3_destructor_ptr); michael@0: michael@0: declareLazyFFI(Sqlite3, "bind_blob", lib, "sqlite3_bind_blob", null, michael@0: /*return*/ Type.int, michael@0: /*statement*/ Type.sqlite3_stmt_ptr, michael@0: /*index*/ Type.int, michael@0: /*value*/ Type.voidptr_t, michael@0: /*nBytes*/ Type.int, michael@0: /*destructor*/ Type.sqlite3_destructor_ptr); michael@0: michael@0: module.exports = { michael@0: get Constants() { michael@0: return Sqlite3.Constants; michael@0: }, michael@0: get Type() { michael@0: return Sqlite3.Type; michael@0: }, michael@0: get open() { michael@0: return Sqlite3.open; michael@0: }, michael@0: get open_v2() { michael@0: return Sqlite3.open_v2; michael@0: }, michael@0: get close() { michael@0: return Sqlite3.close; michael@0: }, michael@0: get prepare_v2() { michael@0: return Sqlite3.prepare_v2; michael@0: }, michael@0: get step() { michael@0: return Sqlite3.step; michael@0: }, michael@0: get finalize() { michael@0: return Sqlite3.finalize; michael@0: }, michael@0: get reset() { michael@0: return Sqlite3.reset; michael@0: }, michael@0: get column_int() { michael@0: return Sqlite3.column_int; michael@0: }, michael@0: get column_blob() { michael@0: return Sqlite3.column_blob; michael@0: }, michael@0: get column_bytes() { michael@0: return Sqlite3.column_bytes; michael@0: }, michael@0: get column_bytes16() { michael@0: return Sqlite3.column_bytes16; michael@0: }, michael@0: get column_double() { michael@0: return Sqlite3.column_double; michael@0: }, michael@0: get column_int64() { michael@0: return Sqlite3.column_int64; michael@0: }, michael@0: get column_text() { michael@0: return Sqlite3.column_text; michael@0: }, michael@0: get column_text16() { michael@0: return Sqlite3.column_text16; michael@0: }, michael@0: get bind_int() { michael@0: return Sqlite3.bind_int; michael@0: }, michael@0: get bind_int64() { michael@0: return Sqlite3.bind_int64; michael@0: }, michael@0: get bind_double() { michael@0: return Sqlite3.bind_double; michael@0: }, michael@0: get bind_null() { michael@0: return Sqlite3.bind_null; michael@0: }, michael@0: get bind_zeroblob() { michael@0: return Sqlite3.bind_zeroblob; michael@0: }, michael@0: get bind_text() { michael@0: return Sqlite3.bind_text; michael@0: }, michael@0: get bind_text16() { michael@0: return Sqlite3.bind_text16; michael@0: }, michael@0: get bind_blob() { michael@0: return Sqlite3.bind_blob; michael@0: } michael@0: };