@homeofthings/sqlite3 6.3.1 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -30
- package/binding.gyp +4 -3
- package/deps/common-sqlite.gypi +1 -1
- package/deps/sqlite-amalgamation-3530000/shell.c +37279 -0
- package/deps/sqlite-amalgamation-3530000/sqlite3.c +268826 -0
- package/deps/sqlite-amalgamation-3530000/sqlite3.h +14335 -0
- package/deps/sqlite-amalgamation-3530000/sqlite3ext.h +739 -0
- package/deps/sqlite3.gyp +4 -32
- package/lib/promise/database.js +14 -2
- package/lib/promise/index.d.ts +1 -0
- package/lib/promise/index.mjs +9 -0
- package/lib/promise/statement.js +4 -0
- package/lib/sqlite3-binding.js +1 -1
- package/lib/sqlite3-callback.js +207 -0
- package/lib/sqlite3.d.ts +25 -0
- package/lib/sqlite3.js +6 -206
- package/lib/sqlite3.mjs +78 -0
- package/package.json +27 -18
- package/prebuilds/darwin-arm64/@homeofthings+sqlite3.glibc.node +0 -0
- package/prebuilds/darwin-x64/@homeofthings+sqlite3.glibc.node +0 -0
- package/prebuilds/linux-arm64/@homeofthings+sqlite3.glibc.node +0 -0
- package/prebuilds/linux-arm64/@homeofthings+sqlite3.musl.node +0 -0
- package/prebuilds/linux-x64/@homeofthings+sqlite3.glibc.node +0 -0
- package/prebuilds/linux-x64/@homeofthings+sqlite3.musl.node +0 -0
- package/prebuilds/win32-x64/@homeofthings+sqlite3.glibc.node +0 -0
- package/src/backup.cc +8 -0
- package/src/macros.h +2 -19
- package/src/node_sqlite3.cc +0 -11
- package/deps/extract.js +0 -19
- package/deps/sqlite-autoconf-3510300.tar.gz +0 -0
package/deps/sqlite3.gyp
CHANGED
|
@@ -47,40 +47,15 @@
|
|
|
47
47
|
},
|
|
48
48
|
|
|
49
49
|
'targets': [
|
|
50
|
-
{
|
|
51
|
-
'target_name': 'action_before_build',
|
|
52
|
-
'type': 'none',
|
|
53
|
-
'hard_dependency': 1,
|
|
54
|
-
'actions': [
|
|
55
|
-
{
|
|
56
|
-
'action_name': 'unpack_sqlite_dep',
|
|
57
|
-
'inputs': [
|
|
58
|
-
'./sqlite-autoconf-<@(sqlite_version).tar.gz'
|
|
59
|
-
],
|
|
60
|
-
'outputs': [
|
|
61
|
-
'<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/sqlite3.c'
|
|
62
|
-
],
|
|
63
|
-
'action': ['node','./extract.js','./sqlite-autoconf-<@(sqlite_version).tar.gz','<(SHARED_INTERMEDIATE_DIR)']
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
'direct_dependent_settings': {
|
|
67
|
-
'include_dirs': [
|
|
68
|
-
'<(SHARED_INTERMEDIATE_DIR)/sqlite-autoconf-<@(sqlite_version)/',
|
|
69
|
-
]
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
50
|
{
|
|
73
51
|
'target_name': 'sqlite3',
|
|
74
52
|
'type': 'static_library',
|
|
75
|
-
'include_dirs': [ '
|
|
76
|
-
'dependencies': [
|
|
77
|
-
'action_before_build'
|
|
78
|
-
],
|
|
53
|
+
'include_dirs': [ './sqlite-amalgamation-<@(sqlite_version)/' ],
|
|
79
54
|
'sources': [
|
|
80
|
-
'
|
|
55
|
+
'./sqlite-amalgamation-<@(sqlite_version)/sqlite3.c'
|
|
81
56
|
],
|
|
82
57
|
'direct_dependent_settings': {
|
|
83
|
-
'include_dirs': [ '
|
|
58
|
+
'include_dirs': [ './sqlite-amalgamation-<@(sqlite_version)/' ],
|
|
84
59
|
'defines': [
|
|
85
60
|
'SQLITE_THREADSAFE=1',
|
|
86
61
|
'HAVE_USLEEP=1',
|
|
@@ -106,9 +81,6 @@
|
|
|
106
81
|
'SQLITE_ENABLE_DBSTAT_VTAB=1',
|
|
107
82
|
'SQLITE_ENABLE_MATH_FUNCTIONS'
|
|
108
83
|
],
|
|
109
|
-
'export_dependent_settings': [
|
|
110
|
-
'action_before_build',
|
|
111
|
-
],
|
|
112
84
|
'conditions': [
|
|
113
85
|
["sqlite_magic != ''", {
|
|
114
86
|
'defines': [
|
|
@@ -118,4 +90,4 @@
|
|
|
118
90
|
],
|
|
119
91
|
}
|
|
120
92
|
]
|
|
121
|
-
}
|
|
93
|
+
}
|
package/lib/promise/database.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const { Database } = require('../sqlite3.js');
|
|
8
|
+
const { Database } = require('../sqlite3-callback.js');
|
|
9
9
|
const { SqliteStatement } = require('./statement');
|
|
10
10
|
const { SqliteBackup } = require('./backup');
|
|
11
11
|
|
|
@@ -324,9 +324,18 @@ class SqliteDatabase {
|
|
|
324
324
|
/**
|
|
325
325
|
* Run callback inside a database transaction
|
|
326
326
|
*
|
|
327
|
+
* IMPORTANT: SQLite provides isolation between different database connections,
|
|
328
|
+
* but NOT between operations on the same connection. If you need concurrent
|
|
329
|
+
* transactions with proper isolation, use separate SqliteDatabase instances.
|
|
330
|
+
*
|
|
331
|
+
* Note: This uses BEGIN IMMEDIATE TRANSACTION which acquires a write lock
|
|
332
|
+
* immediately. If another connection holds a write lock, this will fail
|
|
333
|
+
* with SQLITE_BUSY error.
|
|
334
|
+
*
|
|
327
335
|
* @template T
|
|
328
336
|
* @param {() => Promise<T>} callback - The callback to run in transaction
|
|
329
337
|
* @returns {Promise<T>} A promise that resolves to the callback result
|
|
338
|
+
* @see https://www.sqlite.org/isolation.html
|
|
330
339
|
*/
|
|
331
340
|
async transactionalize(callback) {
|
|
332
341
|
await this.beginTransaction();
|
|
@@ -341,7 +350,10 @@ class SqliteDatabase {
|
|
|
341
350
|
}
|
|
342
351
|
|
|
343
352
|
/**
|
|
344
|
-
* Begin a transaction
|
|
353
|
+
* Begin a transaction using BEGIN IMMEDIATE TRANSACTION
|
|
354
|
+
*
|
|
355
|
+
* This acquires a write lock immediately, preventing deadlocks by
|
|
356
|
+
* failing fast if another connection holds the lock (SQLITE_BUSY).
|
|
345
357
|
*
|
|
346
358
|
* @returns {Promise<SqlRunResult>}
|
|
347
359
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SqliteDatabase, SqliteStatement, SqliteBackup, SqlRunResult } from '../sqlite3';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESM wrapper for the Promise-based API of @homeofthings/sqlite3
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { SqliteDatabase } from '@homeofthings/sqlite3/promise';
|
|
6
|
+
* const db = await SqliteDatabase.open(':memory:');
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { SqliteDatabase, SqliteStatement, SqliteBackup } from './index.js';
|
package/lib/promise/statement.js
CHANGED
|
@@ -60,6 +60,10 @@ class SqliteStatement {
|
|
|
60
60
|
/**
|
|
61
61
|
* Finalizes a prepared statement (freeing any resource used by this statement)
|
|
62
62
|
*
|
|
63
|
+
* IMPORTANT: You MUST finalize all prepared statements before closing the database.
|
|
64
|
+
* If you attempt to close a database with unfinalized statements, you will get:
|
|
65
|
+
* SQLITE_BUSY: unable to close due to unfinalised statements
|
|
66
|
+
*
|
|
63
67
|
* @returns {Promise<void>}
|
|
64
68
|
*/
|
|
65
69
|
finalize() {
|
package/lib/sqlite3-binding.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('
|
|
1
|
+
module.exports = require('node-gyp-build')(require('path').join(__dirname, '..'));
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const sqlite3 = require('./sqlite3-binding.js');
|
|
3
|
+
const EventEmitter = require('events').EventEmitter;
|
|
4
|
+
module.exports = exports = sqlite3;
|
|
5
|
+
|
|
6
|
+
function normalizeMethod (fn) {
|
|
7
|
+
return function (sql) {
|
|
8
|
+
let errBack;
|
|
9
|
+
const args = Array.prototype.slice.call(arguments, 1);
|
|
10
|
+
|
|
11
|
+
if (typeof args[args.length - 1] === 'function') {
|
|
12
|
+
const callback = args[args.length - 1];
|
|
13
|
+
errBack = function(err) {
|
|
14
|
+
if (err) {
|
|
15
|
+
callback(err);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const statement = new Statement(this, sql, errBack);
|
|
20
|
+
return fn.call(this, statement, args);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function inherits(target, source) {
|
|
25
|
+
for (const k in source.prototype)
|
|
26
|
+
target.prototype[k] = source.prototype[k];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
sqlite3.cached = {
|
|
30
|
+
Database: function(file, a, b) {
|
|
31
|
+
if (file === '' || file === ':memory:') {
|
|
32
|
+
// Don't cache special databases.
|
|
33
|
+
return new Database(file, a, b);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let db;
|
|
37
|
+
file = path.resolve(file);
|
|
38
|
+
|
|
39
|
+
if (!sqlite3.cached.objects[file]) {
|
|
40
|
+
db = sqlite3.cached.objects[file] = new Database(file, a, b);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Make sure the callback is called.
|
|
44
|
+
db = sqlite3.cached.objects[file];
|
|
45
|
+
const callback = (typeof a === 'number') ? b : a;
|
|
46
|
+
if (typeof callback === 'function') {
|
|
47
|
+
function cb() { callback.call(db, null); }
|
|
48
|
+
if (db.open) process.nextTick(cb);
|
|
49
|
+
else db.once('open', cb);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return db;
|
|
54
|
+
},
|
|
55
|
+
objects: {}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
const Database = sqlite3.Database;
|
|
60
|
+
const Statement = sqlite3.Statement;
|
|
61
|
+
const Backup = sqlite3.Backup;
|
|
62
|
+
|
|
63
|
+
inherits(Database, EventEmitter);
|
|
64
|
+
inherits(Statement, EventEmitter);
|
|
65
|
+
inherits(Backup, EventEmitter);
|
|
66
|
+
|
|
67
|
+
// Database#prepare(sql, [bind1, bind2, ...], [callback])
|
|
68
|
+
Database.prototype.prepare = normalizeMethod(function(statement, params) {
|
|
69
|
+
return params.length
|
|
70
|
+
? statement.bind.apply(statement, params)
|
|
71
|
+
: statement;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Database#run(sql, [bind1, bind2, ...], [callback])
|
|
75
|
+
Database.prototype.run = normalizeMethod(function(statement, params) {
|
|
76
|
+
statement.run.apply(statement, params).finalize();
|
|
77
|
+
return this;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Database#get(sql, [bind1, bind2, ...], [callback])
|
|
81
|
+
Database.prototype.get = normalizeMethod(function(statement, params) {
|
|
82
|
+
statement.get.apply(statement, params).finalize();
|
|
83
|
+
return this;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Database#all(sql, [bind1, bind2, ...], [callback])
|
|
87
|
+
Database.prototype.all = normalizeMethod(function(statement, params) {
|
|
88
|
+
statement.all.apply(statement, params).finalize();
|
|
89
|
+
return this;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Database#each(sql, [bind1, bind2, ...], [callback], [complete])
|
|
93
|
+
Database.prototype.each = normalizeMethod(function(statement, params) {
|
|
94
|
+
statement.each.apply(statement, params).finalize();
|
|
95
|
+
return this;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
Database.prototype.map = normalizeMethod(function(statement, params) {
|
|
99
|
+
statement.map.apply(statement, params).finalize();
|
|
100
|
+
return this;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Database#backup(filename, [callback])
|
|
104
|
+
// Database#backup(filename, destName, sourceName, filenameIsDest, [callback])
|
|
105
|
+
Database.prototype.backup = function() {
|
|
106
|
+
let backup;
|
|
107
|
+
if (arguments.length <= 2) {
|
|
108
|
+
// By default, we write the main database out to the main database of the named file.
|
|
109
|
+
// This is the most likely use of the backup api.
|
|
110
|
+
backup = new Backup(this, arguments[0], 'main', 'main', true, arguments[1]);
|
|
111
|
+
} else {
|
|
112
|
+
// Otherwise, give the user full control over the sqlite3_backup_init arguments.
|
|
113
|
+
backup = new Backup(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
|
|
114
|
+
}
|
|
115
|
+
// Per the sqlite docs, exclude the following errors as non-fatal by default.
|
|
116
|
+
backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED];
|
|
117
|
+
return backup;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
Statement.prototype.map = function() {
|
|
121
|
+
const params = Array.prototype.slice.call(arguments);
|
|
122
|
+
const callback = params.pop();
|
|
123
|
+
params.push(function(err, rows) {
|
|
124
|
+
if (err) return callback(err);
|
|
125
|
+
const result = {};
|
|
126
|
+
if (rows.length) {
|
|
127
|
+
const keys = Object.keys(rows[0]);
|
|
128
|
+
const key = keys[0];
|
|
129
|
+
if (keys.length > 2) {
|
|
130
|
+
// Value is an object
|
|
131
|
+
for (let i = 0; i < rows.length; i++) {
|
|
132
|
+
result[rows[i][key]] = rows[i];
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
const value = keys[1];
|
|
136
|
+
// Value is a plain value
|
|
137
|
+
for (let i = 0; i < rows.length; i++) {
|
|
138
|
+
result[rows[i][key]] = rows[i][value];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
callback(err, result);
|
|
143
|
+
});
|
|
144
|
+
return this.all.apply(this, params);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
let isVerbose = false;
|
|
148
|
+
|
|
149
|
+
const supportedEvents = [ 'trace', 'profile', 'change' ];
|
|
150
|
+
|
|
151
|
+
Database.prototype.addListener = Database.prototype.on = function(type) {
|
|
152
|
+
const val = EventEmitter.prototype.addListener.apply(this, arguments);
|
|
153
|
+
if (supportedEvents.indexOf(type) >= 0) {
|
|
154
|
+
this.configure(type, true);
|
|
155
|
+
}
|
|
156
|
+
return val;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
Database.prototype.removeListener = function(type) {
|
|
160
|
+
const val = EventEmitter.prototype.removeListener.apply(this, arguments);
|
|
161
|
+
if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
|
|
162
|
+
this.configure(type, false);
|
|
163
|
+
}
|
|
164
|
+
return val;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
Database.prototype.removeAllListeners = function(type) {
|
|
168
|
+
const val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
|
|
169
|
+
if (supportedEvents.indexOf(type) >= 0) {
|
|
170
|
+
this.configure(type, false);
|
|
171
|
+
}
|
|
172
|
+
return val;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Save the stack trace over EIO callbacks.
|
|
176
|
+
sqlite3.verbose = function() {
|
|
177
|
+
if (!isVerbose) {
|
|
178
|
+
const trace = require('./trace');
|
|
179
|
+
[
|
|
180
|
+
'prepare',
|
|
181
|
+
'get',
|
|
182
|
+
'run',
|
|
183
|
+
'all',
|
|
184
|
+
'each',
|
|
185
|
+
'map',
|
|
186
|
+
'close',
|
|
187
|
+
'exec'
|
|
188
|
+
].forEach(function (name) {
|
|
189
|
+
trace.extendTrace(Database.prototype, name);
|
|
190
|
+
});
|
|
191
|
+
[
|
|
192
|
+
'bind',
|
|
193
|
+
'get',
|
|
194
|
+
'run',
|
|
195
|
+
'all',
|
|
196
|
+
'each',
|
|
197
|
+
'map',
|
|
198
|
+
'reset',
|
|
199
|
+
'finalize',
|
|
200
|
+
].forEach(function (name) {
|
|
201
|
+
trace.extendTrace(Statement.prototype, name);
|
|
202
|
+
});
|
|
203
|
+
isVerbose = true;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return sqlite3;
|
|
207
|
+
};
|
package/lib/sqlite3.d.ts
CHANGED
|
@@ -220,6 +220,11 @@ export interface sqlite3 {
|
|
|
220
220
|
verbose(): this;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
// Default export for ESM consumers
|
|
224
|
+
// CJS: const sqlite3 = require('@homeofthings/sqlite3')
|
|
225
|
+
// ESM: import sqlite3 from '@homeofthings/sqlite3'
|
|
226
|
+
export default sqlite3;
|
|
227
|
+
|
|
223
228
|
// Promise-based wrapper classes
|
|
224
229
|
|
|
225
230
|
/**
|
|
@@ -265,7 +270,22 @@ export class SqliteDatabase {
|
|
|
265
270
|
serialize(callback?: () => void): void;
|
|
266
271
|
parallelize(callback?: () => void): void;
|
|
267
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Run callback inside a database transaction.
|
|
275
|
+
*
|
|
276
|
+
* IMPORTANT: SQLite provides isolation between different database connections,
|
|
277
|
+
* but NOT between operations on the same connection. For concurrent transactions
|
|
278
|
+
* with proper isolation, use separate SqliteDatabase instances.
|
|
279
|
+
*
|
|
280
|
+
* Uses BEGIN IMMEDIATE TRANSACTION which acquires a write lock immediately.
|
|
281
|
+
* @see https://www.sqlite.org/isolation.html
|
|
282
|
+
*/
|
|
268
283
|
transactionalize<T>(callback: () => Promise<T>): Promise<T>;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Begin a transaction using BEGIN IMMEDIATE TRANSACTION.
|
|
287
|
+
* Acquires write lock immediately - fails with SQLITE_BUSY if lock unavailable.
|
|
288
|
+
*/
|
|
269
289
|
beginTransaction(): Promise<void>;
|
|
270
290
|
commitTransaction(): Promise<void>;
|
|
271
291
|
rollbackTransaction(): Promise<void>;
|
|
@@ -300,6 +320,11 @@ export class SqliteStatement {
|
|
|
300
320
|
callback?: (err: Error | null, row: T) => void,
|
|
301
321
|
): Promise<number>;
|
|
302
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Finalizes the statement.
|
|
325
|
+
* IMPORTANT: You MUST finalize all prepared statements before closing the database.
|
|
326
|
+
* Otherwise you will get SQLITE_BUSY: unable to close due to unfinalised statements
|
|
327
|
+
*/
|
|
303
328
|
finalize(): Promise<void>;
|
|
304
329
|
}
|
|
305
330
|
|
package/lib/sqlite3.js
CHANGED
|
@@ -1,213 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
module.exports = exports = sqlite3;
|
|
1
|
+
// Main entry point: re-exports the callback API and adds Promise-based wrapper classes.
|
|
2
|
+
// The callback API is in sqlite3-callback.js to avoid circular dependencies
|
|
3
|
+
// (promise modules require sqlite3-callback.js, not this file).
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
return function (sql) {
|
|
8
|
-
let errBack;
|
|
9
|
-
const args = Array.prototype.slice.call(arguments, 1);
|
|
10
|
-
|
|
11
|
-
if (typeof args[args.length - 1] === 'function') {
|
|
12
|
-
const callback = args[args.length - 1];
|
|
13
|
-
errBack = function(err) {
|
|
14
|
-
if (err) {
|
|
15
|
-
callback(err);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
const statement = new Statement(this, sql, errBack);
|
|
20
|
-
return fn.call(this, statement, args);
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function inherits(target, source) {
|
|
25
|
-
for (const k in source.prototype)
|
|
26
|
-
target.prototype[k] = source.prototype[k];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
sqlite3.cached = {
|
|
30
|
-
Database: function(file, a, b) {
|
|
31
|
-
if (file === '' || file === ':memory:') {
|
|
32
|
-
// Don't cache special databases.
|
|
33
|
-
return new Database(file, a, b);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let db;
|
|
37
|
-
file = path.resolve(file);
|
|
38
|
-
|
|
39
|
-
if (!sqlite3.cached.objects[file]) {
|
|
40
|
-
db = sqlite3.cached.objects[file] = new Database(file, a, b);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
// Make sure the callback is called.
|
|
44
|
-
db = sqlite3.cached.objects[file];
|
|
45
|
-
const callback = (typeof a === 'number') ? b : a;
|
|
46
|
-
if (typeof callback === 'function') {
|
|
47
|
-
function cb() { callback.call(db, null); }
|
|
48
|
-
if (db.open) process.nextTick(cb);
|
|
49
|
-
else db.once('open', cb);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return db;
|
|
54
|
-
},
|
|
55
|
-
objects: {}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const Database = sqlite3.Database;
|
|
60
|
-
const Statement = sqlite3.Statement;
|
|
61
|
-
const Backup = sqlite3.Backup;
|
|
62
|
-
|
|
63
|
-
inherits(Database, EventEmitter);
|
|
64
|
-
inherits(Statement, EventEmitter);
|
|
65
|
-
inherits(Backup, EventEmitter);
|
|
66
|
-
|
|
67
|
-
// Database#prepare(sql, [bind1, bind2, ...], [callback])
|
|
68
|
-
Database.prototype.prepare = normalizeMethod(function(statement, params) {
|
|
69
|
-
return params.length
|
|
70
|
-
? statement.bind.apply(statement, params)
|
|
71
|
-
: statement;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// Database#run(sql, [bind1, bind2, ...], [callback])
|
|
75
|
-
Database.prototype.run = normalizeMethod(function(statement, params) {
|
|
76
|
-
statement.run.apply(statement, params).finalize();
|
|
77
|
-
return this;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Database#get(sql, [bind1, bind2, ...], [callback])
|
|
81
|
-
Database.prototype.get = normalizeMethod(function(statement, params) {
|
|
82
|
-
statement.get.apply(statement, params).finalize();
|
|
83
|
-
return this;
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Database#all(sql, [bind1, bind2, ...], [callback])
|
|
87
|
-
Database.prototype.all = normalizeMethod(function(statement, params) {
|
|
88
|
-
statement.all.apply(statement, params).finalize();
|
|
89
|
-
return this;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Database#each(sql, [bind1, bind2, ...], [callback], [complete])
|
|
93
|
-
Database.prototype.each = normalizeMethod(function(statement, params) {
|
|
94
|
-
statement.each.apply(statement, params).finalize();
|
|
95
|
-
return this;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
Database.prototype.map = normalizeMethod(function(statement, params) {
|
|
99
|
-
statement.map.apply(statement, params).finalize();
|
|
100
|
-
return this;
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Database#backup(filename, [callback])
|
|
104
|
-
// Database#backup(filename, destName, sourceName, filenameIsDest, [callback])
|
|
105
|
-
Database.prototype.backup = function() {
|
|
106
|
-
let backup;
|
|
107
|
-
if (arguments.length <= 2) {
|
|
108
|
-
// By default, we write the main database out to the main database of the named file.
|
|
109
|
-
// This is the most likely use of the backup api.
|
|
110
|
-
backup = new Backup(this, arguments[0], 'main', 'main', true, arguments[1]);
|
|
111
|
-
} else {
|
|
112
|
-
// Otherwise, give the user full control over the sqlite3_backup_init arguments.
|
|
113
|
-
backup = new Backup(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
|
|
114
|
-
}
|
|
115
|
-
// Per the sqlite docs, exclude the following errors as non-fatal by default.
|
|
116
|
-
backup.retryErrors = [sqlite3.BUSY, sqlite3.LOCKED];
|
|
117
|
-
return backup;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
Statement.prototype.map = function() {
|
|
121
|
-
const params = Array.prototype.slice.call(arguments);
|
|
122
|
-
const callback = params.pop();
|
|
123
|
-
params.push(function(err, rows) {
|
|
124
|
-
if (err) return callback(err);
|
|
125
|
-
const result = {};
|
|
126
|
-
if (rows.length) {
|
|
127
|
-
const keys = Object.keys(rows[0]);
|
|
128
|
-
const key = keys[0];
|
|
129
|
-
if (keys.length > 2) {
|
|
130
|
-
// Value is an object
|
|
131
|
-
for (let i = 0; i < rows.length; i++) {
|
|
132
|
-
result[rows[i][key]] = rows[i];
|
|
133
|
-
}
|
|
134
|
-
} else {
|
|
135
|
-
const value = keys[1];
|
|
136
|
-
// Value is a plain value
|
|
137
|
-
for (let i = 0; i < rows.length; i++) {
|
|
138
|
-
result[rows[i][key]] = rows[i][value];
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
callback(err, result);
|
|
143
|
-
});
|
|
144
|
-
return this.all.apply(this, params);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
let isVerbose = false;
|
|
148
|
-
|
|
149
|
-
const supportedEvents = [ 'trace', 'profile', 'change' ];
|
|
150
|
-
|
|
151
|
-
Database.prototype.addListener = Database.prototype.on = function(type) {
|
|
152
|
-
const val = EventEmitter.prototype.addListener.apply(this, arguments);
|
|
153
|
-
if (supportedEvents.indexOf(type) >= 0) {
|
|
154
|
-
this.configure(type, true);
|
|
155
|
-
}
|
|
156
|
-
return val;
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
Database.prototype.removeListener = function(type) {
|
|
160
|
-
const val = EventEmitter.prototype.removeListener.apply(this, arguments);
|
|
161
|
-
if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
|
|
162
|
-
this.configure(type, false);
|
|
163
|
-
}
|
|
164
|
-
return val;
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
Database.prototype.removeAllListeners = function(type) {
|
|
168
|
-
const val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
|
|
169
|
-
if (supportedEvents.indexOf(type) >= 0) {
|
|
170
|
-
this.configure(type, false);
|
|
171
|
-
}
|
|
172
|
-
return val;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Save the stack trace over EIO callbacks.
|
|
176
|
-
sqlite3.verbose = function() {
|
|
177
|
-
if (!isVerbose) {
|
|
178
|
-
const trace = require('./trace');
|
|
179
|
-
[
|
|
180
|
-
'prepare',
|
|
181
|
-
'get',
|
|
182
|
-
'run',
|
|
183
|
-
'all',
|
|
184
|
-
'each',
|
|
185
|
-
'map',
|
|
186
|
-
'close',
|
|
187
|
-
'exec'
|
|
188
|
-
].forEach(function (name) {
|
|
189
|
-
trace.extendTrace(Database.prototype, name);
|
|
190
|
-
});
|
|
191
|
-
[
|
|
192
|
-
'bind',
|
|
193
|
-
'get',
|
|
194
|
-
'run',
|
|
195
|
-
'all',
|
|
196
|
-
'each',
|
|
197
|
-
'map',
|
|
198
|
-
'reset',
|
|
199
|
-
'finalize',
|
|
200
|
-
].forEach(function (name) {
|
|
201
|
-
trace.extendTrace(Statement.prototype, name);
|
|
202
|
-
});
|
|
203
|
-
isVerbose = true;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return sqlite3;
|
|
207
|
-
};
|
|
5
|
+
const sqlite3 = require('./sqlite3-callback.js');
|
|
208
6
|
|
|
209
7
|
// Export Promise-based wrapper classes
|
|
210
8
|
const { SqliteDatabase, SqliteStatement, SqliteBackup } = require('./promise');
|
|
211
9
|
sqlite3.SqliteDatabase = SqliteDatabase;
|
|
212
10
|
sqlite3.SqliteStatement = SqliteStatement;
|
|
213
11
|
sqlite3.SqliteBackup = SqliteBackup;
|
|
12
|
+
|
|
13
|
+
module.exports = exports = sqlite3;
|
package/lib/sqlite3.mjs
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESM wrapper for @homeofthings/sqlite3
|
|
3
|
+
*
|
|
4
|
+
* This module provides ESM (ECMAScript Module) entry points that delegate
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* // Default import
|
|
8
|
+
* import sqlite3 from '@homeofthings/sqlite3';
|
|
9
|
+
*
|
|
10
|
+
* // Named imports
|
|
11
|
+
* import { Database, OPEN_CREATE } from '@homeofthings/sqlite3';
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import sqlite3 from './sqlite3.js';
|
|
15
|
+
|
|
16
|
+
export default sqlite3;
|
|
17
|
+
|
|
18
|
+
export const {
|
|
19
|
+
OPEN_READONLY,
|
|
20
|
+
OPEN_READWRITE,
|
|
21
|
+
OPEN_CREATE,
|
|
22
|
+
OPEN_FULLMUTEX,
|
|
23
|
+
OPEN_SHAREDCACHE,
|
|
24
|
+
OPEN_PRIVATECACHE,
|
|
25
|
+
OPEN_URI,
|
|
26
|
+
VERSION,
|
|
27
|
+
SOURCE_ID,
|
|
28
|
+
VERSION_NUMBER,
|
|
29
|
+
OK,
|
|
30
|
+
ERROR,
|
|
31
|
+
INTERNAL,
|
|
32
|
+
PERM,
|
|
33
|
+
ABORT,
|
|
34
|
+
BUSY,
|
|
35
|
+
LOCKED,
|
|
36
|
+
NOMEM,
|
|
37
|
+
READONLY,
|
|
38
|
+
INTERRUPT,
|
|
39
|
+
IOERR,
|
|
40
|
+
CORRUPT,
|
|
41
|
+
NOTFOUND,
|
|
42
|
+
FULL,
|
|
43
|
+
CANTOPEN,
|
|
44
|
+
PROTOCOL,
|
|
45
|
+
EMPTY,
|
|
46
|
+
SCHEMA,
|
|
47
|
+
TOOBIG,
|
|
48
|
+
CONSTRAINT,
|
|
49
|
+
MISMATCH,
|
|
50
|
+
MISUSE,
|
|
51
|
+
NOLFS,
|
|
52
|
+
AUTH,
|
|
53
|
+
FORMAT,
|
|
54
|
+
RANGE,
|
|
55
|
+
NOTADB,
|
|
56
|
+
LIMIT_LENGTH,
|
|
57
|
+
LIMIT_SQL_LENGTH,
|
|
58
|
+
LIMIT_COLUMN,
|
|
59
|
+
LIMIT_EXPR_DEPTH,
|
|
60
|
+
LIMIT_COMPOUND_SELECT,
|
|
61
|
+
LIMIT_VDBE_OP,
|
|
62
|
+
LIMIT_FUNCTION_ARG,
|
|
63
|
+
LIMIT_ATTACHED,
|
|
64
|
+
LIMIT_LIKE_PATTERN_LENGTH,
|
|
65
|
+
LIMIT_VARIABLE_NUMBER,
|
|
66
|
+
LIMIT_TRIGGER_DEPTH,
|
|
67
|
+
LIMIT_WORKER_THREADS,
|
|
68
|
+
cached,
|
|
69
|
+
RunResult,
|
|
70
|
+
Statement,
|
|
71
|
+
Database,
|
|
72
|
+
Backup,
|
|
73
|
+
SqlRunResult,
|
|
74
|
+
SqliteDatabase,
|
|
75
|
+
SqliteStatement,
|
|
76
|
+
SqliteBackup,
|
|
77
|
+
verbose
|
|
78
|
+
} = sqlite3;
|