This commit is contained in:
RochesterX
2026-01-22 12:59:10 -05:00
parent ad7fd4b3bf
commit 1db3224105
301 changed files with 305707 additions and 14 deletions

13
TEST
View File

@@ -1,13 +0,0 @@
1. Move the cursor to this line.
2. Press v and move the cursor to the fifth item below. Notice that the
text is highlighted.
3. Press the : character. At the bottom of the screen :'<,'> will appear.
4. Type w TEST , where TEST is a filename that does not exist yet. Verify
that you see :'<,'>w TEST before you press <ENTER>.
5. Vim will write the selected lines to the file TEST. Use :!dir or :!ls
to see it. Do not remove it yet! We will use it in the next lesson.

104
mssql-wrapper.js Normal file
View File

@@ -0,0 +1,104 @@
// Vibe coded since I needed more resources on my VPS :/
const Database = require('better-sqlite3');
// 1. Connect to the file (creates it if missing)
const db = new Database('project.db');
db.pragma('journal_mode = WAL'); // Faster, safer writes
class FakeMssqlRequest {
constructor(db) {
this.db = db;
this.params = {}; // Stores your inputs: .input('id', 123)
}
// Mimic the .input() method
// We ignore 'type' because SQLite is loosely typed
input(name, type, value) {
// Handle case where value is passed as 2nd arg (omitting type)
if (value === undefined) value = type;
this.params[name] = value;
return this; // Return 'this' to allow chaining (.input().input())
}
// Mimic the .query() method
async query(sqlString) {
try {
let cleanSql = sqlString;
// --- FIX 1: Handle TOP -> LIMIT ---
// Regex detects: SELECT TOP (@amount) ... OR SELECT TOP 10 ...
// It captures the value (@amount or 10)
const topRegex = /SELECT\s+TOP\s*\(?(@?\w+)\)?/i;
const topMatch = cleanSql.match(topRegex);
if (topMatch) {
const limitValue = topMatch[1]; // Extracts '@amount' or '10'
// 1. Remove "TOP (@amount)" from the start
cleanSql = cleanSql.replace(topRegex, 'SELECT ');
// 2. Remove any trailing semicolon so we can append
cleanSql = cleanSql.replace(/;\s*$/, '');
// 3. Append LIMIT to the end
cleanSql += ` LIMIT ${limitValue}`;
}
// 1. Compatibility Fixes (Optional but helpful)
// Replace 'GETDATE()' with SQLite's "datetime('now')"
cleanSql = cleanSql.replace(/GETDATE\(\)/gi, "datetime('now', 'localtime')")
// MS SQL: SYSUTCDATETIME() -> SQLite: datetime('now') (Already UTC)
.replace(/SYSUTCDATETIME\(\)/gi, "datetime('now')")
// --- FIX 3: Clean up Square Brackets ---
.replace(/\[/g, '"').replace(/\]/g, '"')
// --- FIX 4: Handle String Concatenation in LIKE clauses ---
// MSSQL: LIKE '%' + @param + '%'
// SQLite: LIKE '%' || @param || '%'
// This regex looks for: LIKE '%' + @anything + '%'
.replace(/LIKE\s+'%'\s*\+\s*(@\w+)\s*\+\s*'%'/gi, "LIKE '%' || $1 || '%'");
// 2. Determine if it's a SELECT or INSERT/UPDATE
const stmt = this.db.prepare(cleanSql);
console.log(`Running:\n${cleanSql}`)
if (cleanSql.trim().toUpperCase().startsWith('SELECT')) {
// READ: Use .all()
const rows = stmt.all(this.params);
console.log(rows);
return { recordset: rows, rowsAffected: [rows.length] };
} else {
// WRITE: Use .run()
const info = stmt.run(this.params);
console.log(`else`)
return { recordset: [], rowsAffected: [info.changes] };
}
} catch (err) {
console.error("SQLite Error:", err.message);
console.error("Query was:", sqlString);
throw err;
}
}
}
// Mimic the main 'pool' object
const pool = {
connected: true,
request: () => new FakeMssqlRequest(db),
close: () => db.close()
};
module.exports = {
// Mimic the sql.connect() function
connect: async () => {
console.log("Connected to SQLite (via Wrapper)");
return pool;
},
// Export types to prevent "sql.Int is undefined" errors
Int: 'Int',
NVarChar: 'NVarChar',
Bit: 'Bit',
DateTime: 'DateTime'
};

1
node_modules/.bin/prebuild-install generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../prebuild-install/bin.js

1
node_modules/.bin/rc generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../rc/cli.js

349
node_modules/.package-lock.json generated vendored
View File

@@ -348,6 +348,29 @@
"node": ">= 18"
}
},
"node_modules/better-sqlite3": {
"version": "12.6.2",
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.6.2.tgz",
"integrity": "sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"bindings": "^1.5.0",
"prebuild-install": "^7.1.1"
},
"engines": {
"node": "20.x || 22.x || 23.x || 24.x || 25.x"
}
},
"node_modules/bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"license": "MIT",
"dependencies": {
"file-uri-to-path": "1.0.0"
}
},
"node_modules/bl": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-6.1.3.tgz",
@@ -460,6 +483,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"license": "ISC"
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
@@ -536,6 +565,30 @@
}
}
},
"node_modules/decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"license": "MIT",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/default-browser": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
@@ -582,6 +635,15 @@
"node": ">= 0.8"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/dotenv": {
"version": "17.2.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
@@ -631,6 +693,15 @@
"node": ">= 0.8"
}
},
"node_modules/end-of-stream": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
@@ -692,6 +763,15 @@
"node": ">=0.8.x"
}
},
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"license": "(MIT OR WTFPL)",
"engines": {
"node": ">=6"
}
},
"node_modules/express": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
@@ -733,6 +813,12 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"license": "MIT"
},
"node_modules/finalhandler": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
@@ -768,6 +854,12 @@
"node": ">= 0.8"
}
},
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"license": "MIT"
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -814,6 +906,12 @@
"node": ">= 0.4"
}
},
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"license": "MIT"
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -936,6 +1034,12 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -1136,6 +1240,33 @@
"node": ">= 0.6"
}
},
"node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"license": "MIT"
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -1160,6 +1291,12 @@
"node": ">=18"
}
},
"node_modules/napi-build-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
"license": "MIT"
},
"node_modules/native-duplexpair": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/native-duplexpair/-/native-duplexpair-1.0.0.tgz",
@@ -1174,6 +1311,18 @@
"node": ">= 0.6"
}
},
"node_modules/node-abi": {
"version": "3.87.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz",
"integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==",
"license": "MIT",
"dependencies": {
"semver": "^7.3.5"
},
"engines": {
"node": ">=10"
}
},
"node_modules/node-addon-api": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz",
@@ -1270,6 +1419,32 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/prebuild-install": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"license": "MIT",
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp-classic": "^0.5.3",
"napi-build-utils": "^2.0.0",
"node-abi": "^3.3.0",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^4.0.0",
"tar-fs": "^2.0.0",
"tunnel-agent": "^0.6.0"
},
"bin": {
"prebuild-install": "bin.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -1291,6 +1466,16 @@
"node": ">= 0.10"
}
},
"node_modules/pump": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
"license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
@@ -1346,6 +1531,21 @@
"url": "https://opencollective.com/express"
}
},
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
},
"bin": {
"rc": "cli.js"
}
},
"node_modules/readable-stream": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
@@ -1541,6 +1741,51 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/simple-get": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
@@ -1563,6 +1808,92 @@
"safe-buffer": "~5.2.0"
}
},
"node_modules/strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tar-fs": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"license": "MIT",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
}
},
"node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"license": "MIT",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/tar-stream/node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/tar-stream/node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/tar-stream/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/tarn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
@@ -1605,6 +1936,18 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
},
"engines": {
"node": "*"
}
},
"node_modules/type-is": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
@@ -1633,6 +1976,12 @@
"node": ">= 0.8"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",

21
node_modules/better-sqlite3/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 Joshua Wise
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

99
node_modules/better-sqlite3/README.md generated vendored Normal file
View File

@@ -0,0 +1,99 @@
# better-sqlite3 [![Build Status](https://github.com/JoshuaWise/better-sqlite3/actions/workflows/build.yml/badge.svg)](https://github.com/JoshuaWise/better-sqlite3/actions/workflows/build.yml?query=branch%3Amaster)
The fastest and simplest library for SQLite in Node.js.
- Full transaction support
- High performance, efficiency, and safety
- Easy-to-use synchronous API *(better concurrency than an asynchronous API... yes, you read that correctly)*
- Support for user-defined functions, aggregates, virtual tables, and extensions
- 64-bit integers *(invisible until you need them)*
- Worker thread support *(for large/slow queries)*
## Help this project stay strong! &#128170;
`better-sqlite3` is used by thousands of developers and engineers on a daily basis. Long nights and weekends were spent keeping this project strong and dependable, with no ask for compensation or funding, until now. If your company uses `better-sqlite3`, ask your manager to consider supporting the project:
- [Become a GitHub sponsor](https://github.com/sponsors/JoshuaWise)
- [Become a backer on Patreon](https://www.patreon.com/joshuawise)
- [Make a one-time donation on PayPal](https://www.paypal.me/joshuathomaswise)
## How other libraries compare
| |select 1 row &nbsp;`get()`&nbsp;|select 100 rows &nbsp;&nbsp;`all()`&nbsp;&nbsp;|select 100 rows `iterate()` 1-by-1|insert 1 row `run()`|insert 100 rows in a transaction|
|---|---|---|---|---|---|
|better-sqlite3|1x|1x|1x|1x|1x|
|[sqlite](https://www.npmjs.com/package/sqlite) and [sqlite3](https://www.npmjs.com/package/sqlite3)|11.7x slower|2.9x slower|24.4x slower|2.8x slower|15.6x slower|
> You can verify these results by [running the benchmark yourself](./docs/benchmark.md).
## Installation
```bash
npm install better-sqlite3
```
> Requires Node.js v14.21.1 or later. Prebuilt binaries are available for [LTS versions](https://nodejs.org/en/about/releases/). If you have trouble installing, check the [troubleshooting guide](./docs/troubleshooting.md).
## Usage
```js
const db = require('better-sqlite3')('foobar.db', options);
const row = db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
console.log(row.firstName, row.lastName, row.email);
```
Though not required, [it is generally important to set the WAL pragma for performance reasons](https://github.com/WiseLibs/better-sqlite3/blob/master/docs/performance.md).
```js
db.pragma('journal_mode = WAL');
```
##### In ES6 module notation:
```js
import Database from 'better-sqlite3';
const db = new Database('foobar.db', options);
db.pragma('journal_mode = WAL');
```
## Why should I use this instead of [node-sqlite3](https://github.com/mapbox/node-sqlite3)?
- `node-sqlite3` uses asynchronous APIs for tasks that are either CPU-bound or serialized. That's not only bad design, but it wastes tons of resources. It also causes [mutex thrashing](https://en.wikipedia.org/wiki/Resource_contention) which has devastating effects on performance.
- `node-sqlite3` exposes low-level (C language) memory management functions. `better-sqlite3` does it the JavaScript way, allowing the garbage collector to worry about memory management.
- `better-sqlite3` is simpler to use, and it provides nice utilities for some operations that are very difficult or impossible in `node-sqlite3`.
- `better-sqlite3` is much faster than `node-sqlite3` in most cases, and just as fast in all other cases.
#### When is this library not appropriate?
In most cases, if you're attempting something that cannot be reasonably accomplished with `better-sqlite3`, it probably cannot be reasonably accomplished with SQLite in general. For example, if you're executing queries that take one second to complete, and you expect to have many concurrent users executing those queries, no amount of asynchronicity will save you from SQLite's serialized nature. Fortunately, SQLite is very *very* fast. With proper indexing, we've been able to achieve upward of 2000 queries per second with 5-way-joins in a 60 GB database, where each query was handling 550 kilobytes of real data.
If you have a performance problem, the most likely causes are inefficient queries, improper indexing, or a lack of [WAL mode](./docs/performance.md)—not `better-sqlite3` itself. However, there are some cases where `better-sqlite3` could be inappropriate:
- If you expect a high volume of concurrent reads each returning many megabytes of data (i.e., videos)
- If you expect a high volume of concurrent writes (i.e., a social media site)
- If your database's size is near the terabyte range
For these situations, you should probably use a full-fledged RDBMS such as [PostgreSQL](https://www.postgresql.org/).
## Upgrading
Upgrading your `better-sqlite3` dependency can potentially introduce breaking changes, either in the `better-sqlite3` API (if you upgrade to a new [major version](https://semver.org/)), or between your existing database(s) and the underlying version of SQLite. Before upgrading, review:
* [`better-sqlite3` release notes](https://github.com/WiseLibs/better-sqlite3/releases)
* [SQLite release history](https://www.sqlite.org/changes.html)
# Documentation
- [API documentation](./docs/api.md)
- [Performance](./docs/performance.md) (also see [benchmark results](./docs/benchmark.md))
- [64-bit integer support](./docs/integer.md)
- [Worker thread support](./docs/threads.md)
- [Unsafe mode (advanced)](./docs/unsafe.md)
- [SQLite compilation (advanced)](./docs/compilation.md)
- [Contribution rules](./docs/contribution.md)
- [Code of conduct](./docs/conduct.md)
# License
[MIT](./LICENSE)

38
node_modules/better-sqlite3/binding.gyp generated vendored Normal file
View File

@@ -0,0 +1,38 @@
# ===
# This is the main GYP file, which builds better-sqlite3 with SQLite itself.
# ===
{
'includes': ['deps/common.gypi'],
'targets': [
{
'target_name': 'better_sqlite3',
'dependencies': ['deps/sqlite3.gyp:sqlite3'],
'sources': ['src/better_sqlite3.cpp'],
'cflags_cc': ['-std=c++20'],
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': ['-std=c++20', '-stdlib=libc++'],
},
'msvs_settings': {
'VCCLCompilerTool': {
'AdditionalOptions': [
'/std:c++20',
],
},
},
'conditions': [
['OS=="linux"', {
'ldflags': [
'-Wl,-Bsymbolic',
'-Wl,--exclude-libs,ALL',
],
}],
],
},
{
'target_name': 'test_extension',
'dependencies': ['deps/sqlite3.gyp:sqlite3'],
'conditions': [['sqlite3 == ""', { 'sources': ['deps/test_extension.c'] }]],
},
],
}

BIN
node_modules/better-sqlite3/build/Release/better_sqlite3.node generated vendored Executable file

Binary file not shown.

68
node_modules/better-sqlite3/deps/common.gypi generated vendored Normal file
View File

@@ -0,0 +1,68 @@
# ===
# This configuration defines the differences between Release and Debug builds.
# Some miscellaneous Windows settings are also defined here.
# ===
{
'variables': { 'sqlite3%': '' },
'target_defaults': {
'default_configuration': 'Release',
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1,
},
},
'conditions': [
['OS == "win"', {
'defines': ['WIN32'],
}],
],
'configurations': {
'Debug': {
'defines!': [
'NDEBUG',
],
'defines': [
'DEBUG',
'_DEBUG',
'SQLITE_DEBUG',
'SQLITE_MEMDEBUG',
'SQLITE_ENABLE_API_ARMOR',
'SQLITE_WIN32_MALLOC_VALIDATE',
],
'cflags': [
'-O0',
],
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.7',
'GCC_OPTIMIZATION_LEVEL': '0',
'GCC_GENERATE_DEBUGGING_SYMBOLS': 'YES',
},
'msvs_settings': {
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
},
},
},
'Release': {
'defines!': [
'DEBUG',
'_DEBUG',
],
'defines': [
'NDEBUG',
],
'cflags': [
'-O3',
],
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.7',
'GCC_OPTIMIZATION_LEVEL': '3',
'GCC_GENERATE_DEBUGGING_SYMBOLS': 'NO',
'DEAD_CODE_STRIPPING': 'YES',
'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
},
},
},
},
}

31
node_modules/better-sqlite3/deps/copy.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
'use strict';
const path = require('path');
const fs = require('fs');
const dest = process.argv[2];
const source = path.resolve(path.sep, process.argv[3] || path.join(__dirname, 'sqlite3'));
const files = [
{ filename: 'sqlite3.c', optional: false },
{ filename: 'sqlite3.h', optional: false },
];
if (process.argv[3]) {
// Support "_HAVE_SQLITE_CONFIG_H" in custom builds.
files.push({ filename: 'config.h', optional: true });
} else {
// Required for some tests.
files.push({ filename: 'sqlite3ext.h', optional: false });
}
for (const { filename, optional } of files) {
const sourceFilepath = path.join(source, filename);
const destFilepath = path.join(dest, filename);
if (optional && !fs.existsSync(sourceFilepath)) {
continue;
}
fs.accessSync(sourceFilepath);
fs.mkdirSync(path.dirname(destFilepath), { recursive: true });
fs.copyFileSync(sourceFilepath, destFilepath);
}

41
node_modules/better-sqlite3/deps/defines.gypi generated vendored Normal file
View File

@@ -0,0 +1,41 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY deps/download.sh (DO NOT EDIT)
{
'defines': [
'HAVE_INT16_T=1',
'HAVE_INT32_T=1',
'HAVE_INT8_T=1',
'HAVE_STDINT_H=1',
'HAVE_UINT16_T=1',
'HAVE_UINT32_T=1',
'HAVE_UINT8_T=1',
'HAVE_USLEEP=1',
'SQLITE_DEFAULT_CACHE_SIZE=-16000',
'SQLITE_DEFAULT_FOREIGN_KEYS=1',
'SQLITE_DEFAULT_MEMSTATUS=0',
'SQLITE_DEFAULT_WAL_SYNCHRONOUS=1',
'SQLITE_DQS=0',
'SQLITE_ENABLE_COLUMN_METADATA',
'SQLITE_ENABLE_DBSTAT_VTAB',
'SQLITE_ENABLE_DESERIALIZE',
'SQLITE_ENABLE_FTS3',
'SQLITE_ENABLE_FTS3_PARENTHESIS',
'SQLITE_ENABLE_FTS4',
'SQLITE_ENABLE_FTS5',
'SQLITE_ENABLE_GEOPOLY',
'SQLITE_ENABLE_JSON1',
'SQLITE_ENABLE_MATH_FUNCTIONS',
'SQLITE_ENABLE_RTREE',
'SQLITE_ENABLE_STAT4',
'SQLITE_ENABLE_UPDATE_DELETE_LIMIT',
'SQLITE_LIKE_DOESNT_MATCH_BLOBS',
'SQLITE_OMIT_DEPRECATED',
'SQLITE_OMIT_PROGRESS_CALLBACK',
'SQLITE_OMIT_SHARED_CACHE',
'SQLITE_OMIT_TCL_VARIABLE',
'SQLITE_SOUNDEX',
'SQLITE_THREADSAFE=2',
'SQLITE_TRACE_SIZE_LIMIT=32',
'SQLITE_USE_URI=0',
],
}

122
node_modules/better-sqlite3/deps/download.sh generated vendored Executable file
View File

@@ -0,0 +1,122 @@
#!/usr/bin/env bash
# ===
# This script defines and generates the bundled SQLite unit (sqlite3.c).
#
# The following steps are taken:
# 1. populate the shell environment with the defined compile-time options.
# 2. download and extract the SQLite source code into a temporary directory.
# 3. run "sh configure" and "make sqlite3.c" within the source directory.
# 4. copy the generated amalgamation into the output directory (./sqlite3).
# 5. export the defined compile-time options to a gyp file (./defines.gypi).
# 6. update the docs (../docs/compilation.md) with details of this distribution.
#
# When a user builds better-sqlite3, the following steps are taken:
# 1. node-gyp loads the previously exported compile-time options (defines.gypi).
# 2. the copy.js script copies the bundled amalgamation into the build folder.
# 3. node-gyp compiles the copied sqlite3.c along with better_sqlite3.cpp.
# 4. node-gyp links the two resulting binaries to generate better_sqlite3.node.
# ===
YEAR="2026"
VERSION="3510200"
# Defines below are sorted alphabetically
DEFINES="
HAVE_INT16_T=1
HAVE_INT32_T=1
HAVE_INT8_T=1
HAVE_STDINT_H=1
HAVE_UINT16_T=1
HAVE_UINT32_T=1
HAVE_UINT8_T=1
HAVE_USLEEP=1
SQLITE_DEFAULT_CACHE_SIZE=-16000
SQLITE_DEFAULT_FOREIGN_KEYS=1
SQLITE_DEFAULT_MEMSTATUS=0
SQLITE_DEFAULT_WAL_SYNCHRONOUS=1
SQLITE_DQS=0
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_DBSTAT_VTAB
SQLITE_ENABLE_DESERIALIZE
SQLITE_ENABLE_FTS3
SQLITE_ENABLE_FTS3_PARENTHESIS
SQLITE_ENABLE_FTS4
SQLITE_ENABLE_FTS5
SQLITE_ENABLE_GEOPOLY
SQLITE_ENABLE_JSON1
SQLITE_ENABLE_MATH_FUNCTIONS
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_STAT4
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
SQLITE_LIKE_DOESNT_MATCH_BLOBS
SQLITE_OMIT_DEPRECATED
SQLITE_OMIT_PROGRESS_CALLBACK
SQLITE_OMIT_SHARED_CACHE
SQLITE_OMIT_TCL_VARIABLE
SQLITE_SOUNDEX
SQLITE_THREADSAFE=2
SQLITE_TRACE_SIZE_LIMIT=32
SQLITE_USE_URI=0
"
# ========== START SCRIPT ========== #
echo "setting up environment..."
DEPS="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
TEMP="$DEPS/temp"
OUTPUT="$DEPS/sqlite3"
rm -rf "$TEMP"
rm -rf "$OUTPUT"
mkdir -p "$TEMP"
mkdir -p "$OUTPUT"
export CFLAGS=`echo $(echo "$DEFINES" | sed -e "/^\s*$/d" -e "s/^/-D/")`
echo "downloading source..."
curl -#f "https://www.sqlite.org/$YEAR/sqlite-src-$VERSION.zip" > "$TEMP/source.zip" || exit 1
echo "extracting source..."
unzip "$TEMP/source.zip" -d "$TEMP" > /dev/null || exit 1
cd "$TEMP/sqlite-src-$VERSION" || exit 1
echo "configuring amalgamation..."
sh configure > /dev/null || exit 1
echo "building amalgamation..."
make OPTIONS="$CFLAGS" sqlite3.c > /dev/null || exit 1
echo "copying amalgamation..."
cp sqlite3.c sqlite3.h sqlite3ext.h "$OUTPUT/" || exit 1
echo "applying patches..."
cd "$DEPS" || exit 1
for patch in patches/*.patch; do
# If a patch fails, just skip it an move on.
# By default `patch` tries to be clever and reverse the patch, so we have to specify `--forward`.
# If the patch fails, we # don't write .orig and .rej files, so we have to specify `--no-backup-if-mismatch` and `--reject-file=-`.
patch --batch --forward --no-backup-if-mismatch --reject-file=- -p2 < "$patch"
done
echo "updating gyp configs..."
GYP="$DEPS/defines.gypi"
printf "# THIS FILE IS AUTOMATICALLY GENERATED BY deps/download.sh (DO NOT EDIT)\n\n{\n 'defines': [\n" > "$GYP"
printf "$DEFINES" | sed -e "/^\s*$/d" -e "s/\(.*\)/ '\1',/" >> "$GYP"
printf " ],\n}\n" >> "$GYP"
echo "updating docs..."
DOCS="$DEPS/../docs/compilation.md"
MAJOR=`expr "${VERSION:0:1}" + 0`
MINOR=`expr "${VERSION:1:2}" + 0`
PATCH=`expr "${VERSION:3:2}" + 0`
sed -Ei.bak -e "s/version [0-9]+\.[0-9]+\.[0-9]+/version $MAJOR.$MINOR.$PATCH/g" "$DOCS"
sed -i.bak -e "/^SQLITE_/,\$d" "$DOCS"
sed -i.bak -e "/^HAVE_/,\$d" "$DOCS"
rm "$DOCS".bak
printf "$DEFINES" | sed -e "/^\s*$/d" >> "$DOCS"
printf "\`\`\`\n" >> "$DOCS"
echo "cleaning up..."
cd - > /dev/null || exit 1
rm -rf "$TEMP"
echo "done!"

15
node_modules/better-sqlite3/deps/patches/1208.patch generated vendored Normal file
View File

@@ -0,0 +1,15 @@
diff --git a/deps/sqlite3/sqlite3.c b/deps/sqlite3/sqlite3.c
index b1a807f..38bd1e6 100644
--- a/deps/sqlite3/sqlite3.c
+++ b/deps/sqlite3/sqlite3.c
@@ -24887,8 +24887,8 @@ static const struct {
/* 1 */ { 6, "minute", 7.7379e+12, 60.0 },
/* 2 */ { 4, "hour", 1.2897e+11, 3600.0 },
/* 3 */ { 3, "day", 5373485.0, 86400.0 },
- /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 },
- /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 },
+ /* 4 */ { 5, "month", 176546.0, 2592000.0 },
+ /* 5 */ { 4, "year", 14713.0, 31536000.0 },
};
/*

80
node_modules/better-sqlite3/deps/sqlite3.gyp generated vendored Executable file
View File

@@ -0,0 +1,80 @@
# ===
# This configuration defines options specific to compiling SQLite itself.
# Compile-time options are loaded by the auto-generated file "defines.gypi".
# The --sqlite3 option can be provided to use a custom amalgamation instead.
# ===
{
'includes': ['common.gypi'],
'targets': [
{
'target_name': 'locate_sqlite3',
'type': 'none',
'hard_dependency': 1,
'conditions': [
['sqlite3 == ""', {
'actions': [{
'action_name': 'copy_builtin_sqlite3',
'inputs': [
'sqlite3/sqlite3.c',
'sqlite3/sqlite3.h',
'sqlite3/sqlite3ext.h',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.c',
'<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.h',
'<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3ext.h',
],
'action': ['node', 'copy.js', '<(SHARED_INTERMEDIATE_DIR)/sqlite3', ''],
}],
}, {
'actions': [{
'action_name': 'copy_custom_sqlite3',
'inputs': [
'<(sqlite3)/sqlite3.c',
'<(sqlite3)/sqlite3.h',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.c',
'<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.h',
],
'action': ['node', 'copy.js', '<(SHARED_INTERMEDIATE_DIR)/sqlite3', '<(sqlite3)'],
}],
}],
],
},
{
'target_name': 'sqlite3',
'type': 'static_library',
'dependencies': ['locate_sqlite3'],
'sources': ['<(SHARED_INTERMEDIATE_DIR)/sqlite3/sqlite3.c'],
'include_dirs': ['<(SHARED_INTERMEDIATE_DIR)/sqlite3/'],
'direct_dependent_settings': {
'include_dirs': ['<(SHARED_INTERMEDIATE_DIR)/sqlite3/'],
},
'cflags': ['-std=c99', '-w'],
'xcode_settings': {
'OTHER_CFLAGS': ['-std=c99'],
'WARNING_CFLAGS': ['-w'],
},
'conditions': [
['sqlite3 == ""', {
'includes': ['defines.gypi'],
}, {
'defines': [
# This is currently required by better-sqlite3.
'SQLITE_ENABLE_COLUMN_METADATA',
],
}]
],
'configurations': {
'Debug': {
'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 1 } }, # static debug
},
'Release': {
'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 0 } }, # static release
},
},
},
],
}

265969
node_modules/better-sqlite3/deps/sqlite3/sqlite3.c generated vendored Normal file

File diff suppressed because it is too large Load Diff

13968
node_modules/better-sqlite3/deps/sqlite3/sqlite3.h generated vendored Normal file

File diff suppressed because it is too large Load Diff

730
node_modules/better-sqlite3/deps/sqlite3/sqlite3ext.h generated vendored Normal file
View File

@@ -0,0 +1,730 @@
/*
** 2006 June 7
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance. Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
void * (*aggregate_context)(sqlite3_context*,int nBytes);
int (*aggregate_count)(sqlite3_context*);
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
int (*bind_double)(sqlite3_stmt*,int,double);
int (*bind_int)(sqlite3_stmt*,int,int);
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
int (*bind_null)(sqlite3_stmt*,int);
int (*bind_parameter_count)(sqlite3_stmt*);
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
int (*busy_timeout)(sqlite3*,int ms);
int (*changes)(sqlite3*);
int (*close)(sqlite3*);
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const char*));
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const void*));
const void * (*column_blob)(sqlite3_stmt*,int iCol);
int (*column_bytes)(sqlite3_stmt*,int iCol);
int (*column_bytes16)(sqlite3_stmt*,int iCol);
int (*column_count)(sqlite3_stmt*pStmt);
const char * (*column_database_name)(sqlite3_stmt*,int);
const void * (*column_database_name16)(sqlite3_stmt*,int);
const char * (*column_decltype)(sqlite3_stmt*,int i);
const void * (*column_decltype16)(sqlite3_stmt*,int);
double (*column_double)(sqlite3_stmt*,int iCol);
int (*column_int)(sqlite3_stmt*,int iCol);
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
const char * (*column_name)(sqlite3_stmt*,int);
const void * (*column_name16)(sqlite3_stmt*,int);
const char * (*column_origin_name)(sqlite3_stmt*,int);
const void * (*column_origin_name16)(sqlite3_stmt*,int);
const char * (*column_table_name)(sqlite3_stmt*,int);
const void * (*column_table_name16)(sqlite3_stmt*,int);
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
const void * (*column_text16)(sqlite3_stmt*,int iCol);
int (*column_type)(sqlite3_stmt*,int iCol);
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
int (*complete)(const char*sql);
int (*complete16)(const void*sql);
int (*create_collation)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_collation16)(sqlite3*,const void*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_function)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_function16)(sqlite3*,const void*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
int (*data_count)(sqlite3_stmt*pStmt);
sqlite3 * (*db_handle)(sqlite3_stmt*);
int (*declare_vtab)(sqlite3*,const char*);
int (*enable_shared_cache)(int);
int (*errcode)(sqlite3*db);
const char * (*errmsg)(sqlite3*);
const void * (*errmsg16)(sqlite3*);
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
int (*expired)(sqlite3_stmt*);
int (*finalize)(sqlite3_stmt*pStmt);
void (*free)(void*);
void (*free_table)(char**result);
int (*get_autocommit)(sqlite3*);
void * (*get_auxdata)(sqlite3_context*,int);
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
int (*global_recover)(void);
void (*interruptx)(sqlite3*);
sqlite_int64 (*last_insert_rowid)(sqlite3*);
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
char * (*mprintf)(const char*,...);
int (*open)(const char*,sqlite3**);
int (*open16)(const void*,sqlite3**);
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
void *(*realloc)(void*,int);
int (*reset)(sqlite3_stmt*pStmt);
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_double)(sqlite3_context*,double);
void (*result_error)(sqlite3_context*,const char*,int);
void (*result_error16)(sqlite3_context*,const void*,int);
void (*result_int)(sqlite3_context*,int);
void (*result_int64)(sqlite3_context*,sqlite_int64);
void (*result_null)(sqlite3_context*);
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_value)(sqlite3_context*,sqlite3_value*);
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
void (*thread_cleanup)(void);
int (*total_changes)(sqlite3*);
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
sqlite_int64),void*);
void * (*user_data)(sqlite3_context*);
const void * (*value_blob)(sqlite3_value*);
int (*value_bytes)(sqlite3_value*);
int (*value_bytes16)(sqlite3_value*);
double (*value_double)(sqlite3_value*);
int (*value_int)(sqlite3_value*);
sqlite_int64 (*value_int64)(sqlite3_value*);
int (*value_numeric_type)(sqlite3_value*);
const unsigned char * (*value_text)(sqlite3_value*);
const void * (*value_text16)(sqlite3_value*);
const void * (*value_text16be)(sqlite3_value*);
const void * (*value_text16le)(sqlite3_value*);
int (*value_type)(sqlite3_value*);
char *(*vmprintf)(const char*,va_list);
/* Added ??? */
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
/* Added by 3.3.13 */
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
int (*clear_bindings)(sqlite3_stmt*);
/* Added by 3.4.1 */
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
void (*xDestroy)(void *));
/* Added by 3.5.0 */
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
int (*blob_bytes)(sqlite3_blob*);
int (*blob_close)(sqlite3_blob*);
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
int,sqlite3_blob**);
int (*blob_read)(sqlite3_blob*,void*,int,int);
int (*blob_write)(sqlite3_blob*,const void*,int,int);
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*),
void(*)(void*));
int (*file_control)(sqlite3*,const char*,int,void*);
sqlite3_int64 (*memory_highwater)(int);
sqlite3_int64 (*memory_used)(void);
sqlite3_mutex *(*mutex_alloc)(int);
void (*mutex_enter)(sqlite3_mutex*);
void (*mutex_free)(sqlite3_mutex*);
void (*mutex_leave)(sqlite3_mutex*);
int (*mutex_try)(sqlite3_mutex*);
int (*open_v2)(const char*,sqlite3**,int,const char*);
int (*release_memory)(int);
void (*result_error_nomem)(sqlite3_context*);
void (*result_error_toobig)(sqlite3_context*);
int (*sleep)(int);
void (*soft_heap_limit)(int);
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
int (*strnicmp)(const char*,const char*,int);
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
int (*wal_autocheckpoint)(sqlite3*,int);
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
const char *(*db_filename)(sqlite3*,const char*);
int (*db_readonly)(sqlite3*,const char*);
int (*db_release_memory)(sqlite3*);
const char *(*errstr)(int);
int (*stmt_busy)(sqlite3_stmt*);
int (*stmt_readonly)(sqlite3_stmt*);
int (*stricmp)(const char*,const char*);
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
void(*)(void*));
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
void(*)(void*),unsigned char);
int (*cancel_auto_extension)(void(*)(void));
int (*load_extension)(sqlite3*,const char*,const char*,char**);
void *(*malloc64)(sqlite3_uint64);
sqlite3_uint64 (*msize)(void*);
void *(*realloc64)(void*,sqlite3_uint64);
void (*reset_auto_extension)(void);
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
void(*)(void*));
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
void(*)(void*), unsigned char);
int (*strglob)(const char*,const char*);
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
int (*strlike)(const char*,const char*,unsigned int);
int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */
int (*system_errno)(sqlite3*);
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
/* Version 3.18.0 and later */
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
/* Version 3.20.0 and later */
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
sqlite3_stmt**,const char**);
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
sqlite3_stmt**,const void**);
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
int (*vtab_nochange)(sqlite3_context*);
int (*value_nochange)(sqlite3_value*);
const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
int (*keyword_check)(const char*,int);
sqlite3_str *(*str_new)(sqlite3*);
char *(*str_finish)(sqlite3_str*);
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
void (*str_append)(sqlite3_str*, const char *zIn, int N);
void (*str_appendall)(sqlite3_str*, const char *zIn);
void (*str_appendchar)(sqlite3_str*, int N, char C);
void (*str_reset)(sqlite3_str*);
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
/* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
/* Version 3.26.0 and later */
const char *(*normalized_sql)(sqlite3_stmt*);
/* Version 3.28.0 and later */
int (*stmt_isexplain)(sqlite3_stmt*);
int (*value_frombind)(sqlite3_value*);
/* Version 3.30.0 and later */
int (*drop_modules)(sqlite3*,const char**);
/* Version 3.31.0 and later */
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
const char *(*uri_key)(const char*,int);
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
const char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(const char*);
sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*);
/* Version 3.36.1 and later */
sqlite3_int64 (*changes64)(sqlite3*);
sqlite3_int64 (*total_changes64)(sqlite3*);
/* Version 3.37.0 and later */
int (*autovacuum_pages)(sqlite3*,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*, void(*)(void*));
/* Version 3.38.0 and later */
int (*error_offset)(sqlite3*);
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
int (*vtab_distinct)(sqlite3_index_info*);
int (*vtab_in)(sqlite3_index_info*,int,int);
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
/* Version 3.39.0 and later */
int (*deserialize)(sqlite3*,const char*,unsigned char*,
sqlite3_int64,sqlite3_int64,unsigned);
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
unsigned int);
const char *(*db_name)(sqlite3*,int);
/* Version 3.40.0 and later */
int (*value_encoding)(sqlite3_value*);
/* Version 3.41.0 and later */
int (*is_interrupted)(sqlite3*);
/* Version 3.43.0 and later */
int (*stmt_explain)(sqlite3_stmt*,int);
/* Version 3.44.0 and later */
void *(*get_clientdata)(sqlite3*,const char*);
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
/* Version 3.50.0 and later */
int (*setlk_timeout)(sqlite3*,int,int);
/* Version 3.51.0 and later */
int (*set_errmsg)(sqlite3*,int,const char*);
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
sqlite3 *db, /* Handle to the database. */
char **pzErrMsg, /* Used to set error string on failure. */
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition. But the main library does not want to redefine
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob sqlite3_api->bind_blob
#define sqlite3_bind_double sqlite3_api->bind_double
#define sqlite3_bind_int sqlite3_api->bind_int
#define sqlite3_bind_int64 sqlite3_api->bind_int64
#define sqlite3_bind_null sqlite3_api->bind_null
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
#define sqlite3_bind_text sqlite3_api->bind_text
#define sqlite3_bind_text16 sqlite3_api->bind_text16
#define sqlite3_bind_value sqlite3_api->bind_value
#define sqlite3_busy_handler sqlite3_api->busy_handler
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
#define sqlite3_changes sqlite3_api->changes
#define sqlite3_close sqlite3_api->close
#define sqlite3_collation_needed sqlite3_api->collation_needed
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
#define sqlite3_column_blob sqlite3_api->column_blob
#define sqlite3_column_bytes sqlite3_api->column_bytes
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
#define sqlite3_column_count sqlite3_api->column_count
#define sqlite3_column_database_name sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype sqlite3_api->column_decltype
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
#define sqlite3_column_double sqlite3_api->column_double
#define sqlite3_column_int sqlite3_api->column_int
#define sqlite3_column_int64 sqlite3_api->column_int64
#define sqlite3_column_name sqlite3_api->column_name
#define sqlite3_column_name16 sqlite3_api->column_name16
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
#define sqlite3_column_table_name sqlite3_api->column_table_name
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
#define sqlite3_column_text sqlite3_api->column_text
#define sqlite3_column_text16 sqlite3_api->column_text16
#define sqlite3_column_type sqlite3_api->column_type
#define sqlite3_column_value sqlite3_api->column_value
#define sqlite3_commit_hook sqlite3_api->commit_hook
#define sqlite3_complete sqlite3_api->complete
#define sqlite3_complete16 sqlite3_api->complete16
#define sqlite3_create_collation sqlite3_api->create_collation
#define sqlite3_create_collation16 sqlite3_api->create_collation16
#define sqlite3_create_function sqlite3_api->create_function
#define sqlite3_create_function16 sqlite3_api->create_function16
#define sqlite3_create_module sqlite3_api->create_module
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
#define sqlite3_data_count sqlite3_api->data_count
#define sqlite3_db_handle sqlite3_api->db_handle
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
#define sqlite3_errcode sqlite3_api->errcode
#define sqlite3_errmsg sqlite3_api->errmsg
#define sqlite3_errmsg16 sqlite3_api->errmsg16
#define sqlite3_exec sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired sqlite3_api->expired
#endif
#define sqlite3_finalize sqlite3_api->finalize
#define sqlite3_free sqlite3_api->free
#define sqlite3_free_table sqlite3_api->free_table
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
#define sqlite3_get_table sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover sqlite3_api->global_recover
#endif
#define sqlite3_interrupt sqlite3_api->interruptx
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
#define sqlite3_libversion sqlite3_api->libversion
#define sqlite3_libversion_number sqlite3_api->libversion_number
#define sqlite3_malloc sqlite3_api->malloc
#define sqlite3_mprintf sqlite3_api->mprintf
#define sqlite3_open sqlite3_api->open
#define sqlite3_open16 sqlite3_api->open16
#define sqlite3_prepare sqlite3_api->prepare
#define sqlite3_prepare16 sqlite3_api->prepare16
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_profile sqlite3_api->profile
#define sqlite3_progress_handler sqlite3_api->progress_handler
#define sqlite3_realloc sqlite3_api->realloc
#define sqlite3_reset sqlite3_api->reset
#define sqlite3_result_blob sqlite3_api->result_blob
#define sqlite3_result_double sqlite3_api->result_double
#define sqlite3_result_error sqlite3_api->result_error
#define sqlite3_result_error16 sqlite3_api->result_error16
#define sqlite3_result_int sqlite3_api->result_int
#define sqlite3_result_int64 sqlite3_api->result_int64
#define sqlite3_result_null sqlite3_api->result_null
#define sqlite3_result_text sqlite3_api->result_text
#define sqlite3_result_text16 sqlite3_api->result_text16
#define sqlite3_result_text16be sqlite3_api->result_text16be
#define sqlite3_result_text16le sqlite3_api->result_text16le
#define sqlite3_result_value sqlite3_api->result_value
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
#define sqlite3_total_changes sqlite3_api->total_changes
#define sqlite3_trace sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook sqlite3_api->update_hook
#define sqlite3_user_data sqlite3_api->user_data
#define sqlite3_value_blob sqlite3_api->value_blob
#define sqlite3_value_bytes sqlite3_api->value_bytes
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
#define sqlite3_value_double sqlite3_api->value_double
#define sqlite3_value_int sqlite3_api->value_int
#define sqlite3_value_int64 sqlite3_api->value_int64
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
#define sqlite3_value_text sqlite3_api->value_text
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
#define sqlite3_blob_close sqlite3_api->blob_close
#define sqlite3_blob_open sqlite3_api->blob_open
#define sqlite3_blob_read sqlite3_api->blob_read
#define sqlite3_blob_write sqlite3_api->blob_write
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
#define sqlite3_file_control sqlite3_api->file_control
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
#define sqlite3_memory_used sqlite3_api->memory_used
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
#define sqlite3_mutex_free sqlite3_api->mutex_free
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
#define sqlite3_mutex_try sqlite3_api->mutex_try
#define sqlite3_open_v2 sqlite3_api->open_v2
#define sqlite3_release_memory sqlite3_api->release_memory
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
#define sqlite3_sleep sqlite3_api->sleep
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
#define sqlite3_stmt_status sqlite3_api->stmt_status
#define sqlite3_strnicmp sqlite3_api->strnicmp
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook sqlite3_api->wal_hook
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
#define sqlite3_vtab_config sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2 sqlite3_api->close_v2
#define sqlite3_db_filename sqlite3_api->db_filename
#define sqlite3_db_readonly sqlite3_api->db_readonly
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
#define sqlite3_errstr sqlite3_api->errstr
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
#define sqlite3_stricmp sqlite3_api->stricmp
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
#define sqlite3_bind_text64 sqlite3_api->bind_text64
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
#define sqlite3_load_extension sqlite3_api->load_extension
#define sqlite3_malloc64 sqlite3_api->malloc64
#define sqlite3_msize sqlite3_api->msize
#define sqlite3_realloc64 sqlite3_api->realloc64
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
#define sqlite3_result_blob64 sqlite3_api->result_blob64
#define sqlite3_result_text64 sqlite3_api->result_text64
#define sqlite3_strglob sqlite3_api->strglob
/* Version 3.8.11 and later */
#define sqlite3_value_dup sqlite3_api->value_dup
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64 sqlite3_api->status64
#define sqlite3_strlike sqlite3_api->strlike
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
/* Version 3.18.0 and later */
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
/* Version 3.20.0 and later */
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
#define sqlite3_keyword_count sqlite3_api->keyword_count
#define sqlite3_keyword_name sqlite3_api->keyword_name
#define sqlite3_keyword_check sqlite3_api->keyword_check
#define sqlite3_str_new sqlite3_api->str_new
#define sqlite3_str_finish sqlite3_api->str_finish
#define sqlite3_str_appendf sqlite3_api->str_appendf
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
#define sqlite3_str_append sqlite3_api->str_append
#define sqlite3_str_appendall sqlite3_api->str_appendall
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
#define sqlite3_str_reset sqlite3_api->str_reset
#define sqlite3_str_errcode sqlite3_api->str_errcode
#define sqlite3_str_length sqlite3_api->str_length
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
/* Version 3.26.0 and later */
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
/* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
#define sqlite3_value_frombind sqlite3_api->value_frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules sqlite3_api->drop_modules
/* Version 3.31.0 and later */
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
#define sqlite3_uri_key sqlite3_api->uri_key
#define sqlite3_filename_database sqlite3_api->filename_database
#define sqlite3_filename_journal sqlite3_api->filename_journal
#define sqlite3_filename_wal sqlite3_api->filename_wal
/* Version 3.32.0 and later */
#define sqlite3_create_filename sqlite3_api->create_filename
#define sqlite3_free_filename sqlite3_api->free_filename
#define sqlite3_database_file_object sqlite3_api->database_file_object
/* Version 3.34.0 and later */
#define sqlite3_txn_state sqlite3_api->txn_state
/* Version 3.36.1 and later */
#define sqlite3_changes64 sqlite3_api->changes64
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
/* Version 3.38.0 and later */
#define sqlite3_error_offset sqlite3_api->error_offset
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
#define sqlite3_vtab_in sqlite3_api->vtab_in
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
/* Version 3.39.0 and later */
#ifndef SQLITE_OMIT_DESERIALIZE
#define sqlite3_deserialize sqlite3_api->deserialize
#define sqlite3_serialize sqlite3_api->serialize
#endif
#define sqlite3_db_name sqlite3_api->db_name
/* Version 3.40.0 and later */
#define sqlite3_value_encoding sqlite3_api->value_encoding
/* Version 3.41.0 and later */
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
/* Version 3.43.0 and later */
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
/* Version 3.50.0 and later */
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
/* Version 3.51.0 and later */
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
#define sqlite3_db_status64 sqlite3_api->db_status64
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* SQLITE3EXT_H */

21
node_modules/better-sqlite3/deps/test_extension.c generated vendored Normal file
View File

@@ -0,0 +1,21 @@
#include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1
/*
This SQLite extension is used only for testing purposes (npm test).
*/
static void TestExtensionFunction(sqlite3_context* pCtx, int nVal, sqlite3_value** _) {
sqlite3_result_double(pCtx, (double)nVal);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_extension_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi) {
SQLITE_EXTENSION_INIT2(pApi)
if (pzErrMsg != 0) *pzErrMsg = 0;
sqlite3_create_function(db, "testExtensionFunction", -1, SQLITE_UTF8, 0, TestExtensionFunction, 0, 0);
return SQLITE_OK;
}

90
node_modules/better-sqlite3/lib/database.js generated vendored Normal file
View File

@@ -0,0 +1,90 @@
'use strict';
const fs = require('fs');
const path = require('path');
const util = require('./util');
const SqliteError = require('./sqlite-error');
let DEFAULT_ADDON;
function Database(filenameGiven, options) {
if (new.target == null) {
return new Database(filenameGiven, options);
}
// Apply defaults
let buffer;
if (Buffer.isBuffer(filenameGiven)) {
buffer = filenameGiven;
filenameGiven = ':memory:';
}
if (filenameGiven == null) filenameGiven = '';
if (options == null) options = {};
// Validate arguments
if (typeof filenameGiven !== 'string') throw new TypeError('Expected first argument to be a string');
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
if ('readOnly' in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
if ('memory' in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
// Interpret options
const filename = filenameGiven.trim();
const anonymous = filename === '' || filename === ':memory:';
const readonly = util.getBooleanOption(options, 'readonly');
const fileMustExist = util.getBooleanOption(options, 'fileMustExist');
const timeout = 'timeout' in options ? options.timeout : 5000;
const verbose = 'verbose' in options ? options.verbose : null;
const nativeBinding = 'nativeBinding' in options ? options.nativeBinding : null;
// Validate interpreted options
if (readonly && anonymous && !buffer) throw new TypeError('In-memory/temporary databases cannot be readonly');
if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
if (timeout > 0x7fffffff) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
if (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the "verbose" option to be a function');
if (nativeBinding != null && typeof nativeBinding !== 'string' && typeof nativeBinding !== 'object') throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
// Load the native addon
let addon;
if (nativeBinding == null) {
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require('bindings')('better_sqlite3.node'));
} else if (typeof nativeBinding === 'string') {
// See <https://webpack.js.org/api/module-variables/#__non_webpack_require__-webpack-specific>
const requireFunc = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : require;
addon = requireFunc(path.resolve(nativeBinding).replace(/(\.node)?$/, '.node'));
} else {
// See <https://github.com/WiseLibs/better-sqlite3/issues/972>
addon = nativeBinding;
}
if (!addon.isInitialized) {
addon.setErrorConstructor(SqliteError);
addon.isInitialized = true;
}
// Make sure the specified directory exists
if (!anonymous && !filename.startsWith('file:') && !fs.existsSync(path.dirname(filename))) {
throw new TypeError('Cannot open database because the directory does not exist');
}
Object.defineProperties(this, {
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
...wrappers.getters,
});
}
const wrappers = require('./methods/wrappers');
Database.prototype.prepare = wrappers.prepare;
Database.prototype.transaction = require('./methods/transaction');
Database.prototype.pragma = require('./methods/pragma');
Database.prototype.backup = require('./methods/backup');
Database.prototype.serialize = require('./methods/serialize');
Database.prototype.function = require('./methods/function');
Database.prototype.aggregate = require('./methods/aggregate');
Database.prototype.table = require('./methods/table');
Database.prototype.loadExtension = wrappers.loadExtension;
Database.prototype.exec = wrappers.exec;
Database.prototype.close = wrappers.close;
Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
Database.prototype.unsafeMode = wrappers.unsafeMode;
Database.prototype[util.inspect] = require('./methods/inspect');
module.exports = Database;

3
node_modules/better-sqlite3/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
'use strict';
module.exports = require('./database');
module.exports.SqliteError = require('./sqlite-error');

43
node_modules/better-sqlite3/lib/methods/aggregate.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
'use strict';
const { getBooleanOption, cppdb } = require('../util');
module.exports = function defineAggregate(name, options) {
// Validate arguments
if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');
if (typeof options !== 'object' || options === null) throw new TypeError('Expected second argument to be an options object');
if (!name) throw new TypeError('User-defined function name cannot be an empty string');
// Interpret options
const start = 'start' in options ? options.start : null;
const step = getFunctionOption(options, 'step', true);
const inverse = getFunctionOption(options, 'inverse', false);
const result = getFunctionOption(options, 'result', false);
const safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;
const deterministic = getBooleanOption(options, 'deterministic');
const directOnly = getBooleanOption(options, 'directOnly');
const varargs = getBooleanOption(options, 'varargs');
let argCount = -1;
// Determine argument count
if (!varargs) {
argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
if (argCount > 0) argCount -= 1;
if (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');
}
this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
return this;
};
const getFunctionOption = (options, key, required) => {
const value = key in options ? options[key] : null;
if (typeof value === 'function') return value;
if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`);
if (required) throw new TypeError(`Missing required option "${key}"`);
return null;
};
const getLength = ({ length }) => {
if (Number.isInteger(length) && length >= 0) return length;
throw new TypeError('Expected function.length to be a positive integer');
};

67
node_modules/better-sqlite3/lib/methods/backup.js generated vendored Normal file
View File

@@ -0,0 +1,67 @@
'use strict';
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const { cppdb } = require('../util');
const fsAccess = promisify(fs.access);
module.exports = async function backup(filename, options) {
if (options == null) options = {};
// Validate arguments
if (typeof filename !== 'string') throw new TypeError('Expected first argument to be a string');
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
// Interpret options
filename = filename.trim();
const attachedName = 'attached' in options ? options.attached : 'main';
const handler = 'progress' in options ? options.progress : null;
// Validate interpreted options
if (!filename) throw new TypeError('Backup filename cannot be an empty string');
if (filename === ':memory:') throw new TypeError('Invalid backup filename ":memory:"');
if (typeof attachedName !== 'string') throw new TypeError('Expected the "attached" option to be a string');
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
if (handler != null && typeof handler !== 'function') throw new TypeError('Expected the "progress" option to be a function');
// Make sure the specified directory exists
await fsAccess(path.dirname(filename)).catch(() => {
throw new TypeError('Cannot save backup because the directory does not exist');
});
const isNewFile = await fsAccess(filename).then(() => false, () => true);
return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
};
const runBackup = (backup, handler) => {
let rate = 0;
let useDefault = true;
return new Promise((resolve, reject) => {
setImmediate(function step() {
try {
const progress = backup.transfer(rate);
if (!progress.remainingPages) {
backup.close();
resolve(progress);
return;
}
if (useDefault) {
useDefault = false;
rate = 100;
}
if (handler) {
const ret = handler(progress);
if (ret !== undefined) {
if (typeof ret === 'number' && ret === ret) rate = Math.max(0, Math.min(0x7fffffff, Math.round(ret)));
else throw new TypeError('Expected progress callback to return a number or undefined');
}
}
setImmediate(step);
} catch (err) {
backup.close();
reject(err);
}
});
});
};

31
node_modules/better-sqlite3/lib/methods/function.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
'use strict';
const { getBooleanOption, cppdb } = require('../util');
module.exports = function defineFunction(name, options, fn) {
// Apply defaults
if (options == null) options = {};
if (typeof options === 'function') { fn = options; options = {}; }
// Validate arguments
if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');
if (typeof fn !== 'function') throw new TypeError('Expected last argument to be a function');
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
if (!name) throw new TypeError('User-defined function name cannot be an empty string');
// Interpret options
const safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;
const deterministic = getBooleanOption(options, 'deterministic');
const directOnly = getBooleanOption(options, 'directOnly');
const varargs = getBooleanOption(options, 'varargs');
let argCount = -1;
// Determine argument count
if (!varargs) {
argCount = fn.length;
if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError('Expected function.length to be a positive integer');
if (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');
}
this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
return this;
};

7
node_modules/better-sqlite3/lib/methods/inspect.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
'use strict';
const DatabaseInspection = function Database() {};
module.exports = function inspect(depth, opts) {
return Object.assign(new DatabaseInspection(), this);
};

12
node_modules/better-sqlite3/lib/methods/pragma.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
'use strict';
const { getBooleanOption, cppdb } = require('../util');
module.exports = function pragma(source, options) {
if (options == null) options = {};
if (typeof source !== 'string') throw new TypeError('Expected first argument to be a string');
if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');
const simple = getBooleanOption(options, 'simple');
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
return simple ? stmt.pluck().get() : stmt.all();
};

16
node_modules/better-sqlite3/lib/methods/serialize.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
'use strict';
const { cppdb } = require('../util');
module.exports = function serialize(options) {
if (options == null) options = {};
// Validate arguments
if (typeof options !== 'object') throw new TypeError('Expected first argument to be an options object');
// Interpret and validate options
const attachedName = 'attached' in options ? options.attached : 'main';
if (typeof attachedName !== 'string') throw new TypeError('Expected the "attached" option to be a string');
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
return this[cppdb].serialize(attachedName);
};

189
node_modules/better-sqlite3/lib/methods/table.js generated vendored Normal file
View File

@@ -0,0 +1,189 @@
'use strict';
const { cppdb } = require('../util');
module.exports = function defineTable(name, factory) {
// Validate arguments
if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');
if (!name) throw new TypeError('Virtual table module name cannot be an empty string');
// Determine whether the module is eponymous-only or not
let eponymous = false;
if (typeof factory === 'object' && factory !== null) {
eponymous = true;
factory = defer(parseTableDefinition(factory, 'used', name));
} else {
if (typeof factory !== 'function') throw new TypeError('Expected second argument to be a function or a table definition object');
factory = wrapFactory(factory);
}
this[cppdb].table(factory, name, eponymous);
return this;
};
function wrapFactory(factory) {
return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
const thisObject = {
module: moduleName,
database: databaseName,
table: tableName,
};
// Generate a new table definition by invoking the factory
const def = apply.call(factory, thisObject, args);
if (typeof def !== 'object' || def === null) {
throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
}
return parseTableDefinition(def, 'returned', moduleName);
};
}
function parseTableDefinition(def, verb, moduleName) {
// Validate required properties
if (!hasOwnProperty.call(def, 'rows')) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
}
if (!hasOwnProperty.call(def, 'columns')) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
}
// Validate "rows" property
const rows = def.rows;
if (typeof rows !== 'function' || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
}
// Validate "columns" property
let columns = def.columns;
if (!Array.isArray(columns) || !(columns = [...columns]).every(x => typeof x === 'string')) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
}
if (columns.length !== new Set(columns).size) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
}
if (!columns.length) {
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
}
// Validate "parameters" property
let parameters;
if (hasOwnProperty.call(def, 'parameters')) {
parameters = def.parameters;
if (!Array.isArray(parameters) || !(parameters = [...parameters]).every(x => typeof x === 'string')) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
}
} else {
parameters = inferParameters(rows);
}
if (parameters.length !== new Set(parameters).size) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
}
if (parameters.length > 32) {
throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
}
for (const parameter of parameters) {
if (columns.includes(parameter)) {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
}
}
// Validate "safeIntegers" option
let safeIntegers = 2;
if (hasOwnProperty.call(def, 'safeIntegers')) {
const bool = def.safeIntegers;
if (typeof bool !== 'boolean') {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
}
safeIntegers = +bool;
}
// Validate "directOnly" option
let directOnly = false;
if (hasOwnProperty.call(def, 'directOnly')) {
directOnly = def.directOnly;
if (typeof directOnly !== 'boolean') {
throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
}
}
// Generate SQL for the virtual table definition
const columnDefinitions = [
...parameters.map(identifier).map(str => `${str} HIDDEN`),
...columns.map(identifier),
];
return [
`CREATE TABLE x(${columnDefinitions.join(', ')});`,
wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),
parameters,
safeIntegers,
directOnly,
];
}
function wrapGenerator(generator, columnMap, moduleName) {
return function* virtualTable(...args) {
/*
We must defensively clone any buffers in the arguments, because
otherwise the generator could mutate one of them, which would cause
us to return incorrect values for hidden columns, potentially
corrupting the database.
*/
const output = args.map(x => Buffer.isBuffer(x) ? Buffer.from(x) : x);
for (let i = 0; i < columnMap.size; ++i) {
output.push(null); // Fill with nulls to prevent gaps in array (v8 optimization)
}
for (const row of generator(...args)) {
if (Array.isArray(row)) {
extractRowArray(row, output, columnMap.size, moduleName);
yield output;
} else if (typeof row === 'object' && row !== null) {
extractRowObject(row, output, columnMap, moduleName);
yield output;
} else {
throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
}
}
};
}
function extractRowArray(row, output, columnCount, moduleName) {
if (row.length !== columnCount) {
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
}
const offset = output.length - columnCount;
for (let i = 0; i < columnCount; ++i) {
output[i + offset] = row[i];
}
}
function extractRowObject(row, output, columnMap, moduleName) {
let count = 0;
for (const key of Object.keys(row)) {
const index = columnMap.get(key);
if (index === undefined) {
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
}
output[index] = row[key];
count += 1;
}
if (count !== columnMap.size) {
throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
}
}
function inferParameters({ length }) {
if (!Number.isInteger(length) || length < 0) {
throw new TypeError('Expected function.length to be a positive integer');
}
const params = [];
for (let i = 0; i < length; ++i) {
params.push(`$${i + 1}`);
}
return params;
}
const { hasOwnProperty } = Object.prototype;
const { apply } = Function.prototype;
const GeneratorFunctionPrototype = Object.getPrototypeOf(function*(){});
const identifier = str => `"${str.replace(/"/g, '""')}"`;
const defer = x => () => x;

78
node_modules/better-sqlite3/lib/methods/transaction.js generated vendored Normal file
View File

@@ -0,0 +1,78 @@
'use strict';
const { cppdb } = require('../util');
const controllers = new WeakMap();
module.exports = function transaction(fn) {
if (typeof fn !== 'function') throw new TypeError('Expected first argument to be a function');
const db = this[cppdb];
const controller = getController(db, this);
const { apply } = Function.prototype;
// Each version of the transaction function has these same properties
const properties = {
default: { value: wrapTransaction(apply, fn, db, controller.default) },
deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
database: { value: this, enumerable: true },
};
Object.defineProperties(properties.default.value, properties);
Object.defineProperties(properties.deferred.value, properties);
Object.defineProperties(properties.immediate.value, properties);
Object.defineProperties(properties.exclusive.value, properties);
// Return the default version of the transaction function
return properties.default.value;
};
// Return the database's cached transaction controller, or create a new one
const getController = (db, self) => {
let controller = controllers.get(db);
if (!controller) {
const shared = {
commit: db.prepare('COMMIT', self, false),
rollback: db.prepare('ROLLBACK', self, false),
savepoint: db.prepare('SAVEPOINT `\t_bs3.\t`', self, false),
release: db.prepare('RELEASE `\t_bs3.\t`', self, false),
rollbackTo: db.prepare('ROLLBACK TO `\t_bs3.\t`', self, false),
};
controllers.set(db, controller = {
default: Object.assign({ begin: db.prepare('BEGIN', self, false) }, shared),
deferred: Object.assign({ begin: db.prepare('BEGIN DEFERRED', self, false) }, shared),
immediate: Object.assign({ begin: db.prepare('BEGIN IMMEDIATE', self, false) }, shared),
exclusive: Object.assign({ begin: db.prepare('BEGIN EXCLUSIVE', self, false) }, shared),
});
}
return controller;
};
// Return a new transaction function by wrapping the given function
const wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
let before, after, undo;
if (db.inTransaction) {
before = savepoint;
after = release;
undo = rollbackTo;
} else {
before = begin;
after = commit;
undo = rollback;
}
before.run();
try {
const result = apply.call(fn, this, arguments);
if (result && typeof result.then === 'function') {
throw new TypeError('Transaction function cannot return a promise');
}
after.run();
return result;
} catch (ex) {
if (db.inTransaction) {
undo.run();
if (undo !== rollback) after.run();
}
throw ex;
}
};

54
node_modules/better-sqlite3/lib/methods/wrappers.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
'use strict';
const { cppdb } = require('../util');
exports.prepare = function prepare(sql) {
return this[cppdb].prepare(sql, this, false);
};
exports.exec = function exec(sql) {
this[cppdb].exec(sql);
return this;
};
exports.close = function close() {
this[cppdb].close();
return this;
};
exports.loadExtension = function loadExtension(...args) {
this[cppdb].loadExtension(...args);
return this;
};
exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
this[cppdb].defaultSafeIntegers(...args);
return this;
};
exports.unsafeMode = function unsafeMode(...args) {
this[cppdb].unsafeMode(...args);
return this;
};
exports.getters = {
name: {
get: function name() { return this[cppdb].name; },
enumerable: true,
},
open: {
get: function open() { return this[cppdb].open; },
enumerable: true,
},
inTransaction: {
get: function inTransaction() { return this[cppdb].inTransaction; },
enumerable: true,
},
readonly: {
get: function readonly() { return this[cppdb].readonly; },
enumerable: true,
},
memory: {
get: function memory() { return this[cppdb].memory; },
enumerable: true,
},
};

20
node_modules/better-sqlite3/lib/sqlite-error.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
'use strict';
const descriptor = { value: 'SqliteError', writable: true, enumerable: false, configurable: true };
function SqliteError(message, code) {
if (new.target !== SqliteError) {
return new SqliteError(message, code);
}
if (typeof code !== 'string') {
throw new TypeError('Expected second argument to be a string');
}
Error.call(this, message);
descriptor.value = '' + message;
Object.defineProperty(this, 'message', descriptor);
Error.captureStackTrace(this, SqliteError);
this.code = code;
}
Object.setPrototypeOf(SqliteError, Error);
Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
Object.defineProperty(SqliteError.prototype, 'name', descriptor);
module.exports = SqliteError;

12
node_modules/better-sqlite3/lib/util.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
'use strict';
exports.getBooleanOption = (options, key) => {
let value = false;
if (key in options && typeof (value = options[key]) !== 'boolean') {
throw new TypeError(`Expected the "${key}" option to be a boolean`);
}
return value;
};
exports.cppdb = Symbol();
exports.inspect = Symbol.for('nodejs.util.inspect.custom');

59
node_modules/better-sqlite3/package.json generated vendored Normal file
View File

@@ -0,0 +1,59 @@
{
"name": "better-sqlite3",
"version": "12.6.2",
"description": "The fastest and simplest library for SQLite in Node.js.",
"homepage": "http://github.com/WiseLibs/better-sqlite3",
"author": "Joshua Wise <joshuathomaswise@gmail.com>",
"repository": {
"type": "git",
"url": "git://github.com/WiseLibs/better-sqlite3.git"
},
"main": "lib/index.js",
"files": [
"binding.gyp",
"src/**/*.[ch]pp",
"lib/**",
"deps/**"
],
"engines": {
"node": "20.x || 22.x || 23.x || 24.x || 25.x"
},
"dependencies": {
"bindings": "^1.5.0",
"prebuild-install": "^7.1.1"
},
"overrides": {
"prebuild": {
"node-abi": "^4.25.0"
}
},
"devDependencies": {
"chai": "^4.3.8",
"cli-color": "^2.0.3",
"fs-extra": "^11.1.1",
"mocha": "^10.2.0",
"nodemark": "^0.3.0",
"prebuild": "^13.0.1",
"sqlite": "^5.0.1",
"sqlite3": "^5.1.6"
},
"scripts": {
"install": "prebuild-install || node-gyp rebuild --release",
"build-release": "node-gyp rebuild --release",
"build-debug": "node-gyp rebuild --debug",
"test": "mocha --exit --slow=75 --timeout=5000",
"benchmark": "node benchmark",
"download": "bash ./deps/download.sh"
},
"license": "MIT",
"keywords": [
"sql",
"sqlite",
"sqlite3",
"transactions",
"user-defined functions",
"aggregate functions",
"window functions",
"database"
]
}

47
node_modules/better-sqlite3/src/addon.cpp generated vendored Normal file
View File

@@ -0,0 +1,47 @@
struct Addon {
explicit Addon(v8::Isolate* isolate) :
privileged_info(NULL),
next_id(0),
cs(isolate) {}
static void Cleanup(void* ptr) {
Addon* addon = static_cast<Addon*>(ptr);
for (Database* db : addon->dbs) db->CloseHandles();
addon->dbs.clear();
delete addon;
}
inline sqlite3_uint64 NextId() {
return next_id++;
}
static void ConfigureURI() {
static std::once_flag init_flag;
std::call_once(init_flag, [](){
const char* env = getenv("SQLITE_USE_URI");
if (env != NULL) {
if (strcmp(env, "1") == 0) {
int status = sqlite3_config(SQLITE_CONFIG_URI, 1);
assert(status == SQLITE_OK); ((void)status);
} else if (strcmp(env, "0") == 0) {
int status = sqlite3_config(SQLITE_CONFIG_URI, 0);
assert(status == SQLITE_OK); ((void)status);
}
}
});
}
static NODE_METHOD(JS_setErrorConstructor) {
REQUIRE_ARGUMENT_FUNCTION(first, v8::Local<v8::Function> SqliteError);
OnlyAddon->SqliteError.Reset(OnlyIsolate, SqliteError);
}
v8::Global<v8::Function> Statement;
v8::Global<v8::Function> StatementIterator;
v8::Global<v8::Function> Backup;
v8::Global<v8::Function> SqliteError;
NODE_ARGUMENTS_POINTER privileged_info;
sqlite3_uint64 next_id;
CS cs;
std::set<Database*, Database::CompareDatabase> dbs;
};

74
node_modules/better-sqlite3/src/better_sqlite3.cpp generated vendored Normal file
View File

@@ -0,0 +1,74 @@
#include <climits>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <mutex>
#include <sqlite3.h>
#include <node.h>
#include <node_object_wrap.h>
#include <node_buffer.h>
struct Addon;
class Database;
class Statement;
class StatementIterator;
class Backup;
#include "util/macros.cpp"
#include "util/helpers.cpp"
#include "util/constants.cpp"
#include "util/bind-map.cpp"
#include "util/data-converter.cpp"
#include "util/data.cpp"
#if defined(NODE_MODULE_VERSION) && NODE_MODULE_VERSION >= 127
#include "util/row-builder.cpp"
#endif
#include "objects/backup.hpp"
#include "objects/statement.hpp"
#include "objects/database.hpp"
#include "addon.cpp"
#include "objects/statement-iterator.hpp"
#include "util/query-macros.cpp"
#include "util/custom-function.cpp"
#include "util/custom-aggregate.cpp"
#include "util/custom-table.cpp"
#include "util/binder.cpp"
#include "objects/backup.cpp"
#include "objects/statement.cpp"
#include "objects/database.cpp"
#include "objects/statement-iterator.cpp"
NODE_MODULE_INIT(/* exports, context */) {
#if defined(NODE_MODULE_VERSION) && NODE_MODULE_VERSION >= 140
// Use Isolate::GetCurrent as stated in deprecation message within v8_context.h 13.9.72320122
v8::Isolate* isolate = v8::Isolate::GetCurrent();
#else
v8::Isolate* isolate = context->GetIsolate();
#endif
v8::HandleScope scope(isolate);
Addon::ConfigureURI();
// Initialize addon instance.
Addon* addon = new Addon(isolate);
v8::Local<v8::External> data = v8::External::New(isolate, addon);
node::AddEnvironmentCleanupHook(isolate, Addon::Cleanup, addon);
// Create and export native-backed classes and functions.
exports->Set(context, InternalizedFromLatin1(isolate, "Database"), Database::Init(isolate, data)).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "Statement"), Statement::Init(isolate, data)).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "StatementIterator"), StatementIterator::Init(isolate, data)).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "Backup"), Backup::Init(isolate, data)).FromJust();
exports->Set(context, InternalizedFromLatin1(isolate, "setErrorConstructor"), v8::FunctionTemplate::New(isolate, Addon::JS_setErrorConstructor, data)->GetFunction(context).ToLocalChecked()).FromJust();
// Store addon instance data.
addon->Statement.Reset(isolate, exports->Get(context, InternalizedFromLatin1(isolate, "Statement")).ToLocalChecked().As<v8::Function>());
addon->StatementIterator.Reset(isolate, exports->Get(context, InternalizedFromLatin1(isolate, "StatementIterator")).ToLocalChecked().As<v8::Function>());
addon->Backup.Reset(isolate, exports->Get(context, InternalizedFromLatin1(isolate, "Backup")).ToLocalChecked().As<v8::Function>());
}

120
node_modules/better-sqlite3/src/objects/backup.cpp generated vendored Normal file
View File

@@ -0,0 +1,120 @@
Backup::Backup(
Database* db,
sqlite3* dest_handle,
sqlite3_backup* backup_handle,
sqlite3_uint64 id,
bool unlink
) :
node::ObjectWrap(),
db(db),
dest_handle(dest_handle),
backup_handle(backup_handle),
id(id),
alive(true),
unlink(unlink) {
assert(db != NULL);
assert(dest_handle != NULL);
assert(backup_handle != NULL);
db->AddBackup(this);
}
Backup::~Backup() {
if (alive) db->RemoveBackup(this);
CloseHandles();
}
// Whenever this is used, db->RemoveBackup must be invoked beforehand.
void Backup::CloseHandles() {
if (alive) {
alive = false;
std::string filename(sqlite3_db_filename(dest_handle, "main"));
sqlite3_backup_finish(backup_handle);
int status = sqlite3_close(dest_handle);
assert(status == SQLITE_OK); ((void)status);
if (unlink) remove(filename.c_str());
}
}
INIT(Backup::Init) {
v8::Local<v8::FunctionTemplate> t = NewConstructorTemplate(isolate, data, JS_new, "Backup");
SetPrototypeMethod(isolate, data, t, "transfer", JS_transfer);
SetPrototypeMethod(isolate, data, t, "close", JS_close);
return t->GetFunction(OnlyContext).ToLocalChecked();
}
NODE_METHOD(Backup::JS_new) {
UseAddon;
if (!addon->privileged_info) return ThrowTypeError("Disabled constructor");
assert(info.IsConstructCall());
Database* db = Unwrap<Database>(addon->privileged_info->This());
REQUIRE_DATABASE_OPEN(db->GetState());
REQUIRE_DATABASE_NOT_BUSY(db->GetState());
v8::Local<v8::Object> database = (*addon->privileged_info)[0].As<v8::Object>();
v8::Local<v8::String> attachedName = (*addon->privileged_info)[1].As<v8::String>();
v8::Local<v8::String> destFile = (*addon->privileged_info)[2].As<v8::String>();
bool unlink = (*addon->privileged_info)[3].As<v8::Boolean>()->Value();
UseIsolate;
sqlite3* dest_handle;
v8::String::Utf8Value dest_file(isolate, destFile);
v8::String::Utf8Value attached_name(isolate, attachedName);
int mask = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
if (sqlite3_open_v2(*dest_file, &dest_handle, mask, NULL) != SQLITE_OK) {
Database::ThrowSqliteError(addon, dest_handle);
int status = sqlite3_close(dest_handle);
assert(status == SQLITE_OK); ((void)status);
return;
}
sqlite3_extended_result_codes(dest_handle, 1);
sqlite3_limit(dest_handle, SQLITE_LIMIT_LENGTH, INT_MAX);
sqlite3_backup* backup_handle = sqlite3_backup_init(dest_handle, "main", db->GetHandle(), *attached_name);
if (backup_handle == NULL) {
Database::ThrowSqliteError(addon, dest_handle);
int status = sqlite3_close(dest_handle);
assert(status == SQLITE_OK); ((void)status);
return;
}
Backup* backup = new Backup(db, dest_handle, backup_handle, addon->NextId(), unlink);
backup->Wrap(info.This());
SetFrozen(isolate, OnlyContext, info.This(), addon->cs.database, database);
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Backup::JS_transfer) {
Backup* backup = Unwrap<Backup>(info.This());
REQUIRE_ARGUMENT_INT32(first, int pages);
REQUIRE_DATABASE_OPEN(backup->db->GetState());
assert(backup->db->GetState()->busy == false);
assert(backup->alive == true);
sqlite3_backup* backup_handle = backup->backup_handle;
int status = sqlite3_backup_step(backup_handle, pages) & 0xff;
Addon* addon = backup->db->GetAddon();
if (status == SQLITE_OK || status == SQLITE_DONE || status == SQLITE_BUSY) {
int total_pages = sqlite3_backup_pagecount(backup_handle);
int remaining_pages = sqlite3_backup_remaining(backup_handle);
UseIsolate;
UseContext;
v8::Local<v8::Object> result = v8::Object::New(isolate);
result->Set(ctx, addon->cs.totalPages.Get(isolate), v8::Int32::New(isolate, total_pages)).FromJust();
result->Set(ctx, addon->cs.remainingPages.Get(isolate), v8::Int32::New(isolate, remaining_pages)).FromJust();
info.GetReturnValue().Set(result);
if (status == SQLITE_DONE) backup->unlink = false;
} else {
Database::ThrowSqliteError(addon, sqlite3_errstr(status), status);
}
}
NODE_METHOD(Backup::JS_close) {
Backup* backup = Unwrap<Backup>(info.This());
assert(backup->db->GetState()->busy == false);
if (backup->alive) backup->db->RemoveBackup(backup);
backup->CloseHandles();
info.GetReturnValue().Set(info.This());
}

36
node_modules/better-sqlite3/src/objects/backup.hpp generated vendored Normal file
View File

@@ -0,0 +1,36 @@
class Backup : public node::ObjectWrap {
public:
~Backup();
// Whenever this is used, db->RemoveBackup must be invoked beforehand.
void CloseHandles();
// Used to support ordered containers.
static inline bool Compare(Backup const * const a, Backup const * const b) {
return a->id < b->id;
}
static INIT(Init);
private:
explicit Backup(
Database* db,
sqlite3* dest_handle,
sqlite3_backup* backup_handle,
sqlite3_uint64 id,
bool unlink
);
static NODE_METHOD(JS_new);
static NODE_METHOD(JS_transfer);
static NODE_METHOD(JS_close);
Database* const db;
sqlite3* const dest_handle;
sqlite3_backup* const backup_handle;
const sqlite3_uint64 id;
bool alive;
bool unlink;
};

417
node_modules/better-sqlite3/src/objects/database.cpp generated vendored Normal file
View File

@@ -0,0 +1,417 @@
const int Database::MAX_BUFFER_SIZE = (
node::Buffer::kMaxLength > INT_MAX
? INT_MAX
: static_cast<int>(node::Buffer::kMaxLength)
);
const int Database::MAX_STRING_SIZE = (
v8::String::kMaxLength > INT_MAX
? INT_MAX
: static_cast<int>(v8::String::kMaxLength)
);
Database::Database(
v8::Isolate* isolate,
Addon* addon,
sqlite3* db_handle,
v8::Local<v8::Value> logger
) :
node::ObjectWrap(),
db_handle(db_handle),
open(true),
busy(false),
safe_ints(false),
unsafe_mode(false),
was_js_error(false),
has_logger(logger->IsFunction()),
iterators(0),
addon(addon),
logger(isolate, logger),
stmts(),
backups() {
assert(db_handle != NULL);
addon->dbs.insert(this);
}
Database::~Database() {
if (open) addon->dbs.erase(this);
CloseHandles();
}
// Whenever this is used, addon->dbs.erase() must be invoked beforehand.
void Database::CloseHandles() {
if (open) {
open = false;
for (Statement* stmt : stmts) stmt->CloseHandles();
for (Backup* backup : backups) backup->CloseHandles();
stmts.clear();
backups.clear();
int status = sqlite3_close(db_handle);
assert(status == SQLITE_OK); ((void)status);
}
}
void Database::ThrowDatabaseError() {
if (was_js_error) was_js_error = false;
else ThrowSqliteError(addon, db_handle);
}
void Database::ThrowSqliteError(Addon* addon, sqlite3* db_handle) {
assert(db_handle != NULL);
ThrowSqliteError(addon, sqlite3_errmsg(db_handle), sqlite3_extended_errcode(db_handle));
}
void Database::ThrowSqliteError(Addon* addon, const char* message, int code) {
assert(message != NULL);
assert((code & 0xff) != SQLITE_OK);
assert((code & 0xff) != SQLITE_ROW);
assert((code & 0xff) != SQLITE_DONE);
EasyIsolate;
v8::Local<v8::Value> args[2] = {
StringFromUtf8(isolate, message, -1),
addon->cs.Code(isolate, code)
};
isolate->ThrowException(addon->SqliteError.Get(isolate)
->NewInstance(OnlyContext, 2, args)
.ToLocalChecked());
}
// Allows Statements to log their executed SQL.
bool Database::Log(v8::Isolate* isolate, sqlite3_stmt* handle) {
assert(was_js_error == false);
if (!has_logger) return false;
char* expanded = sqlite3_expanded_sql(handle);
v8::Local<v8::Value> arg = StringFromUtf8(isolate, expanded ? expanded : sqlite3_sql(handle), -1);
was_js_error = logger.Get(isolate).As<v8::Function>()
->Call(OnlyContext, v8::Undefined(isolate), 1, &arg)
.IsEmpty();
if (expanded) sqlite3_free(expanded);
return was_js_error;
}
bool Database::Deserialize(
v8::Local<v8::Object> buffer,
Addon* addon,
sqlite3* db_handle,
bool readonly
) {
size_t length = node::Buffer::Length(buffer);
unsigned char* data = (unsigned char*)sqlite3_malloc64(length);
unsigned int flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE;
if (readonly) {
flags |= SQLITE_DESERIALIZE_READONLY;
}
if (length) {
if (!data) {
ThrowError("Out of memory");
return false;
}
memcpy(data, node::Buffer::Data(buffer), length);
}
int status = sqlite3_deserialize(db_handle, "main", data, length, length, flags);
if (status != SQLITE_OK) {
ThrowSqliteError(addon, status == SQLITE_ERROR ? "unable to deserialize database" : sqlite3_errstr(status), status);
return false;
}
return true;
}
void Database::FreeSerialization(char* data, void* _) {
sqlite3_free(data);
}
INIT(Database::Init) {
v8::Local<v8::FunctionTemplate> t = NewConstructorTemplate(isolate, data, JS_new, "Database");
SetPrototypeMethod(isolate, data, t, "prepare", JS_prepare);
SetPrototypeMethod(isolate, data, t, "exec", JS_exec);
SetPrototypeMethod(isolate, data, t, "backup", JS_backup);
SetPrototypeMethod(isolate, data, t, "serialize", JS_serialize);
SetPrototypeMethod(isolate, data, t, "function", JS_function);
SetPrototypeMethod(isolate, data, t, "aggregate", JS_aggregate);
SetPrototypeMethod(isolate, data, t, "table", JS_table);
SetPrototypeMethod(isolate, data, t, "loadExtension", JS_loadExtension);
SetPrototypeMethod(isolate, data, t, "close", JS_close);
SetPrototypeMethod(isolate, data, t, "defaultSafeIntegers", JS_defaultSafeIntegers);
SetPrototypeMethod(isolate, data, t, "unsafeMode", JS_unsafeMode);
SetPrototypeGetter(isolate, data, t, "open", JS_open);
SetPrototypeGetter(isolate, data, t, "inTransaction", JS_inTransaction);
return t->GetFunction(OnlyContext).ToLocalChecked();
}
NODE_METHOD(Database::JS_new) {
assert(info.IsConstructCall());
REQUIRE_ARGUMENT_STRING(first, v8::Local<v8::String> filename);
REQUIRE_ARGUMENT_STRING(second, v8::Local<v8::String> filenameGiven);
REQUIRE_ARGUMENT_BOOLEAN(third, bool in_memory);
REQUIRE_ARGUMENT_BOOLEAN(fourth, bool readonly);
REQUIRE_ARGUMENT_BOOLEAN(fifth, bool must_exist);
REQUIRE_ARGUMENT_INT32(sixth, int timeout);
REQUIRE_ARGUMENT_ANY(seventh, v8::Local<v8::Value> logger);
REQUIRE_ARGUMENT_ANY(eighth, v8::Local<v8::Value> buffer);
UseAddon;
UseIsolate;
sqlite3* db_handle;
v8::String::Utf8Value utf8(isolate, filename);
int mask = readonly ? SQLITE_OPEN_READONLY
: must_exist ? SQLITE_OPEN_READWRITE
: (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
if (sqlite3_open_v2(*utf8, &db_handle, mask, NULL) != SQLITE_OK) {
ThrowSqliteError(addon, db_handle);
int status = sqlite3_close(db_handle);
assert(status == SQLITE_OK); ((void)status);
return;
}
assert(sqlite3_db_mutex(db_handle) == NULL);
sqlite3_extended_result_codes(db_handle, 1);
sqlite3_busy_timeout(db_handle, timeout);
sqlite3_limit(db_handle, SQLITE_LIMIT_LENGTH, MAX_BUFFER_SIZE < MAX_STRING_SIZE ? MAX_BUFFER_SIZE : MAX_STRING_SIZE);
sqlite3_limit(db_handle, SQLITE_LIMIT_SQL_LENGTH, MAX_STRING_SIZE);
int status = sqlite3_db_config(db_handle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);
assert(status == SQLITE_OK); ((void)status);
status = sqlite3_db_config(db_handle, SQLITE_DBCONFIG_DEFENSIVE, 1, NULL);
assert(status == SQLITE_OK); ((void)status);
if (node::Buffer::HasInstance(buffer) && !Deserialize(buffer.As<v8::Object>(), addon, db_handle, readonly)) {
int status = sqlite3_close(db_handle);
assert(status == SQLITE_OK); ((void)status);
return;
}
UseContext;
Database* db = new Database(isolate, addon, db_handle, logger);
db->Wrap(info.This());
SetFrozen(isolate, ctx, info.This(), addon->cs.memory, v8::Boolean::New(isolate, in_memory));
SetFrozen(isolate, ctx, info.This(), addon->cs.readonly, v8::Boolean::New(isolate, readonly));
SetFrozen(isolate, ctx, info.This(), addon->cs.name, filenameGiven);
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Database::JS_prepare) {
REQUIRE_ARGUMENT_STRING(first, v8::Local<v8::String> source);
REQUIRE_ARGUMENT_OBJECT(second, v8::Local<v8::Object> database);
REQUIRE_ARGUMENT_BOOLEAN(third, bool pragmaMode);
(void)source;
(void)database;
(void)pragmaMode;
UseAddon;
UseIsolate;
v8::Local<v8::Function> c = addon->Statement.Get(isolate);
addon->privileged_info = &info;
v8::MaybeLocal<v8::Object> maybeStatement = c->NewInstance(OnlyContext, 0, NULL);
addon->privileged_info = NULL;
if (!maybeStatement.IsEmpty()) info.GetReturnValue().Set(maybeStatement.ToLocalChecked());
}
NODE_METHOD(Database::JS_exec) {
Database* db = Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_STRING(first, v8::Local<v8::String> source);
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS_UNLESS_UNSAFE(db);
db->busy = true;
UseIsolate;
v8::String::Utf8Value utf8(isolate, source);
const char* sql = *utf8;
const char* tail;
int status;
const bool has_logger = db->has_logger;
sqlite3* const db_handle = db->db_handle;
sqlite3_stmt* handle;
for (;;) {
while (IS_SKIPPED(*sql)) ++sql;
status = sqlite3_prepare_v2(db_handle, sql, -1, &handle, &tail);
sql = tail;
if (!handle) break;
if (has_logger && db->Log(isolate, handle)) {
sqlite3_finalize(handle);
status = -1;
break;
}
do status = sqlite3_step(handle);
while (status == SQLITE_ROW);
status = sqlite3_finalize(handle);
if (status != SQLITE_OK) break;
}
db->busy = false;
if (status != SQLITE_OK) {
db->ThrowDatabaseError();
}
}
NODE_METHOD(Database::JS_backup) {
REQUIRE_ARGUMENT_OBJECT(first, v8::Local<v8::Object> database);
REQUIRE_ARGUMENT_STRING(second, v8::Local<v8::String> attachedName);
REQUIRE_ARGUMENT_STRING(third, v8::Local<v8::String> destFile);
REQUIRE_ARGUMENT_BOOLEAN(fourth, bool unlink);
(void)database;
(void)attachedName;
(void)destFile;
(void)unlink;
UseAddon;
UseIsolate;
v8::Local<v8::Function> c = addon->Backup.Get(isolate);
addon->privileged_info = &info;
v8::MaybeLocal<v8::Object> maybeBackup = c->NewInstance(OnlyContext, 0, NULL);
addon->privileged_info = NULL;
if (!maybeBackup.IsEmpty()) info.GetReturnValue().Set(maybeBackup.ToLocalChecked());
}
NODE_METHOD(Database::JS_serialize) {
Database* db = Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_STRING(first, v8::Local<v8::String> attachedName);
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
UseIsolate;
v8::String::Utf8Value attached_name(isolate, attachedName);
sqlite3_int64 length = -1;
unsigned char* data = sqlite3_serialize(db->db_handle, *attached_name, &length, 0);
if (!data && length) {
ThrowError("Out of memory");
return;
}
info.GetReturnValue().Set(
SAFE_NEW_BUFFER(isolate, reinterpret_cast<char*>(data), length, FreeSerialization, NULL).ToLocalChecked()
);
}
NODE_METHOD(Database::JS_function) {
Database* db = Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_FUNCTION(first, v8::Local<v8::Function> fn);
REQUIRE_ARGUMENT_STRING(second, v8::Local<v8::String> nameString);
REQUIRE_ARGUMENT_INT32(third, int argc);
REQUIRE_ARGUMENT_INT32(fourth, int safe_ints);
REQUIRE_ARGUMENT_BOOLEAN(fifth, bool deterministic);
REQUIRE_ARGUMENT_BOOLEAN(sixth, bool direct_only);
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
UseIsolate;
v8::String::Utf8Value name(isolate, nameString);
int mask = SQLITE_UTF8;
if (deterministic) mask |= SQLITE_DETERMINISTIC;
if (direct_only) mask |= SQLITE_DIRECTONLY;
safe_ints = safe_ints < 2 ? safe_ints : static_cast<int>(db->safe_ints);
if (sqlite3_create_function_v2(db->db_handle, *name, argc, mask, new CustomFunction(isolate, db, *name, fn, safe_ints), CustomFunction::xFunc, NULL, NULL, CustomFunction::xDestroy) != SQLITE_OK) {
db->ThrowDatabaseError();
}
}
NODE_METHOD(Database::JS_aggregate) {
Database* db = Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_ANY(first, v8::Local<v8::Value> start);
REQUIRE_ARGUMENT_FUNCTION(second, v8::Local<v8::Function> step);
REQUIRE_ARGUMENT_ANY(third, v8::Local<v8::Value> inverse);
REQUIRE_ARGUMENT_ANY(fourth, v8::Local<v8::Value> result);
REQUIRE_ARGUMENT_STRING(fifth, v8::Local<v8::String> nameString);
REQUIRE_ARGUMENT_INT32(sixth, int argc);
REQUIRE_ARGUMENT_INT32(seventh, int safe_ints);
REQUIRE_ARGUMENT_BOOLEAN(eighth, bool deterministic);
REQUIRE_ARGUMENT_BOOLEAN(ninth, bool direct_only);
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
UseIsolate;
v8::String::Utf8Value name(isolate, nameString);
auto xInverse = inverse->IsFunction() ? CustomAggregate::xInverse : NULL;
auto xValue = xInverse ? CustomAggregate::xValue : NULL;
int mask = SQLITE_UTF8;
if (deterministic) mask |= SQLITE_DETERMINISTIC;
if (direct_only) mask |= SQLITE_DIRECTONLY;
safe_ints = safe_ints < 2 ? safe_ints : static_cast<int>(db->safe_ints);
if (sqlite3_create_window_function(db->db_handle, *name, argc, mask, new CustomAggregate(isolate, db, *name, start, step, inverse, result, safe_ints), CustomAggregate::xStep, CustomAggregate::xFinal, xValue, xInverse, CustomAggregate::xDestroy) != SQLITE_OK) {
db->ThrowDatabaseError();
}
}
NODE_METHOD(Database::JS_table) {
Database* db = Unwrap<Database>(info.This());
REQUIRE_ARGUMENT_FUNCTION(first, v8::Local<v8::Function> factory);
REQUIRE_ARGUMENT_STRING(second, v8::Local<v8::String> nameString);
REQUIRE_ARGUMENT_BOOLEAN(third, bool eponymous);
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
UseIsolate;
v8::String::Utf8Value name(isolate, nameString);
sqlite3_module* module = eponymous ? &CustomTable::EPONYMOUS_MODULE : &CustomTable::MODULE;
db->busy = true;
if (sqlite3_create_module_v2(db->db_handle, *name, module, new CustomTable(isolate, db, *name, factory), CustomTable::Destructor) != SQLITE_OK) {
db->ThrowDatabaseError();
}
db->busy = false;
}
NODE_METHOD(Database::JS_loadExtension) {
Database* db = Unwrap<Database>(info.This());
v8::Local<v8::String> entryPoint;
REQUIRE_ARGUMENT_STRING(first, v8::Local<v8::String> filename);
if (info.Length() > 1) { REQUIRE_ARGUMENT_STRING(second, entryPoint); }
REQUIRE_DATABASE_OPEN(db);
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
UseIsolate;
char* error;
int status = sqlite3_load_extension(
db->db_handle,
*v8::String::Utf8Value(isolate, filename),
entryPoint.IsEmpty() ? NULL : *v8::String::Utf8Value(isolate, entryPoint),
&error
);
if (status != SQLITE_OK) {
ThrowSqliteError(db->addon, error, status);
}
sqlite3_free(error);
}
NODE_METHOD(Database::JS_close) {
Database* db = Unwrap<Database>(info.This());
if (db->open) {
REQUIRE_DATABASE_NOT_BUSY(db);
REQUIRE_DATABASE_NO_ITERATORS(db);
db->addon->dbs.erase(db);
db->CloseHandles();
}
}
NODE_METHOD(Database::JS_defaultSafeIntegers) {
Database* db = Unwrap<Database>(info.This());
if (info.Length() == 0) db->safe_ints = true;
else { REQUIRE_ARGUMENT_BOOLEAN(first, db->safe_ints); }
}
NODE_METHOD(Database::JS_unsafeMode) {
Database* db = Unwrap<Database>(info.This());
if (info.Length() == 0) db->unsafe_mode = true;
else { REQUIRE_ARGUMENT_BOOLEAN(first, db->unsafe_mode); }
sqlite3_db_config(db->db_handle, SQLITE_DBCONFIG_DEFENSIVE, static_cast<int>(!db->unsafe_mode), NULL);
}
NODE_GETTER(Database::JS_open) {
info.GetReturnValue().Set(Unwrap<Database>(info.This())->open);
}
NODE_GETTER(Database::JS_inTransaction) {
Database* db = Unwrap<Database>(info.This());
info.GetReturnValue().Set(db->open && !static_cast<bool>(sqlite3_get_autocommit(db->db_handle)));
}

103
node_modules/better-sqlite3/src/objects/database.hpp generated vendored Normal file
View File

@@ -0,0 +1,103 @@
class Database : public node::ObjectWrap {
public:
~Database();
// Whenever this is used, addon->dbs.erase() must be invoked beforehand.
void CloseHandles();
// Used to support ordered containers.
class CompareDatabase { public:
inline bool operator() (Database const * const a, Database const * const b) const {
return a < b;
}
};
class CompareStatement { public:
inline bool operator() (Statement const * const a, Statement const * const b) const {
return Statement::Compare(a, b);
}
};
class CompareBackup { public:
inline bool operator() (Backup const * const a, Backup const * const b) const {
return Backup::Compare(a, b);
}
};
// Proper error handling logic for when an sqlite3 operation fails.
void ThrowDatabaseError();
static void ThrowSqliteError(Addon* addon, sqlite3* db_handle);
static void ThrowSqliteError(Addon* addon, const char* message, int code);
// Allows Statements to log their executed SQL.
bool Log(v8::Isolate* isolate, sqlite3_stmt* handle);
// Allow Statements to manage themselves when created and garbage collected.
inline void AddStatement(Statement* stmt) { stmts.insert(stmts.end(), stmt); }
inline void RemoveStatement(Statement* stmt) { stmts.erase(stmt); }
// Allow Backups to manage themselves when created and garbage collected.
inline void AddBackup(Backup* backup) { backups.insert(backups.end(), backup); }
inline void RemoveBackup(Backup* backup) { backups.erase(backup); }
// A view for Statements to see and modify Database state.
// The order of these fields must exactly match their actual order.
struct State {
const bool open;
bool busy;
const bool safe_ints;
const bool unsafe_mode;
bool was_js_error;
const bool has_logger;
unsigned short iterators;
Addon* const addon;
};
inline State* GetState() { return reinterpret_cast<State*>(&open); }
inline sqlite3* GetHandle() { return db_handle; }
inline Addon* GetAddon() { return addon; }
static INIT(Init);
private:
explicit Database(
v8::Isolate* isolate,
Addon* addon,
sqlite3* db_handle,
v8::Local<v8::Value> logger
);
static NODE_METHOD(JS_new);
static NODE_METHOD(JS_prepare);
static NODE_METHOD(JS_exec);
static NODE_METHOD(JS_backup);
static NODE_METHOD(JS_serialize);
static NODE_METHOD(JS_function);
static NODE_METHOD(JS_aggregate);
static NODE_METHOD(JS_table);
static NODE_METHOD(JS_loadExtension);
static NODE_METHOD(JS_close);
static NODE_METHOD(JS_defaultSafeIntegers);
static NODE_METHOD(JS_unsafeMode);
static NODE_GETTER(JS_open);
static NODE_GETTER(JS_inTransaction);
static bool Deserialize(v8::Local<v8::Object> buffer, Addon* addon, sqlite3* db_handle, bool readonly);
static void FreeSerialization(char* data, void* _);
static const int MAX_BUFFER_SIZE;
static const int MAX_STRING_SIZE;
sqlite3* const db_handle;
bool open;
bool busy;
bool safe_ints;
bool unsafe_mode;
bool was_js_error;
const bool has_logger;
unsigned short iterators;
Addon* const addon;
const v8::Global<v8::Value> logger;
std::set<Statement*, CompareStatement> stmts;
std::set<Backup*, CompareBackup> backups;
};

View File

@@ -0,0 +1,113 @@
StatementIterator::StatementIterator(Statement* stmt, bool bound) :
node::ObjectWrap(),
stmt(stmt),
handle(stmt->handle),
db_state(stmt->db->GetState()),
bound(bound),
safe_ints(stmt->safe_ints),
mode(stmt->mode),
alive(true),
logged(!db_state->has_logger) {
assert(stmt != NULL);
assert(handle != NULL);
assert(stmt->bound == bound);
assert(stmt->alive == true);
assert(stmt->locked == false);
assert(db_state->iterators < USHRT_MAX);
stmt->locked = true;
db_state->iterators += 1;
}
// The ~Statement destructor currently covers any state this object creates.
// Additionally, we actually DON'T want to revert stmt->locked or db_state
// ->iterators in this destructor, to ensure deterministic database access.
StatementIterator::~StatementIterator() {}
void StatementIterator::Next(NODE_ARGUMENTS info) {
assert(alive == true);
db_state->busy = true;
if (!logged) {
logged = true;
if (stmt->db->Log(OnlyIsolate, handle)) {
db_state->busy = false;
Throw();
return;
}
}
int status = sqlite3_step(handle);
db_state->busy = false;
if (status == SQLITE_ROW) {
UseIsolate;
UseContext;
info.GetReturnValue().Set(
NewRecord(isolate, ctx, Data::GetRowJS(isolate, ctx, handle, safe_ints, mode), db_state->addon, false)
);
} else {
if (status == SQLITE_DONE) Return(info);
else Throw();
}
}
void StatementIterator::Return(NODE_ARGUMENTS info) {
Cleanup();
STATEMENT_RETURN_LOGIC(DoneRecord(OnlyIsolate, db_state->addon));
}
void StatementIterator::Throw() {
Cleanup();
Database* db = stmt->db;
STATEMENT_THROW_LOGIC();
}
void StatementIterator::Cleanup() {
assert(alive == true);
alive = false;
stmt->locked = false;
db_state->iterators -= 1;
sqlite3_reset(handle);
}
INIT(StatementIterator::Init) {
v8::Local<v8::FunctionTemplate> t = NewConstructorTemplate(isolate, data, JS_new, "StatementIterator");
SetPrototypeMethod(isolate, data, t, "next", JS_next);
SetPrototypeMethod(isolate, data, t, "return", JS_return);
SetPrototypeSymbolMethod(isolate, data, t, v8::Symbol::GetIterator(isolate), JS_symbolIterator);
return t->GetFunction(OnlyContext).ToLocalChecked();
}
NODE_METHOD(StatementIterator::JS_new) {
UseAddon;
if (!addon->privileged_info) return ThrowTypeError("Disabled constructor");
assert(info.IsConstructCall());
StatementIterator* iter;
{
NODE_ARGUMENTS info = *addon->privileged_info;
STATEMENT_START_LOGIC(REQUIRE_STATEMENT_RETURNS_DATA, DOES_ADD_ITERATOR);
iter = new StatementIterator(stmt, bound);
}
UseIsolate;
UseContext;
iter->Wrap(info.This());
SetFrozen(isolate, ctx, info.This(), addon->cs.statement, addon->privileged_info->This());
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(StatementIterator::JS_next) {
StatementIterator* iter = Unwrap<StatementIterator>(info.This());
REQUIRE_DATABASE_NOT_BUSY(iter->db_state);
if (iter->alive) iter->Next(info);
else info.GetReturnValue().Set(DoneRecord(OnlyIsolate, iter->db_state->addon));
}
NODE_METHOD(StatementIterator::JS_return) {
StatementIterator* iter = Unwrap<StatementIterator>(info.This());
REQUIRE_DATABASE_NOT_BUSY(iter->db_state);
if (iter->alive) iter->Return(info);
else info.GetReturnValue().Set(DoneRecord(OnlyIsolate, iter->db_state->addon));
}
NODE_METHOD(StatementIterator::JS_symbolIterator) {
info.GetReturnValue().Set(info.This());
}

View File

@@ -0,0 +1,50 @@
class StatementIterator : public node::ObjectWrap {
public:
// The ~Statement destructor currently covers any state this object creates.
// Additionally, we actually DON'T want to revert stmt->locked or db_state
// ->iterators in this destructor, to ensure deterministic database access.
~StatementIterator();
static INIT(Init);
private:
explicit StatementIterator(Statement* stmt, bool bound);
void Next(NODE_ARGUMENTS info);
void Return(NODE_ARGUMENTS info);
void Throw();
void Cleanup();
static inline v8::Local<v8::Object> NewRecord(
v8::Isolate* isolate,
v8::Local<v8::Context> ctx,
v8::Local<v8::Value> value,
Addon* addon,
bool done
) {
v8::Local<v8::Object> record = v8::Object::New(isolate);
record->Set(ctx, addon->cs.value.Get(isolate), value).FromJust();
record->Set(ctx, addon->cs.done.Get(isolate), v8::Boolean::New(isolate, done)).FromJust();
return record;
}
static inline v8::Local<v8::Object> DoneRecord(v8::Isolate* isolate, Addon* addon) {
return NewRecord(isolate, OnlyContext, v8::Undefined(isolate), addon, true);
}
static NODE_METHOD(JS_new);
static NODE_METHOD(JS_next);
static NODE_METHOD(JS_return);
static NODE_METHOD(JS_symbolIterator);
Statement* const stmt;
sqlite3_stmt* const handle;
Database::State* const db_state;
const bool bound;
const bool safe_ints;
const char mode;
bool alive;
bool logged;
};

383
node_modules/better-sqlite3/src/objects/statement.cpp generated vendored Normal file
View File

@@ -0,0 +1,383 @@
Statement::Statement(
Database* db,
sqlite3_stmt* handle,
sqlite3_uint64 id,
bool returns_data
) :
node::ObjectWrap(),
db(db),
handle(handle),
extras(new Extras(id)),
alive(true),
locked(false),
bound(false),
has_bind_map(false),
safe_ints(db->GetState()->safe_ints),
mode(Data::FLAT),
returns_data(returns_data) {
assert(db != NULL);
assert(handle != NULL);
assert(db->GetState()->open);
assert(!db->GetState()->busy);
db->AddStatement(this);
}
Statement::~Statement() {
if (alive) db->RemoveStatement(this);
CloseHandles();
delete extras;
}
// Whenever this is used, db->RemoveStatement must be invoked beforehand.
void Statement::CloseHandles() {
if (alive) {
alive = false;
sqlite3_finalize(handle);
}
}
// Returns the Statement's bind map (creates it upon first execution).
BindMap* Statement::GetBindMap(v8::Isolate* isolate) {
if (has_bind_map) return &extras->bind_map;
BindMap* bind_map = &extras->bind_map;
int param_count = sqlite3_bind_parameter_count(handle);
for (int i = 1; i <= param_count; ++i) {
const char* name = sqlite3_bind_parameter_name(handle, i);
if (name != NULL) bind_map->Add(isolate, name + 1, i);
}
has_bind_map = true;
return bind_map;
}
Statement::Extras::Extras(sqlite3_uint64 id)
: bind_map(0), id(id) {}
INIT(Statement::Init) {
v8::Local<v8::FunctionTemplate> t = NewConstructorTemplate(isolate, data, JS_new, "Statement");
SetPrototypeMethod(isolate, data, t, "run", JS_run);
SetPrototypeMethod(isolate, data, t, "get", JS_get);
SetPrototypeMethod(isolate, data, t, "all", JS_all);
SetPrototypeMethod(isolate, data, t, "iterate", JS_iterate);
SetPrototypeMethod(isolate, data, t, "bind", JS_bind);
SetPrototypeMethod(isolate, data, t, "pluck", JS_pluck);
SetPrototypeMethod(isolate, data, t, "expand", JS_expand);
SetPrototypeMethod(isolate, data, t, "raw", JS_raw);
SetPrototypeMethod(isolate, data, t, "safeIntegers", JS_safeIntegers);
SetPrototypeMethod(isolate, data, t, "columns", JS_columns);
SetPrototypeGetter(isolate, data, t, "busy", JS_busy);
return t->GetFunction(OnlyContext).ToLocalChecked();
}
NODE_METHOD(Statement::JS_new) {
UseAddon;
if (!addon->privileged_info) {
return ThrowTypeError("Statements can only be constructed by the db.prepare() method");
}
assert(info.IsConstructCall());
Database* db = Unwrap<Database>(addon->privileged_info->This());
REQUIRE_DATABASE_OPEN(db->GetState());
REQUIRE_DATABASE_NOT_BUSY(db->GetState());
v8::Local<v8::String> source = (*addon->privileged_info)[0].As<v8::String>();
v8::Local<v8::Object> database = (*addon->privileged_info)[1].As<v8::Object>();
bool pragmaMode = (*addon->privileged_info)[2].As<v8::Boolean>()->Value();
int flags = SQLITE_PREPARE_PERSISTENT;
if (pragmaMode) {
REQUIRE_DATABASE_NO_ITERATORS_UNLESS_UNSAFE(db->GetState());
flags = 0;
}
UseIsolate;
v8::String::Utf8Value utf8(isolate, source);
sqlite3_stmt* handle;
const char* tail;
if (sqlite3_prepare_v3(db->GetHandle(), *utf8, utf8.length() + 1, flags, &handle, &tail) != SQLITE_OK) {
return db->ThrowDatabaseError();
}
if (handle == NULL) {
return ThrowRangeError("The supplied SQL string contains no statements");
}
// https://github.com/WiseLibs/better-sqlite3/issues/975#issuecomment-1520934678
for (char c; (c = *tail); ) {
if (IS_SKIPPED(c)) {
++tail;
continue;
}
if (c == '/' && tail[1] == '*') {
tail += 2;
for (char c; (c = *tail); ++tail) {
if (c == '*' && tail[1] == '/') {
tail += 2;
break;
}
}
} else if (c == '-' && tail[1] == '-') {
tail += 2;
for (char c; (c = *tail); ++tail) {
if (c == '\n') {
++tail;
break;
}
}
} else {
sqlite3_finalize(handle);
return ThrowRangeError("The supplied SQL string contains more than one statement");
}
}
UseContext;
bool returns_data = sqlite3_column_count(handle) >= 1 || pragmaMode;
Statement* stmt = new Statement(db, handle, addon->NextId(), returns_data);
stmt->Wrap(info.This());
SetFrozen(isolate, ctx, info.This(), addon->cs.reader, v8::Boolean::New(isolate, returns_data));
SetFrozen(isolate, ctx, info.This(), addon->cs.readonly, v8::Boolean::New(isolate, sqlite3_stmt_readonly(handle) != 0));
SetFrozen(isolate, ctx, info.This(), addon->cs.source, source);
SetFrozen(isolate, ctx, info.This(), addon->cs.database, database);
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Statement::JS_run) {
STATEMENT_START(ALLOW_ANY_STATEMENT, DOES_MUTATE);
sqlite3* db_handle = db->GetHandle();
int total_changes_before = sqlite3_total_changes(db_handle);
sqlite3_step(handle);
if (sqlite3_reset(handle) == SQLITE_OK) {
int changes = sqlite3_total_changes(db_handle) == total_changes_before ? 0 : sqlite3_changes(db_handle);
sqlite3_int64 id = sqlite3_last_insert_rowid(db_handle);
Addon* addon = db->GetAddon();
UseContext;
v8::Local<v8::Object> result = v8::Object::New(isolate);
result->Set(ctx, addon->cs.changes.Get(isolate), v8::Int32::New(isolate, changes)).FromJust();
result->Set(ctx, addon->cs.lastInsertRowid.Get(isolate),
stmt->safe_ints
? v8::BigInt::New(isolate, id).As<v8::Value>()
: v8::Number::New(isolate, (double)id).As<v8::Value>()
).FromJust();
STATEMENT_RETURN(result);
}
STATEMENT_THROW();
}
NODE_METHOD(Statement::JS_get) {
STATEMENT_START(REQUIRE_STATEMENT_RETURNS_DATA, DOES_NOT_MUTATE);
int status = sqlite3_step(handle);
if (status == SQLITE_ROW) {
v8::Local<v8::Value> result = Data::GetRowJS(isolate, OnlyContext, handle, stmt->safe_ints, stmt->mode);
sqlite3_reset(handle);
STATEMENT_RETURN(result);
} else if (status == SQLITE_DONE) {
sqlite3_reset(handle);
STATEMENT_RETURN(v8::Undefined(isolate));
}
sqlite3_reset(handle);
STATEMENT_THROW();
}
NODE_METHOD(Statement::JS_all) {
STATEMENT_START(REQUIRE_STATEMENT_RETURNS_DATA, DOES_NOT_MUTATE);
UseContext;
const bool safe_ints = stmt->safe_ints;
const char mode = stmt->mode;
#if !defined(NODE_MODULE_VERSION) || NODE_MODULE_VERSION < 127
bool js_error = false;
uint32_t row_count = 0;
v8::Local<v8::Array> result = v8::Array::New(isolate, 0);
while (sqlite3_step(handle) == SQLITE_ROW) {
if (row_count == 0xffffffff) { ThrowRangeError("Array overflow (too many rows returned)"); js_error = true; break; }
result->Set(ctx, row_count++, Data::GetRowJS(isolate, ctx, handle, safe_ints, mode)).FromJust();
}
if (sqlite3_reset(handle) == SQLITE_OK && !js_error) {
STATEMENT_RETURN(result);
}
if (js_error) db->GetState()->was_js_error = true;
STATEMENT_THROW();
#else
v8::LocalVector<v8::Value> rows(isolate);
rows.reserve(8);
if (mode == Data::FLAT) {
RowBuilder rowBuilder(isolate, handle, safe_ints);
while (sqlite3_step(handle) == SQLITE_ROW) {
rows.emplace_back(rowBuilder.GetRowJS());
}
} else {
while (sqlite3_step(handle) == SQLITE_ROW) {
rows.emplace_back(Data::GetRowJS(isolate, ctx, handle, safe_ints, mode));
}
}
if (sqlite3_reset(handle) == SQLITE_OK) {
if (rows.size() > 0xffffffff) {
ThrowRangeError("Array overflow (too many rows returned)");
db->GetState()->was_js_error = true;
} else {
STATEMENT_RETURN(v8::Array::New(isolate, rows.data(), rows.size()));
}
}
STATEMENT_THROW();
#endif
}
NODE_METHOD(Statement::JS_iterate) {
UseAddon;
UseIsolate;
v8::Local<v8::Function> c = addon->StatementIterator.Get(isolate);
addon->privileged_info = &info;
v8::MaybeLocal<v8::Object> maybeIterator = c->NewInstance(OnlyContext, 0, NULL);
addon->privileged_info = NULL;
if (!maybeIterator.IsEmpty()) info.GetReturnValue().Set(maybeIterator.ToLocalChecked());
}
NODE_METHOD(Statement::JS_bind) {
Statement* stmt = Unwrap<Statement>(info.This());
if (stmt->bound) return ThrowTypeError("The bind() method can only be invoked once per statement object");
REQUIRE_DATABASE_OPEN(stmt->db->GetState());
REQUIRE_DATABASE_NOT_BUSY(stmt->db->GetState());
REQUIRE_STATEMENT_NOT_LOCKED(stmt);
STATEMENT_BIND(stmt->handle);
stmt->bound = true;
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Statement::JS_pluck) {
Statement* stmt = Unwrap<Statement>(info.This());
if (!stmt->returns_data) return ThrowTypeError("The pluck() method is only for statements that return data");
REQUIRE_DATABASE_NOT_BUSY(stmt->db->GetState());
REQUIRE_STATEMENT_NOT_LOCKED(stmt);
bool use = true;
if (info.Length() != 0) { REQUIRE_ARGUMENT_BOOLEAN(first, use); }
stmt->mode = use ? Data::PLUCK : stmt->mode == Data::PLUCK ? Data::FLAT : stmt->mode;
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Statement::JS_expand) {
Statement* stmt = Unwrap<Statement>(info.This());
if (!stmt->returns_data) return ThrowTypeError("The expand() method is only for statements that return data");
REQUIRE_DATABASE_NOT_BUSY(stmt->db->GetState());
REQUIRE_STATEMENT_NOT_LOCKED(stmt);
bool use = true;
if (info.Length() != 0) { REQUIRE_ARGUMENT_BOOLEAN(first, use); }
stmt->mode = use ? Data::EXPAND : stmt->mode == Data::EXPAND ? Data::FLAT : stmt->mode;
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Statement::JS_raw) {
Statement* stmt = Unwrap<Statement>(info.This());
if (!stmt->returns_data) return ThrowTypeError("The raw() method is only for statements that return data");
REQUIRE_DATABASE_NOT_BUSY(stmt->db->GetState());
REQUIRE_STATEMENT_NOT_LOCKED(stmt);
bool use = true;
if (info.Length() != 0) { REQUIRE_ARGUMENT_BOOLEAN(first, use); }
stmt->mode = use ? Data::RAW : stmt->mode == Data::RAW ? Data::FLAT : stmt->mode;
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Statement::JS_safeIntegers) {
Statement* stmt = Unwrap<Statement>(info.This());
REQUIRE_DATABASE_NOT_BUSY(stmt->db->GetState());
REQUIRE_STATEMENT_NOT_LOCKED(stmt);
if (info.Length() == 0) stmt->safe_ints = true;
else { REQUIRE_ARGUMENT_BOOLEAN(first, stmt->safe_ints); }
info.GetReturnValue().Set(info.This());
}
NODE_METHOD(Statement::JS_columns) {
Statement* stmt = Unwrap<Statement>(info.This());
if (!stmt->returns_data) return ThrowTypeError("The columns() method is only for statements that return data");
REQUIRE_DATABASE_OPEN(stmt->db->GetState());
REQUIRE_DATABASE_NOT_BUSY(stmt->db->GetState());
Addon* addon = stmt->db->GetAddon();
UseIsolate;
#if !defined(NODE_MODULE_VERSION) || NODE_MODULE_VERSION < 127
UseContext;
int column_count = sqlite3_column_count(stmt->handle);
v8::Local<v8::Array> columns = v8::Array::New(isolate);
v8::Local<v8::String> name = addon->cs.name.Get(isolate);
v8::Local<v8::String> columnName = addon->cs.column.Get(isolate);
v8::Local<v8::String> tableName = addon->cs.table.Get(isolate);
v8::Local<v8::String> databaseName = addon->cs.database.Get(isolate);
v8::Local<v8::String> typeName = addon->cs.type.Get(isolate);
for (int i = 0; i < column_count; ++i) {
v8::Local<v8::Object> column = v8::Object::New(isolate);
column->Set(ctx, name,
InternalizedFromUtf8OrNull(isolate, sqlite3_column_name(stmt->handle, i), -1)
).FromJust();
column->Set(ctx, columnName,
InternalizedFromUtf8OrNull(isolate, sqlite3_column_origin_name(stmt->handle, i), -1)
).FromJust();
column->Set(ctx, tableName,
InternalizedFromUtf8OrNull(isolate, sqlite3_column_table_name(stmt->handle, i), -1)
).FromJust();
column->Set(ctx, databaseName,
InternalizedFromUtf8OrNull(isolate, sqlite3_column_database_name(stmt->handle, i), -1)
).FromJust();
column->Set(ctx, typeName,
InternalizedFromUtf8OrNull(isolate, sqlite3_column_decltype(stmt->handle, i), -1)
).FromJust();
columns->Set(ctx, i, column).FromJust();
}
info.GetReturnValue().Set(columns);
#else
v8::LocalVector<v8::Name> keys(isolate);
keys.reserve(5);
keys.emplace_back(addon->cs.name.Get(isolate).As<v8::Name>());
keys.emplace_back(addon->cs.column.Get(isolate).As<v8::Name>());
keys.emplace_back(addon->cs.table.Get(isolate).As<v8::Name>());
keys.emplace_back(addon->cs.database.Get(isolate).As<v8::Name>());
keys.emplace_back(addon->cs.type.Get(isolate).As<v8::Name>());
int column_count = sqlite3_column_count(stmt->handle);
v8::LocalVector<v8::Value> columns(isolate);
columns.reserve(column_count);
for (int i = 0; i < column_count; ++i) {
v8::LocalVector<v8::Value> values(isolate);
keys.reserve(5);
values.emplace_back(
InternalizedFromUtf8OrNull(isolate, sqlite3_column_name(stmt->handle, i), -1)
);
values.emplace_back(
InternalizedFromUtf8OrNull(isolate, sqlite3_column_origin_name(stmt->handle, i), -1)
);
values.emplace_back(
InternalizedFromUtf8OrNull(isolate, sqlite3_column_table_name(stmt->handle, i), -1)
);
values.emplace_back(
InternalizedFromUtf8OrNull(isolate, sqlite3_column_database_name(stmt->handle, i), -1)
);
values.emplace_back(
InternalizedFromUtf8OrNull(isolate, sqlite3_column_decltype(stmt->handle, i), -1)
);
columns.emplace_back(
v8::Object::New(isolate,
GET_PROTOTYPE(v8::Object::New(isolate)),
keys.data(),
values.data(),
keys.size()
)
);
}
info.GetReturnValue().Set(
v8::Array::New(isolate, columns.data(), columns.size())
);
#endif
}
NODE_GETTER(Statement::JS_busy) {
Statement* stmt = Unwrap<Statement>(info.This());
info.GetReturnValue().Set(stmt->alive && stmt->locked);
}

58
node_modules/better-sqlite3/src/objects/statement.hpp generated vendored Normal file
View File

@@ -0,0 +1,58 @@
class Statement : public node::ObjectWrap { friend class StatementIterator;
public:
~Statement();
// Whenever this is used, db->RemoveStatement must be invoked beforehand.
void CloseHandles();
// Used to support ordered containers.
static inline bool Compare(Statement const * const a, Statement const * const b) {
return a->extras->id < b->extras->id;
}
// Returns the Statement's bind map (creates it upon first execution).
BindMap* GetBindMap(v8::Isolate* isolate);
static INIT(Init);
private:
// A class for holding values that are less often used.
class Extras { friend class Statement;
explicit Extras(sqlite3_uint64 id);
BindMap bind_map;
const sqlite3_uint64 id;
};
explicit Statement(
Database* db,
sqlite3_stmt* handle,
sqlite3_uint64 id,
bool returns_data
);
static NODE_METHOD(JS_new);
static NODE_METHOD(JS_run);
static NODE_METHOD(JS_get);
static NODE_METHOD(JS_all);
static NODE_METHOD(JS_iterate);
static NODE_METHOD(JS_bind);
static NODE_METHOD(JS_pluck);
static NODE_METHOD(JS_expand);
static NODE_METHOD(JS_raw);
static NODE_METHOD(JS_safeIntegers);
static NODE_METHOD(JS_columns);
static NODE_GETTER(JS_busy);
Database* const db;
sqlite3_stmt* const handle;
Extras* const extras;
bool alive;
bool locked;
bool bound;
bool has_bind_map;
bool safe_ints;
char mode;
const bool returns_data;
};

73
node_modules/better-sqlite3/src/util/bind-map.cpp generated vendored Normal file
View File

@@ -0,0 +1,73 @@
class BindMap {
public:
// This nested class represents a single mapping between a parameter name
// and its associated parameter index in a prepared statement.
class Pair { friend class BindMap;
public:
inline int GetIndex() {
return index;
}
inline v8::Local<v8::String> GetName(v8::Isolate* isolate) {
return name.Get(isolate);
}
private:
explicit Pair(v8::Isolate* isolate, const char* name, int index)
: name(isolate, InternalizedFromUtf8(isolate, name, -1)), index(index) {}
explicit Pair(v8::Isolate* isolate, Pair* pair)
: name(isolate, pair->name), index(pair->index) {}
const v8::Global<v8::String> name;
const int index;
};
explicit BindMap(char _) {
assert(_ == 0);
pairs = NULL;
capacity = 0;
length = 0;
}
~BindMap() {
while (length) pairs[--length].~Pair();
FREE_ARRAY<Pair>(pairs);
}
inline Pair* GetPairs() {
return pairs;
}
inline int GetSize() {
return length;
}
// Adds a pair to the bind map, expanding the capacity if necessary.
void Add(v8::Isolate* isolate, const char* name, int index) {
assert(name != NULL);
if (capacity == length) Grow(isolate);
new (pairs + length++) Pair(isolate, name, index);
}
private:
void Grow(v8::Isolate* isolate) {
assert(capacity == length);
capacity = (capacity << 1) | 2;
Pair* new_pairs = ALLOC_ARRAY<Pair>(capacity);
for (int i = 0; i < length; ++i) {
new (new_pairs + i) Pair(isolate, pairs + i);
pairs[i].~Pair();
}
FREE_ARRAY<Pair>(pairs);
pairs = new_pairs;
}
Pair* pairs;
int capacity;
int length;
};

193
node_modules/better-sqlite3/src/util/binder.cpp generated vendored Normal file
View File

@@ -0,0 +1,193 @@
class Binder {
public:
explicit Binder(sqlite3_stmt* _handle) {
handle = _handle;
param_count = sqlite3_bind_parameter_count(_handle);
anon_index = 0;
success = true;
}
bool Bind(NODE_ARGUMENTS info, int argc, Statement* stmt) {
assert(anon_index == 0);
Result result = BindArgs(info, argc, stmt);
if (success && result.count != param_count) {
if (result.count < param_count) {
if (!result.bound_object && stmt->GetBindMap(OnlyIsolate)->GetSize()) {
Fail(ThrowTypeError, "Missing named parameters");
} else {
Fail(ThrowRangeError, "Too few parameter values were provided");
}
} else {
Fail(ThrowRangeError, "Too many parameter values were provided");
}
}
return success;
}
private:
struct Result {
int count;
bool bound_object;
};
static bool IsPlainObject(v8::Isolate* isolate, v8::Local<v8::Object> obj) {
v8::Local<v8::Value> proto = GET_PROTOTYPE(obj);
v8::Local<v8::Context> ctx = obj->GetCreationContext().ToLocalChecked();
ctx->Enter();
v8::Local<v8::Value> baseProto = GET_PROTOTYPE(v8::Object::New(isolate));
ctx->Exit();
return proto->StrictEquals(baseProto) || proto->StrictEquals(v8::Null(isolate));
}
void Fail(void (*Throw)(const char* _), const char* message) {
assert(success == true);
assert((Throw == NULL) == (message == NULL));
assert(Throw == ThrowError || Throw == ThrowTypeError || Throw == ThrowRangeError || Throw == NULL);
if (Throw) Throw(message);
success = false;
}
int NextAnonIndex() {
while (sqlite3_bind_parameter_name(handle, ++anon_index) != NULL) {}
return anon_index;
}
// Binds the value at the given index or throws an appropriate error.
void BindValue(v8::Isolate* isolate, v8::Local<v8::Value> value, int index) {
int status = Data::BindValueFromJS(isolate, handle, index, value);
if (status != SQLITE_OK) {
switch (status) {
case -1:
return Fail(ThrowTypeError, "SQLite3 can only bind numbers, strings, bigints, buffers, and null");
case SQLITE_TOOBIG:
return Fail(ThrowRangeError, "The bound string, buffer, or bigint is too big");
case SQLITE_RANGE:
return Fail(ThrowRangeError, "Too many parameter values were provided");
case SQLITE_NOMEM:
return Fail(ThrowError, "Out of memory");
default:
return Fail(ThrowError, "An unexpected error occured while trying to bind parameters");
}
assert(false);
}
}
// Binds each value in the array or throws an appropriate error.
// The number of successfully bound parameters is returned.
int BindArray(v8::Isolate* isolate, v8::Local<v8::Array> arr) {
UseContext;
uint32_t length = arr->Length();
if (length > INT_MAX) {
Fail(ThrowRangeError, "Too many parameter values were provided");
return 0;
}
int len = static_cast<int>(length);
for (int i = 0; i < len; ++i) {
v8::MaybeLocal<v8::Value> maybeValue = arr->Get(ctx, i);
if (maybeValue.IsEmpty()) {
Fail(NULL, NULL);
return i;
}
BindValue(isolate, maybeValue.ToLocalChecked(), NextAnonIndex());
if (!success) {
return i;
}
}
return len;
}
// Binds all named parameters using the values found in the given object.
// The number of successfully bound parameters is returned.
// If a named parameter is missing from the object, an error is thrown.
// This should only be invoked once per instance.
int BindObject(v8::Isolate* isolate, v8::Local<v8::Object> obj, Statement* stmt) {
UseContext;
BindMap* bind_map = stmt->GetBindMap(isolate);
BindMap::Pair* pairs = bind_map->GetPairs();
int len = bind_map->GetSize();
for (int i = 0; i < len; ++i) {
v8::Local<v8::String> key = pairs[i].GetName(isolate);
// Check if the named parameter was provided.
v8::Maybe<bool> has_property = obj->HasOwnProperty(ctx, key);
if (has_property.IsNothing()) {
Fail(NULL, NULL);
return i;
}
if (!has_property.FromJust()) {
v8::String::Utf8Value param_name(isolate, key);
Fail(ThrowRangeError, (std::string("Missing named parameter \"") + *param_name + "\"").c_str());
return i;
}
// Get the current property value.
v8::MaybeLocal<v8::Value> maybeValue = obj->Get(ctx, key);
if (maybeValue.IsEmpty()) {
Fail(NULL, NULL);
return i;
}
BindValue(isolate, maybeValue.ToLocalChecked(), pairs[i].GetIndex());
if (!success) {
return i;
}
}
return len;
}
// Binds all parameters using the values found in the arguments object.
// Anonymous parameter values can be directly in the arguments object or in an Array.
// Named parameter values can be provided in a plain Object argument.
// Only one plain Object argument may be provided.
// If an error occurs, an appropriate error is thrown.
// The return value is a struct indicating how many parameters were successfully bound
// and whether or not it tried to bind an object.
Result BindArgs(NODE_ARGUMENTS info, int argc, Statement* stmt) {
UseIsolate;
int count = 0;
bool bound_object = false;
for (int i = 0; i < argc; ++i) {
v8::Local<v8::Value> arg = info[i];
if (arg->IsArray()) {
count += BindArray(isolate, arg.As<v8::Array>());
if (!success) break;
continue;
}
if (arg->IsObject() && !node::Buffer::HasInstance(arg)) {
v8::Local<v8::Object> obj = arg.As<v8::Object>();
if (IsPlainObject(isolate, obj)) {
if (bound_object) {
Fail(ThrowTypeError, "You cannot specify named parameters in two different objects");
break;
}
bound_object = true;
count += BindObject(isolate, obj, stmt);
if (!success) break;
continue;
} else if (stmt->GetBindMap(isolate)->GetSize()) {
Fail(ThrowTypeError, "Named parameters can only be passed within plain objects");
break;
}
}
BindValue(isolate, arg, NextAnonIndex());
if (!success) break;
count += 1;
}
return { count, bound_object };
}
sqlite3_stmt* handle;
int param_count;
int anon_index; // This value should only be used by NextAnonIndex()
bool success; // This value should only be set by Fail()
};

172
node_modules/better-sqlite3/src/util/constants.cpp generated vendored Normal file
View File

@@ -0,0 +1,172 @@
class CS {
public:
v8::Local<v8::String> Code(v8::Isolate* isolate, int code) {
auto element = codes.find(code);
if (element != codes.end()) return element->second.Get(isolate);
return StringFromUtf8(isolate, (std::string("UNKNOWN_SQLITE_ERROR_") + std::to_string(code)).c_str(), -1);
}
explicit CS(v8::Isolate* isolate) {
SetString(isolate, database, "database");
SetString(isolate, reader, "reader");
SetString(isolate, source, "source");
SetString(isolate, memory, "memory");
SetString(isolate, readonly, "readonly");
SetString(isolate, name, "name");
SetString(isolate, next, "next");
SetString(isolate, length, "length");
SetString(isolate, done, "done");
SetString(isolate, value, "value");
SetString(isolate, changes, "changes");
SetString(isolate, lastInsertRowid, "lastInsertRowid");
SetString(isolate, statement, "statement");
SetString(isolate, column, "column");
SetString(isolate, table, "table");
SetString(isolate, type, "type");
SetString(isolate, totalPages, "totalPages");
SetString(isolate, remainingPages, "remainingPages");
SetCode(isolate, SQLITE_OK, "SQLITE_OK");
SetCode(isolate, SQLITE_ERROR, "SQLITE_ERROR");
SetCode(isolate, SQLITE_INTERNAL, "SQLITE_INTERNAL");
SetCode(isolate, SQLITE_PERM, "SQLITE_PERM");
SetCode(isolate, SQLITE_ABORT, "SQLITE_ABORT");
SetCode(isolate, SQLITE_BUSY, "SQLITE_BUSY");
SetCode(isolate, SQLITE_LOCKED, "SQLITE_LOCKED");
SetCode(isolate, SQLITE_NOMEM, "SQLITE_NOMEM");
SetCode(isolate, SQLITE_READONLY, "SQLITE_READONLY");
SetCode(isolate, SQLITE_INTERRUPT, "SQLITE_INTERRUPT");
SetCode(isolate, SQLITE_IOERR, "SQLITE_IOERR");
SetCode(isolate, SQLITE_CORRUPT, "SQLITE_CORRUPT");
SetCode(isolate, SQLITE_NOTFOUND, "SQLITE_NOTFOUND");
SetCode(isolate, SQLITE_FULL, "SQLITE_FULL");
SetCode(isolate, SQLITE_CANTOPEN, "SQLITE_CANTOPEN");
SetCode(isolate, SQLITE_PROTOCOL, "SQLITE_PROTOCOL");
SetCode(isolate, SQLITE_EMPTY, "SQLITE_EMPTY");
SetCode(isolate, SQLITE_SCHEMA, "SQLITE_SCHEMA");
SetCode(isolate, SQLITE_TOOBIG, "SQLITE_TOOBIG");
SetCode(isolate, SQLITE_CONSTRAINT, "SQLITE_CONSTRAINT");
SetCode(isolate, SQLITE_MISMATCH, "SQLITE_MISMATCH");
SetCode(isolate, SQLITE_MISUSE, "SQLITE_MISUSE");
SetCode(isolate, SQLITE_NOLFS, "SQLITE_NOLFS");
SetCode(isolate, SQLITE_AUTH, "SQLITE_AUTH");
SetCode(isolate, SQLITE_FORMAT, "SQLITE_FORMAT");
SetCode(isolate, SQLITE_RANGE, "SQLITE_RANGE");
SetCode(isolate, SQLITE_NOTADB, "SQLITE_NOTADB");
SetCode(isolate, SQLITE_NOTICE, "SQLITE_NOTICE");
SetCode(isolate, SQLITE_WARNING, "SQLITE_WARNING");
SetCode(isolate, SQLITE_ROW, "SQLITE_ROW");
SetCode(isolate, SQLITE_DONE, "SQLITE_DONE");
SetCode(isolate, SQLITE_ERROR_MISSING_COLLSEQ, "SQLITE_ERROR_MISSING_COLLSEQ");
SetCode(isolate, SQLITE_ERROR_RETRY, "SQLITE_ERROR_RETRY");
SetCode(isolate, SQLITE_ERROR_SNAPSHOT, "SQLITE_ERROR_SNAPSHOT");
SetCode(isolate, SQLITE_IOERR_READ, "SQLITE_IOERR_READ");
SetCode(isolate, SQLITE_IOERR_SHORT_READ, "SQLITE_IOERR_SHORT_READ");
SetCode(isolate, SQLITE_IOERR_WRITE, "SQLITE_IOERR_WRITE");
SetCode(isolate, SQLITE_IOERR_FSYNC, "SQLITE_IOERR_FSYNC");
SetCode(isolate, SQLITE_IOERR_DIR_FSYNC, "SQLITE_IOERR_DIR_FSYNC");
SetCode(isolate, SQLITE_IOERR_TRUNCATE, "SQLITE_IOERR_TRUNCATE");
SetCode(isolate, SQLITE_IOERR_FSTAT, "SQLITE_IOERR_FSTAT");
SetCode(isolate, SQLITE_IOERR_UNLOCK, "SQLITE_IOERR_UNLOCK");
SetCode(isolate, SQLITE_IOERR_RDLOCK, "SQLITE_IOERR_RDLOCK");
SetCode(isolate, SQLITE_IOERR_DELETE, "SQLITE_IOERR_DELETE");
SetCode(isolate, SQLITE_IOERR_BLOCKED, "SQLITE_IOERR_BLOCKED");
SetCode(isolate, SQLITE_IOERR_NOMEM, "SQLITE_IOERR_NOMEM");
SetCode(isolate, SQLITE_IOERR_ACCESS, "SQLITE_IOERR_ACCESS");
SetCode(isolate, SQLITE_IOERR_CHECKRESERVEDLOCK, "SQLITE_IOERR_CHECKRESERVEDLOCK");
SetCode(isolate, SQLITE_IOERR_LOCK, "SQLITE_IOERR_LOCK");
SetCode(isolate, SQLITE_IOERR_CLOSE, "SQLITE_IOERR_CLOSE");
SetCode(isolate, SQLITE_IOERR_DIR_CLOSE, "SQLITE_IOERR_DIR_CLOSE");
SetCode(isolate, SQLITE_IOERR_SHMOPEN, "SQLITE_IOERR_SHMOPEN");
SetCode(isolate, SQLITE_IOERR_SHMSIZE, "SQLITE_IOERR_SHMSIZE");
SetCode(isolate, SQLITE_IOERR_SHMLOCK, "SQLITE_IOERR_SHMLOCK");
SetCode(isolate, SQLITE_IOERR_SHMMAP, "SQLITE_IOERR_SHMMAP");
SetCode(isolate, SQLITE_IOERR_SEEK, "SQLITE_IOERR_SEEK");
SetCode(isolate, SQLITE_IOERR_DELETE_NOENT, "SQLITE_IOERR_DELETE_NOENT");
SetCode(isolate, SQLITE_IOERR_MMAP, "SQLITE_IOERR_MMAP");
SetCode(isolate, SQLITE_IOERR_GETTEMPPATH, "SQLITE_IOERR_GETTEMPPATH");
SetCode(isolate, SQLITE_IOERR_CONVPATH, "SQLITE_IOERR_CONVPATH");
SetCode(isolate, SQLITE_IOERR_VNODE, "SQLITE_IOERR_VNODE");
SetCode(isolate, SQLITE_IOERR_AUTH, "SQLITE_IOERR_AUTH");
SetCode(isolate, SQLITE_IOERR_BEGIN_ATOMIC, "SQLITE_IOERR_BEGIN_ATOMIC");
SetCode(isolate, SQLITE_IOERR_COMMIT_ATOMIC, "SQLITE_IOERR_COMMIT_ATOMIC");
SetCode(isolate, SQLITE_IOERR_ROLLBACK_ATOMIC, "SQLITE_IOERR_ROLLBACK_ATOMIC");
SetCode(isolate, SQLITE_IOERR_DATA, "SQLITE_IOERR_DATA");
SetCode(isolate, SQLITE_IOERR_CORRUPTFS, "SQLITE_IOERR_CORRUPTFS");
SetCode(isolate, SQLITE_IOERR_IN_PAGE, "SQLITE_IOERR_IN_PAGE");
SetCode(isolate, SQLITE_LOCKED_SHAREDCACHE, "SQLITE_LOCKED_SHAREDCACHE");
SetCode(isolate, SQLITE_LOCKED_VTAB, "SQLITE_LOCKED_VTAB");
SetCode(isolate, SQLITE_BUSY_RECOVERY, "SQLITE_BUSY_RECOVERY");
SetCode(isolate, SQLITE_BUSY_SNAPSHOT, "SQLITE_BUSY_SNAPSHOT");
SetCode(isolate, SQLITE_CANTOPEN_NOTEMPDIR, "SQLITE_CANTOPEN_NOTEMPDIR");
SetCode(isolate, SQLITE_CANTOPEN_ISDIR, "SQLITE_CANTOPEN_ISDIR");
SetCode(isolate, SQLITE_CANTOPEN_FULLPATH, "SQLITE_CANTOPEN_FULLPATH");
SetCode(isolate, SQLITE_CANTOPEN_CONVPATH, "SQLITE_CANTOPEN_CONVPATH");
SetCode(isolate, SQLITE_CANTOPEN_DIRTYWAL, "SQLITE_CANTOPEN_DIRTYWAL");
SetCode(isolate, SQLITE_CANTOPEN_SYMLINK, "SQLITE_CANTOPEN_SYMLINK");
SetCode(isolate, SQLITE_CORRUPT_VTAB, "SQLITE_CORRUPT_VTAB");
SetCode(isolate, SQLITE_CORRUPT_SEQUENCE, "SQLITE_CORRUPT_SEQUENCE");
SetCode(isolate, SQLITE_CORRUPT_INDEX, "SQLITE_CORRUPT_INDEX");
SetCode(isolate, SQLITE_READONLY_RECOVERY, "SQLITE_READONLY_RECOVERY");
SetCode(isolate, SQLITE_READONLY_CANTLOCK, "SQLITE_READONLY_CANTLOCK");
SetCode(isolate, SQLITE_READONLY_ROLLBACK, "SQLITE_READONLY_ROLLBACK");
SetCode(isolate, SQLITE_READONLY_DBMOVED, "SQLITE_READONLY_DBMOVED");
SetCode(isolate, SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT");
SetCode(isolate, SQLITE_READONLY_DIRECTORY, "SQLITE_READONLY_DIRECTORY");
SetCode(isolate, SQLITE_ABORT_ROLLBACK, "SQLITE_ABORT_ROLLBACK");
SetCode(isolate, SQLITE_CONSTRAINT_CHECK, "SQLITE_CONSTRAINT_CHECK");
SetCode(isolate, SQLITE_CONSTRAINT_COMMITHOOK, "SQLITE_CONSTRAINT_COMMITHOOK");
SetCode(isolate, SQLITE_CONSTRAINT_FOREIGNKEY, "SQLITE_CONSTRAINT_FOREIGNKEY");
SetCode(isolate, SQLITE_CONSTRAINT_FUNCTION, "SQLITE_CONSTRAINT_FUNCTION");
SetCode(isolate, SQLITE_CONSTRAINT_NOTNULL, "SQLITE_CONSTRAINT_NOTNULL");
SetCode(isolate, SQLITE_CONSTRAINT_PRIMARYKEY, "SQLITE_CONSTRAINT_PRIMARYKEY");
SetCode(isolate, SQLITE_CONSTRAINT_TRIGGER, "SQLITE_CONSTRAINT_TRIGGER");
SetCode(isolate, SQLITE_CONSTRAINT_UNIQUE, "SQLITE_CONSTRAINT_UNIQUE");
SetCode(isolate, SQLITE_CONSTRAINT_VTAB, "SQLITE_CONSTRAINT_VTAB");
SetCode(isolate, SQLITE_CONSTRAINT_ROWID, "SQLITE_CONSTRAINT_ROWID");
SetCode(isolate, SQLITE_CONSTRAINT_PINNED, "SQLITE_CONSTRAINT_PINNED");
SetCode(isolate, SQLITE_CONSTRAINT_DATATYPE, "SQLITE_CONSTRAINT_DATATYPE");
SetCode(isolate, SQLITE_NOTICE_RECOVER_WAL, "SQLITE_NOTICE_RECOVER_WAL");
SetCode(isolate, SQLITE_NOTICE_RECOVER_ROLLBACK, "SQLITE_NOTICE_RECOVER_ROLLBACK");
SetCode(isolate, SQLITE_NOTICE_RBU, "SQLITE_NOTICE_RBU");
SetCode(isolate, SQLITE_WARNING_AUTOINDEX, "SQLITE_WARNING_AUTOINDEX");
SetCode(isolate, SQLITE_AUTH_USER, "SQLITE_AUTH_USER");
SetCode(isolate, SQLITE_OK_LOAD_PERMANENTLY, "SQLITE_OK_LOAD_PERMANENTLY");
SetCode(isolate, SQLITE_OK_SYMLINK, "SQLITE_OK_SYMLINK");
}
v8::Global<v8::String> database;
v8::Global<v8::String> reader;
v8::Global<v8::String> source;
v8::Global<v8::String> memory;
v8::Global<v8::String> readonly;
v8::Global<v8::String> name;
v8::Global<v8::String> next;
v8::Global<v8::String> length;
v8::Global<v8::String> done;
v8::Global<v8::String> value;
v8::Global<v8::String> changes;
v8::Global<v8::String> lastInsertRowid;
v8::Global<v8::String> statement;
v8::Global<v8::String> column;
v8::Global<v8::String> table;
v8::Global<v8::String> type;
v8::Global<v8::String> totalPages;
v8::Global<v8::String> remainingPages;
private:
static void SetString(v8::Isolate* isolate, v8::Global<v8::String>& constant, const char* str) {
constant.Reset(isolate, InternalizedFromLatin1(isolate, str));
}
void SetCode(v8::Isolate* isolate, int code, const char* str) {
codes.emplace(std::piecewise_construct,
std::forward_as_tuple(code),
std::forward_as_tuple(isolate, InternalizedFromLatin1(isolate, str)));
}
std::unordered_map<int, v8::Global<v8::String> > codes;
};

View File

@@ -0,0 +1,121 @@
class CustomAggregate : public CustomFunction {
public:
explicit CustomAggregate(
v8::Isolate* isolate,
Database* db,
const char* name,
v8::Local<v8::Value> start,
v8::Local<v8::Function> step,
v8::Local<v8::Value> inverse,
v8::Local<v8::Value> result,
bool safe_ints
) :
CustomFunction(isolate, db, name, step, safe_ints),
invoke_result(result->IsFunction()),
invoke_start(start->IsFunction()),
inverse(isolate, inverse->IsFunction() ? inverse.As<v8::Function>() : v8::Local<v8::Function>()),
result(isolate, result->IsFunction() ? result.As<v8::Function>() : v8::Local<v8::Function>()),
start(isolate, start) {}
static void xStep(sqlite3_context* invocation, int argc, sqlite3_value** argv) {
xStepBase(invocation, argc, argv, &CustomAggregate::fn);
}
static void xInverse(sqlite3_context* invocation, int argc, sqlite3_value** argv) {
xStepBase(invocation, argc, argv, &CustomAggregate::inverse);
}
static void xValue(sqlite3_context* invocation) {
xValueBase(invocation, false);
}
static void xFinal(sqlite3_context* invocation) {
xValueBase(invocation, true);
}
private:
static inline void xStepBase(sqlite3_context* invocation, int argc, sqlite3_value** argv, const v8::Global<v8::Function> CustomAggregate::*ptrtm) {
AGGREGATE_START();
v8::Local<v8::Value> args_fast[5];
v8::Local<v8::Value>* args = argc <= 4 ? args_fast : ALLOC_ARRAY<v8::Local<v8::Value>>(argc + 1);
args[0] = acc->value.Get(isolate);
if (argc != 0) Data::GetArgumentsJS(isolate, args + 1, argv, argc, self->safe_ints);
v8::MaybeLocal<v8::Value> maybeReturnValue = (self->*ptrtm).Get(isolate)->Call(OnlyContext, v8::Undefined(isolate), argc + 1, args);
if (args != args_fast) delete[] args;
if (maybeReturnValue.IsEmpty()) {
self->PropagateJSError(invocation);
} else {
v8::Local<v8::Value> returnValue = maybeReturnValue.ToLocalChecked();
if (!returnValue->IsUndefined()) acc->value.Reset(isolate, returnValue);
}
}
static inline void xValueBase(sqlite3_context* invocation, bool is_final) {
AGGREGATE_START();
if (!is_final) {
acc->is_window = true;
} else if (acc->is_window) {
DestroyAccumulator(invocation);
return;
}
v8::Local<v8::Value> result = acc->value.Get(isolate);
if (self->invoke_result) {
v8::MaybeLocal<v8::Value> maybeResult = self->result.Get(isolate)->Call(OnlyContext, v8::Undefined(isolate), 1, &result);
if (maybeResult.IsEmpty()) {
self->PropagateJSError(invocation);
return;
}
result = maybeResult.ToLocalChecked();
}
Data::ResultValueFromJS(isolate, invocation, result, self);
if (is_final) DestroyAccumulator(invocation);
}
struct Accumulator { public:
v8::Global<v8::Value> value;
bool initialized;
bool is_window;
};
Accumulator* GetAccumulator(sqlite3_context* invocation) {
Accumulator* acc = static_cast<Accumulator*>(sqlite3_aggregate_context(invocation, sizeof(Accumulator)));
if (!acc->initialized) {
assert(acc->value.IsEmpty());
acc->initialized = true;
if (invoke_start) {
v8::MaybeLocal<v8::Value> maybeSeed = start.Get(isolate).As<v8::Function>()->Call(OnlyContext, v8::Undefined(isolate), 0, NULL);
if (maybeSeed.IsEmpty()) PropagateJSError(invocation);
else acc->value.Reset(isolate, maybeSeed.ToLocalChecked());
} else {
assert(!start.IsEmpty());
acc->value.Reset(isolate, start);
}
}
return acc;
}
static void DestroyAccumulator(sqlite3_context* invocation) {
Accumulator* acc = static_cast<Accumulator*>(sqlite3_aggregate_context(invocation, sizeof(Accumulator)));
assert(acc->initialized);
acc->value.Reset();
}
void PropagateJSError(sqlite3_context* invocation) {
DestroyAccumulator(invocation);
CustomFunction::PropagateJSError(invocation);
}
const bool invoke_result;
const bool invoke_start;
const v8::Global<v8::Function> inverse;
const v8::Global<v8::Function> result;
const v8::Global<v8::Value> start;
};

View File

@@ -0,0 +1,59 @@
class CustomFunction : protected DataConverter {
public:
explicit CustomFunction(
v8::Isolate* isolate,
Database* db,
const char* name,
v8::Local<v8::Function> fn,
bool safe_ints
) :
name(name),
db(db),
isolate(isolate),
fn(isolate, fn),
safe_ints(safe_ints) {}
virtual ~CustomFunction() {}
static void xDestroy(void* self) {
delete static_cast<CustomFunction*>(self);
}
static void xFunc(sqlite3_context* invocation, int argc, sqlite3_value** argv) {
FUNCTION_START();
v8::Local<v8::Value> args_fast[4];
v8::Local<v8::Value>* args = NULL;
if (argc != 0) {
args = argc <= 4 ? args_fast : ALLOC_ARRAY<v8::Local<v8::Value>>(argc);
Data::GetArgumentsJS(isolate, args, argv, argc, self->safe_ints);
}
v8::MaybeLocal<v8::Value> maybeReturnValue = self->fn.Get(isolate)->Call(OnlyContext, v8::Undefined(isolate), argc, args);
if (args != args_fast) delete[] args;
if (maybeReturnValue.IsEmpty()) self->PropagateJSError(invocation);
else Data::ResultValueFromJS(isolate, invocation, maybeReturnValue.ToLocalChecked(), self);
}
protected:
void PropagateJSError(sqlite3_context* invocation) {
assert(db->GetState()->was_js_error == false);
db->GetState()->was_js_error = true;
sqlite3_result_error(invocation, "", 0);
}
std::string GetDataErrorPrefix() {
return std::string("User-defined function ") + name + "() returned";
}
private:
const std::string name;
Database* const db;
protected:
v8::Isolate* const isolate;
const v8::Global<v8::Function> fn;
const bool safe_ints;
};

409
node_modules/better-sqlite3/src/util/custom-table.cpp generated vendored Normal file
View File

@@ -0,0 +1,409 @@
class CustomTable {
public:
explicit CustomTable(
v8::Isolate* isolate,
Database* db,
const char* name,
v8::Local<v8::Function> factory
) :
addon(db->GetAddon()),
isolate(isolate),
db(db),
name(name),
factory(isolate, factory) {}
static void Destructor(void* self) {
delete static_cast<CustomTable*>(self);
}
static sqlite3_module MODULE;
static sqlite3_module EPONYMOUS_MODULE;
private:
// This nested class is instantiated on each CREATE VIRTUAL TABLE statement.
class VTab { friend class CustomTable;
explicit VTab(
CustomTable* parent,
v8::Local<v8::Function> generator,
std::vector<std::string> parameter_names,
bool safe_ints
) :
parent(parent),
parameter_count(parameter_names.size()),
safe_ints(safe_ints),
generator(parent->isolate, generator),
parameter_names(parameter_names) {
((void)base);
}
static inline CustomTable::VTab* Upcast(sqlite3_vtab* vtab) {
return reinterpret_cast<VTab*>(vtab);
}
inline sqlite3_vtab* Downcast() {
return reinterpret_cast<sqlite3_vtab*>(this);
}
sqlite3_vtab base;
CustomTable * const parent;
const int parameter_count;
const bool safe_ints;
const v8::Global<v8::Function> generator;
const std::vector<std::string> parameter_names;
};
// This nested class is instantiated each time a virtual table is scanned.
class Cursor { friend class CustomTable;
static inline CustomTable::Cursor* Upcast(sqlite3_vtab_cursor* cursor) {
return reinterpret_cast<Cursor*>(cursor);
}
inline sqlite3_vtab_cursor* Downcast() {
return reinterpret_cast<sqlite3_vtab_cursor*>(this);
}
inline CustomTable::VTab* GetVTab() {
return VTab::Upcast(base.pVtab);
}
sqlite3_vtab_cursor base;
v8::Global<v8::Object> iterator;
v8::Global<v8::Function> next;
v8::Global<v8::Array> row;
bool done;
sqlite_int64 rowid;
};
// This nested class is used by Data::ResultValueFromJS to report errors.
class TempDataConverter : DataConverter { friend class CustomTable;
explicit TempDataConverter(CustomTable* parent) :
parent(parent),
status(SQLITE_OK) {}
void PropagateJSError(sqlite3_context* invocation) {
status = SQLITE_ERROR;
parent->PropagateJSError();
}
std::string GetDataErrorPrefix() {
return std::string("Virtual table module \"") + parent->name + "\" yielded";
}
CustomTable * const parent;
int status;
};
// Although this function does nothing, we cannot use xConnect directly,
// because that would cause SQLite to register an eponymous virtual table.
static int xCreate(sqlite3* db_handle, void* _self, int argc, const char* const * argv, sqlite3_vtab** output, char** errOutput) {
return xConnect(db_handle, _self, argc, argv, output, errOutput);
}
// This method uses the factory function to instantiate a new virtual table.
static int xConnect(sqlite3* db_handle, void* _self, int argc, const char* const * argv, sqlite3_vtab** output, char** errOutput) {
CustomTable* self = static_cast<CustomTable*>(_self);
v8::Isolate* isolate = self->isolate;
v8::HandleScope scope(isolate);
UseContext;
v8::Local<v8::Value>* args = ALLOC_ARRAY<v8::Local<v8::Value>>(argc);
for (int i = 0; i < argc; ++i) {
args[i] = StringFromUtf8(isolate, argv[i], -1);
}
// Run the factory function to receive a new virtual table definition.
v8::MaybeLocal<v8::Value> maybeReturnValue = self->factory.Get(isolate)->Call(ctx, v8::Undefined(isolate), argc, args);
delete[] args;
if (maybeReturnValue.IsEmpty()) {
self->PropagateJSError();
return SQLITE_ERROR;
}
// Extract each part of the virtual table definition.
v8::Local<v8::Array> returnValue = maybeReturnValue.ToLocalChecked().As<v8::Array>();
v8::Local<v8::String> sqlString = returnValue->Get(ctx, 0).ToLocalChecked().As<v8::String>();
v8::Local<v8::Function> generator = returnValue->Get(ctx, 1).ToLocalChecked().As<v8::Function>();
v8::Local<v8::Array> parameterNames = returnValue->Get(ctx, 2).ToLocalChecked().As<v8::Array>();
int safe_ints = returnValue->Get(ctx, 3).ToLocalChecked().As<v8::Int32>()->Value();
bool direct_only = returnValue->Get(ctx, 4).ToLocalChecked().As<v8::Boolean>()->Value();
v8::String::Utf8Value sql(isolate, sqlString);
safe_ints = safe_ints < 2 ? safe_ints : static_cast<int>(self->db->GetState()->safe_ints);
// Copy the parameter names into a std::vector.
std::vector<std::string> parameter_names;
for (int i = 0, len = parameterNames->Length(); i < len; ++i) {
v8::Local<v8::String> parameterName = parameterNames->Get(ctx, i).ToLocalChecked().As<v8::String>();
v8::String::Utf8Value parameter_name(isolate, parameterName);
parameter_names.emplace_back(*parameter_name);
}
// Pass our SQL table definition to SQLite (this should never fail).
if (sqlite3_declare_vtab(db_handle, *sql) != SQLITE_OK) {
*errOutput = sqlite3_mprintf("failed to declare virtual table \"%s\"", argv[2]);
return SQLITE_ERROR;
}
if (direct_only && sqlite3_vtab_config(db_handle, SQLITE_VTAB_DIRECTONLY) != SQLITE_OK) {
*errOutput = sqlite3_mprintf("failed to configure virtual table \"%s\"", argv[2]);
return SQLITE_ERROR;
}
// Return the successfully created virtual table.
*output = (new VTab(self, generator, parameter_names, safe_ints))->Downcast();
return SQLITE_OK;
}
static int xDisconnect(sqlite3_vtab* vtab) {
delete VTab::Upcast(vtab);
return SQLITE_OK;
}
static int xOpen(sqlite3_vtab* vtab, sqlite3_vtab_cursor** output) {
*output = (new Cursor())->Downcast();
return SQLITE_OK;
}
static int xClose(sqlite3_vtab_cursor* cursor) {
delete Cursor::Upcast(cursor);
return SQLITE_OK;
}
// This method uses a fresh cursor to start a new scan of a virtual table.
// The args and idxNum are provided by xBestIndex (idxStr is unused).
// idxNum is a bitmap that provides the proper indices of the received args.
static int xFilter(sqlite3_vtab_cursor* _cursor, int idxNum, const char* idxStr, int argc, sqlite3_value** argv) {
Cursor* cursor = Cursor::Upcast(_cursor);
VTab* vtab = cursor->GetVTab();
CustomTable* self = vtab->parent;
Addon* addon = self->addon;
v8::Isolate* isolate = self->isolate;
v8::HandleScope scope(isolate);
UseContext;
// Convert the SQLite arguments into JavaScript arguments. Note that
// the values in argv may be in the wrong order, so we fix that here.
v8::Local<v8::Value> args_fast[4];
v8::Local<v8::Value>* args = NULL;
int parameter_count = vtab->parameter_count;
if (parameter_count != 0) {
args = parameter_count <= 4 ? args_fast : ALLOC_ARRAY<v8::Local<v8::Value>>(parameter_count);
int argn = 0;
bool safe_ints = vtab->safe_ints;
for (int i = 0; i < parameter_count; ++i) {
if (idxNum & 1 << i) {
args[i] = Data::GetValueJS(isolate, argv[argn++], safe_ints);
// If any arguments are NULL, the result set is necessarily
// empty, so don't bother to run the generator function.
if (args[i]->IsNull()) {
if (args != args_fast) delete[] args;
cursor->done = true;
return SQLITE_OK;
}
} else {
args[i] = v8::Undefined(isolate);
}
}
}
// Invoke the generator function to create a new iterator.
v8::MaybeLocal<v8::Value> maybeIterator = vtab->generator.Get(isolate)->Call(ctx, v8::Undefined(isolate), parameter_count, args);
if (args != args_fast) delete[] args;
if (maybeIterator.IsEmpty()) {
self->PropagateJSError();
return SQLITE_ERROR;
}
// Store the iterator and its next() method; we'll be using it a lot.
v8::Local<v8::Object> iterator = maybeIterator.ToLocalChecked().As<v8::Object>();
v8::Local<v8::Function> next = iterator->Get(ctx, addon->cs.next.Get(isolate)).ToLocalChecked().As<v8::Function>();
cursor->iterator.Reset(isolate, iterator);
cursor->next.Reset(isolate, next);
cursor->rowid = 0;
// Advance the iterator/cursor to the first row.
return xNext(cursor->Downcast());
}
// This method advances a virtual table's cursor to the next row.
// SQLite will call this method repeatedly, driving the generator function.
static int xNext(sqlite3_vtab_cursor* _cursor) {
Cursor* cursor = Cursor::Upcast(_cursor);
CustomTable* self = cursor->GetVTab()->parent;
Addon* addon = self->addon;
v8::Isolate* isolate = self->isolate;
v8::HandleScope scope(isolate);
UseContext;
v8::Local<v8::Object> iterator = cursor->iterator.Get(isolate);
v8::Local<v8::Function> next = cursor->next.Get(isolate);
v8::MaybeLocal<v8::Value> maybeRecord = next->Call(ctx, iterator, 0, NULL);
if (maybeRecord.IsEmpty()) {
self->PropagateJSError();
return SQLITE_ERROR;
}
v8::Local<v8::Object> record = maybeRecord.ToLocalChecked().As<v8::Object>();
bool done = record->Get(ctx, addon->cs.done.Get(isolate)).ToLocalChecked().As<v8::Boolean>()->Value();
if (!done) {
cursor->row.Reset(isolate, record->Get(ctx, addon->cs.value.Get(isolate)).ToLocalChecked().As<v8::Array>());
}
cursor->done = done;
cursor->rowid += 1;
return SQLITE_OK;
}
// If this method returns 1, SQLite will stop scanning the virtual table.
static int xEof(sqlite3_vtab_cursor* cursor) {
return Cursor::Upcast(cursor)->done;
}
// This method extracts some column from the cursor's current row.
static int xColumn(sqlite3_vtab_cursor* _cursor, sqlite3_context* invocation, int column) {
Cursor* cursor = Cursor::Upcast(_cursor);
CustomTable* self = cursor->GetVTab()->parent;
TempDataConverter temp_data_converter(self);
v8::Isolate* isolate = self->isolate;
v8::HandleScope scope(isolate);
v8::Local<v8::Array> row = cursor->row.Get(isolate);
v8::MaybeLocal<v8::Value> maybeColumnValue = row->Get(OnlyContext, column);
if (maybeColumnValue.IsEmpty()) {
temp_data_converter.PropagateJSError(NULL);
} else {
Data::ResultValueFromJS(isolate, invocation, maybeColumnValue.ToLocalChecked(), &temp_data_converter);
}
return temp_data_converter.status;
}
// This method outputs the rowid of the cursor's current row.
static int xRowid(sqlite3_vtab_cursor* cursor, sqlite_int64* output) {
*output = Cursor::Upcast(cursor)->rowid;
return SQLITE_OK;
}
// This method tells SQLite how to *plan* queries on our virtual table.
// It gets invoked (typically multiple times) during db.prepare().
static int xBestIndex(sqlite3_vtab* vtab, sqlite3_index_info* output) {
int parameter_count = VTab::Upcast(vtab)->parameter_count;
int argument_count = 0;
std::vector<std::pair<int, int>> forwarded;
for (int i = 0, len = output->nConstraint; i < len; ++i) {
auto item = output->aConstraint[i];
// The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
// operators have no left-hand operand, and so for those operators the
// corresponding item.iColumn is meaningless.
// We don't care those constraints.
if (item.op == SQLITE_INDEX_CONSTRAINT_LIMIT || item.op == SQLITE_INDEX_CONSTRAINT_OFFSET) {
continue;
}
// We only care about constraints on parameters, not regular columns.
if (item.iColumn >= 0 && item.iColumn < parameter_count) {
if (item.op != SQLITE_INDEX_CONSTRAINT_EQ) {
sqlite3_free(vtab->zErrMsg);
vtab->zErrMsg = sqlite3_mprintf(
"virtual table parameter \"%s\" can only be constrained by the '=' operator",
VTab::Upcast(vtab)->parameter_names.at(item.iColumn).c_str());
return SQLITE_ERROR;
}
if (!item.usable) {
// Don't allow SQLite to make plans that ignore arguments.
// Otherwise, a user could pass arguments, but then they
// could appear undefined in the generator function.
return SQLITE_CONSTRAINT;
}
forwarded.emplace_back(item.iColumn, i);
}
}
// Tell SQLite to forward arguments to xFilter.
std::sort(forwarded.begin(), forwarded.end());
for (std::pair<int, int> pair : forwarded) {
int bit = 1 << pair.first;
if (!(output->idxNum & bit)) {
output->idxNum |= bit;
output->aConstraintUsage[pair.second].argvIndex = ++argument_count;
output->aConstraintUsage[pair.second].omit = 1;
}
}
// Use a very high estimated cost so SQLite is not tempted to invoke the
// generator function within a loop, if it can be avoided.
output->estimatedCost = output->estimatedRows = 1000000000 / (argument_count + 1);
return SQLITE_OK;
}
void PropagateJSError() {
assert(db->GetState()->was_js_error == false);
db->GetState()->was_js_error = true;
}
Addon* const addon;
v8::Isolate* const isolate;
Database* const db;
const std::string name;
const v8::Global<v8::Function> factory;
};
sqlite3_module CustomTable::MODULE = {
0, /* iVersion */
xCreate, /* xCreate */
xConnect, /* xConnect */
xBestIndex, /* xBestIndex */
xDisconnect, /* xDisconnect */
xDisconnect, /* xDestroy */
xOpen, /* xOpen */
xClose, /* xClose */
xFilter, /* xFilter */
xNext, /* xNext */
xEof, /* xEof */
xColumn, /* xColumn */
xRowid, /* xRowid */
NULL, /* xUpdate */
NULL, /* xBegin */
NULL, /* xSync */
NULL, /* xCommit */
NULL, /* xRollback */
NULL, /* xFindMethod */
NULL, /* xRename */
NULL, /* xSavepoint */
NULL, /* xRelease */
NULL, /* xRollbackTo */
NULL, /* xShadowName */
NULL /* xIntegrity */
};
sqlite3_module CustomTable::EPONYMOUS_MODULE = {
0, /* iVersion */
NULL, /* xCreate */
xConnect, /* xConnect */
xBestIndex, /* xBestIndex */
xDisconnect, /* xDisconnect */
xDisconnect, /* xDestroy */
xOpen, /* xOpen */
xClose, /* xClose */
xFilter, /* xFilter */
xNext, /* xNext */
xEof, /* xEof */
xColumn, /* xColumn */
xRowid, /* xRowid */
NULL, /* xUpdate */
NULL, /* xBegin */
NULL, /* xSync */
NULL, /* xCommit */
NULL, /* xRollback */
NULL, /* xFindMethod */
NULL, /* xRename */
NULL, /* xSavepoint */
NULL, /* xRelease */
NULL, /* xRollbackTo */
NULL, /* xShadowName */
NULL /* xIntegrity */
};

View File

@@ -0,0 +1,17 @@
class DataConverter {
public:
void ThrowDataConversionError(sqlite3_context* invocation, bool isBigInt) {
if (isBigInt) {
ThrowRangeError((GetDataErrorPrefix() + " a bigint that was too big").c_str());
} else {
ThrowTypeError((GetDataErrorPrefix() + " an invalid value").c_str());
}
PropagateJSError(invocation);
}
protected:
virtual void PropagateJSError(sqlite3_context* invocation) = 0;
virtual std::string GetDataErrorPrefix() = 0;
};

194
node_modules/better-sqlite3/src/util/data.cpp generated vendored Normal file
View File

@@ -0,0 +1,194 @@
#define JS_VALUE_TO_SQLITE(to, value, isolate, ...) \
if (value->IsNumber()) { \
return sqlite3_##to##_double( \
__VA_ARGS__, \
value.As<v8::Number>()->Value() \
); \
} else if (value->IsBigInt()) { \
bool lossless; \
int64_t v = value.As<v8::BigInt>()->Int64Value(&lossless); \
if (lossless) { \
return sqlite3_##to##_int64(__VA_ARGS__, v); \
} \
} else if (value->IsString()) { \
v8::String::Utf8Value utf8(isolate, value.As<v8::String>()); \
return sqlite3_##to##_text( \
__VA_ARGS__, \
*utf8, \
utf8.length(), \
SQLITE_TRANSIENT \
); \
} else if (node::Buffer::HasInstance(value)) { \
const char* data = node::Buffer::Data(value); \
return sqlite3_##to##_blob( \
__VA_ARGS__, \
data ? data : "", \
node::Buffer::Length(value), \
SQLITE_TRANSIENT \
); \
} else if (value->IsNull() || value->IsUndefined()) { \
return sqlite3_##to##_null(__VA_ARGS__); \
}
#define SQLITE_VALUE_TO_JS(from, isolate, safe_ints, ...) \
switch (sqlite3_##from##_type(__VA_ARGS__)) { \
case SQLITE_INTEGER: \
if (safe_ints) { \
return v8::BigInt::New( \
isolate, \
sqlite3_##from##_int64(__VA_ARGS__) \
); \
} \
case SQLITE_FLOAT: \
return v8::Number::New( \
isolate, \
sqlite3_##from##_double(__VA_ARGS__) \
); \
case SQLITE_TEXT: \
return StringFromUtf8( \
isolate, \
reinterpret_cast<const char*>(sqlite3_##from##_text(__VA_ARGS__)), \
sqlite3_##from##_bytes(__VA_ARGS__) \
); \
case SQLITE_BLOB: \
return node::Buffer::Copy( \
isolate, \
static_cast<const char*>(sqlite3_##from##_blob(__VA_ARGS__)), \
sqlite3_##from##_bytes(__VA_ARGS__) \
).ToLocalChecked(); \
default: \
assert(sqlite3_##from##_type(__VA_ARGS__) == SQLITE_NULL); \
return v8::Null(isolate); \
} \
assert(false);
namespace Data {
static const char FLAT = 0;
static const char PLUCK = 1;
static const char EXPAND = 2;
static const char RAW = 3;
v8::Local<v8::Value> GetValueJS(v8::Isolate* isolate, sqlite3_stmt* handle, int column, bool safe_ints) {
SQLITE_VALUE_TO_JS(column, isolate, safe_ints, handle, column);
}
v8::Local<v8::Value> GetValueJS(v8::Isolate* isolate, sqlite3_value* value, bool safe_ints) {
SQLITE_VALUE_TO_JS(value, isolate, safe_ints, value);
}
v8::Local<v8::Value> GetExpandedRowJS(v8::Isolate* isolate, v8::Local<v8::Context> ctx, sqlite3_stmt* handle, bool safe_ints) {
v8::Local<v8::Object> row = v8::Object::New(isolate);
int column_count = sqlite3_column_count(handle);
for (int i = 0; i < column_count; ++i) {
const char* table_raw = sqlite3_column_table_name(handle, i);
v8::Local<v8::String> table = InternalizedFromUtf8(isolate, table_raw == NULL ? "$" : table_raw, -1);
v8::Local<v8::String> column = InternalizedFromUtf8(isolate, sqlite3_column_name(handle, i), -1);
v8::Local<v8::Value> value = Data::GetValueJS(isolate, handle, i, safe_ints);
if (row->HasOwnProperty(ctx, table).FromJust()) {
row->Get(ctx, table).ToLocalChecked().As<v8::Object>()->Set(ctx, column, value).FromJust();
} else {
v8::Local<v8::Object> nested = v8::Object::New(isolate);
row->Set(ctx, table, nested).FromJust();
nested->Set(ctx, column, value).FromJust();
}
}
return row;
}
#if !defined(NODE_MODULE_VERSION) || NODE_MODULE_VERSION < 127
v8::Local<v8::Value> GetFlatRowJS(v8::Isolate* isolate, v8::Local<v8::Context> ctx, sqlite3_stmt* handle, bool safe_ints) {
v8::Local<v8::Object> row = v8::Object::New(isolate);
int column_count = sqlite3_column_count(handle);
for (int i = 0; i < column_count; ++i) {
row->Set(ctx,
InternalizedFromUtf8(isolate, sqlite3_column_name(handle, i), -1),
Data::GetValueJS(isolate, handle, i, safe_ints)
).FromJust();
}
return row;
}
v8::Local<v8::Value> GetRawRowJS(v8::Isolate* isolate, v8::Local<v8::Context> ctx, sqlite3_stmt* handle, bool safe_ints) {
v8::Local<v8::Array> row = v8::Array::New(isolate);
int column_count = sqlite3_column_count(handle);
for (int i = 0; i < column_count; ++i) {
row->Set(ctx, i, Data::GetValueJS(isolate, handle, i, safe_ints)).FromJust();
}
return row;
}
v8::Local<v8::Value> GetRowJS(v8::Isolate* isolate, v8::Local<v8::Context> ctx, sqlite3_stmt* handle, bool safe_ints, char mode) {
if (mode == FLAT) return GetFlatRowJS(isolate, ctx, handle, safe_ints);
if (mode == PLUCK) return GetValueJS(isolate, handle, 0, safe_ints);
if (mode == EXPAND) return GetExpandedRowJS(isolate, ctx, handle, safe_ints);
if (mode == RAW) return GetRawRowJS(isolate, ctx, handle, safe_ints);
assert(false);
return v8::Local<v8::Value>();
}
#else
v8::Local<v8::Value> GetFlatRowJS(v8::Isolate* isolate, sqlite3_stmt* handle, bool safe_ints) {
int column_count = sqlite3_column_count(handle);
v8::LocalVector<v8::Name> keys(isolate);
v8::LocalVector<v8::Value> values(isolate);
keys.reserve(column_count);
values.reserve(column_count);
for (int i = 0; i < column_count; ++i) {
keys.emplace_back(
InternalizedFromUtf8(isolate, sqlite3_column_name(handle, i), -1).As<v8::Name>()
);
values.emplace_back(
Data::GetValueJS(isolate, handle, i, safe_ints)
);
}
return v8::Object::New(
isolate,
GET_PROTOTYPE(v8::Object::New(isolate)),
keys.data(),
values.data(),
column_count
);
}
v8::Local<v8::Value> GetRawRowJS(v8::Isolate* isolate, sqlite3_stmt* handle, bool safe_ints) {
int column_count = sqlite3_column_count(handle);
v8::LocalVector<v8::Value> row(isolate);
row.reserve(column_count);
for (int i = 0; i < column_count; ++i) {
row.emplace_back(Data::GetValueJS(isolate, handle, i, safe_ints));
}
return v8::Array::New(isolate, row.data(), row.size());
}
v8::Local<v8::Value> GetRowJS(v8::Isolate* isolate, v8::Local<v8::Context> ctx, sqlite3_stmt* handle, bool safe_ints, char mode) {
if (mode == FLAT) return GetFlatRowJS(isolate, handle, safe_ints);
if (mode == PLUCK) return GetValueJS(isolate, handle, 0, safe_ints);
if (mode == EXPAND) return GetExpandedRowJS(isolate, ctx, handle, safe_ints);
if (mode == RAW) return GetRawRowJS(isolate, handle, safe_ints);
assert(false);
return v8::Local<v8::Value>();
}
#endif
void GetArgumentsJS(v8::Isolate* isolate, v8::Local<v8::Value>* out, sqlite3_value** values, int argument_count, bool safe_ints) {
assert(argument_count > 0);
for (int i = 0; i < argument_count; ++i) {
out[i] = Data::GetValueJS(isolate, values[i], safe_ints);
}
}
int BindValueFromJS(v8::Isolate* isolate, sqlite3_stmt* handle, int index, v8::Local<v8::Value> value) {
JS_VALUE_TO_SQLITE(bind, value, isolate, handle, index);
return value->IsBigInt() ? SQLITE_TOOBIG : -1;
}
void ResultValueFromJS(v8::Isolate* isolate, sqlite3_context* invocation, v8::Local<v8::Value> value, DataConverter* converter) {
JS_VALUE_TO_SQLITE(result, value, isolate, invocation);
converter->ThrowDataConversionError(invocation, value->IsBigInt());
}
}

109
node_modules/better-sqlite3/src/util/helpers.cpp generated vendored Normal file
View File

@@ -0,0 +1,109 @@
inline v8::Local<v8::String> StringFromUtf8(v8::Isolate* isolate, const char* data, int length) {
return v8::String::NewFromUtf8(isolate, data, v8::NewStringType::kNormal, length).ToLocalChecked();
}
inline v8::Local<v8::String> InternalizedFromUtf8(v8::Isolate* isolate, const char* data, int length) {
return v8::String::NewFromUtf8(isolate, data, v8::NewStringType::kInternalized, length).ToLocalChecked();
}
inline v8::Local<v8::Value> InternalizedFromUtf8OrNull(v8::Isolate* isolate, const char* data, int length) {
if (data == NULL) return v8::Null(isolate);
return InternalizedFromUtf8(isolate, data, length);
}
inline v8::Local<v8::String> InternalizedFromLatin1(v8::Isolate* isolate, const char* str) {
return v8::String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(str), v8::NewStringType::kInternalized).ToLocalChecked();
}
inline void SetFrozen(v8::Isolate* isolate, v8::Local<v8::Context> ctx, v8::Local<v8::Object> obj, v8::Global<v8::String>& key, v8::Local<v8::Value> value) {
obj->DefineOwnProperty(ctx, key.Get(isolate), value, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly)).FromJust();
}
void ThrowError(const char* message) { EasyIsolate; isolate->ThrowException(v8::Exception::Error(StringFromUtf8(isolate, message, -1))); }
void ThrowTypeError(const char* message) { EasyIsolate; isolate->ThrowException(v8::Exception::TypeError(StringFromUtf8(isolate, message, -1))); }
void ThrowRangeError(const char* message) { EasyIsolate; isolate->ThrowException(v8::Exception::RangeError(StringFromUtf8(isolate, message, -1))); }
// Determines whether to skip the given character at the start of an SQL string.
inline bool IS_SKIPPED(char c) {
return c == ' ' || c == ';' || (c >= '\t' && c <= '\r');
}
// Allocates an empty array, without calling constructors/initializers.
template<class T> inline T* ALLOC_ARRAY(size_t count) {
return static_cast<T*>(::operator new[](count * sizeof(T)));
}
// Deallocates an array, without calling destructors.
template<class T> inline void FREE_ARRAY(T* array_pointer) {
::operator delete[](array_pointer);
}
v8::Local<v8::FunctionTemplate> NewConstructorTemplate(
v8::Isolate* isolate,
v8::Local<v8::External> data,
v8::FunctionCallback func,
const char* name
) {
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate, func, data);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(InternalizedFromLatin1(isolate, name));
return t;
}
void SetPrototypeMethod(
v8::Isolate* isolate,
v8::Local<v8::External> data,
v8::Local<v8::FunctionTemplate> recv,
const char* name,
v8::FunctionCallback func
) {
v8::HandleScope scope(isolate);
recv->PrototypeTemplate()->Set(
InternalizedFromLatin1(isolate, name),
v8::FunctionTemplate::New(isolate, func, data, v8::Signature::New(isolate, recv))
);
}
void SetPrototypeSymbolMethod(
v8::Isolate* isolate,
v8::Local<v8::External> data,
v8::Local<v8::FunctionTemplate> recv,
v8::Local<v8::Symbol> symbol,
v8::FunctionCallback func
) {
v8::HandleScope scope(isolate);
recv->PrototypeTemplate()->Set(
symbol,
v8::FunctionTemplate::New(isolate, func, data, v8::Signature::New(isolate, recv))
);
}
void SetPrototypeGetter(
v8::Isolate* isolate,
v8::Local<v8::External> data,
v8::Local<v8::FunctionTemplate> recv,
const char* name,
v8::AccessorNameGetterCallback func
) {
v8::HandleScope scope(isolate);
recv->InstanceTemplate()->SetNativeDataProperty(
InternalizedFromLatin1(isolate, name),
func,
0,
data
);
}
#if defined(V8_ENABLE_SANDBOX)
// When V8 Sandbox is enabled (in newer Electron versions), we need to use Buffer::Copy
// instead of Buffer::New to ensure the ArrayBuffer backing store is allocated inside the sandbox
static inline v8::MaybeLocal<v8::Object> BufferSandboxNew(v8::Isolate* isolate, char* data, size_t length, void (*finalizeCallback)(char*, void*), void* finalizeHint) {
v8::MaybeLocal<v8::Object> buffer = node::Buffer::Copy(isolate, data, length);
finalizeCallback(data, finalizeHint);
return buffer;
}
#define SAFE_NEW_BUFFER(env, data, length, finalizeCallback, finalizeHint) BufferSandboxNew(env, data, length, finalizeCallback, finalizeHint)
#else
// When V8 Sandbox is not enabled, we can use the more efficient Buffer::New
#define SAFE_NEW_BUFFER(env, data, length, finalizeCallback, finalizeHint) node::Buffer::New(env, data, length, finalizeCallback, finalizeHint)
#endif

70
node_modules/better-sqlite3/src/util/macros.cpp generated vendored Normal file
View File

@@ -0,0 +1,70 @@
#define NODE_ARGUMENTS const v8::FunctionCallbackInfo<v8::Value>&
#define NODE_ARGUMENTS_POINTER const v8::FunctionCallbackInfo<v8::Value>*
#define NODE_METHOD(name) void name(NODE_ARGUMENTS info)
#define NODE_GETTER(name) void name(v8::Local<v8::Name> _, const v8::PropertyCallbackInfo<v8::Value>& info)
#define INIT(name) v8::Local<v8::Function> name(v8::Isolate* isolate, v8::Local<v8::External> data)
#if defined(V8_MAJOR_VERSION) && V8_MAJOR_VERSION >= 13
// v8::Object::GetPrototype has been deprecated. See http://crbug.com/333672197
#define GET_PROTOTYPE(obj) ((obj)->GetPrototypeV2())
#else
#define GET_PROTOTYPE(obj) ((obj)->GetPrototype())
#endif
#define EasyIsolate v8::Isolate* isolate = v8::Isolate::GetCurrent()
#define OnlyIsolate info.GetIsolate()
#define OnlyContext isolate->GetCurrentContext()
#define OnlyAddon static_cast<Addon*>(info.Data().As<v8::External>()->Value())
#define UseIsolate v8::Isolate* isolate = OnlyIsolate
#define UseContext v8::Local<v8::Context> ctx = OnlyContext
#define UseAddon Addon* addon = OnlyAddon
#define Unwrap node::ObjectWrap::Unwrap
#define REQUIRE_ARGUMENT_ANY(at, var) \
if (info.Length() <= (at())) \
return ThrowTypeError("Expected a "#at" argument"); \
var = info[at()]
#define _REQUIRE_ARGUMENT(at, var, Type, message, ...) \
if (info.Length() <= (at()) || !info[at()]->Is##Type()) \
return ThrowTypeError("Expected "#at" argument to be "#message); \
var = (info[at()].As<v8::Type>())__VA_ARGS__
#define REQUIRE_ARGUMENT_INT32(at, var) \
_REQUIRE_ARGUMENT(at, var, Int32, a 32-bit signed integer, ->Value())
#define REQUIRE_ARGUMENT_BOOLEAN(at, var) \
_REQUIRE_ARGUMENT(at, var, Boolean, a boolean, ->Value())
#define REQUIRE_ARGUMENT_STRING(at, var) \
_REQUIRE_ARGUMENT(at, var, String, a string)
#define REQUIRE_ARGUMENT_OBJECT(at, var) \
_REQUIRE_ARGUMENT(at, var, Object, an object)
#define REQUIRE_ARGUMENT_FUNCTION(at, var) \
_REQUIRE_ARGUMENT(at, var, Function, a function)
#define REQUIRE_DATABASE_OPEN(db) \
if (!db->open) \
return ThrowTypeError("The database connection is not open")
#define REQUIRE_DATABASE_NOT_BUSY(db) \
if (db->busy) \
return ThrowTypeError("This database connection is busy executing a query")
#define REQUIRE_DATABASE_NO_ITERATORS(db) \
if (db->iterators) \
return ThrowTypeError("This database connection is busy executing a query")
#define REQUIRE_DATABASE_NO_ITERATORS_UNLESS_UNSAFE(db) \
if (!db->unsafe_mode) { \
REQUIRE_DATABASE_NO_ITERATORS(db); \
} ((void)0)
#define REQUIRE_STATEMENT_NOT_LOCKED(stmt) \
if (stmt->locked) \
return ThrowTypeError("This statement is busy executing a query")
#define first() 0
#define second() 1
#define third() 2
#define fourth() 3
#define fifth() 4
#define sixth() 5
#define seventh() 6
#define eighth() 7
#define ninth() 8
#define tenth() 9

71
node_modules/better-sqlite3/src/util/query-macros.cpp generated vendored Normal file
View File

@@ -0,0 +1,71 @@
#define STATEMENT_BIND(handle) \
Binder binder(handle); \
if (!binder.Bind(info, info.Length(), stmt)) { \
sqlite3_clear_bindings(handle); \
return; \
} ((void)0)
#define STATEMENT_THROW_LOGIC() \
db->ThrowDatabaseError(); \
if (!bound) { sqlite3_clear_bindings(handle); } \
return
#define STATEMENT_RETURN_LOGIC(return_value) \
info.GetReturnValue().Set(return_value); \
if (!bound) { sqlite3_clear_bindings(handle); } \
return
#define STATEMENT_START_LOGIC(RETURNS_DATA_CHECK, MUTATE_CHECK) \
Statement* stmt = Unwrap<Statement>(info.This()); \
RETURNS_DATA_CHECK(); \
sqlite3_stmt* handle = stmt->handle; \
Database* db = stmt->db; \
REQUIRE_DATABASE_OPEN(db->GetState()); \
REQUIRE_DATABASE_NOT_BUSY(db->GetState()); \
MUTATE_CHECK(); \
const bool bound = stmt->bound; \
if (!bound) { \
STATEMENT_BIND(handle); \
} else if (info.Length() > 0) { \
return ThrowTypeError("This statement already has bound parameters"); \
} ((void)0)
#define STATEMENT_THROW() db->GetState()->busy = false; STATEMENT_THROW_LOGIC()
#define STATEMENT_RETURN(x) db->GetState()->busy = false; STATEMENT_RETURN_LOGIC(x)
#define STATEMENT_START(x, y) \
STATEMENT_START_LOGIC(x, y); \
db->GetState()->busy = true; \
UseIsolate; \
if (db->Log(isolate, handle)) { \
STATEMENT_THROW(); \
} ((void)0)
#define DOES_NOT_MUTATE() REQUIRE_STATEMENT_NOT_LOCKED(stmt)
#define DOES_MUTATE() \
REQUIRE_STATEMENT_NOT_LOCKED(stmt); \
REQUIRE_DATABASE_NO_ITERATORS_UNLESS_UNSAFE(db->GetState())
#define DOES_ADD_ITERATOR() \
DOES_NOT_MUTATE(); \
if (db->GetState()->iterators == USHRT_MAX) \
return ThrowRangeError("Too many active database iterators")
#define REQUIRE_STATEMENT_RETURNS_DATA() \
if (!stmt->returns_data) \
return ThrowTypeError("This statement does not return data. Use run() instead")
#define ALLOW_ANY_STATEMENT() \
((void)0)
#define _FUNCTION_START(type) \
type* self = static_cast<type*>(sqlite3_user_data(invocation)); \
v8::Isolate* isolate = self->isolate; \
v8::HandleScope scope(isolate)
#define FUNCTION_START() \
_FUNCTION_START(CustomFunction)
#define AGGREGATE_START() \
_FUNCTION_START(CustomAggregate); \
Accumulator* acc = self->GetAccumulator(invocation); \
if (acc->value.IsEmpty()) return

49
node_modules/better-sqlite3/src/util/row-builder.cpp generated vendored Normal file
View File

@@ -0,0 +1,49 @@
class RowBuilder {
public:
explicit RowBuilder(
v8::Isolate* isolate,
sqlite3_stmt* handle,
bool safe_ints
) :
isolate(isolate),
handle(handle),
column_count(-1),
safe_ints(safe_ints),
keys(isolate) {}
v8::Local<v8::Value> GetRowJS() {
if (column_count < 0) {
column_count = sqlite3_column_count(handle);
keys.reserve(column_count);
for (int i = 0; i < column_count; ++i) {
keys.emplace_back(
InternalizedFromUtf8(isolate, sqlite3_column_name(handle, i), -1)
.As<v8::Name>()
);
}
}
v8::LocalVector<v8::Value> values(isolate);
values.reserve(column_count);
for (int i = 0; i < column_count; ++i) {
values.emplace_back(
Data::GetValueJS(isolate, handle, i, safe_ints)
);
}
return v8::Object::New(isolate,
GET_PROTOTYPE(v8::Object::New(isolate)),
keys.data(),
values.data(),
column_count
);
}
private:
v8::Isolate* isolate;
sqlite3_stmt* handle;
int column_count;
const bool safe_ints;
v8::LocalVector<v8::Name> keys;
};

22
node_modules/bindings/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

98
node_modules/bindings/README.md generated vendored Normal file
View File

@@ -0,0 +1,98 @@
node-bindings
=============
### Helper module for loading your native module's `.node` file
This is a helper module for authors of Node.js native addon modules.
It is basically the "swiss army knife" of `require()`ing your native module's
`.node` file.
Throughout the course of Node's native addon history, addons have ended up being
compiled in a variety of different places, depending on which build tool and which
version of node was used. To make matters worse, now the `gyp` build tool can
produce either a __Release__ or __Debug__ build, each being built into different
locations.
This module checks _all_ the possible locations that a native addon would be built
at, and returns the first one that loads successfully.
Installation
------------
Install with `npm`:
``` bash
$ npm install --save bindings
```
Or add it to the `"dependencies"` section of your `package.json` file.
Example
-------
`require()`ing the proper bindings file for the current node version, platform
and architecture is as simple as:
``` js
var bindings = require('bindings')('binding.node')
// Use your bindings defined in your C files
bindings.your_c_function()
```
Nice Error Output
-----------------
When the `.node` file could not be loaded, `node-bindings` throws an Error with
a nice error message telling you exactly what was tried. You can also check the
`err.tries` Array property.
```
Error: Could not load the bindings file. Tried:
→ /Users/nrajlich/ref/build/binding.node
→ /Users/nrajlich/ref/build/Debug/binding.node
→ /Users/nrajlich/ref/build/Release/binding.node
→ /Users/nrajlich/ref/out/Debug/binding.node
→ /Users/nrajlich/ref/Debug/binding.node
→ /Users/nrajlich/ref/out/Release/binding.node
→ /Users/nrajlich/ref/Release/binding.node
→ /Users/nrajlich/ref/build/default/binding.node
→ /Users/nrajlich/ref/compiled/0.8.2/darwin/x64/binding.node
at bindings (/Users/nrajlich/ref/node_modules/bindings/bindings.js:84:13)
at Object.<anonymous> (/Users/nrajlich/ref/lib/ref.js:5:47)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
...
```
The searching for the `.node` file will originate from the first directory in which has a `package.json` file is found.
License
-------
(The MIT License)
Copyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

221
node_modules/bindings/bindings.js generated vendored Normal file
View File

@@ -0,0 +1,221 @@
/**
* Module dependencies.
*/
var fs = require('fs'),
path = require('path'),
fileURLToPath = require('file-uri-to-path'),
join = path.join,
dirname = path.dirname,
exists =
(fs.accessSync &&
function(path) {
try {
fs.accessSync(path);
} catch (e) {
return false;
}
return true;
}) ||
fs.existsSync ||
path.existsSync,
defaults = {
arrow: process.env.NODE_BINDINGS_ARROW || ' → ',
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled',
platform: process.platform,
arch: process.arch,
nodePreGyp:
'node-v' +
process.versions.modules +
'-' +
process.platform +
'-' +
process.arch,
version: process.versions.node,
bindings: 'bindings.node',
try: [
// node-gyp's linked version in the "build" dir
['module_root', 'build', 'bindings'],
// node-waf and gyp_addon (a.k.a node-gyp)
['module_root', 'build', 'Debug', 'bindings'],
['module_root', 'build', 'Release', 'bindings'],
// Debug files, for development (legacy behavior, remove for node v0.9)
['module_root', 'out', 'Debug', 'bindings'],
['module_root', 'Debug', 'bindings'],
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
['module_root', 'out', 'Release', 'bindings'],
['module_root', 'Release', 'bindings'],
// Legacy from node-waf, node <= 0.4.x
['module_root', 'build', 'default', 'bindings'],
// Production "Release" buildtype binary (meh...)
['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'],
// node-qbs builds
['module_root', 'addon-build', 'release', 'install-root', 'bindings'],
['module_root', 'addon-build', 'debug', 'install-root', 'bindings'],
['module_root', 'addon-build', 'default', 'install-root', 'bindings'],
// node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}
['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings']
]
};
/**
* The main `bindings()` function loads the compiled bindings for a given module.
* It uses V8's Error API to determine the parent filename that this function is
* being invoked from, which is then used to find the root directory.
*/
function bindings(opts) {
// Argument surgery
if (typeof opts == 'string') {
opts = { bindings: opts };
} else if (!opts) {
opts = {};
}
// maps `defaults` onto `opts` object
Object.keys(defaults).map(function(i) {
if (!(i in opts)) opts[i] = defaults[i];
});
// Get the module root
if (!opts.module_root) {
opts.module_root = exports.getRoot(exports.getFileName());
}
// Ensure the given bindings name ends with .node
if (path.extname(opts.bindings) != '.node') {
opts.bindings += '.node';
}
// https://github.com/webpack/webpack/issues/4175#issuecomment-342931035
var requireFunc =
typeof __webpack_require__ === 'function'
? __non_webpack_require__
: require;
var tries = [],
i = 0,
l = opts.try.length,
n,
b,
err;
for (; i < l; i++) {
n = join.apply(
null,
opts.try[i].map(function(p) {
return opts[p] || p;
})
);
tries.push(n);
try {
b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
if (!opts.path) {
b.path = n;
}
return b;
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND' &&
e.code !== 'QUALIFIED_PATH_RESOLUTION_FAILED' &&
!/not find/i.test(e.message)) {
throw e;
}
}
}
err = new Error(
'Could not locate the bindings file. Tried:\n' +
tries
.map(function(a) {
return opts.arrow + a;
})
.join('\n')
);
err.tries = tries;
throw err;
}
module.exports = exports = bindings;
/**
* Gets the filename of the JavaScript file that invokes this function.
* Used to help find the root directory of a module.
* Optionally accepts an filename argument to skip when searching for the invoking filename
*/
exports.getFileName = function getFileName(calling_file) {
var origPST = Error.prepareStackTrace,
origSTL = Error.stackTraceLimit,
dummy = {},
fileName;
Error.stackTraceLimit = 10;
Error.prepareStackTrace = function(e, st) {
for (var i = 0, l = st.length; i < l; i++) {
fileName = st[i].getFileName();
if (fileName !== __filename) {
if (calling_file) {
if (fileName !== calling_file) {
return;
}
} else {
return;
}
}
}
};
// run the 'prepareStackTrace' function above
Error.captureStackTrace(dummy);
dummy.stack;
// cleanup
Error.prepareStackTrace = origPST;
Error.stackTraceLimit = origSTL;
// handle filename that starts with "file://"
var fileSchema = 'file://';
if (fileName.indexOf(fileSchema) === 0) {
fileName = fileURLToPath(fileName);
}
return fileName;
};
/**
* Gets the root directory of a module, given an arbitrary filename
* somewhere in the module tree. The "root directory" is the directory
* containing the `package.json` file.
*
* In: /home/nate/node-native-module/lib/index.js
* Out: /home/nate/node-native-module
*/
exports.getRoot = function getRoot(file) {
var dir = dirname(file),
prev;
while (true) {
if (dir === '.') {
// Avoids an infinite loop in rare cases, like the REPL
dir = process.cwd();
}
if (
exists(join(dir, 'package.json')) ||
exists(join(dir, 'node_modules'))
) {
// Found the 'package.json' file or 'node_modules' dir; we're done
return dir;
}
if (prev === dir) {
// Got to the top
throw new Error(
'Could not find module root given file: "' +
file +
'". Do you have a `package.json` file? '
);
}
// Try the parent dir next
prev = dir;
dir = join(dir, '..');
}
};

28
node_modules/bindings/package.json generated vendored Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "bindings",
"description": "Helper module for loading your native module's .node file",
"keywords": [
"native",
"addon",
"bindings",
"gyp",
"waf",
"c",
"c++"
],
"version": "1.5.0",
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://tootallnate.net)",
"repository": {
"type": "git",
"url": "git://github.com/TooTallNate/node-bindings.git"
},
"main": "./bindings.js",
"bugs": {
"url": "https://github.com/TooTallNate/node-bindings/issues"
},
"homepage": "https://github.com/TooTallNate/node-bindings",
"license": "MIT",
"dependencies": {
"file-uri-to-path": "1.0.0"
}
}

15
node_modules/chownr/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,15 @@
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

3
node_modules/chownr/README.md generated vendored Normal file
View File

@@ -0,0 +1,3 @@
Like `chown -R`.
Takes the same arguments as `fs.chown()`

167
node_modules/chownr/chownr.js generated vendored Normal file
View File

@@ -0,0 +1,167 @@
'use strict'
const fs = require('fs')
const path = require('path')
/* istanbul ignore next */
const LCHOWN = fs.lchown ? 'lchown' : 'chown'
/* istanbul ignore next */
const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync'
/* istanbul ignore next */
const needEISDIRHandled = fs.lchown &&
!process.version.match(/v1[1-9]+\./) &&
!process.version.match(/v10\.[6-9]/)
const lchownSync = (path, uid, gid) => {
try {
return fs[LCHOWNSYNC](path, uid, gid)
} catch (er) {
if (er.code !== 'ENOENT')
throw er
}
}
/* istanbul ignore next */
const chownSync = (path, uid, gid) => {
try {
return fs.chownSync(path, uid, gid)
} catch (er) {
if (er.code !== 'ENOENT')
throw er
}
}
/* istanbul ignore next */
const handleEISDIR =
needEISDIRHandled ? (path, uid, gid, cb) => er => {
// Node prior to v10 had a very questionable implementation of
// fs.lchown, which would always try to call fs.open on a directory
// Fall back to fs.chown in those cases.
if (!er || er.code !== 'EISDIR')
cb(er)
else
fs.chown(path, uid, gid, cb)
}
: (_, __, ___, cb) => cb
/* istanbul ignore next */
const handleEISDirSync =
needEISDIRHandled ? (path, uid, gid) => {
try {
return lchownSync(path, uid, gid)
} catch (er) {
if (er.code !== 'EISDIR')
throw er
chownSync(path, uid, gid)
}
}
: (path, uid, gid) => lchownSync(path, uid, gid)
// fs.readdir could only accept an options object as of node v6
const nodeVersion = process.version
let readdir = (path, options, cb) => fs.readdir(path, options, cb)
let readdirSync = (path, options) => fs.readdirSync(path, options)
/* istanbul ignore next */
if (/^v4\./.test(nodeVersion))
readdir = (path, options, cb) => fs.readdir(path, cb)
const chown = (cpath, uid, gid, cb) => {
fs[LCHOWN](cpath, uid, gid, handleEISDIR(cpath, uid, gid, er => {
// Skip ENOENT error
cb(er && er.code !== 'ENOENT' ? er : null)
}))
}
const chownrKid = (p, child, uid, gid, cb) => {
if (typeof child === 'string')
return fs.lstat(path.resolve(p, child), (er, stats) => {
// Skip ENOENT error
if (er)
return cb(er.code !== 'ENOENT' ? er : null)
stats.name = child
chownrKid(p, stats, uid, gid, cb)
})
if (child.isDirectory()) {
chownr(path.resolve(p, child.name), uid, gid, er => {
if (er)
return cb(er)
const cpath = path.resolve(p, child.name)
chown(cpath, uid, gid, cb)
})
} else {
const cpath = path.resolve(p, child.name)
chown(cpath, uid, gid, cb)
}
}
const chownr = (p, uid, gid, cb) => {
readdir(p, { withFileTypes: true }, (er, children) => {
// any error other than ENOTDIR or ENOTSUP means it's not readable,
// or doesn't exist. give up.
if (er) {
if (er.code === 'ENOENT')
return cb()
else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
return cb(er)
}
if (er || !children.length)
return chown(p, uid, gid, cb)
let len = children.length
let errState = null
const then = er => {
if (errState)
return
if (er)
return cb(errState = er)
if (-- len === 0)
return chown(p, uid, gid, cb)
}
children.forEach(child => chownrKid(p, child, uid, gid, then))
})
}
const chownrKidSync = (p, child, uid, gid) => {
if (typeof child === 'string') {
try {
const stats = fs.lstatSync(path.resolve(p, child))
stats.name = child
child = stats
} catch (er) {
if (er.code === 'ENOENT')
return
else
throw er
}
}
if (child.isDirectory())
chownrSync(path.resolve(p, child.name), uid, gid)
handleEISDirSync(path.resolve(p, child.name), uid, gid)
}
const chownrSync = (p, uid, gid) => {
let children
try {
children = readdirSync(p, { withFileTypes: true })
} catch (er) {
if (er.code === 'ENOENT')
return
else if (er.code === 'ENOTDIR' || er.code === 'ENOTSUP')
return handleEISDirSync(p, uid, gid)
else
throw er
}
if (children && children.length)
children.forEach(child => chownrKidSync(p, child, uid, gid))
return handleEISDirSync(p, uid, gid)
}
module.exports = chownr
chownr.sync = chownrSync

29
node_modules/chownr/package.json generated vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "chownr",
"description": "like `chown -R`",
"version": "1.1.4",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/chownr.git"
},
"main": "chownr.js",
"files": [
"chownr.js"
],
"devDependencies": {
"mkdirp": "0.3",
"rimraf": "^2.7.1",
"tap": "^14.10.6"
},
"tap": {
"check-coverage": true
},
"scripts": {
"test": "tap",
"preversion": "npm test",
"postversion": "npm publish",
"prepublishOnly": "git push origin --follow-tags"
},
"license": "ISC"
}

22
node_modules/decompress-response/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,22 @@
/// <reference types="node"/>
import {IncomingMessage} from 'http';
/**
Decompress a HTTP response if needed.
@param response - The HTTP incoming stream with compressed data.
@returns The decompressed HTTP response stream.
@example
```
import {http} from 'http';
import decompressResponse = require('decompress-response');
http.get('https://sindresorhus.com', response => {
response = decompressResponse(response);
});
```
*/
declare function decompressResponse(response: IncomingMessage): IncomingMessage;
export = decompressResponse;

58
node_modules/decompress-response/index.js generated vendored Normal file
View File

@@ -0,0 +1,58 @@
'use strict';
const {Transform, PassThrough} = require('stream');
const zlib = require('zlib');
const mimicResponse = require('mimic-response');
module.exports = response => {
const contentEncoding = (response.headers['content-encoding'] || '').toLowerCase();
if (!['gzip', 'deflate', 'br'].includes(contentEncoding)) {
return response;
}
// TODO: Remove this when targeting Node.js 12.
const isBrotli = contentEncoding === 'br';
if (isBrotli && typeof zlib.createBrotliDecompress !== 'function') {
response.destroy(new Error('Brotli is not supported on Node.js < 12'));
return response;
}
let isEmpty = true;
const checker = new Transform({
transform(data, _encoding, callback) {
isEmpty = false;
callback(null, data);
},
flush(callback) {
callback();
}
});
const finalStream = new PassThrough({
autoDestroy: false,
destroy(error, callback) {
response.destroy();
callback(error);
}
});
const decompressStream = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip();
decompressStream.once('error', error => {
if (isEmpty && !response.readable) {
finalStream.end();
return;
}
finalStream.destroy(error);
});
mimicResponse(response, finalStream);
response.pipe(checker).pipe(decompressStream).pipe(finalStream);
return finalStream;
};

9
node_modules/decompress-response/license generated vendored Normal file
View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

56
node_modules/decompress-response/package.json generated vendored Normal file
View File

@@ -0,0 +1,56 @@
{
"name": "decompress-response",
"version": "6.0.0",
"description": "Decompress a HTTP response if needed",
"license": "MIT",
"repository": "sindresorhus/decompress-response",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"engines": {
"node": ">=10"
},
"scripts": {
"test": "xo && ava && tsd"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"decompress",
"response",
"http",
"https",
"zlib",
"gzip",
"zip",
"deflate",
"unzip",
"ungzip",
"incoming",
"message",
"stream",
"compressed",
"brotli"
],
"dependencies": {
"mimic-response": "^3.1.0"
},
"devDependencies": {
"@types/node": "^14.0.1",
"ava": "^2.2.0",
"get-stream": "^5.0.0",
"pify": "^5.0.0",
"tsd": "^0.11.0",
"xo": "^0.30.0"
},
"xo": {
"rules": {
"@typescript-eslint/prefer-readonly-parameter-types": "off"
}
}
}

48
node_modules/decompress-response/readme.md generated vendored Normal file
View File

@@ -0,0 +1,48 @@
# decompress-response [![Build Status](https://travis-ci.com/sindresorhus/decompress-response.svg?branch=master)](https://travis-ci.com/sindresorhus/decompress-response)
> Decompress a HTTP response if needed
Decompresses the [response](https://nodejs.org/api/http.html#http_class_http_incomingmessage) from [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) if it's gzipped, deflated or compressed with Brotli, otherwise just passes it through.
Used by [`got`](https://github.com/sindresorhus/got).
## Install
```
$ npm install decompress-response
```
## Usage
```js
const http = require('http');
const decompressResponse = require('decompress-response');
http.get('https://sindresorhus.com', response => {
response = decompressResponse(response);
});
```
## API
### decompressResponse(response)
Returns the decompressed HTTP response stream.
#### response
Type: [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
The HTTP incoming stream with compressed data.
---
<div align="center">
<b>
<a href="https://tidelift.com/subscription/pkg/npm-decompress-response?utm_source=npm-decompress-response&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>
</div>

46
node_modules/deep-extend/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,46 @@
Changelog
=========
v0.6.0
------
- Updated "devDependencies" versions to fix vulnerability alerts
- Dropped support of io.js and node.js v0.12.x and lower since new versions of
"devDependencies" couldn't work with those old node.js versions
(minimal supported version of node.js now is v4.0.0)
v0.5.1
------
- Fix prototype pollution vulnerability (thanks to @mwakerman for the PR)
- Avoid using deprecated Buffer API (thanks to @ChALkeR for the PR)
v0.5.0
------
- Auto-testing provided by Travis CI;
- Support older Node.JS versions (`v0.11.x` and `v0.10.x`);
- Removed tests files from npm package.
v0.4.2
------
- Fix for `null` as an argument.
v0.4.1
------
- Removed test code from <b>npm</b> package
([see pull request #21](https://github.com/unclechu/node-deep-extend/pull/21));
- Increased minimal version of Node from `0.4.0` to `0.12.0`
(because can't run tests on lesser version anyway).
v0.4.0
------
- **WARNING!** Broken backward compatibility with `v0.3.x`;
- Fixed bug with extending arrays instead of cloning;
- Deep cloning for arrays;
- Check for own property;
- Fixed some documentation issues;
- Strict JS mode.

20
node_modules/deep-extend/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013-2018, Viacheslav Lotsmanov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

91
node_modules/deep-extend/README.md generated vendored Normal file
View File

@@ -0,0 +1,91 @@
Deep Extend
===========
Recursive object extending.
[![Build Status](https://api.travis-ci.org/unclechu/node-deep-extend.svg?branch=master)](https://travis-ci.org/unclechu/node-deep-extend)
[![NPM](https://nodei.co/npm/deep-extend.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/deep-extend/)
Install
-------
```bash
$ npm install deep-extend
```
Usage
-----
```javascript
var deepExtend = require('deep-extend');
var obj1 = {
a: 1,
b: 2,
d: {
a: 1,
b: [],
c: { test1: 123, test2: 321 }
},
f: 5,
g: 123,
i: 321,
j: [1, 2]
};
var obj2 = {
b: 3,
c: 5,
d: {
b: { first: 'one', second: 'two' },
c: { test2: 222 }
},
e: { one: 1, two: 2 },
f: [],
g: (void 0),
h: /abc/g,
i: null,
j: [3, 4]
};
deepExtend(obj1, obj2);
console.log(obj1);
/*
{ a: 1,
b: 3,
d:
{ a: 1,
b: { first: 'one', second: 'two' },
c: { test1: 123, test2: 222 } },
f: [],
g: undefined,
c: 5,
e: { one: 1, two: 2 },
h: /abc/g,
i: null,
j: [3, 4] }
*/
```
Unit testing
------------
```bash
$ npm test
```
Changelog
---------
[CHANGELOG.md](./CHANGELOG.md)
Any issues?
-----------
Please, report about issues
[here](https://github.com/unclechu/node-deep-extend/issues).
License
-------
[MIT](./LICENSE)

1
node_modules/deep-extend/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./lib/deep-extend');

150
node_modules/deep-extend/lib/deep-extend.js generated vendored Normal file
View File

@@ -0,0 +1,150 @@
/*!
* @description Recursive object extending
* @author Viacheslav Lotsmanov <lotsmanov89@gmail.com>
* @license MIT
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2018 Viacheslav Lotsmanov
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';
function isSpecificValue(val) {
return (
val instanceof Buffer
|| val instanceof Date
|| val instanceof RegExp
) ? true : false;
}
function cloneSpecificValue(val) {
if (val instanceof Buffer) {
var x = Buffer.alloc
? Buffer.alloc(val.length)
: new Buffer(val.length);
val.copy(x);
return x;
} else if (val instanceof Date) {
return new Date(val.getTime());
} else if (val instanceof RegExp) {
return new RegExp(val);
} else {
throw new Error('Unexpected situation');
}
}
/**
* Recursive cloning array.
*/
function deepCloneArray(arr) {
var clone = [];
arr.forEach(function (item, index) {
if (typeof item === 'object' && item !== null) {
if (Array.isArray(item)) {
clone[index] = deepCloneArray(item);
} else if (isSpecificValue(item)) {
clone[index] = cloneSpecificValue(item);
} else {
clone[index] = deepExtend({}, item);
}
} else {
clone[index] = item;
}
});
return clone;
}
function safeGetProperty(object, property) {
return property === '__proto__' ? undefined : object[property];
}
/**
* Extening object that entered in first argument.
*
* Returns extended object or false if have no target object or incorrect type.
*
* If you wish to clone source object (without modify it), just use empty new
* object as first argument, like this:
* deepExtend({}, yourObj_1, [yourObj_N]);
*/
var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) {
if (arguments.length < 1 || typeof arguments[0] !== 'object') {
return false;
}
if (arguments.length < 2) {
return arguments[0];
}
var target = arguments[0];
// convert arguments to array and cut off target object
var args = Array.prototype.slice.call(arguments, 1);
var val, src, clone;
args.forEach(function (obj) {
// skip argument if isn't an object, is null, or is an array
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
return;
}
Object.keys(obj).forEach(function (key) {
src = safeGetProperty(target, key); // source value
val = safeGetProperty(obj, key); // new value
// recursion prevention
if (val === target) {
return;
/**
* if new value isn't object then just overwrite by new value
* instead of extending.
*/
} else if (typeof val !== 'object' || val === null) {
target[key] = val;
return;
// just clone arrays (and recursive clone objects inside)
} else if (Array.isArray(val)) {
target[key] = deepCloneArray(val);
return;
// custom cloning and overwrite for specific objects
} else if (isSpecificValue(val)) {
target[key] = cloneSpecificValue(val);
return;
// overwrite by new value if source isn't object or array
} else if (typeof src !== 'object' || src === null || Array.isArray(src)) {
target[key] = deepExtend({}, val);
return;
// source value and new value is objects both, extending...
} else {
target[key] = deepExtend(src, val);
return;
}
});
});
return target;
};

62
node_modules/deep-extend/package.json generated vendored Normal file
View File

@@ -0,0 +1,62 @@
{
"name": "deep-extend",
"description": "Recursive object extending",
"license": "MIT",
"version": "0.6.0",
"homepage": "https://github.com/unclechu/node-deep-extend",
"keywords": [
"deep-extend",
"extend",
"deep",
"recursive",
"xtend",
"clone",
"merge",
"json"
],
"licenses": [
{
"type": "MIT",
"url": "https://raw.githubusercontent.com/unclechu/node-deep-extend/master/LICENSE"
}
],
"repository": {
"type": "git",
"url": "git://github.com/unclechu/node-deep-extend.git"
},
"author": "Viacheslav Lotsmanov <lotsmanov89@gmail.com>",
"bugs": "https://github.com/unclechu/node-deep-extend/issues",
"contributors": [
{
"name": "Romain Prieto",
"url": "https://github.com/rprieto"
},
{
"name": "Max Maximov",
"url": "https://github.com/maxmaximov"
},
{
"name": "Marshall Bowers",
"url": "https://github.com/maxdeviant"
},
{
"name": "Misha Wakerman",
"url": "https://github.com/mwakerman"
}
],
"main": "lib/deep-extend.js",
"engines": {
"node": ">=4.0.0"
},
"scripts": {
"test": "./node_modules/.bin/mocha"
},
"devDependencies": {
"mocha": "5.2.0",
"should": "13.2.1"
},
"files": [
"index.js",
"lib/"
]
}

201
node_modules/detect-libc/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

163
node_modules/detect-libc/README.md generated vendored Normal file
View File

@@ -0,0 +1,163 @@
# detect-libc
Node.js module to detect details of the C standard library (libc)
implementation provided by a given Linux system.
Currently supports detection of GNU glibc and MUSL libc.
Provides asychronous and synchronous functions for the
family (e.g. `glibc`, `musl`) and version (e.g. `1.23`, `1.2.3`).
The version numbers of libc implementations
are not guaranteed to be semver-compliant.
For previous v1.x releases, please see the
[v1](https://github.com/lovell/detect-libc/tree/v1) branch.
## Install
```sh
npm install detect-libc
```
## API
### GLIBC
```ts
const GLIBC: string = 'glibc';
```
A String constant containing the value `glibc`.
### MUSL
```ts
const MUSL: string = 'musl';
```
A String constant containing the value `musl`.
### family
```ts
function family(): Promise<string | null>;
```
Resolves asychronously with:
* `glibc` or `musl` when the libc family can be determined
* `null` when the libc family cannot be determined
* `null` when run on a non-Linux platform
```js
const { family, GLIBC, MUSL } = require('detect-libc');
switch (await family()) {
case GLIBC: ...
case MUSL: ...
case null: ...
}
```
### familySync
```ts
function familySync(): string | null;
```
Synchronous version of `family()`.
```js
const { familySync, GLIBC, MUSL } = require('detect-libc');
switch (familySync()) {
case GLIBC: ...
case MUSL: ...
case null: ...
}
```
### version
```ts
function version(): Promise<string | null>;
```
Resolves asychronously with:
* The version when it can be determined
* `null` when the libc family cannot be determined
* `null` when run on a non-Linux platform
```js
const { version } = require('detect-libc');
const v = await version();
if (v) {
const [major, minor, patch] = v.split('.');
}
```
### versionSync
```ts
function versionSync(): string | null;
```
Synchronous version of `version()`.
```js
const { versionSync } = require('detect-libc');
const v = versionSync();
if (v) {
const [major, minor, patch] = v.split('.');
}
```
### isNonGlibcLinux
```ts
function isNonGlibcLinux(): Promise<boolean>;
```
Resolves asychronously with:
* `false` when the libc family is `glibc`
* `true` when the libc family is not `glibc`
* `false` when run on a non-Linux platform
```js
const { isNonGlibcLinux } = require('detect-libc');
if (await isNonGlibcLinux()) { ... }
```
### isNonGlibcLinuxSync
```ts
function isNonGlibcLinuxSync(): boolean;
```
Synchronous version of `isNonGlibcLinux()`.
```js
const { isNonGlibcLinuxSync } = require('detect-libc');
if (isNonGlibcLinuxSync()) { ... }
```
## Licensing
Copyright 2017 Lovell Fuller and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

14
node_modules/detect-libc/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
// Copyright 2017 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
export const GLIBC: 'glibc';
export const MUSL: 'musl';
export function family(): Promise<string | null>;
export function familySync(): string | null;
export function isNonGlibcLinux(): Promise<boolean>;
export function isNonGlibcLinuxSync(): boolean;
export function version(): Promise<string | null>;
export function versionSync(): string | null;

313
node_modules/detect-libc/lib/detect-libc.js generated vendored Normal file
View File

@@ -0,0 +1,313 @@
// Copyright 2017 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const childProcess = require('child_process');
const { isLinux, getReport } = require('./process');
const { LDD_PATH, SELF_PATH, readFile, readFileSync } = require('./filesystem');
const { interpreterPath } = require('./elf');
let cachedFamilyInterpreter;
let cachedFamilyFilesystem;
let cachedVersionFilesystem;
const command = 'getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true';
let commandOut = '';
const safeCommand = () => {
if (!commandOut) {
return new Promise((resolve) => {
childProcess.exec(command, (err, out) => {
commandOut = err ? ' ' : out;
resolve(commandOut);
});
});
}
return commandOut;
};
const safeCommandSync = () => {
if (!commandOut) {
try {
commandOut = childProcess.execSync(command, { encoding: 'utf8' });
} catch (_err) {
commandOut = ' ';
}
}
return commandOut;
};
/**
* A String constant containing the value `glibc`.
* @type {string}
* @public
*/
const GLIBC = 'glibc';
/**
* A Regexp constant to get the GLIBC Version.
* @type {string}
*/
const RE_GLIBC_VERSION = /LIBC[a-z0-9 \-).]*?(\d+\.\d+)/i;
/**
* A String constant containing the value `musl`.
* @type {string}
* @public
*/
const MUSL = 'musl';
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-');
const familyFromReport = () => {
const report = getReport();
if (report.header && report.header.glibcVersionRuntime) {
return GLIBC;
}
if (Array.isArray(report.sharedObjects)) {
if (report.sharedObjects.some(isFileMusl)) {
return MUSL;
}
}
return null;
};
const familyFromCommand = (out) => {
const [getconf, ldd1] = out.split(/[\r\n]+/);
if (getconf && getconf.includes(GLIBC)) {
return GLIBC;
}
if (ldd1 && ldd1.includes(MUSL)) {
return MUSL;
}
return null;
};
const familyFromInterpreterPath = (path) => {
if (path) {
if (path.includes('/ld-musl-')) {
return MUSL;
} else if (path.includes('/ld-linux-')) {
return GLIBC;
}
}
return null;
};
const getFamilyFromLddContent = (content) => {
content = content.toString();
if (content.includes('musl')) {
return MUSL;
}
if (content.includes('GNU C Library')) {
return GLIBC;
}
return null;
};
const familyFromFilesystem = async () => {
if (cachedFamilyFilesystem !== undefined) {
return cachedFamilyFilesystem;
}
cachedFamilyFilesystem = null;
try {
const lddContent = await readFile(LDD_PATH);
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
} catch (e) {}
return cachedFamilyFilesystem;
};
const familyFromFilesystemSync = () => {
if (cachedFamilyFilesystem !== undefined) {
return cachedFamilyFilesystem;
}
cachedFamilyFilesystem = null;
try {
const lddContent = readFileSync(LDD_PATH);
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
} catch (e) {}
return cachedFamilyFilesystem;
};
const familyFromInterpreter = async () => {
if (cachedFamilyInterpreter !== undefined) {
return cachedFamilyInterpreter;
}
cachedFamilyInterpreter = null;
try {
const selfContent = await readFile(SELF_PATH);
const path = interpreterPath(selfContent);
cachedFamilyInterpreter = familyFromInterpreterPath(path);
} catch (e) {}
return cachedFamilyInterpreter;
};
const familyFromInterpreterSync = () => {
if (cachedFamilyInterpreter !== undefined) {
return cachedFamilyInterpreter;
}
cachedFamilyInterpreter = null;
try {
const selfContent = readFileSync(SELF_PATH);
const path = interpreterPath(selfContent);
cachedFamilyInterpreter = familyFromInterpreterPath(path);
} catch (e) {}
return cachedFamilyInterpreter;
};
/**
* Resolves with the libc family when it can be determined, `null` otherwise.
* @returns {Promise<?string>}
*/
const family = async () => {
let family = null;
if (isLinux()) {
family = await familyFromInterpreter();
if (!family) {
family = await familyFromFilesystem();
if (!family) {
family = familyFromReport();
}
if (!family) {
const out = await safeCommand();
family = familyFromCommand(out);
}
}
}
return family;
};
/**
* Returns the libc family when it can be determined, `null` otherwise.
* @returns {?string}
*/
const familySync = () => {
let family = null;
if (isLinux()) {
family = familyFromInterpreterSync();
if (!family) {
family = familyFromFilesystemSync();
if (!family) {
family = familyFromReport();
}
if (!family) {
const out = safeCommandSync();
family = familyFromCommand(out);
}
}
}
return family;
};
/**
* Resolves `true` only when the platform is Linux and the libc family is not `glibc`.
* @returns {Promise<boolean>}
*/
const isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC;
/**
* Returns `true` only when the platform is Linux and the libc family is not `glibc`.
* @returns {boolean}
*/
const isNonGlibcLinuxSync = () => isLinux() && familySync() !== GLIBC;
const versionFromFilesystem = async () => {
if (cachedVersionFilesystem !== undefined) {
return cachedVersionFilesystem;
}
cachedVersionFilesystem = null;
try {
const lddContent = await readFile(LDD_PATH);
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
if (versionMatch) {
cachedVersionFilesystem = versionMatch[1];
}
} catch (e) {}
return cachedVersionFilesystem;
};
const versionFromFilesystemSync = () => {
if (cachedVersionFilesystem !== undefined) {
return cachedVersionFilesystem;
}
cachedVersionFilesystem = null;
try {
const lddContent = readFileSync(LDD_PATH);
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
if (versionMatch) {
cachedVersionFilesystem = versionMatch[1];
}
} catch (e) {}
return cachedVersionFilesystem;
};
const versionFromReport = () => {
const report = getReport();
if (report.header && report.header.glibcVersionRuntime) {
return report.header.glibcVersionRuntime;
}
return null;
};
const versionSuffix = (s) => s.trim().split(/\s+/)[1];
const versionFromCommand = (out) => {
const [getconf, ldd1, ldd2] = out.split(/[\r\n]+/);
if (getconf && getconf.includes(GLIBC)) {
return versionSuffix(getconf);
}
if (ldd1 && ldd2 && ldd1.includes(MUSL)) {
return versionSuffix(ldd2);
}
return null;
};
/**
* Resolves with the libc version when it can be determined, `null` otherwise.
* @returns {Promise<?string>}
*/
const version = async () => {
let version = null;
if (isLinux()) {
version = await versionFromFilesystem();
if (!version) {
version = versionFromReport();
}
if (!version) {
const out = await safeCommand();
version = versionFromCommand(out);
}
}
return version;
};
/**
* Returns the libc version when it can be determined, `null` otherwise.
* @returns {?string}
*/
const versionSync = () => {
let version = null;
if (isLinux()) {
version = versionFromFilesystemSync();
if (!version) {
version = versionFromReport();
}
if (!version) {
const out = safeCommandSync();
version = versionFromCommand(out);
}
}
return version;
};
module.exports = {
GLIBC,
MUSL,
family,
familySync,
isNonGlibcLinux,
isNonGlibcLinuxSync,
version,
versionSync
};

39
node_modules/detect-libc/lib/elf.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
// Copyright 2017 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const interpreterPath = (elf) => {
if (elf.length < 64) {
return null;
}
if (elf.readUInt32BE(0) !== 0x7F454C46) {
// Unexpected magic bytes
return null;
}
if (elf.readUInt8(4) !== 2) {
// Not a 64-bit ELF
return null;
}
if (elf.readUInt8(5) !== 1) {
// Not little-endian
return null;
}
const offset = elf.readUInt32LE(32);
const size = elf.readUInt16LE(54);
const count = elf.readUInt16LE(56);
for (let i = 0; i < count; i++) {
const headerOffset = offset + (i * size);
const type = elf.readUInt32LE(headerOffset);
if (type === 3) {
const fileOffset = elf.readUInt32LE(headerOffset + 8);
const fileSize = elf.readUInt32LE(headerOffset + 32);
return elf.subarray(fileOffset, fileOffset + fileSize).toString().replace(/\0.*$/g, '');
}
}
return null;
};
module.exports = {
interpreterPath
};

51
node_modules/detect-libc/lib/filesystem.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
// Copyright 2017 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const fs = require('fs');
const LDD_PATH = '/usr/bin/ldd';
const SELF_PATH = '/proc/self/exe';
const MAX_LENGTH = 2048;
/**
* Read the content of a file synchronous
*
* @param {string} path
* @returns {Buffer}
*/
const readFileSync = (path) => {
const fd = fs.openSync(path, 'r');
const buffer = Buffer.alloc(MAX_LENGTH);
const bytesRead = fs.readSync(fd, buffer, 0, MAX_LENGTH, 0);
fs.close(fd, () => {});
return buffer.subarray(0, bytesRead);
};
/**
* Read the content of a file
*
* @param {string} path
* @returns {Promise<Buffer>}
*/
const readFile = (path) => new Promise((resolve, reject) => {
fs.open(path, 'r', (err, fd) => {
if (err) {
reject(err);
} else {
const buffer = Buffer.alloc(MAX_LENGTH);
fs.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
resolve(buffer.subarray(0, bytesRead));
fs.close(fd, () => {});
});
}
});
});
module.exports = {
LDD_PATH,
SELF_PATH,
readFileSync,
readFile
};

24
node_modules/detect-libc/lib/process.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// Copyright 2017 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const isLinux = () => process.platform === 'linux';
let report = null;
const getReport = () => {
if (!report) {
/* istanbul ignore next */
if (isLinux() && process.report) {
const orig = process.report.excludeNetwork;
process.report.excludeNetwork = true;
report = process.report.getReport();
process.report.excludeNetwork = orig;
} else {
report = {};
}
}
return report;
};
module.exports = { isLinux, getReport };

44
node_modules/detect-libc/package.json generated vendored Normal file
View File

@@ -0,0 +1,44 @@
{
"name": "detect-libc",
"version": "2.1.2",
"description": "Node.js module to detect the C standard library (libc) implementation family and version",
"main": "lib/detect-libc.js",
"files": [
"lib/",
"index.d.ts"
],
"scripts": {
"test": "semistandard && nyc --reporter=text --check-coverage --branches=100 ava test/unit.js",
"changelog": "conventional-changelog -i CHANGELOG.md -s",
"bench": "node benchmark/detect-libc",
"bench:calls": "node benchmark/call-familySync.js && sleep 1 && node benchmark/call-isNonGlibcLinuxSync.js && sleep 1 && node benchmark/call-versionSync.js"
},
"repository": {
"type": "git",
"url": "git://github.com/lovell/detect-libc.git"
},
"keywords": [
"libc",
"glibc",
"musl"
],
"author": "Lovell Fuller <npm@lovell.info>",
"contributors": [
"Niklas Salmoukas <niklas@salmoukas.com>",
"Vinícius Lourenço <vinyygamerlol@gmail.com>"
],
"license": "Apache-2.0",
"devDependencies": {
"ava": "^2.4.0",
"benchmark": "^2.1.4",
"conventional-changelog-cli": "^5.0.0",
"eslint-config-standard": "^13.0.1",
"nyc": "^15.1.0",
"proxyquire": "^2.1.3",
"semistandard": "^14.2.3"
},
"engines": {
"node": ">=8"
},
"types": "index.d.ts"
}

21
node_modules/end-of-stream/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Mathias Buus
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

54
node_modules/end-of-stream/README.md generated vendored Normal file
View File

@@ -0,0 +1,54 @@
# end-of-stream
A node module that calls a callback when a readable/writable/duplex stream has completed or failed.
npm install end-of-stream
[![Build status](https://travis-ci.org/mafintosh/end-of-stream.svg?branch=master)](https://travis-ci.org/mafintosh/end-of-stream)
## Usage
Simply pass a stream and a callback to the `eos`.
Both legacy streams, streams2 and stream3 are supported.
``` js
var eos = require('end-of-stream');
eos(readableStream, function(err) {
// this will be set to the stream instance
if (err) return console.log('stream had an error or closed early');
console.log('stream has ended', this === readableStream);
});
eos(writableStream, function(err) {
if (err) return console.log('stream had an error or closed early');
console.log('stream has finished', this === writableStream);
});
eos(duplexStream, function(err) {
if (err) return console.log('stream had an error or closed early');
console.log('stream has ended and finished', this === duplexStream);
});
eos(duplexStream, {readable:false}, function(err) {
if (err) return console.log('stream had an error or closed early');
console.log('stream has finished but might still be readable');
});
eos(duplexStream, {writable:false}, function(err) {
if (err) return console.log('stream had an error or closed early');
console.log('stream has ended but might still be writable');
});
eos(readableStream, {error:false}, function(err) {
// do not treat emit('error', err) as a end-of-stream
});
```
## License
MIT
## Related
`end-of-stream` is part of the [mississippi stream utility collection](https://github.com/maxogden/mississippi) which includes more useful stream modules similar to this one.

96
node_modules/end-of-stream/index.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
var once = require('once');
var noop = function() {};
var qnt = global.Bare ? queueMicrotask : process.nextTick.bind(process);
var isRequest = function(stream) {
return stream.setHeader && typeof stream.abort === 'function';
};
var isChildProcess = function(stream) {
return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3
};
var eos = function(stream, opts, callback) {
if (typeof opts === 'function') return eos(stream, null, opts);
if (!opts) opts = {};
callback = once(callback || noop);
var ws = stream._writableState;
var rs = stream._readableState;
var readable = opts.readable || (opts.readable !== false && stream.readable);
var writable = opts.writable || (opts.writable !== false && stream.writable);
var cancelled = false;
var onlegacyfinish = function() {
if (!stream.writable) onfinish();
};
var onfinish = function() {
writable = false;
if (!readable) callback.call(stream);
};
var onend = function() {
readable = false;
if (!writable) callback.call(stream);
};
var onexit = function(exitCode) {
callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null);
};
var onerror = function(err) {
callback.call(stream, err);
};
var onclose = function() {
qnt(onclosenexttick);
};
var onclosenexttick = function() {
if (cancelled) return;
if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close'));
if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close'));
};
var onrequest = function() {
stream.req.on('finish', onfinish);
};
if (isRequest(stream)) {
stream.on('complete', onfinish);
stream.on('abort', onclose);
if (stream.req) onrequest();
else stream.on('request', onrequest);
} else if (writable && !ws) { // legacy streams
stream.on('end', onlegacyfinish);
stream.on('close', onlegacyfinish);
}
if (isChildProcess(stream)) stream.on('exit', onexit);
stream.on('end', onend);
stream.on('finish', onfinish);
if (opts.error !== false) stream.on('error', onerror);
stream.on('close', onclose);
return function() {
cancelled = true;
stream.removeListener('complete', onfinish);
stream.removeListener('abort', onclose);
stream.removeListener('request', onrequest);
if (stream.req) stream.req.removeListener('finish', onfinish);
stream.removeListener('end', onlegacyfinish);
stream.removeListener('close', onlegacyfinish);
stream.removeListener('finish', onfinish);
stream.removeListener('exit', onexit);
stream.removeListener('end', onend);
stream.removeListener('error', onerror);
stream.removeListener('close', onclose);
};
};
module.exports = eos;

37
node_modules/end-of-stream/package.json generated vendored Normal file
View File

@@ -0,0 +1,37 @@
{
"name": "end-of-stream",
"version": "1.4.5",
"description": "Call a callback when a readable/writable/duplex stream has completed or failed.",
"repository": {
"type": "git",
"url": "git://github.com/mafintosh/end-of-stream.git"
},
"dependencies": {
"once": "^1.4.0"
},
"scripts": {
"test": "node test.js"
},
"files": [
"index.js"
],
"keywords": [
"stream",
"streams",
"callback",
"finish",
"close",
"end",
"wait"
],
"bugs": {
"url": "https://github.com/mafintosh/end-of-stream/issues"
},
"homepage": "https://github.com/mafintosh/end-of-stream",
"main": "index.js",
"author": "Mathias Buus <mathiasbuus@gmail.com>",
"license": "MIT",
"devDependencies": {
"tape": "^4.11.0"
}
}

6
node_modules/expand-template/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,6 @@
language: node_js
node_js:
- 6
- 8
- 10

21
node_modules/expand-template/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Lars-Magnus Skog
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

43
node_modules/expand-template/README.md generated vendored Normal file
View File

@@ -0,0 +1,43 @@
# expand-template
> Expand placeholders in a template string.
[![npm](https://img.shields.io/npm/v/expand-template.svg)](https://www.npmjs.com/package/expand-template)
![Node version](https://img.shields.io/node/v/expand-template.svg)
[![Build Status](https://travis-ci.org/ralphtheninja/expand-template.svg?branch=master)](https://travis-ci.org/ralphtheninja/expand-template)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
## Install
```
$ npm i expand-template -S
```
## Usage
Default functionality expands templates using `{}` as separators for string placeholders.
```js
var expand = require('expand-template')()
var template = '{foo}/{foo}/{bar}/{bar}'
console.log(expand(template, {
foo: 'BAR',
bar: 'FOO'
}))
// -> BAR/BAR/FOO/FOO
```
Custom separators:
```js
var expand = require('expand-template')({ sep: '[]' })
var template = '[foo]/[foo]/[bar]/[bar]'
console.log(expand(template, {
foo: 'BAR',
bar: 'FOO'
}))
// -> BAR/BAR/FOO/FOO
```
## License
All code, unless stated otherwise, is dual-licensed under [`WTFPL`](http://www.wtfpl.net/txt/copying/) and [`MIT`](https://opensource.org/licenses/MIT).

26
node_modules/expand-template/index.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
module.exports = function (opts) {
var sep = opts ? opts.sep : '{}'
var len = sep.length
var whitespace = '\\s*'
var left = escape(sep.substring(0, len / 2)) + whitespace
var right = whitespace + escape(sep.substring(len / 2, len))
return function (template, values) {
Object.keys(values).forEach(function (key) {
var value = String(values[key]).replace(/\$/g, '$$$$')
template = template.replace(regExp(key), value)
})
return template
}
function escape (s) {
return [].map.call(s, function (char) {
return '\\' + char
}).join('')
}
function regExp (key) {
return new RegExp(left + key + right, 'g')
}
}

29
node_modules/expand-template/package.json generated vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "expand-template",
"version": "2.0.3",
"description": "Expand placeholders in a template string",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/ralphtheninja/expand-template.git"
},
"homepage": "https://github.com/ralphtheninja/expand-template",
"scripts": {
"test": "tape test.js && standard"
},
"keywords": [
"template",
"expand",
"replace"
],
"author": "LM <ralphtheninja@riseup.net>",
"license": "(MIT OR WTFPL)",
"dependencies": {},
"devDependencies": {
"standard": "^12.0.0",
"tape": "^4.2.2"
},
"engines": {
"node": ">=6"
}
}

67
node_modules/expand-template/test.js generated vendored Normal file
View File

@@ -0,0 +1,67 @@
var test = require('tape')
var Expand = require('./')
test('default expands {} placeholders', function (t) {
var expand = Expand()
t.equal(typeof expand, 'function', 'is a function')
t.equal(expand('{foo}/{bar}', {
foo: 'BAR', bar: 'FOO'
}), 'BAR/FOO')
t.equal(expand('{foo}{foo}{foo}', {
foo: 'FOO'
}), 'FOOFOOFOO', 'expands one placeholder many times')
t.end()
})
test('support for custom separators', function (t) {
var expand = Expand({ sep: '[]' })
t.equal(expand('[foo]/[bar]', {
foo: 'BAR', bar: 'FOO'
}), 'BAR/FOO')
t.equal(expand('[foo][foo][foo]', {
foo: 'FOO'
}), 'FOOFOOFOO', 'expands one placeholder many times')
t.end()
})
test('support for longer custom separators', function (t) {
var expand = Expand({ sep: '[[]]' })
t.equal(expand('[[foo]]/[[bar]]', {
foo: 'BAR', bar: 'FOO'
}), 'BAR/FOO')
t.equal(expand('[[foo]][[foo]][[foo]]', {
foo: 'FOO'
}), 'FOOFOOFOO', 'expands one placeholder many times')
t.end()
})
test('whitespace-insensitive', function (t) {
var expand = Expand({ sep: '[]' })
t.equal(expand('[ foo ]/[ bar ]', {
foo: 'BAR', bar: 'FOO'
}), 'BAR/FOO')
t.equal(expand('[ foo ][ foo ][ foo]', {
foo: 'FOO'
}), 'FOOFOOFOO', 'expands one placeholder many times')
t.end()
})
test('dollar escape', function (t) {
var expand = Expand()
t.equal(expand('before {foo} after', {
foo: '$'
}), 'before $ after')
t.equal(expand('before {foo} after', {
foo: '$&'
}), 'before $& after')
t.equal(expand('before {foo} after', {
foo: '$`'
}), 'before $` after')
t.equal(expand('before {foo} after', {
foo: '$\''
}), 'before $\' after')
t.equal(expand('before {foo} after', {
foo: '$0'
}), 'before $0 after')
t.end()
})

1
node_modules/file-uri-to-path/.npmignore generated vendored Normal file
View File

@@ -0,0 +1 @@
/node_modules

30
node_modules/file-uri-to-path/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,30 @@
sudo: false
language: node_js
node_js:
- "0.8"
- "0.10"
- "0.12"
- "1"
- "2"
- "3"
- "4"
- "5"
- "6"
- "7"
- "8"
install:
- PATH="`npm bin`:`npm bin -g`:$PATH"
# Node 0.8 comes with a too obsolete npm
- if [[ "`node --version`" =~ ^v0\.8\. ]]; then npm install -g npm@1.4.28 ; fi
# Install dependencies and build
- npm install
script:
# Output useful info for debugging
- node --version
- npm --version
# Run tests
- npm test

21
node_modules/file-uri-to-path/History.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
1.0.0 / 2017-07-06
==================
* update "mocha" to v3
* fixed unicode URI decoding (#6)
* add typings for Typescript
* README: use SVG Travis-CI badge
* add LICENSE file (MIT)
* add .travis.yml file (testing Node.js 0.8 through 8 currently)
* add README.md file
0.0.2 / 2014-01-27
==================
* index: invert the path separators on Windows
0.0.1 / 2014-01-27
==================
* initial commit

20
node_modules/file-uri-to-path/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright (c) 2014 Nathan Rajlich <nathan@tootallnate.net>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

74
node_modules/file-uri-to-path/README.md generated vendored Normal file
View File

@@ -0,0 +1,74 @@
file-uri-to-path
================
### Convert a `file:` URI to a file path
[![Build Status](https://travis-ci.org/TooTallNate/file-uri-to-path.svg?branch=master)](https://travis-ci.org/TooTallNate/file-uri-to-path)
Accepts a `file:` URI and returns a regular file path suitable for use with the
`fs` module functions.
Installation
------------
Install with `npm`:
``` bash
$ npm install file-uri-to-path
```
Example
-------
``` js
var uri2path = require('file-uri-to-path');
uri2path('file://localhost/c|/WINDOWS/clock.avi');
// "c:\\WINDOWS\\clock.avi"
uri2path('file:///c|/WINDOWS/clock.avi');
// "c:\\WINDOWS\\clock.avi"
uri2path('file://localhost/c:/WINDOWS/clock.avi');
// "c:\\WINDOWS\\clock.avi"
uri2path('file://hostname/path/to/the%20file.txt');
// "\\\\hostname\\path\\to\\the file.txt"
uri2path('file:///c:/path/to/the%20file.txt');
// "c:\\path\\to\\the file.txt"
```
API
---
### fileUriToPath(String uri) → String
License
-------
(The MIT License)
Copyright (c) 2014 Nathan Rajlich &lt;nathan@tootallnate.net&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

2
node_modules/file-uri-to-path/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
declare function fileUriToPath(uri: string): string;
export = fileUriToPath;

66
node_modules/file-uri-to-path/index.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
/**
* Module dependencies.
*/
var sep = require('path').sep || '/';
/**
* Module exports.
*/
module.exports = fileUriToPath;
/**
* File URI to Path function.
*
* @param {String} uri
* @return {String} path
* @api public
*/
function fileUriToPath (uri) {
if ('string' != typeof uri ||
uri.length <= 7 ||
'file://' != uri.substring(0, 7)) {
throw new TypeError('must pass in a file:// URI to convert to a file path');
}
var rest = decodeURI(uri.substring(7));
var firstSlash = rest.indexOf('/');
var host = rest.substring(0, firstSlash);
var path = rest.substring(firstSlash + 1);
// 2. Scheme Definition
// As a special case, <host> can be the string "localhost" or the empty
// string; this is interpreted as "the machine from which the URL is
// being interpreted".
if ('localhost' == host) host = '';
if (host) {
host = sep + sep + host;
}
// 3.2 Drives, drive letters, mount points, file system root
// Drive letters are mapped into the top of a file URI in various ways,
// depending on the implementation; some applications substitute
// vertical bar ("|") for the colon after the drive letter, yielding
// "file:///c|/tmp/test.txt". In some cases, the colon is left
// unchanged, as in "file:///c:/tmp/test.txt". In other cases, the
// colon is simply omitted, as in "file:///c/tmp/test.txt".
path = path.replace(/^(.+)\|/, '$1:');
// for Windows, we need to invert the path separators from what a URI uses
if (sep == '\\') {
path = path.replace(/\//g, '\\');
}
if (/^.+\:/.test(path)) {
// has Windows drive at beginning of path
} else {
// unix path…
path = sep + path;
}
return host + path;
}

32
node_modules/file-uri-to-path/package.json generated vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "file-uri-to-path",
"version": "1.0.0",
"description": "Convert a file: URI to a file path",
"main": "index.js",
"types": "index.d.ts",
"directories": {
"test": "test"
},
"scripts": {
"test": "mocha --reporter spec"
},
"repository": {
"type": "git",
"url": "git://github.com/TooTallNate/file-uri-to-path.git"
},
"keywords": [
"file",
"uri",
"convert",
"path"
],
"author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
"license": "MIT",
"bugs": {
"url": "https://github.com/TooTallNate/file-uri-to-path/issues"
},
"homepage": "https://github.com/TooTallNate/file-uri-to-path",
"devDependencies": {
"mocha": "3"
}
}

Some files were not shown because too many files have changed in this diff Show More