better-sqlite3-multiple-ciphers 7.4.7-beta.1 → 7.5.0-beta.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 +1 -1
- package/deps/download.sh +111 -108
- package/deps/setup.ps1 +9 -11
- package/deps/sqlite3/sqlite3.c +272560 -0
- package/deps/sqlite3/sqlite3.h +12770 -0
- package/deps/sqlite3/sqlite3ext.h +675 -0
- package/deps/sqlite3.gyp +13 -7
- package/deps/symlink.js +7 -4
- package/lib/database.js +17 -6
- package/lib/sqlite-error.js +1 -2
- package/package.json +10 -4
- package/src/better_sqlite3.cpp +46 -35
- package/src/better_sqlite3.hpp +40 -38
- package/.gitattributes +0 -1
- package/.github/workflows/prebuild.yml +0 -49
- package/.github/workflows/test.yml +0 -59
- package/benchmark/benchmark.js +0 -31
- package/benchmark/drivers.js +0 -21
- package/benchmark/index.js +0 -83
- package/benchmark/seed.js +0 -47
- package/benchmark/trials.js +0 -65
- package/benchmark/types/insert.js +0 -16
- package/benchmark/types/select-all.js +0 -14
- package/benchmark/types/select-iterate.js +0 -23
- package/benchmark/types/select.js +0 -14
- package/benchmark/types/transaction.js +0 -40
- package/deps/extract.js +0 -16
- package/deps/sqlite3.tar.gz +0 -0
- package/docs/api.md +0 -645
- package/docs/benchmark.md +0 -38
- package/docs/compilation.md +0 -76
- package/docs/integer.md +0 -79
- package/docs/performance.md +0 -39
- package/docs/threads.md +0 -97
- package/docs/tips.md +0 -35
- package/docs/troubleshooting.md +0 -23
- package/docs/unsafe.md +0 -16
- package/src/better_sqlite3.lzz +0 -88
- package/src/objects/backup.lzz +0 -138
- package/src/objects/database.lzz +0 -468
- package/src/objects/statement-iterator.lzz +0 -138
- package/src/objects/statement.lzz +0 -323
- package/src/util/bind-map.lzz +0 -73
- package/src/util/binder.lzz +0 -190
- package/src/util/constants.lzz +0 -151
- package/src/util/custom-aggregate.lzz +0 -121
- package/src/util/custom-function.lzz +0 -59
- package/src/util/custom-table.lzz +0 -397
- package/src/util/data-converter.lzz +0 -17
- package/src/util/data.lzz +0 -145
- package/src/util/macros.lzz +0 -159
- package/src/util/query-macros.lzz +0 -71
- package/test/00.setup.js +0 -25
- package/test/01.sqlite-error.js +0 -27
- package/test/10.database.open.js +0 -159
- package/test/11.database.close.js +0 -68
- package/test/12.database.pragma.js +0 -65
- package/test/13.database.prepare.js +0 -60
- package/test/14.database.exec.js +0 -46
- package/test/20.statement.run.js +0 -170
- package/test/21.statement.get.js +0 -109
- package/test/22.statement.all.js +0 -129
- package/test/23.statement.iterate.js +0 -223
- package/test/24.statement.bind.js +0 -107
- package/test/25.statement.columns.js +0 -46
- package/test/30.database.transaction.js +0 -157
- package/test/31.database.checkpoint.js +0 -62
- package/test/32.database.function.js +0 -211
- package/test/33.database.aggregate.js +0 -603
- package/test/34.database.table.js +0 -671
- package/test/35.database.load-extension.js +0 -75
- package/test/36.database.backup.js +0 -240
- package/test/37.database.serialize.js +0 -81
- package/test/40.bigints.js +0 -145
- package/test/41.at-exit.js +0 -52
- package/test/42.integrity.js +0 -531
- package/test/43.verbose.js +0 -100
- package/test/44.worker-threads.js +0 -66
- package/test/45.unsafe-mode.js +0 -52
- package/test/46.encryption.js +0 -69
- package/test/50.misc.js +0 -44
package/benchmark/benchmark.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
const benchmark = require('nodemark');
|
|
4
|
-
|
|
5
|
-
const sync = (fn) => {
|
|
6
|
-
display(benchmark(fn));
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const async = (fn) => {
|
|
10
|
-
const wrapped = cb => fn().then(() => cb(), cb);
|
|
11
|
-
benchmark(wrapped).then(display);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const display = (result) => {
|
|
15
|
-
process.stdout.write(String(result).replace(/ \(.*/, ''));
|
|
16
|
-
process.exit();
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
(async () => {
|
|
20
|
-
process.on('unhandledRejection', (err) => { throw err; });
|
|
21
|
-
const ctx = JSON.parse(process.argv[2]);
|
|
22
|
-
const type = require(`./types/${ctx.type}`);
|
|
23
|
-
const db = await require('./drivers').get(ctx.driver)('../temp/benchmark.db', ctx.pragma);
|
|
24
|
-
if (!type.readonly) {
|
|
25
|
-
for (const table of ctx.tables) await db.exec(`DELETE FROM ${table} WHERE rowid > 1;`);
|
|
26
|
-
await db.exec('VACUUM;');
|
|
27
|
-
}
|
|
28
|
-
const fn = type[ctx.driver](db, ctx);
|
|
29
|
-
if (typeof fn === 'function') setImmediate(sync, fn);
|
|
30
|
-
else setImmediate(async, await fn);
|
|
31
|
-
})();
|
package/benchmark/drivers.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
Every benchmark trial will be executed once for each SQLite3 driver listed
|
|
5
|
-
below. Each driver has a function to open a new database connection on a
|
|
6
|
-
given filename and a list of PRAGMA statements.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
module.exports = new Map([
|
|
10
|
-
['better-sqlite3', async (filename, pragma) => {
|
|
11
|
-
const db = require('../.')(filename);
|
|
12
|
-
for (const str of pragma) db.pragma(str);
|
|
13
|
-
return db;
|
|
14
|
-
}],
|
|
15
|
-
['node-sqlite3', async (filename, pragma) => {
|
|
16
|
-
const driver = require('sqlite3').Database;
|
|
17
|
-
const db = await (require('sqlite').open)({ filename, driver });
|
|
18
|
-
for (const str of pragma) await db.run(`PRAGMA ${str}`);
|
|
19
|
-
return db;
|
|
20
|
-
}],
|
|
21
|
-
]);
|
package/benchmark/index.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const { execFileSync } = require('child_process');
|
|
3
|
-
const clc = require('cli-color');
|
|
4
|
-
|
|
5
|
-
const getTrials = (searchTerms) => {
|
|
6
|
-
// Without any command-line arguments, we do a general-purpose benchmark.
|
|
7
|
-
if (!searchTerms.length) return require('./trials').default;
|
|
8
|
-
|
|
9
|
-
// With command-line arguments, the user can run specific groups of trials.
|
|
10
|
-
return require('./trials').searchable.filter(filterBySearchTerms(searchTerms));
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const filterBySearchTerms = (searchTerms) => (trial) => {
|
|
14
|
-
const terms = [
|
|
15
|
-
trial.type,
|
|
16
|
-
trial.table,
|
|
17
|
-
`(${trial.columns.join(', ')})`,
|
|
18
|
-
`(${trial.columns.join(',')})`,
|
|
19
|
-
...trial.columns,
|
|
20
|
-
...trial.customPragma,
|
|
21
|
-
];
|
|
22
|
-
return searchTerms.every(arg => terms.includes(arg));
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const sortTrials = (a, b) => {
|
|
26
|
-
const aRo = require(`./types/${a.type}`).readonly;
|
|
27
|
-
const bRo = require(`./types/${b.type}`).readonly;
|
|
28
|
-
if (typeof aRo !== 'boolean') throw new TypeError(`Missing readonly export in benchmark type ${a.type}`);
|
|
29
|
-
if (typeof bRo !== 'boolean') throw new TypeError(`Missing readonly export in benchmark type ${b.type}`);
|
|
30
|
-
return bRo - aRo;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const displayTrialName = (trial) => {
|
|
34
|
-
if (trial.description) return console.log(clc.magenta(`--- ${trial.description} ---`));
|
|
35
|
-
const name = `${trial.type} ${trial.table} (${trial.columns.join(', ')})`;
|
|
36
|
-
const pragma = trial.customPragma.length ? ` | ${trial.customPragma.join('; ')}` : '';
|
|
37
|
-
console.log(clc.magenta(name) + clc.yellow(pragma));
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const createContext = (trial, driver) => {
|
|
41
|
-
const tableInfo = Object.assign({}, tables.get(trial.table), { data: undefined });
|
|
42
|
-
return JSON.stringify(Object.assign({}, trial, tableInfo, { driver, tables: [...tables.keys()] }));
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const erase = () => {
|
|
46
|
-
return clc.move(0, -1) + clc.erase.line;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// Determine which trials should be executed.
|
|
50
|
-
process.chdir(__dirname);
|
|
51
|
-
const trials = getTrials(process.argv.slice(2)).sort(sortTrials);
|
|
52
|
-
if (!trials.length) {
|
|
53
|
-
console.log(clc.yellow('No matching benchmarks found!'));
|
|
54
|
-
process.exit();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Create the temporary database needed to run the benchmark trials.
|
|
58
|
-
console.log('Generating tables...');
|
|
59
|
-
const tables = require('./seed')();
|
|
60
|
-
process.stdout.write(erase());
|
|
61
|
-
|
|
62
|
-
// Execute each trial for each available driver.
|
|
63
|
-
const drivers = require('./drivers');
|
|
64
|
-
const nameLength = [...drivers.keys()].reduce((m, d) => Math.max(m, d.length), 0);
|
|
65
|
-
for (const trial of trials) {
|
|
66
|
-
displayTrialName(trial);
|
|
67
|
-
for (const driver of drivers.keys()) {
|
|
68
|
-
const driverName = driver.padEnd(nameLength);
|
|
69
|
-
const ctx = createContext(trial, driver);
|
|
70
|
-
process.stdout.write(`${driver} (running...)\n`);
|
|
71
|
-
try {
|
|
72
|
-
const result = execFileSync('node', ['./benchmark.js', ctx], { stdio: 'pipe', encoding: 'utf8' });
|
|
73
|
-
console.log(erase() + `${driverName} x ${result}`);
|
|
74
|
-
} catch (err) {
|
|
75
|
-
console.log(erase() + clc.red(`${driverName} ERROR (probably out of memory)`));
|
|
76
|
-
process.stderr.write(clc.xterm(247)(clc.strip(err.stderr)));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
console.log('');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log(clc.green('All benchmarks complete!'));
|
|
83
|
-
process.exit();
|
package/benchmark/seed.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
const tables = new Map([
|
|
6
|
-
['small', {
|
|
7
|
-
schema: '(nul, integer INTEGER, real REAL, text TEXT, blob BLOB)',
|
|
8
|
-
data: [null, 0x7fffffff, 1 / 3, 'this is the text', Buffer.from('this is the blob')],
|
|
9
|
-
count: 10000,
|
|
10
|
-
}],
|
|
11
|
-
['large_text', {
|
|
12
|
-
schema: '(text TEXT)',
|
|
13
|
-
data: ['this is the text'.repeat(2048)],
|
|
14
|
-
count: 10000,
|
|
15
|
-
}],
|
|
16
|
-
['large_blob', {
|
|
17
|
-
schema: '(blob BLOB)',
|
|
18
|
-
data: [Buffer.from('this is the blob'.repeat(2048))],
|
|
19
|
-
count: 10000,
|
|
20
|
-
}],
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
/*
|
|
24
|
-
This function creates a pre-populated database that is deleted when the
|
|
25
|
-
process exits.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
module.exports = () => {
|
|
29
|
-
const tempDir = path.join(__dirname, '..', 'temp');
|
|
30
|
-
process.on('exit', () => fs.removeSync(tempDir));
|
|
31
|
-
fs.removeSync(tempDir);
|
|
32
|
-
fs.ensureDirSync(tempDir);
|
|
33
|
-
|
|
34
|
-
const db = require('../.')(path.join(tempDir, 'benchmark.db'));
|
|
35
|
-
db.pragma('journal_mode = OFF');
|
|
36
|
-
db.pragma('synchronous = OFF');
|
|
37
|
-
|
|
38
|
-
for (const [name, ctx] of tables.entries()) {
|
|
39
|
-
db.exec(`CREATE TABLE ${name} ${ctx.schema}`);
|
|
40
|
-
const columns = db.pragma(`table_info(${name})`).map(() => '?');
|
|
41
|
-
const insert = db.prepare(`INSERT INTO ${name} VALUES (${columns.join(', ')})`).bind(ctx.data);
|
|
42
|
-
for (let i = 0; i < ctx.count; ++i) insert.run();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
db.close();
|
|
46
|
-
return tables;
|
|
47
|
-
};
|
package/benchmark/trials.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
exports.default = [
|
|
4
|
-
{ type: 'select', table: 'small', columns: ['nul', 'integer', 'real', 'text'],
|
|
5
|
-
description: 'reading rows individually' },
|
|
6
|
-
{ type: 'select-all', table: 'small', columns: ['nul', 'integer', 'real', 'text'],
|
|
7
|
-
description: 'reading 100 rows into an array' },
|
|
8
|
-
{ type: 'select-iterate', table: 'small', columns: ['nul', 'integer', 'real', 'text'],
|
|
9
|
-
description: 'iterating over 100 rows' },
|
|
10
|
-
{ type: 'insert', table: 'small', columns: ['nul', 'integer', 'real', 'text'],
|
|
11
|
-
description: 'inserting rows individually' },
|
|
12
|
-
{ type: 'transaction', table: 'small', columns: ['nul', 'integer', 'real', 'text'],
|
|
13
|
-
description: 'inserting 100 rows in a single transaction' },
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
exports.searchable = [
|
|
17
|
-
{ type: 'select', table: 'small', columns: ['nul'] },
|
|
18
|
-
{ type: 'select', table: 'small', columns: ['integer'] },
|
|
19
|
-
{ type: 'select', table: 'small', columns: ['real'] },
|
|
20
|
-
{ type: 'select', table: 'small', columns: ['text'] },
|
|
21
|
-
{ type: 'select', table: 'small', columns: ['blob'] },
|
|
22
|
-
{ type: 'select', table: 'large_text', columns: ['text'] },
|
|
23
|
-
{ type: 'select', table: 'large_blob', columns: ['blob'] },
|
|
24
|
-
{ type: 'select-all', table: 'small', columns: ['nul'] },
|
|
25
|
-
{ type: 'select-all', table: 'small', columns: ['integer'] },
|
|
26
|
-
{ type: 'select-all', table: 'small', columns: ['real'] },
|
|
27
|
-
{ type: 'select-all', table: 'small', columns: ['text'] },
|
|
28
|
-
{ type: 'select-all', table: 'small', columns: ['blob'] },
|
|
29
|
-
{ type: 'select-all', table: 'large_text', columns: ['text'] },
|
|
30
|
-
{ type: 'select-all', table: 'large_blob', columns: ['blob'] },
|
|
31
|
-
{ type: 'select-iterate', table: 'small', columns: ['nul'] },
|
|
32
|
-
{ type: 'select-iterate', table: 'small', columns: ['integer'] },
|
|
33
|
-
{ type: 'select-iterate', table: 'small', columns: ['real'] },
|
|
34
|
-
{ type: 'select-iterate', table: 'small', columns: ['text'] },
|
|
35
|
-
{ type: 'select-iterate', table: 'small', columns: ['blob'] },
|
|
36
|
-
{ type: 'select-iterate', table: 'large_text', columns: ['text'] },
|
|
37
|
-
{ type: 'select-iterate', table: 'large_blob', columns: ['blob'] },
|
|
38
|
-
{ type: 'insert', table: 'small', columns: ['nul'] },
|
|
39
|
-
{ type: 'insert', table: 'small', columns: ['integer'] },
|
|
40
|
-
{ type: 'insert', table: 'small', columns: ['real'] },
|
|
41
|
-
{ type: 'insert', table: 'small', columns: ['text'] },
|
|
42
|
-
{ type: 'insert', table: 'small', columns: ['blob'] },
|
|
43
|
-
{ type: 'insert', table: 'large_text', columns: ['text'] },
|
|
44
|
-
{ type: 'insert', table: 'large_blob', columns: ['blob'] },
|
|
45
|
-
{ type: 'transaction', table: 'small', columns: ['nul'] },
|
|
46
|
-
{ type: 'transaction', table: 'small', columns: ['integer'] },
|
|
47
|
-
{ type: 'transaction', table: 'small', columns: ['real'] },
|
|
48
|
-
{ type: 'transaction', table: 'small', columns: ['text'] },
|
|
49
|
-
{ type: 'transaction', table: 'small', columns: ['blob'] },
|
|
50
|
-
{ type: 'transaction', table: 'large_text', columns: ['text'] },
|
|
51
|
-
{ type: 'transaction', table: 'large_blob', columns: ['blob'] },
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
(() => {
|
|
55
|
-
const defaultPragma = [];
|
|
56
|
-
const yes = /^\s*(1|true|on|yes)\s*$/i;
|
|
57
|
-
if (yes.test(process.env.NO_CACHE)) defaultPragma.push('cache_size = 0');
|
|
58
|
-
else defaultPragma.push('cache_size = -16000');
|
|
59
|
-
if (yes.test(process.env.NO_WAL)) defaultPragma.push('journal_mode = DELETE', 'synchronous = FULL');
|
|
60
|
-
else defaultPragma.push('journal_mode = WAL', 'synchronous = NORMAL');
|
|
61
|
-
for (const trial of [].concat(...Object.values(exports))) {
|
|
62
|
-
trial.customPragma = trial.pragma || [];
|
|
63
|
-
trial.pragma = defaultPragma.concat(trial.customPragma);
|
|
64
|
-
}
|
|
65
|
-
})();
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
exports.readonly = false; // Inserting rows individually (`.run()`)
|
|
3
|
-
|
|
4
|
-
exports['better-sqlite3'] = (db, { table, columns }) => {
|
|
5
|
-
const stmt = db.prepare(`INSERT INTO ${table} (${columns.join(', ')}) VALUES (${columns.map(x => '@' + x).join(', ')})`);
|
|
6
|
-
const row = db.prepare(`SELECT * FROM ${table} LIMIT 1`).get();
|
|
7
|
-
return () => stmt.run(row);
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
exports['node-sqlite3'] = async (db, { table, columns }) => {
|
|
11
|
-
const sql = `INSERT INTO ${table} (${columns.join(', ')}) VALUES (${columns.map(x => '@' + x).join(', ')})`;
|
|
12
|
-
const row = Object.assign({}, ...Object.entries(await db.get(`SELECT * FROM ${table} LIMIT 1`))
|
|
13
|
-
.filter(([k]) => columns.includes(k))
|
|
14
|
-
.map(([k, v]) => ({ ['@' + k]: v })));
|
|
15
|
-
return () => db.run(sql, row);
|
|
16
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
exports.readonly = true; // Reading 100 rows into an array (`.all()`)
|
|
3
|
-
|
|
4
|
-
exports['better-sqlite3'] = (db, { table, columns, count }) => {
|
|
5
|
-
const stmt = db.prepare(`SELECT ${columns.join(', ')} FROM ${table} WHERE rowid >= ? LIMIT 100`);
|
|
6
|
-
let rowid = -100;
|
|
7
|
-
return () => stmt.all((rowid += 100) % count + 1);
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
exports['node-sqlite3'] = async (db, { table, columns, count }) => {
|
|
11
|
-
const sql = `SELECT ${columns.join(', ')} FROM ${table} WHERE rowid >= ? LIMIT 100`;
|
|
12
|
-
let rowid = -100;
|
|
13
|
-
return () => db.all(sql, (rowid += 100) % count + 1);
|
|
14
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
exports.readonly = true; // Iterating over 100 rows (`.iterate()`)
|
|
3
|
-
|
|
4
|
-
exports['better-sqlite3'] = (db, { table, columns, count }) => {
|
|
5
|
-
const stmt = db.prepare(`SELECT ${columns.join(', ')} FROM ${table} WHERE rowid >= ? LIMIT 100`);
|
|
6
|
-
let rowid = -100;
|
|
7
|
-
return () => {
|
|
8
|
-
for (const row of stmt.iterate((rowid += 100) % count + 1)) {}
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
exports['node-sqlite3'] = async (db, { table, columns, count }) => {
|
|
13
|
-
const sql = `SELECT ${columns.join(', ')} FROM ${table} WHERE rowid = ?`;
|
|
14
|
-
let rowid = -100;
|
|
15
|
-
return () => {
|
|
16
|
-
rowid += 100;
|
|
17
|
-
let index = 0;
|
|
18
|
-
return (function next() {
|
|
19
|
-
if (index === 100) return;
|
|
20
|
-
return db.get(sql, (rowid + index++) % count + 1).then(next);
|
|
21
|
-
})();
|
|
22
|
-
};
|
|
23
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
exports.readonly = true; // Reading rows individually (`.get()`)
|
|
3
|
-
|
|
4
|
-
exports['better-sqlite3'] = (db, { table, columns, count }) => {
|
|
5
|
-
const stmt = db.prepare(`SELECT ${columns.join(', ')} FROM ${table} WHERE rowid = ?`);
|
|
6
|
-
let rowid = -1;
|
|
7
|
-
return () => stmt.get(++rowid % count + 1);
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
exports['node-sqlite3'] = async (db, { table, columns, count }) => {
|
|
11
|
-
const sql = `SELECT ${columns.join(', ')} FROM ${table} WHERE rowid = ?`;
|
|
12
|
-
let rowid = -1;
|
|
13
|
-
return () => db.get(sql, ++rowid % count + 1);
|
|
14
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
exports.readonly = false; // Inserting 100 rows in a single transaction
|
|
3
|
-
|
|
4
|
-
exports['better-sqlite3'] = (db, { table, columns }) => {
|
|
5
|
-
const stmt = db.prepare(`INSERT INTO ${table} (${columns.join(', ')}) VALUES (${columns.map(x => '@' + x).join(', ')})`);
|
|
6
|
-
const row = db.prepare(`SELECT * FROM ${table} LIMIT 1`).get();
|
|
7
|
-
const trx = db.transaction((row) => {
|
|
8
|
-
for (let i = 0; i < 100; ++i) stmt.run(row);
|
|
9
|
-
});
|
|
10
|
-
return () => trx(row);
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
exports['node-sqlite3'] = async (db, { table, columns, driver, pragma }) => {
|
|
14
|
-
const sql = `INSERT INTO ${table} (${columns.join(', ')}) VALUES (${columns.map(x => '@' + x).join(', ')})`;
|
|
15
|
-
const row = Object.assign({}, ...Object.entries(await db.get(`SELECT * FROM ${table} LIMIT 1`))
|
|
16
|
-
.filter(([k]) => columns.includes(k))
|
|
17
|
-
.map(([k, v]) => ({ ['@' + k]: v })));
|
|
18
|
-
const open = require('../drivers').get(driver);
|
|
19
|
-
/*
|
|
20
|
-
The only way to create an isolated transaction with node-sqlite3 in a
|
|
21
|
-
random-access environment (i.e., a web server) is to open a new database
|
|
22
|
-
connection for each transaction.
|
|
23
|
-
(http://github.com/mapbox/node-sqlite3/issues/304#issuecomment-45242331)
|
|
24
|
-
*/
|
|
25
|
-
return () => open('../temp/benchmark.db', pragma).then(async (db) => {
|
|
26
|
-
try {
|
|
27
|
-
await db.run('BEGIN');
|
|
28
|
-
try {
|
|
29
|
-
for (let i = 0; i < 100; ++i) await db.run(sql, row);
|
|
30
|
-
await db.run('COMMIT');
|
|
31
|
-
} catch (err) {
|
|
32
|
-
try { await db.run('ROLLBACK'); }
|
|
33
|
-
catch (_) { /* this is necessary because there's no db.inTransaction property */ }
|
|
34
|
-
throw err;
|
|
35
|
-
}
|
|
36
|
-
} finally {
|
|
37
|
-
await db.close();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
};
|
package/deps/extract.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const tar = require('tar');
|
|
4
|
-
|
|
5
|
-
const dest = process.argv[2];
|
|
6
|
-
const source = path.join(__dirname, 'sqlite3.tar.gz');
|
|
7
|
-
|
|
8
|
-
process.on('unhandledRejection', (err) => { throw err; });
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
This extracts the bundled sqlite3.tar.gz file and places the resulting files
|
|
12
|
-
into the directory specified by <$2>.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
tar.extract({ file: source, cwd: dest, onwarn: process.emitWarning })
|
|
16
|
-
.then(() => process.exit(0));
|
package/deps/sqlite3.tar.gz
DELETED
|
Binary file
|