├── .eslintrc.js ├── .github └── workflows │ ├── ci.yml │ └── lint.yml ├── LICENSE ├── README.md ├── binding.gyp ├── buildcheck.js ├── deps └── sqlite3 │ ├── sqlite3.gyp │ ├── sqlite3mc_amalgamation.c │ └── sqlite3mc_amalgamation.h ├── lib └── index.js ├── package.json ├── src └── binding.cc └── test ├── common.js ├── test-basic.js ├── test-end.js └── test.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: '@mscdex/eslint-config', 5 | }; 6 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [ master ] 7 | 8 | jobs: 9 | tests-linux: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | node-version: [10.7.0, 10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 22.x] 15 | steps: 16 | - uses: actions/checkout@v4 17 | with: 18 | persist-credentials: false 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - name: Check Node.js version 24 | run: node -pe process.versions 25 | - name: Check npm version 26 | run: npm -v 27 | - name: Install Python 2.7 (node <16.x) 28 | if: ${{ contains(fromJSON('["10.7.0", "10.x", "12.x", "14.x"]'), matrix.node-version) }} 29 | uses: LizardByte/setup-python-action@v2024.1105.190605 30 | with: 31 | python-version: '2.7' 32 | - name: Use Python 2.7 (node <16.x) 33 | if: ${{ contains(fromJSON('["10.7.0", "10.x", "12.x", "14.x"]'), matrix.node-version) }} 34 | run: echo "PYTHON=$(which python2.7)" >> "$GITHUB_ENV" 35 | - name: Install module 36 | run: npm install 37 | - name: Run tests 38 | run: npm test 39 | tests-macos: 40 | runs-on: macos-latest 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | node-version: [16.x, 18.x, 20.x, 22.x] 45 | steps: 46 | - uses: actions/checkout@v4 47 | with: 48 | persist-credentials: false 49 | - name: Use Node.js ${{ matrix.node-version }} 50 | uses: actions/setup-node@v4 51 | with: 52 | node-version: ${{ matrix.node-version }} 53 | - name: Install Python 3.10 54 | uses: actions/setup-python@v5 55 | with: 56 | python-version: '3.10' 57 | - name: Check Node.js version 58 | run: node -pe process.versions 59 | - name: Check npm version 60 | run: npm -v 61 | - name: Install module 62 | run: npm install 63 | - name: Run tests 64 | run: npm test 65 | tests-windows: 66 | runs-on: windows-2019 67 | strategy: 68 | fail-fast: false 69 | matrix: 70 | node-version: [12.x, 14.x, 16.x, 18.x, 20.x, 22.x] 71 | steps: 72 | - uses: actions/checkout@v4 73 | with: 74 | persist-credentials: false 75 | - name: Use Node.js ${{ matrix.node-version }} 76 | uses: actions/setup-node@v4 77 | with: 78 | node-version: ${{ matrix.node-version }} 79 | - name: Check Node.js version 80 | run: node -pe process.versions 81 | - name: Check npm version 82 | run: npm -v 83 | - name: Install module 84 | run: npm install 85 | - name: Run tests 86 | run: npm test 87 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [ master ] 7 | 8 | env: 9 | NODE_VERSION: 18.x 10 | 11 | jobs: 12 | lint-js: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | persist-credentials: false 18 | - name: Use Node.js ${{ env.NODE_VERSION }} 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: ${{ env.NODE_VERSION }} 22 | - name: Check Node.js version 23 | run: node -pe process.versions 24 | - name: Install ESLint + ESLint configs/plugins 25 | run: npm install --only=dev 26 | - name: Lint files 27 | run: npm run lint 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Brian White. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Description 2 | =========== 3 | 4 | An SQLite (more accurately [SQLite3MultipleCiphers](https://utelle.github.io/SQLite3MultipleCiphers/)) binding for [node.js](https://nodejs.org) focused on simplicity and (async) performance. 5 | 6 | Current SQLite version: 3.49.1 7 | 8 | When dealing with encrypted sqlite databases, this binding only supports the 9 | ChaCha20-Poly1305 cipher to keep things simple, secure, and working well across 10 | multiple platforms. 11 | 12 | Available/Relevant special `PRAGMA`s: 13 | 14 | * [`PRAGMA kdf_iter`](https://utelle.github.io/SQLite3MultipleCiphers/docs/configuration/config_sql_pragmas/#pragma-kdf_iter) 15 | * [`PRAGMA key`](https://utelle.github.io/SQLite3MultipleCiphers/docs/configuration/config_sql_pragmas/#pragma-key) 16 | * [`PRAGMA rekey`](https://utelle.github.io/SQLite3MultipleCiphers/docs/configuration/config_sql_pragmas/#pragma-rekey) 17 | 18 | Table of Contents 19 | ================= 20 | 21 | * [Implementation/Design Notes](#implementationdesign-notes) 22 | * [Performance](#performance) 23 | * [Requirements](#requirements) 24 | * [Installation](#installation) 25 | * [Examples](#examples) 26 | * [API](#api) 27 | 28 | # Implementation/Design Notes 29 | 30 | The goal of this addon/binding is to provide a simple and consistent interface 31 | for interacting with SQLite databases. What that means on a technical level is: 32 | 33 | * Only synchronous opening and closing of databases 34 | * **Why?** To simplify things. Opening and closing should be fast enough and 35 | are typically not done that often anyway. 36 | 37 | * Only async queries, which are processed in a queue 38 | * **Why?** Async because queries could easily have the potential to disrupt 39 | the node.js event loop. A per-connection queue is used because of the 40 | threading model used with SQLite, which not only avoids a lot of extra 41 | mutexes but also avoids various race conditions that can still occur even 42 | with SQLite in a serialized/"thread-safe" threading model. 43 | 44 | * Only strings, `null`, and `Buffer`s for column values 45 | * **Why?** To provide a consistent set of data types without any "gotchas." 46 | In particular there is no awkward number value handling that plagues a lot 47 | of node.js database bindings in general due to JavaScript's use of a 48 | double type for its numbers (although there is built-in bigint now, it is 49 | a separate type and can't be used with regular JavaScript numbers very 50 | easily). 51 | 52 | Some bindings deal with this problem by allowing you to configure 53 | number-handling behavior, however in general that ultimately means you 54 | will probably end up adding some kind of type checking and whatnot when 55 | processing query results to support different configurations. 56 | 57 | * Only SQLite's UTF-8 APIs are used/supported 58 | * **Why?** To be clear, this doesn't mean databases utilizing UTF-16 can't 59 | be used with this addon, it just means that SQLite will be forced to do 60 | some transformations that would ordinarily be unnecessary with a database 61 | that used UTF-8 for string values from the get-go. This incurs additional 62 | overhead when executing queries. Also, SQLite has some APIs that only 63 | accept UTF-8 strings anyway so it makes even more sense from a 64 | consistency perspective. 65 | 66 | # Performance 67 | 68 | When discussing performance (particularly node.js sqlite driver performance), 69 | it's important to reiterate that your mileage may vary and that it mostly boils 70 | down to how the sqlite database is accessed. Specifically I'm referring to 71 | synchronous vs. asynchronous. Both have their advantages and disadvantages and 72 | have different scaling properties. 73 | 74 | Because `esqlite` only provides an async API and the fact that sqlite directly 75 | accesses the disk, it means queries run in the thread pool to ensure the main 76 | thread is not blocked. With other types of databases where you make a network 77 | connection to the database, this is unnecessary and can be done without the 78 | thread pool (and without writing/using C/C++ code) because you're simply waiting 79 | for I/O, which node.js can easily and more efficiently do. 80 | 81 | With that in mind, what this means is that for some workloads, synchronous 82 | queries will perform better than asynchronous queries because of the overhead 83 | of queueing work to the thread pool and the additional copying of results 84 | because you cannot access V8 APIs from threads in a *node addon*. 85 | 86 | For benchmarking, I generated a single, unencrypted database with 100k records. 87 | The schema looked like: 88 | 89 | ```sql 90 | CREATE TABLE data ( 91 | ID INT, 92 | EmailAddress VARCHAR(500), 93 | FirstName VARCHAR(500), 94 | LastName VARCHAR(500), 95 | IPAddress VARCHAR(500), 96 | Age INT 97 | ) 98 | ``` 99 | 100 | The node.js version benchmarked with here was **v20.14.0**. 101 | 102 | The sqlite packages being benchmarked: 103 | 104 | Package | Version 105 | -----------------|--------: 106 | [better-sqlite3] | 11.7.0 107 | [esqlite] | 0.0.19 108 | [sqlite3] | 5.1.7 109 | 110 | [better-sqlite3]: https://github.com/WiseLibs/better-sqlite3 111 | [esqlite]: https://github.com/mscdex/esqlite 112 | [sqlite3]: https://github.com/TryGhost/node-sqlite3 113 | 114 | Here is the code and the results for a couple of different queries that I ran on 115 | my Linux desktop: 116 | 117 | * `SELECT * FROM data` (retrieves all 100k rows) 118 | 119 | * Code 120 | 121 | * `better-sqlite3` 122 | ```js 123 | const openDB = require('better-sqlite3'); 124 | const db = openDB('/tmp/test.db', { readonly: true }); 125 | 126 | console.time('select'); 127 | db.prepare('SELECT * FROM data').all(); 128 | console.timeEnd('select'); 129 | db.close(); 130 | ``` 131 | * `esqlite` 132 | ```js 133 | const { Database, OPEN_FLAGS } = require('esqlite'); 134 | const db = new Database('/tmp/test.db'); 135 | db.open(OPEN_FLAGS.READONLY); 136 | 137 | console.time('select'); 138 | db.query('SELECT * FROM data', () => { 139 | console.timeEnd('select'); 140 | db.close(); 141 | }); 142 | ``` 143 | * `sqlite3` 144 | ```js 145 | const sqlite3 = require('sqlite3'); 146 | const db = new sqlite3.Database('/tmp/test.db', sqlite3.OPEN_READONLY); 147 | 148 | console.time('select'); 149 | db.all('SELECT * FROM data', () => { 150 | console.timeEnd('select'); 151 | db.close(); 152 | }); 153 | ``` 154 | 155 | * Results 156 | 157 | Package | Average time (ms) | Average max RSS (MB) 158 | ---------------|------------------:|---------------------: 159 | better-sqlite3 | `121` | `101` 160 | esqlite | `88` | `129` 161 | sqlite3 | `189` | `146` 162 | 163 | * `SELECT * FROM data LIMIT 1000` 164 | 165 | * Code same as before, but with the SQL string changed appropriately 166 | 167 | * Results 168 | 169 | Package | Average time (ms) | Average max RSS (MB) 170 | ---------------|------------------:|---------------------: 171 | better-sqlite3 | `1.5` | `51` 172 | esqlite | `1.3` | `50` 173 | sqlite3 | `2.3` | `47` 174 | 175 | * `SELECT * FROM data LIMIT 10` 176 | 177 | * Code same as before, but with the SQL string changed appropriately 178 | 179 | * Results 180 | 181 | Package | Average time (ms) | Average max RSS (MB) 182 | ---------------|------------------:|---------------------: 183 | better-sqlite3 | `0.185` | `50` 184 | esqlite | `0.500` | `46` 185 | sqlite3 | `0.603` | `47` 186 | 187 | 188 | # Requirements 189 | 190 | * [node.js](http://nodejs.org/) 191 | * Windows: node v12.x or newer 192 | * All other platforms: node v10.7.0 or newer 193 | * An appropriate build environment -- see [node-gyp's documentation](https://github.com/nodejs/node-gyp/blob/main/README.md) 194 | 195 | 196 | # Installation 197 | 198 | npm install esqlite 199 | 200 | 201 | # Examples 202 | 203 | * Create/Open an encrypted database 204 | ```js 205 | const { Database } = require('esqlite'); 206 | 207 | const db = new Database('/path/to/database'); 208 | db.open(); 209 | db.query(`PRAGMA key = 'my passphrase'`, (err) => { 210 | if (err) throw err; 211 | 212 | // Perform queries as normal ... 213 | 214 | // ... and eventually close the database 215 | db.close(); 216 | }); 217 | ``` 218 | 219 | * Binding values 220 | ```js 221 | const { Database } = require('esqlite'); 222 | 223 | const db = new Database('/path/to/database'); 224 | db.open(); 225 | 226 | // Using nameless/ordered parameters 227 | db.query('SELECT * FROM posts WHERE id = ?', [1234], (err, rows) => { 228 | if (err) throw err; 229 | 230 | db.close(); 231 | }); 232 | 233 | // Using named parameters 234 | const values = { id: 1234 }; 235 | db.query('SELECT * FROM posts WHERE id = :id', { values }, (err, rows) => { 236 | if (err) throw err; 237 | 238 | db.close(); 239 | }); 240 | ``` 241 | 242 | 243 | # API 244 | 245 | ## Exports 246 | 247 | * `Database` - A class that represents a connection to an SQLite database. 248 | 249 | * `OPEN_FLAGS` - *object* - Contains various flags that can be passed to 250 | `database.open()`: 251 | 252 | * `CREATE` - The database is created if it does not exist. 253 | * `MEMORY` - The database will be opened as an in-memory database. The 254 | database is named by the `filename` argument passed to the 255 | `Database` constructor for the purposes of cache-sharing if 256 | shared cache mode is enabled, otherwise the `filename` is 257 | ignored. 258 | * `NOFOLLOW` - When opening the database, the database path is not allowed 259 | to be a symbolic link. 260 | * `PRIVATECACHE` - The database is opened with shared cache disabled. 261 | * `READONLY` - The database is opened in read-only mode. If the database 262 | does not already exist, an error is thrown. 263 | * `READWRITE` - The database is opened for reading and writing if possible, 264 | or reading only if the file is write protected by the 265 | operating system. In either case the database must already 266 | exist, otherwise an error is thrown. 267 | * `SHAREDCACHE` - The database is opened with shared cache enabled. 268 | 269 | * `PREPARE_FLAGS` - *object* - Contains various flags related to query 270 | preparation that can be passed to `query()`: 271 | 272 | * `NO_VTAB` - Causes the query to fail if the statement uses any virtual 273 | tables. 274 | 275 | * `version` - *string* - Contains the SQLite and SQLite3MultipleCiphers 276 | versions. 277 | 278 | --- 279 | 280 | ## `Database` methods 281 | 282 | * Database(< _string_ >path) - Creates a new `Database` object for operating 283 | on the database located at `path`. 284 | 285 | * autoCommitEnabled() - *boolean* - Returns whether the opened database 286 | currently has auto-commit enabled. 287 | 288 | * close() - *(void)* - Closes the database. 289 | 290 | * end() - *(void)* - Automatically closes the database when the query queue is 291 | empty. If the queue is empty when `end()` is called, then the database is 292 | immediately closed. 293 | 294 | * interrupt(< _function_ >callback) - *(void)* - Interrupts the currently 295 | running query. `callback` has no arguments and is called after any query has 296 | been interrupted. 297 | 298 | * open([ < _integer_ >flags ]) - *(void)* - Opens the database with optional 299 | flags whose values come from `OPEN_FLAGS`. 300 | **Default `flags`:** `CREATE | READWRITE` 301 | 302 | * query(< _string_ >sql[, < _object_ >options][, < _array_ >values][, < _function_ >callback) - 303 | Executes the statement(s) in `sql`. `options` may contain: 304 | 305 | * `prepareFlags` - *integer* - Flags to be used during preparation of the 306 | statement(s) whose values come from `PREPARE_FLAGS`. 307 | **Default:** (no flags) 308 | 309 | * `single` - *boolean* - Whether only a single statement should be executed 310 | from `sql`. This can be useful to help avoid some SQL injection attacks. 311 | **Default:** `true` 312 | 313 | * `values` - *mixed* - Either an object containing named bind parameters and 314 | their associated values or an array containing values for nameless/ordered 315 | bind parameters. **Default:** (none) 316 | 317 | If using nameless/ordered values, then an array `values` may be passed 318 | directly in `query()`. 319 | 320 | If an error occurs while preparing/parsing a statement, further processing 321 | of `sql` stops immediately (only relevant when `options.single === false`). 322 | 323 | `callback` is called when zero or more of the statement(s) finish and has the 324 | signature `(err, rows)`. In the case of a single statement, `err` is a 325 | possible `Error` instance and `rows` is a possible array of rows returned from 326 | the statement. In the case of multiple statements, if any one of the 327 | statements ended in an error, then `err` will be an array. If there was no 328 | error, `rows` will contain a 2D array of rows, one set of rows per statement. 329 | It is possible that the length of `err` and/or `rows` will not equal the 330 | number of statements if there was a fatal error that halted execution of any 331 | further statements. 332 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | { 4 | 'target_name': 'esqlite3', 5 | 'dependencies': [ 'deps/sqlite3/sqlite3.gyp:sqlite3mc' ], 6 | 'include_dirs': [ 7 | 'src', 8 | "' but it appears the 51 | # decorated symbol name changes across node versions which would 52 | # be a pain to maintain here... 53 | '/OPT:NOREF', 54 | ], 55 | }, 56 | }, 57 | }], 58 | ], 59 | }, 60 | ], 61 | } 62 | -------------------------------------------------------------------------------- /buildcheck.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BuildEnvironment = require('buildcheck'); 4 | 5 | const be = new BuildEnvironment(); 6 | 7 | const gyp = { 8 | defines: [], 9 | libraries: [], 10 | }; 11 | 12 | [ 13 | 'inttypes.h', 14 | 'malloc.h', 15 | 'memory.h', 16 | 'stdint.h', 17 | 'stdlib.h', 18 | 'string.h', 19 | 'strings.h', 20 | 'sys/types.h', 21 | 'sys/stat.h', 22 | 'unistd.h', 23 | ].forEach((headerName) => { 24 | be.checkHeader('c', headerName); 25 | }); 26 | 27 | // On Windows localtime_s is a macro, so we need to use `checkDeclared()` 28 | [ 29 | ['localtime_s', { headers: ['time.h'] }], 30 | ].forEach((fnName) => { 31 | if (Array.isArray(fnName)) 32 | be.checkDeclared('c', ...fnName); 33 | else 34 | be.checkDeclared('c', fnName); 35 | }); 36 | 37 | [ 38 | ['fdatasync', { searchLibs: ['rt'] }], 39 | 'gmtime_r', 40 | 'isnan', 41 | 'localtime_r', 42 | 'malloc_usable_size', 43 | 'posix_fallocate', 44 | 'pread', 45 | 'pread64', 46 | 'pwrite', 47 | 'pwrite64', 48 | 'strchrnul', 49 | 'usleep', 50 | 'utime', 51 | ].forEach((fnName) => { 52 | if (Array.isArray(fnName)) 53 | be.checkFunction('c', ...fnName); 54 | else 55 | be.checkFunction('c', fnName); 56 | }); 57 | 58 | [ 59 | 'strerror_r', 60 | ].forEach((feat) => { 61 | be.checkFeature(feat); 62 | }); 63 | 64 | // Custom defines -------------------------------------------------------------- 65 | gyp.defines.push( 66 | 'SQLITE_ENABLE_FTS3', 67 | 'SQLITE_ENABLE_JSON1', 68 | ); 69 | 70 | if (be.checkFunction('c', 'log', { searchLibs: ['m'] })) 71 | gyp.defines.push('SQLITE_ENABLE_FTS4', 'SQLITE_ENABLE_FTS5'); 72 | 73 | if (be.checkFunction('c', 'ceil', { searchLibs: ['m'] })) 74 | gyp.defines.push('SQLITE_ENABLE_MATH_FUNCTIONS'); 75 | // ----------------------------------------------------------------------------- 76 | 77 | // Add the things we detected 78 | gyp.defines.push(...be.defines(null, true)); 79 | gyp.libraries.push(...be.libs()); 80 | 81 | console.log(JSON.stringify(gyp, null, 2)); 82 | -------------------------------------------------------------------------------- /deps/sqlite3/sqlite3.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'targets': [ 3 | { 4 | 'target_name': 'sqlite3mc', 5 | 'type': 'static_library', 6 | 'sources': [ 7 | 'sqlite3mc_amalgamation.c', 8 | ], 9 | 'cflags': [ '-O3' ], 10 | 'defines': [ 11 | # General defines for SQLite 12 | '_REENTRANT=1', 13 | 'SQLITE_DEFAULT_CACHE_SIZE=-16000', 14 | 'SQLITE_DQS=0', 15 | 'SQLITE_LIKE_DOESNT_MATCH_BLOBS', 16 | 'SQLITE_DEFAULT_MEMSTATUS=0', 17 | 'SQLITE_OMIT_AUTHORIZATION', 18 | 'SQLITE_OMIT_AUTOINIT', 19 | 'SQLITE_OMIT_AUTORESET', 20 | 'SQLITE_OMIT_COMPLETE', 21 | 'SQLITE_OMIT_DEPRECATED', 22 | 'SQLITE_OMIT_GET_TABLE', 23 | 'SQLITE_OMIT_PROGRESS_CALLBACK', 24 | 'SQLITE_OMIT_SHARED_CACHE', 25 | 'SQLITE_OMIT_TCL_VARIABLE', 26 | 'SQLITE_OMIT_TRACE', 27 | 'SQLITE_THREADSAFE=2', 28 | 'SQLITE_TRACE_SIZE_LIMIT=32', 29 | 'SQLITE_UNTESTABLE', 30 | 'SQLITE_USE_URI=0', 31 | 32 | # Defines from/for SQLite3MultipleCiphers 33 | 'CODEC_TYPE=CODEC_TYPE_CHACHA20', 34 | 'HAVE_CIPHER_CHACHA20=1', 35 | 'HAVE_CIPHER_AES_128_CBC=0', 36 | 'HAVE_CIPHER_AES_256_CBC=0', 37 | 'HAVE_CIPHER_SQLCIPHER=0', 38 | 'HAVE_CIPHER_RC4=0', 39 | 'SQLITE_CORE=1', 40 | 'SQLITE_ENABLE_CSV=1', 41 | 'SQLITE_ENABLE_EXTFUNC=1', 42 | 'SQLITE_ENABLE_REGEXP=1', 43 | 'SQLITE_ENABLE_SERIES=1', 44 | 'SQLITE_ENABLE_UUID=1', 45 | 'SQLITE_SECURE_DELETE=1', 46 | 'SQLITE_TEMP_STORE=2', 47 | 'SQLITE_USER_AUTHENTICATION=0', 48 | ], 49 | 50 | # System-specific and feature configs for SQLite 51 | # Use generated config 52 | 'includes': [ 53 | '../../buildcheck.gypi', 54 | ], 55 | 'conditions': [ 56 | [ 'OS != "win"', { 57 | # SQLite3MultipleCiphers and SQLite3 can be very noisy, mostly due to 58 | # unused functions and variables 59 | 'cflags': [ '-w' ], 60 | 'xcode_settings': { 61 | 'WARNING_CFLAGS': [ 62 | '-w', 63 | ], 64 | }, 65 | }], 66 | ], 67 | 68 | 'direct_dependent_settings': { 69 | 'include_dirs': ['.'], 70 | 'defines': [ 71 | # Manually-tracked custom git revision 72 | 'SQLITE3MC_VERSION_REV=17abb48a42b16a79ee8611616d62cdf61d1a649d', 73 | ], 74 | }, 75 | }, 76 | ], 77 | } 78 | -------------------------------------------------------------------------------- /deps/sqlite3/sqlite3mc_amalgamation.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef SQLITE3MC_H_ 4 | #define SQLITE3MC_H_ 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | #ifndef SQLITE3MC_VERSION_H_ 14 | #define SQLITE3MC_VERSION_H_ 15 | 16 | #define SQLITE3MC_VERSION_MAJOR 2 17 | #define SQLITE3MC_VERSION_MINOR 1 18 | #define SQLITE3MC_VERSION_RELEASE 0 19 | #define SQLITE3MC_VERSION_SUBRELEASE 0 20 | #define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 2.1.0" 21 | 22 | #endif 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | #ifndef SQLITE3_H 31 | #define SQLITE3_H 32 | #include 33 | 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | 40 | 41 | #ifndef SQLITE_EXTERN 42 | # define SQLITE_EXTERN extern 43 | #endif 44 | #ifndef SQLITE_API 45 | # define SQLITE_API 46 | #endif 47 | #ifndef SQLITE_CDECL 48 | # define SQLITE_CDECL 49 | #endif 50 | #ifndef SQLITE_APICALL 51 | # define SQLITE_APICALL 52 | #endif 53 | #ifndef SQLITE_STDCALL 54 | # define SQLITE_STDCALL SQLITE_APICALL 55 | #endif 56 | #ifndef SQLITE_CALLBACK 57 | # define SQLITE_CALLBACK 58 | #endif 59 | #ifndef SQLITE_SYSAPI 60 | # define SQLITE_SYSAPI 61 | #endif 62 | 63 | 64 | #define SQLITE_DEPRECATED 65 | #define SQLITE_EXPERIMENTAL 66 | 67 | 68 | #ifdef SQLITE_VERSION 69 | # undef SQLITE_VERSION 70 | #endif 71 | #ifdef SQLITE_VERSION_NUMBER 72 | # undef SQLITE_VERSION_NUMBER 73 | #endif 74 | 75 | 76 | #define SQLITE_VERSION "3.49.1" 77 | #define SQLITE_VERSION_NUMBER 3049001 78 | #define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70" 79 | 80 | 81 | SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; 82 | SQLITE_API const char *sqlite3_libversion(void); 83 | SQLITE_API const char *sqlite3_sourceid(void); 84 | SQLITE_API int sqlite3_libversion_number(void); 85 | 86 | 87 | #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS 88 | SQLITE_API int sqlite3_compileoption_used(const char *zOptName); 89 | SQLITE_API const char *sqlite3_compileoption_get(int N); 90 | #else 91 | # define sqlite3_compileoption_used(X) 0 92 | # define sqlite3_compileoption_get(X) ((void*)0) 93 | #endif 94 | 95 | 96 | SQLITE_API int sqlite3_threadsafe(void); 97 | 98 | 99 | typedef struct sqlite3 sqlite3; 100 | 101 | 102 | #ifdef SQLITE_INT64_TYPE 103 | typedef SQLITE_INT64_TYPE sqlite_int64; 104 | # ifdef SQLITE_UINT64_TYPE 105 | typedef SQLITE_UINT64_TYPE sqlite_uint64; 106 | # else 107 | typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; 108 | # endif 109 | #elif defined(_MSC_VER) || defined(__BORLANDC__) 110 | typedef __int64 sqlite_int64; 111 | typedef unsigned __int64 sqlite_uint64; 112 | #else 113 | typedef long long int sqlite_int64; 114 | typedef unsigned long long int sqlite_uint64; 115 | #endif 116 | typedef sqlite_int64 sqlite3_int64; 117 | typedef sqlite_uint64 sqlite3_uint64; 118 | 119 | 120 | #ifdef SQLITE_OMIT_FLOATING_POINT 121 | # define double sqlite3_int64 122 | #endif 123 | 124 | 125 | SQLITE_API int sqlite3_close(sqlite3*); 126 | SQLITE_API int sqlite3_close_v2(sqlite3*); 127 | 128 | 129 | typedef int (*sqlite3_callback)(void*,int,char**, char**); 130 | 131 | 132 | SQLITE_API int sqlite3_exec( 133 | sqlite3*, 134 | const char *sql, 135 | int (*callback)(void*,int,char**,char**), 136 | void *, 137 | char **errmsg 138 | ); 139 | 140 | 141 | #define SQLITE_OK 0 142 | 143 | #define SQLITE_ERROR 1 144 | #define SQLITE_INTERNAL 2 145 | #define SQLITE_PERM 3 146 | #define SQLITE_ABORT 4 147 | #define SQLITE_BUSY 5 148 | #define SQLITE_LOCKED 6 149 | #define SQLITE_NOMEM 7 150 | #define SQLITE_READONLY 8 151 | #define SQLITE_INTERRUPT 9 152 | #define SQLITE_IOERR 10 153 | #define SQLITE_CORRUPT 11 154 | #define SQLITE_NOTFOUND 12 155 | #define SQLITE_FULL 13 156 | #define SQLITE_CANTOPEN 14 157 | #define SQLITE_PROTOCOL 15 158 | #define SQLITE_EMPTY 16 159 | #define SQLITE_SCHEMA 17 160 | #define SQLITE_TOOBIG 18 161 | #define SQLITE_CONSTRAINT 19 162 | #define SQLITE_MISMATCH 20 163 | #define SQLITE_MISUSE 21 164 | #define SQLITE_NOLFS 22 165 | #define SQLITE_AUTH 23 166 | #define SQLITE_FORMAT 24 167 | #define SQLITE_RANGE 25 168 | #define SQLITE_NOTADB 26 169 | #define SQLITE_NOTICE 27 170 | #define SQLITE_WARNING 28 171 | #define SQLITE_ROW 100 172 | #define SQLITE_DONE 101 173 | 174 | 175 | 176 | #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) 177 | #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) 178 | #define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) 179 | #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) 180 | #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) 181 | #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) 182 | #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) 183 | #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) 184 | #define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) 185 | #define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) 186 | #define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) 187 | #define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) 188 | #define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) 189 | #define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) 190 | #define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) 191 | #define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) 192 | #define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) 193 | #define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) 194 | #define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) 195 | #define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) 196 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) 197 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) 198 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) 199 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) 200 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) 201 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) 202 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) 203 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) 204 | #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) 205 | #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) 206 | #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) 207 | #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) 208 | #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) 209 | #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) 210 | #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) 211 | #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) 212 | #define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) 213 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) 214 | #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) 215 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) 216 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) 217 | #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8)) 218 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) 219 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) 220 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) 221 | #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) 222 | #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) 223 | #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) 224 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) 225 | #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) 226 | #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8)) 227 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) 228 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) 229 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) 230 | #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) 231 | #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) 232 | #define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) 233 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) 234 | #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) 235 | #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) 236 | #define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) 237 | #define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) 238 | #define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) 239 | #define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) 240 | #define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) 241 | #define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) 242 | #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) 243 | #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) 244 | #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) 245 | #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) 246 | #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) 247 | #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) 248 | #define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) 249 | #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) 250 | #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) 251 | #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) 252 | #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) 253 | 254 | 255 | #define SQLITE_OPEN_READONLY 0x00000001 256 | #define SQLITE_OPEN_READWRITE 0x00000002 257 | #define SQLITE_OPEN_CREATE 0x00000004 258 | #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 259 | #define SQLITE_OPEN_EXCLUSIVE 0x00000010 260 | #define SQLITE_OPEN_AUTOPROXY 0x00000020 261 | #define SQLITE_OPEN_URI 0x00000040 262 | #define SQLITE_OPEN_MEMORY 0x00000080 263 | #define SQLITE_OPEN_MAIN_DB 0x00000100 264 | #define SQLITE_OPEN_TEMP_DB 0x00000200 265 | #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 266 | #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 267 | #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 268 | #define SQLITE_OPEN_SUBJOURNAL 0x00002000 269 | #define SQLITE_OPEN_SUPER_JOURNAL 0x00004000 270 | #define SQLITE_OPEN_NOMUTEX 0x00008000 271 | #define SQLITE_OPEN_FULLMUTEX 0x00010000 272 | #define SQLITE_OPEN_SHAREDCACHE 0x00020000 273 | #define SQLITE_OPEN_PRIVATECACHE 0x00040000 274 | #define SQLITE_OPEN_WAL 0x00080000 275 | #define SQLITE_OPEN_NOFOLLOW 0x01000000 276 | #define SQLITE_OPEN_EXRESCODE 0x02000000 277 | 278 | 279 | 280 | #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 281 | 282 | 283 | 284 | #define SQLITE_IOCAP_ATOMIC 0x00000001 285 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 286 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 287 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 288 | #define SQLITE_IOCAP_ATOMIC4K 0x00000010 289 | #define SQLITE_IOCAP_ATOMIC8K 0x00000020 290 | #define SQLITE_IOCAP_ATOMIC16K 0x00000040 291 | #define SQLITE_IOCAP_ATOMIC32K 0x00000080 292 | #define SQLITE_IOCAP_ATOMIC64K 0x00000100 293 | #define SQLITE_IOCAP_SAFE_APPEND 0x00000200 294 | #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 295 | #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 296 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 297 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 298 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 299 | #define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 300 | 301 | 302 | #define SQLITE_LOCK_NONE 0 303 | #define SQLITE_LOCK_SHARED 1 304 | #define SQLITE_LOCK_RESERVED 2 305 | #define SQLITE_LOCK_PENDING 3 306 | #define SQLITE_LOCK_EXCLUSIVE 4 307 | 308 | 309 | #define SQLITE_SYNC_NORMAL 0x00002 310 | #define SQLITE_SYNC_FULL 0x00003 311 | #define SQLITE_SYNC_DATAONLY 0x00010 312 | 313 | 314 | typedef struct sqlite3_file sqlite3_file; 315 | struct sqlite3_file { 316 | const struct sqlite3_io_methods *pMethods; 317 | }; 318 | 319 | 320 | typedef struct sqlite3_io_methods sqlite3_io_methods; 321 | struct sqlite3_io_methods { 322 | int iVersion; 323 | int (*xClose)(sqlite3_file*); 324 | int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 325 | int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); 326 | int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); 327 | int (*xSync)(sqlite3_file*, int flags); 328 | int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); 329 | int (*xLock)(sqlite3_file*, int); 330 | int (*xUnlock)(sqlite3_file*, int); 331 | int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); 332 | int (*xFileControl)(sqlite3_file*, int op, void *pArg); 333 | int (*xSectorSize)(sqlite3_file*); 334 | int (*xDeviceCharacteristics)(sqlite3_file*); 335 | 336 | int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); 337 | int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); 338 | void (*xShmBarrier)(sqlite3_file*); 339 | int (*xShmUnmap)(sqlite3_file*, int deleteFlag); 340 | 341 | int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); 342 | int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); 343 | 344 | 345 | }; 346 | 347 | 348 | #define SQLITE_FCNTL_LOCKSTATE 1 349 | #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 350 | #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 351 | #define SQLITE_FCNTL_LAST_ERRNO 4 352 | #define SQLITE_FCNTL_SIZE_HINT 5 353 | #define SQLITE_FCNTL_CHUNK_SIZE 6 354 | #define SQLITE_FCNTL_FILE_POINTER 7 355 | #define SQLITE_FCNTL_SYNC_OMITTED 8 356 | #define SQLITE_FCNTL_WIN32_AV_RETRY 9 357 | #define SQLITE_FCNTL_PERSIST_WAL 10 358 | #define SQLITE_FCNTL_OVERWRITE 11 359 | #define SQLITE_FCNTL_VFSNAME 12 360 | #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 361 | #define SQLITE_FCNTL_PRAGMA 14 362 | #define SQLITE_FCNTL_BUSYHANDLER 15 363 | #define SQLITE_FCNTL_TEMPFILENAME 16 364 | #define SQLITE_FCNTL_MMAP_SIZE 18 365 | #define SQLITE_FCNTL_TRACE 19 366 | #define SQLITE_FCNTL_HAS_MOVED 20 367 | #define SQLITE_FCNTL_SYNC 21 368 | #define SQLITE_FCNTL_COMMIT_PHASETWO 22 369 | #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 370 | #define SQLITE_FCNTL_WAL_BLOCK 24 371 | #define SQLITE_FCNTL_ZIPVFS 25 372 | #define SQLITE_FCNTL_RBU 26 373 | #define SQLITE_FCNTL_VFS_POINTER 27 374 | #define SQLITE_FCNTL_JOURNAL_POINTER 28 375 | #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 376 | #define SQLITE_FCNTL_PDB 30 377 | #define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 378 | #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 379 | #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 380 | #define SQLITE_FCNTL_LOCK_TIMEOUT 34 381 | #define SQLITE_FCNTL_DATA_VERSION 35 382 | #define SQLITE_FCNTL_SIZE_LIMIT 36 383 | #define SQLITE_FCNTL_CKPT_DONE 37 384 | #define SQLITE_FCNTL_RESERVE_BYTES 38 385 | #define SQLITE_FCNTL_CKPT_START 39 386 | #define SQLITE_FCNTL_EXTERNAL_READER 40 387 | #define SQLITE_FCNTL_CKSM_FILE 41 388 | #define SQLITE_FCNTL_RESET_CACHE 42 389 | #define SQLITE_FCNTL_NULL_IO 43 390 | 391 | 392 | #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE 393 | #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE 394 | #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO 395 | 396 | 397 | 398 | typedef struct sqlite3_mutex sqlite3_mutex; 399 | 400 | 401 | typedef struct sqlite3_api_routines sqlite3_api_routines; 402 | 403 | 404 | typedef const char *sqlite3_filename; 405 | 406 | 407 | typedef struct sqlite3_vfs sqlite3_vfs; 408 | typedef void (*sqlite3_syscall_ptr)(void); 409 | struct sqlite3_vfs { 410 | int iVersion; 411 | int szOsFile; 412 | int mxPathname; 413 | sqlite3_vfs *pNext; 414 | const char *zName; 415 | void *pAppData; 416 | int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, 417 | int flags, int *pOutFlags); 418 | int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); 419 | int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); 420 | int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); 421 | void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); 422 | void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); 423 | void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); 424 | void (*xDlClose)(sqlite3_vfs*, void*); 425 | int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); 426 | int (*xSleep)(sqlite3_vfs*, int microseconds); 427 | int (*xCurrentTime)(sqlite3_vfs*, double*); 428 | int (*xGetLastError)(sqlite3_vfs*, int, char *); 429 | 430 | int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); 431 | 432 | int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); 433 | sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); 434 | const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); 435 | 436 | }; 437 | 438 | 439 | #define SQLITE_ACCESS_EXISTS 0 440 | #define SQLITE_ACCESS_READWRITE 1 441 | #define SQLITE_ACCESS_READ 2 442 | 443 | 444 | #define SQLITE_SHM_UNLOCK 1 445 | #define SQLITE_SHM_LOCK 2 446 | #define SQLITE_SHM_SHARED 4 447 | #define SQLITE_SHM_EXCLUSIVE 8 448 | 449 | 450 | #define SQLITE_SHM_NLOCK 8 451 | 452 | 453 | 454 | SQLITE_API int sqlite3_initialize(void); 455 | SQLITE_API int sqlite3_shutdown(void); 456 | SQLITE_API int sqlite3_os_init(void); 457 | SQLITE_API int sqlite3_os_end(void); 458 | 459 | 460 | SQLITE_API int sqlite3_config(int, ...); 461 | 462 | 463 | SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); 464 | 465 | 466 | typedef struct sqlite3_mem_methods sqlite3_mem_methods; 467 | struct sqlite3_mem_methods { 468 | void *(*xMalloc)(int); 469 | void (*xFree)(void*); 470 | void *(*xRealloc)(void*,int); 471 | int (*xSize)(void*); 472 | int (*xRoundup)(int); 473 | int (*xInit)(void*); 474 | void (*xShutdown)(void*); 475 | void *pAppData; 476 | }; 477 | 478 | 479 | #define SQLITE_CONFIG_SINGLETHREAD 1 480 | #define SQLITE_CONFIG_MULTITHREAD 2 481 | #define SQLITE_CONFIG_SERIALIZED 3 482 | #define SQLITE_CONFIG_MALLOC 4 483 | #define SQLITE_CONFIG_GETMALLOC 5 484 | #define SQLITE_CONFIG_SCRATCH 6 485 | #define SQLITE_CONFIG_PAGECACHE 7 486 | #define SQLITE_CONFIG_HEAP 8 487 | #define SQLITE_CONFIG_MEMSTATUS 9 488 | #define SQLITE_CONFIG_MUTEX 10 489 | #define SQLITE_CONFIG_GETMUTEX 11 490 | 491 | #define SQLITE_CONFIG_LOOKASIDE 13 492 | #define SQLITE_CONFIG_PCACHE 14 493 | #define SQLITE_CONFIG_GETPCACHE 15 494 | #define SQLITE_CONFIG_LOG 16 495 | #define SQLITE_CONFIG_URI 17 496 | #define SQLITE_CONFIG_PCACHE2 18 497 | #define SQLITE_CONFIG_GETPCACHE2 19 498 | #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 499 | #define SQLITE_CONFIG_SQLLOG 21 500 | #define SQLITE_CONFIG_MMAP_SIZE 22 501 | #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 502 | #define SQLITE_CONFIG_PCACHE_HDRSZ 24 503 | #define SQLITE_CONFIG_PMASZ 25 504 | #define SQLITE_CONFIG_STMTJRNL_SPILL 26 505 | #define SQLITE_CONFIG_SMALL_MALLOC 27 506 | #define SQLITE_CONFIG_SORTERREF_SIZE 28 507 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 508 | #define SQLITE_CONFIG_ROWID_IN_VIEW 30 509 | 510 | 511 | #define SQLITE_DBCONFIG_MAINDBNAME 1000 512 | #define SQLITE_DBCONFIG_LOOKASIDE 1001 513 | #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 514 | #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 515 | #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 516 | #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 517 | #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 518 | #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 519 | #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 520 | #define SQLITE_DBCONFIG_RESET_DATABASE 1009 521 | #define SQLITE_DBCONFIG_DEFENSIVE 1010 522 | #define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 523 | #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 524 | #define SQLITE_DBCONFIG_DQS_DML 1013 525 | #define SQLITE_DBCONFIG_DQS_DDL 1014 526 | #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 527 | #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 528 | #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 529 | #define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 530 | #define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 531 | #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 532 | #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 533 | #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 534 | #define SQLITE_DBCONFIG_MAX 1022 535 | 536 | 537 | SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); 538 | 539 | 540 | SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); 541 | 542 | 543 | SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); 544 | 545 | 546 | SQLITE_API int sqlite3_changes(sqlite3*); 547 | SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*); 548 | 549 | 550 | SQLITE_API int sqlite3_total_changes(sqlite3*); 551 | SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); 552 | 553 | 554 | SQLITE_API void sqlite3_interrupt(sqlite3*); 555 | SQLITE_API int sqlite3_is_interrupted(sqlite3*); 556 | 557 | 558 | SQLITE_API int sqlite3_complete(const char *sql); 559 | SQLITE_API int sqlite3_complete16(const void *sql); 560 | 561 | 562 | SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); 563 | 564 | 565 | SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); 566 | 567 | 568 | SQLITE_API int sqlite3_get_table( 569 | sqlite3 *db, 570 | const char *zSql, 571 | char ***pazResult, 572 | int *pnRow, 573 | int *pnColumn, 574 | char **pzErrmsg 575 | ); 576 | SQLITE_API void sqlite3_free_table(char **result); 577 | 578 | 579 | SQLITE_API char *sqlite3_mprintf(const char*,...); 580 | SQLITE_API char *sqlite3_vmprintf(const char*, va_list); 581 | SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); 582 | SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); 583 | 584 | 585 | SQLITE_API void *sqlite3_malloc(int); 586 | SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); 587 | SQLITE_API void *sqlite3_realloc(void*, int); 588 | SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); 589 | SQLITE_API void sqlite3_free(void*); 590 | SQLITE_API sqlite3_uint64 sqlite3_msize(void*); 591 | 592 | 593 | SQLITE_API sqlite3_int64 sqlite3_memory_used(void); 594 | SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); 595 | 596 | 597 | SQLITE_API void sqlite3_randomness(int N, void *P); 598 | 599 | 600 | SQLITE_API int sqlite3_set_authorizer( 601 | sqlite3*, 602 | int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), 603 | void *pUserData 604 | ); 605 | 606 | 607 | #define SQLITE_DENY 1 608 | #define SQLITE_IGNORE 2 609 | 610 | 611 | 612 | #define SQLITE_CREATE_INDEX 1 613 | #define SQLITE_CREATE_TABLE 2 614 | #define SQLITE_CREATE_TEMP_INDEX 3 615 | #define SQLITE_CREATE_TEMP_TABLE 4 616 | #define SQLITE_CREATE_TEMP_TRIGGER 5 617 | #define SQLITE_CREATE_TEMP_VIEW 6 618 | #define SQLITE_CREATE_TRIGGER 7 619 | #define SQLITE_CREATE_VIEW 8 620 | #define SQLITE_DELETE 9 621 | #define SQLITE_DROP_INDEX 10 622 | #define SQLITE_DROP_TABLE 11 623 | #define SQLITE_DROP_TEMP_INDEX 12 624 | #define SQLITE_DROP_TEMP_TABLE 13 625 | #define SQLITE_DROP_TEMP_TRIGGER 14 626 | #define SQLITE_DROP_TEMP_VIEW 15 627 | #define SQLITE_DROP_TRIGGER 16 628 | #define SQLITE_DROP_VIEW 17 629 | #define SQLITE_INSERT 18 630 | #define SQLITE_PRAGMA 19 631 | #define SQLITE_READ 20 632 | #define SQLITE_SELECT 21 633 | #define SQLITE_TRANSACTION 22 634 | #define SQLITE_UPDATE 23 635 | #define SQLITE_ATTACH 24 636 | #define SQLITE_DETACH 25 637 | #define SQLITE_ALTER_TABLE 26 638 | #define SQLITE_REINDEX 27 639 | #define SQLITE_ANALYZE 28 640 | #define SQLITE_CREATE_VTABLE 29 641 | #define SQLITE_DROP_VTABLE 30 642 | #define SQLITE_FUNCTION 31 643 | #define SQLITE_SAVEPOINT 32 644 | #define SQLITE_COPY 0 645 | #define SQLITE_RECURSIVE 33 646 | 647 | 648 | SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, 649 | void(*xTrace)(void*,const char*), void*); 650 | SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, 651 | void(*xProfile)(void*,const char*,sqlite3_uint64), void*); 652 | 653 | 654 | #define SQLITE_TRACE_STMT 0x01 655 | #define SQLITE_TRACE_PROFILE 0x02 656 | #define SQLITE_TRACE_ROW 0x04 657 | #define SQLITE_TRACE_CLOSE 0x08 658 | 659 | 660 | SQLITE_API int sqlite3_trace_v2( 661 | sqlite3*, 662 | unsigned uMask, 663 | int(*xCallback)(unsigned,void*,void*,void*), 664 | void *pCtx 665 | ); 666 | 667 | 668 | SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); 669 | 670 | 671 | SQLITE_API int sqlite3_open( 672 | const char *filename, 673 | sqlite3 **ppDb 674 | ); 675 | SQLITE_API int sqlite3_open16( 676 | const void *filename, 677 | sqlite3 **ppDb 678 | ); 679 | SQLITE_API int sqlite3_open_v2( 680 | const char *filename, 681 | sqlite3 **ppDb, 682 | int flags, 683 | const char *zVfs 684 | ); 685 | 686 | 687 | SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); 688 | SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); 689 | SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); 690 | SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); 691 | 692 | 693 | SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); 694 | SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); 695 | SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); 696 | 697 | 698 | SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); 699 | 700 | 701 | SQLITE_API sqlite3_filename sqlite3_create_filename( 702 | const char *zDatabase, 703 | const char *zJournal, 704 | const char *zWal, 705 | int nParam, 706 | const char **azParam 707 | ); 708 | SQLITE_API void sqlite3_free_filename(sqlite3_filename); 709 | 710 | 711 | SQLITE_API int sqlite3_errcode(sqlite3 *db); 712 | SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); 713 | SQLITE_API const char *sqlite3_errmsg(sqlite3*); 714 | SQLITE_API const void *sqlite3_errmsg16(sqlite3*); 715 | SQLITE_API const char *sqlite3_errstr(int); 716 | SQLITE_API int sqlite3_error_offset(sqlite3 *db); 717 | 718 | 719 | typedef struct sqlite3_stmt sqlite3_stmt; 720 | 721 | 722 | SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); 723 | 724 | 725 | #define SQLITE_LIMIT_LENGTH 0 726 | #define SQLITE_LIMIT_SQL_LENGTH 1 727 | #define SQLITE_LIMIT_COLUMN 2 728 | #define SQLITE_LIMIT_EXPR_DEPTH 3 729 | #define SQLITE_LIMIT_COMPOUND_SELECT 4 730 | #define SQLITE_LIMIT_VDBE_OP 5 731 | #define SQLITE_LIMIT_FUNCTION_ARG 6 732 | #define SQLITE_LIMIT_ATTACHED 7 733 | #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 734 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 735 | #define SQLITE_LIMIT_TRIGGER_DEPTH 10 736 | #define SQLITE_LIMIT_WORKER_THREADS 11 737 | 738 | 739 | #define SQLITE_PREPARE_PERSISTENT 0x01 740 | #define SQLITE_PREPARE_NORMALIZE 0x02 741 | #define SQLITE_PREPARE_NO_VTAB 0x04 742 | #define SQLITE_PREPARE_DONT_LOG 0x10 743 | 744 | 745 | SQLITE_API int sqlite3_prepare( 746 | sqlite3 *db, 747 | const char *zSql, 748 | int nByte, 749 | sqlite3_stmt **ppStmt, 750 | const char **pzTail 751 | ); 752 | SQLITE_API int sqlite3_prepare_v2( 753 | sqlite3 *db, 754 | const char *zSql, 755 | int nByte, 756 | sqlite3_stmt **ppStmt, 757 | const char **pzTail 758 | ); 759 | SQLITE_API int sqlite3_prepare_v3( 760 | sqlite3 *db, 761 | const char *zSql, 762 | int nByte, 763 | unsigned int prepFlags, 764 | sqlite3_stmt **ppStmt, 765 | const char **pzTail 766 | ); 767 | SQLITE_API int sqlite3_prepare16( 768 | sqlite3 *db, 769 | const void *zSql, 770 | int nByte, 771 | sqlite3_stmt **ppStmt, 772 | const void **pzTail 773 | ); 774 | SQLITE_API int sqlite3_prepare16_v2( 775 | sqlite3 *db, 776 | const void *zSql, 777 | int nByte, 778 | sqlite3_stmt **ppStmt, 779 | const void **pzTail 780 | ); 781 | SQLITE_API int sqlite3_prepare16_v3( 782 | sqlite3 *db, 783 | const void *zSql, 784 | int nByte, 785 | unsigned int prepFlags, 786 | sqlite3_stmt **ppStmt, 787 | const void **pzTail 788 | ); 789 | 790 | 791 | SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); 792 | SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); 793 | #ifdef SQLITE_ENABLE_NORMALIZE 794 | SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); 795 | #endif 796 | 797 | 798 | SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); 799 | 800 | 801 | SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); 802 | 803 | 804 | SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); 805 | 806 | 807 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); 808 | 809 | 810 | typedef struct sqlite3_value sqlite3_value; 811 | 812 | 813 | typedef struct sqlite3_context sqlite3_context; 814 | 815 | 816 | SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); 817 | SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, 818 | void(*)(void*)); 819 | SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); 820 | SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); 821 | SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); 822 | SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); 823 | SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); 824 | SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); 825 | SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, 826 | void(*)(void*), unsigned char encoding); 827 | SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); 828 | SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); 829 | SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); 830 | SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); 831 | 832 | 833 | SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); 834 | 835 | 836 | SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); 837 | 838 | 839 | SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); 840 | 841 | 842 | SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); 843 | 844 | 845 | SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); 846 | 847 | 848 | SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); 849 | SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); 850 | 851 | 852 | SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); 853 | SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); 854 | SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); 855 | SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); 856 | SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); 857 | SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); 858 | 859 | 860 | SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); 861 | SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); 862 | 863 | 864 | SQLITE_API int sqlite3_step(sqlite3_stmt*); 865 | 866 | 867 | SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); 868 | 869 | 870 | #define SQLITE_INTEGER 1 871 | #define SQLITE_FLOAT 2 872 | #define SQLITE_BLOB 4 873 | #define SQLITE_NULL 5 874 | #ifdef SQLITE_TEXT 875 | # undef SQLITE_TEXT 876 | #else 877 | # define SQLITE_TEXT 3 878 | #endif 879 | #define SQLITE3_TEXT 3 880 | 881 | 882 | SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); 883 | SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); 884 | SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); 885 | SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); 886 | SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); 887 | SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); 888 | SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); 889 | SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); 890 | SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); 891 | SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); 892 | 893 | 894 | SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); 895 | 896 | 897 | SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); 898 | 899 | 900 | 901 | SQLITE_API int sqlite3_create_function( 902 | sqlite3 *db, 903 | const char *zFunctionName, 904 | int nArg, 905 | int eTextRep, 906 | void *pApp, 907 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 908 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 909 | void (*xFinal)(sqlite3_context*) 910 | ); 911 | SQLITE_API int sqlite3_create_function16( 912 | sqlite3 *db, 913 | const void *zFunctionName, 914 | int nArg, 915 | int eTextRep, 916 | void *pApp, 917 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 918 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 919 | void (*xFinal)(sqlite3_context*) 920 | ); 921 | SQLITE_API int sqlite3_create_function_v2( 922 | sqlite3 *db, 923 | const char *zFunctionName, 924 | int nArg, 925 | int eTextRep, 926 | void *pApp, 927 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), 928 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 929 | void (*xFinal)(sqlite3_context*), 930 | void(*xDestroy)(void*) 931 | ); 932 | SQLITE_API int sqlite3_create_window_function( 933 | sqlite3 *db, 934 | const char *zFunctionName, 935 | int nArg, 936 | int eTextRep, 937 | void *pApp, 938 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), 939 | void (*xFinal)(sqlite3_context*), 940 | void (*xValue)(sqlite3_context*), 941 | void (*xInverse)(sqlite3_context*,int,sqlite3_value**), 942 | void(*xDestroy)(void*) 943 | ); 944 | 945 | 946 | #define SQLITE_UTF8 1 947 | #define SQLITE_UTF16LE 2 948 | #define SQLITE_UTF16BE 3 949 | #define SQLITE_UTF16 4 950 | #define SQLITE_ANY 5 951 | #define SQLITE_UTF16_ALIGNED 8 952 | 953 | 954 | #define SQLITE_DETERMINISTIC 0x000000800 955 | #define SQLITE_DIRECTONLY 0x000080000 956 | #define SQLITE_SUBTYPE 0x000100000 957 | #define SQLITE_INNOCUOUS 0x000200000 958 | #define SQLITE_RESULT_SUBTYPE 0x001000000 959 | #define SQLITE_SELFORDER1 0x002000000 960 | 961 | 962 | #ifndef SQLITE_OMIT_DEPRECATED 963 | SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); 964 | SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); 965 | SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); 966 | SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); 967 | SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); 968 | SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), 969 | void*,sqlite3_int64); 970 | #endif 971 | 972 | 973 | SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); 974 | SQLITE_API double sqlite3_value_double(sqlite3_value*); 975 | SQLITE_API int sqlite3_value_int(sqlite3_value*); 976 | SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); 977 | SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*); 978 | SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); 979 | SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); 980 | SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); 981 | SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); 982 | SQLITE_API int sqlite3_value_bytes(sqlite3_value*); 983 | SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); 984 | SQLITE_API int sqlite3_value_type(sqlite3_value*); 985 | SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); 986 | SQLITE_API int sqlite3_value_nochange(sqlite3_value*); 987 | SQLITE_API int sqlite3_value_frombind(sqlite3_value*); 988 | 989 | 990 | SQLITE_API int sqlite3_value_encoding(sqlite3_value*); 991 | 992 | 993 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); 994 | 995 | 996 | SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*); 997 | SQLITE_API void sqlite3_value_free(sqlite3_value*); 998 | 999 | 1000 | SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); 1001 | 1002 | 1003 | SQLITE_API void *sqlite3_user_data(sqlite3_context*); 1004 | 1005 | 1006 | SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); 1007 | 1008 | 1009 | SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); 1010 | SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); 1011 | 1012 | 1013 | SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*); 1014 | SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); 1015 | 1016 | 1017 | typedef void (*sqlite3_destructor_type)(void*); 1018 | #define SQLITE_STATIC ((sqlite3_destructor_type)0) 1019 | #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) 1020 | 1021 | 1022 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); 1023 | SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, 1024 | sqlite3_uint64,void(*)(void*)); 1025 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); 1026 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); 1027 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); 1028 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); 1029 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); 1030 | SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); 1031 | SQLITE_API void sqlite3_result_int(sqlite3_context*, int); 1032 | SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); 1033 | SQLITE_API void sqlite3_result_null(sqlite3_context*); 1034 | SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); 1035 | SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, 1036 | void(*)(void*), unsigned char encoding); 1037 | SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); 1038 | SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); 1039 | SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); 1040 | SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); 1041 | SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); 1042 | SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); 1043 | SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); 1044 | 1045 | 1046 | 1047 | SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); 1048 | 1049 | 1050 | SQLITE_API int sqlite3_create_collation( 1051 | sqlite3*, 1052 | const char *zName, 1053 | int eTextRep, 1054 | void *pArg, 1055 | int(*xCompare)(void*,int,const void*,int,const void*) 1056 | ); 1057 | SQLITE_API int sqlite3_create_collation_v2( 1058 | sqlite3*, 1059 | const char *zName, 1060 | int eTextRep, 1061 | void *pArg, 1062 | int(*xCompare)(void*,int,const void*,int,const void*), 1063 | void(*xDestroy)(void*) 1064 | ); 1065 | SQLITE_API int sqlite3_create_collation16( 1066 | sqlite3*, 1067 | const void *zName, 1068 | int eTextRep, 1069 | void *pArg, 1070 | int(*xCompare)(void*,int,const void*,int,const void*) 1071 | ); 1072 | 1073 | 1074 | SQLITE_API int sqlite3_collation_needed( 1075 | sqlite3*, 1076 | void*, 1077 | void(*)(void*,sqlite3*,int eTextRep,const char*) 1078 | ); 1079 | SQLITE_API int sqlite3_collation_needed16( 1080 | sqlite3*, 1081 | void*, 1082 | void(*)(void*,sqlite3*,int eTextRep,const void*) 1083 | ); 1084 | 1085 | #ifdef SQLITE_ENABLE_CEROD 1086 | 1087 | SQLITE_API void sqlite3_activate_cerod( 1088 | const char *zPassPhrase 1089 | ); 1090 | #endif 1091 | 1092 | 1093 | SQLITE_API int sqlite3_sleep(int); 1094 | 1095 | 1096 | SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; 1097 | 1098 | 1099 | SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; 1100 | 1101 | 1102 | SQLITE_API int sqlite3_win32_set_directory( 1103 | unsigned long type, 1104 | void *zValue 1105 | ); 1106 | SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); 1107 | SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); 1108 | 1109 | 1110 | #define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1 1111 | #define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2 1112 | 1113 | 1114 | SQLITE_API int sqlite3_get_autocommit(sqlite3*); 1115 | 1116 | 1117 | SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); 1118 | 1119 | 1120 | SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N); 1121 | 1122 | 1123 | SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); 1124 | 1125 | 1126 | SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); 1127 | 1128 | 1129 | SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); 1130 | 1131 | 1132 | #define SQLITE_TXN_NONE 0 1133 | #define SQLITE_TXN_READ 1 1134 | #define SQLITE_TXN_WRITE 2 1135 | 1136 | 1137 | SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); 1138 | 1139 | 1140 | SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); 1141 | SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); 1142 | 1143 | 1144 | SQLITE_API int sqlite3_autovacuum_pages( 1145 | sqlite3 *db, 1146 | unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), 1147 | void*, 1148 | void(*)(void*) 1149 | ); 1150 | 1151 | 1152 | 1153 | SQLITE_API void *sqlite3_update_hook( 1154 | sqlite3*, 1155 | void(*)(void *,int ,char const *,char const *,sqlite3_int64), 1156 | void* 1157 | ); 1158 | 1159 | 1160 | SQLITE_API int sqlite3_enable_shared_cache(int); 1161 | 1162 | 1163 | SQLITE_API int sqlite3_release_memory(int); 1164 | 1165 | 1166 | SQLITE_API int sqlite3_db_release_memory(sqlite3*); 1167 | 1168 | 1169 | SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); 1170 | SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); 1171 | 1172 | 1173 | SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); 1174 | 1175 | 1176 | 1177 | SQLITE_API int sqlite3_table_column_metadata( 1178 | sqlite3 *db, 1179 | const char *zDbName, 1180 | const char *zTableName, 1181 | const char *zColumnName, 1182 | char const **pzDataType, 1183 | char const **pzCollSeq, 1184 | int *pNotNull, 1185 | int *pPrimaryKey, 1186 | int *pAutoinc 1187 | ); 1188 | 1189 | 1190 | SQLITE_API int sqlite3_load_extension( 1191 | sqlite3 *db, 1192 | const char *zFile, 1193 | const char *zProc, 1194 | char **pzErrMsg 1195 | ); 1196 | 1197 | 1198 | SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); 1199 | 1200 | 1201 | SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void)); 1202 | 1203 | 1204 | SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); 1205 | 1206 | 1207 | SQLITE_API void sqlite3_reset_auto_extension(void); 1208 | 1209 | 1210 | typedef struct sqlite3_vtab sqlite3_vtab; 1211 | typedef struct sqlite3_index_info sqlite3_index_info; 1212 | typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; 1213 | typedef struct sqlite3_module sqlite3_module; 1214 | 1215 | 1216 | struct sqlite3_module { 1217 | int iVersion; 1218 | int (*xCreate)(sqlite3*, void *pAux, 1219 | int argc, const char *const*argv, 1220 | sqlite3_vtab **ppVTab, char**); 1221 | int (*xConnect)(sqlite3*, void *pAux, 1222 | int argc, const char *const*argv, 1223 | sqlite3_vtab **ppVTab, char**); 1224 | int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); 1225 | int (*xDisconnect)(sqlite3_vtab *pVTab); 1226 | int (*xDestroy)(sqlite3_vtab *pVTab); 1227 | int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); 1228 | int (*xClose)(sqlite3_vtab_cursor*); 1229 | int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, 1230 | int argc, sqlite3_value **argv); 1231 | int (*xNext)(sqlite3_vtab_cursor*); 1232 | int (*xEof)(sqlite3_vtab_cursor*); 1233 | int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); 1234 | int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); 1235 | int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); 1236 | int (*xBegin)(sqlite3_vtab *pVTab); 1237 | int (*xSync)(sqlite3_vtab *pVTab); 1238 | int (*xCommit)(sqlite3_vtab *pVTab); 1239 | int (*xRollback)(sqlite3_vtab *pVTab); 1240 | int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, 1241 | void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), 1242 | void **ppArg); 1243 | int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); 1244 | 1245 | int (*xSavepoint)(sqlite3_vtab *pVTab, int); 1246 | int (*xRelease)(sqlite3_vtab *pVTab, int); 1247 | int (*xRollbackTo)(sqlite3_vtab *pVTab, int); 1248 | 1249 | int (*xShadowName)(const char*); 1250 | 1251 | int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, 1252 | const char *zTabName, int mFlags, char **pzErr); 1253 | }; 1254 | 1255 | 1256 | struct sqlite3_index_info { 1257 | 1258 | int nConstraint; 1259 | struct sqlite3_index_constraint { 1260 | int iColumn; 1261 | unsigned char op; 1262 | unsigned char usable; 1263 | int iTermOffset; 1264 | } *aConstraint; 1265 | int nOrderBy; 1266 | struct sqlite3_index_orderby { 1267 | int iColumn; 1268 | unsigned char desc; 1269 | } *aOrderBy; 1270 | 1271 | struct sqlite3_index_constraint_usage { 1272 | int argvIndex; 1273 | unsigned char omit; 1274 | } *aConstraintUsage; 1275 | int idxNum; 1276 | char *idxStr; 1277 | int needToFreeIdxStr; 1278 | int orderByConsumed; 1279 | double estimatedCost; 1280 | 1281 | sqlite3_int64 estimatedRows; 1282 | 1283 | int idxFlags; 1284 | 1285 | sqlite3_uint64 colUsed; 1286 | }; 1287 | 1288 | 1289 | #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 1290 | #define SQLITE_INDEX_SCAN_HEX 0x00000002 1291 | 1292 | 1293 | 1294 | #define SQLITE_INDEX_CONSTRAINT_EQ 2 1295 | #define SQLITE_INDEX_CONSTRAINT_GT 4 1296 | #define SQLITE_INDEX_CONSTRAINT_LE 8 1297 | #define SQLITE_INDEX_CONSTRAINT_LT 16 1298 | #define SQLITE_INDEX_CONSTRAINT_GE 32 1299 | #define SQLITE_INDEX_CONSTRAINT_MATCH 64 1300 | #define SQLITE_INDEX_CONSTRAINT_LIKE 65 1301 | #define SQLITE_INDEX_CONSTRAINT_GLOB 66 1302 | #define SQLITE_INDEX_CONSTRAINT_REGEXP 67 1303 | #define SQLITE_INDEX_CONSTRAINT_NE 68 1304 | #define SQLITE_INDEX_CONSTRAINT_ISNOT 69 1305 | #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 1306 | #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 1307 | #define SQLITE_INDEX_CONSTRAINT_IS 72 1308 | #define SQLITE_INDEX_CONSTRAINT_LIMIT 73 1309 | #define SQLITE_INDEX_CONSTRAINT_OFFSET 74 1310 | #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 1311 | 1312 | 1313 | SQLITE_API int sqlite3_create_module( 1314 | sqlite3 *db, 1315 | const char *zName, 1316 | const sqlite3_module *p, 1317 | void *pClientData 1318 | ); 1319 | SQLITE_API int sqlite3_create_module_v2( 1320 | sqlite3 *db, 1321 | const char *zName, 1322 | const sqlite3_module *p, 1323 | void *pClientData, 1324 | void(*xDestroy)(void*) 1325 | ); 1326 | 1327 | 1328 | SQLITE_API int sqlite3_drop_modules( 1329 | sqlite3 *db, 1330 | const char **azKeep 1331 | ); 1332 | 1333 | 1334 | struct sqlite3_vtab { 1335 | const sqlite3_module *pModule; 1336 | int nRef; 1337 | char *zErrMsg; 1338 | 1339 | }; 1340 | 1341 | 1342 | struct sqlite3_vtab_cursor { 1343 | sqlite3_vtab *pVtab; 1344 | 1345 | }; 1346 | 1347 | 1348 | SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); 1349 | 1350 | 1351 | SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); 1352 | 1353 | 1354 | typedef struct sqlite3_blob sqlite3_blob; 1355 | 1356 | 1357 | SQLITE_API int sqlite3_blob_open( 1358 | sqlite3*, 1359 | const char *zDb, 1360 | const char *zTable, 1361 | const char *zColumn, 1362 | sqlite3_int64 iRow, 1363 | int flags, 1364 | sqlite3_blob **ppBlob 1365 | ); 1366 | 1367 | 1368 | SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); 1369 | 1370 | 1371 | SQLITE_API int sqlite3_blob_close(sqlite3_blob *); 1372 | 1373 | 1374 | SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); 1375 | 1376 | 1377 | SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); 1378 | 1379 | 1380 | SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); 1381 | 1382 | 1383 | SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); 1384 | SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); 1385 | SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); 1386 | 1387 | 1388 | SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); 1389 | SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); 1390 | SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); 1391 | SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); 1392 | SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); 1393 | 1394 | 1395 | typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; 1396 | struct sqlite3_mutex_methods { 1397 | int (*xMutexInit)(void); 1398 | int (*xMutexEnd)(void); 1399 | sqlite3_mutex *(*xMutexAlloc)(int); 1400 | void (*xMutexFree)(sqlite3_mutex *); 1401 | void (*xMutexEnter)(sqlite3_mutex *); 1402 | int (*xMutexTry)(sqlite3_mutex *); 1403 | void (*xMutexLeave)(sqlite3_mutex *); 1404 | int (*xMutexHeld)(sqlite3_mutex *); 1405 | int (*xMutexNotheld)(sqlite3_mutex *); 1406 | }; 1407 | 1408 | 1409 | #ifndef NDEBUG 1410 | SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); 1411 | SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); 1412 | #endif 1413 | 1414 | 1415 | #define SQLITE_MUTEX_FAST 0 1416 | #define SQLITE_MUTEX_RECURSIVE 1 1417 | #define SQLITE_MUTEX_STATIC_MAIN 2 1418 | #define SQLITE_MUTEX_STATIC_MEM 3 1419 | #define SQLITE_MUTEX_STATIC_MEM2 4 1420 | #define SQLITE_MUTEX_STATIC_OPEN 4 1421 | #define SQLITE_MUTEX_STATIC_PRNG 5 1422 | #define SQLITE_MUTEX_STATIC_LRU 6 1423 | #define SQLITE_MUTEX_STATIC_LRU2 7 1424 | #define SQLITE_MUTEX_STATIC_PMEM 7 1425 | #define SQLITE_MUTEX_STATIC_APP1 8 1426 | #define SQLITE_MUTEX_STATIC_APP2 9 1427 | #define SQLITE_MUTEX_STATIC_APP3 10 1428 | #define SQLITE_MUTEX_STATIC_VFS1 11 1429 | #define SQLITE_MUTEX_STATIC_VFS2 12 1430 | #define SQLITE_MUTEX_STATIC_VFS3 13 1431 | 1432 | 1433 | #define SQLITE_MUTEX_STATIC_MASTER 2 1434 | 1435 | 1436 | 1437 | SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); 1438 | 1439 | 1440 | SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); 1441 | 1442 | 1443 | SQLITE_API int sqlite3_test_control(int op, ...); 1444 | 1445 | 1446 | #define SQLITE_TESTCTRL_FIRST 5 1447 | #define SQLITE_TESTCTRL_PRNG_SAVE 5 1448 | #define SQLITE_TESTCTRL_PRNG_RESTORE 6 1449 | #define SQLITE_TESTCTRL_PRNG_RESET 7 1450 | #define SQLITE_TESTCTRL_FK_NO_ACTION 7 1451 | #define SQLITE_TESTCTRL_BITVEC_TEST 8 1452 | #define SQLITE_TESTCTRL_FAULT_INSTALL 9 1453 | #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 1454 | #define SQLITE_TESTCTRL_PENDING_BYTE 11 1455 | #define SQLITE_TESTCTRL_ASSERT 12 1456 | #define SQLITE_TESTCTRL_ALWAYS 13 1457 | #define SQLITE_TESTCTRL_RESERVE 14 1458 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 1459 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 1460 | #define SQLITE_TESTCTRL_ISKEYWORD 16 1461 | #define SQLITE_TESTCTRL_GETOPT 16 1462 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 1463 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 1464 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 1465 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 1466 | #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 1467 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 1468 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 1469 | #define SQLITE_TESTCTRL_BYTEORDER 22 1470 | #define SQLITE_TESTCTRL_ISINIT 23 1471 | #define SQLITE_TESTCTRL_SORTER_MMAP 24 1472 | #define SQLITE_TESTCTRL_IMPOSTER 25 1473 | #define SQLITE_TESTCTRL_PARSER_COVERAGE 26 1474 | #define SQLITE_TESTCTRL_RESULT_INTREAL 27 1475 | #define SQLITE_TESTCTRL_PRNG_SEED 28 1476 | #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 1477 | #define SQLITE_TESTCTRL_SEEK_COUNT 30 1478 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 1479 | #define SQLITE_TESTCTRL_TUNE 32 1480 | #define SQLITE_TESTCTRL_LOGEST 33 1481 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 1482 | #define SQLITE_TESTCTRL_LAST 34 1483 | 1484 | 1485 | SQLITE_API int sqlite3_keyword_count(void); 1486 | SQLITE_API int sqlite3_keyword_name(int,const char**,int*); 1487 | SQLITE_API int sqlite3_keyword_check(const char*,int); 1488 | 1489 | 1490 | typedef struct sqlite3_str sqlite3_str; 1491 | 1492 | 1493 | SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); 1494 | 1495 | 1496 | SQLITE_API char *sqlite3_str_finish(sqlite3_str*); 1497 | 1498 | 1499 | SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); 1500 | SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); 1501 | SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); 1502 | SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); 1503 | SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); 1504 | SQLITE_API void sqlite3_str_reset(sqlite3_str*); 1505 | 1506 | 1507 | SQLITE_API int sqlite3_str_errcode(sqlite3_str*); 1508 | SQLITE_API int sqlite3_str_length(sqlite3_str*); 1509 | SQLITE_API char *sqlite3_str_value(sqlite3_str*); 1510 | 1511 | 1512 | SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); 1513 | SQLITE_API int sqlite3_status64( 1514 | int op, 1515 | sqlite3_int64 *pCurrent, 1516 | sqlite3_int64 *pHighwater, 1517 | int resetFlag 1518 | ); 1519 | 1520 | 1521 | 1522 | #define SQLITE_STATUS_MEMORY_USED 0 1523 | #define SQLITE_STATUS_PAGECACHE_USED 1 1524 | #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 1525 | #define SQLITE_STATUS_SCRATCH_USED 3 1526 | #define SQLITE_STATUS_SCRATCH_OVERFLOW 4 1527 | #define SQLITE_STATUS_MALLOC_SIZE 5 1528 | #define SQLITE_STATUS_PARSER_STACK 6 1529 | #define SQLITE_STATUS_PAGECACHE_SIZE 7 1530 | #define SQLITE_STATUS_SCRATCH_SIZE 8 1531 | #define SQLITE_STATUS_MALLOC_COUNT 9 1532 | 1533 | 1534 | SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); 1535 | 1536 | 1537 | #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 1538 | #define SQLITE_DBSTATUS_CACHE_USED 1 1539 | #define SQLITE_DBSTATUS_SCHEMA_USED 2 1540 | #define SQLITE_DBSTATUS_STMT_USED 3 1541 | #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 1542 | #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 1543 | #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 1544 | #define SQLITE_DBSTATUS_CACHE_HIT 7 1545 | #define SQLITE_DBSTATUS_CACHE_MISS 8 1546 | #define SQLITE_DBSTATUS_CACHE_WRITE 9 1547 | #define SQLITE_DBSTATUS_DEFERRED_FKS 10 1548 | #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 1549 | #define SQLITE_DBSTATUS_CACHE_SPILL 12 1550 | #define SQLITE_DBSTATUS_MAX 12 1551 | 1552 | 1553 | 1554 | SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); 1555 | 1556 | 1557 | #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 1558 | #define SQLITE_STMTSTATUS_SORT 2 1559 | #define SQLITE_STMTSTATUS_AUTOINDEX 3 1560 | #define SQLITE_STMTSTATUS_VM_STEP 4 1561 | #define SQLITE_STMTSTATUS_REPREPARE 5 1562 | #define SQLITE_STMTSTATUS_RUN 6 1563 | #define SQLITE_STMTSTATUS_FILTER_MISS 7 1564 | #define SQLITE_STMTSTATUS_FILTER_HIT 8 1565 | #define SQLITE_STMTSTATUS_MEMUSED 99 1566 | 1567 | 1568 | typedef struct sqlite3_pcache sqlite3_pcache; 1569 | 1570 | 1571 | typedef struct sqlite3_pcache_page sqlite3_pcache_page; 1572 | struct sqlite3_pcache_page { 1573 | void *pBuf; 1574 | void *pExtra; 1575 | }; 1576 | 1577 | 1578 | typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; 1579 | struct sqlite3_pcache_methods2 { 1580 | int iVersion; 1581 | void *pArg; 1582 | int (*xInit)(void*); 1583 | void (*xShutdown)(void*); 1584 | sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); 1585 | void (*xCachesize)(sqlite3_pcache*, int nCachesize); 1586 | int (*xPagecount)(sqlite3_pcache*); 1587 | sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); 1588 | void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); 1589 | void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, 1590 | unsigned oldKey, unsigned newKey); 1591 | void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); 1592 | void (*xDestroy)(sqlite3_pcache*); 1593 | void (*xShrink)(sqlite3_pcache*); 1594 | }; 1595 | 1596 | 1597 | typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; 1598 | struct sqlite3_pcache_methods { 1599 | void *pArg; 1600 | int (*xInit)(void*); 1601 | void (*xShutdown)(void*); 1602 | sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); 1603 | void (*xCachesize)(sqlite3_pcache*, int nCachesize); 1604 | int (*xPagecount)(sqlite3_pcache*); 1605 | void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); 1606 | void (*xUnpin)(sqlite3_pcache*, void*, int discard); 1607 | void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); 1608 | void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); 1609 | void (*xDestroy)(sqlite3_pcache*); 1610 | }; 1611 | 1612 | 1613 | 1614 | typedef struct sqlite3_backup sqlite3_backup; 1615 | 1616 | 1617 | SQLITE_API sqlite3_backup *sqlite3_backup_init( 1618 | sqlite3 *pDest, 1619 | const char *zDestName, 1620 | sqlite3 *pSource, 1621 | const char *zSourceName 1622 | ); 1623 | SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); 1624 | SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); 1625 | SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); 1626 | SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); 1627 | 1628 | 1629 | SQLITE_API int sqlite3_unlock_notify( 1630 | sqlite3 *pBlocked, 1631 | void (*xNotify)(void **apArg, int nArg), 1632 | void *pNotifyArg 1633 | ); 1634 | 1635 | 1636 | 1637 | SQLITE_API int sqlite3_stricmp(const char *, const char *); 1638 | SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); 1639 | 1640 | 1641 | SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); 1642 | 1643 | 1644 | SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); 1645 | 1646 | 1647 | SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); 1648 | 1649 | 1650 | SQLITE_API void *sqlite3_wal_hook( 1651 | sqlite3*, 1652 | int(*)(void *,sqlite3*,const char*,int), 1653 | void* 1654 | ); 1655 | 1656 | 1657 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); 1658 | 1659 | 1660 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); 1661 | 1662 | 1663 | SQLITE_API int sqlite3_wal_checkpoint_v2( 1664 | sqlite3 *db, 1665 | const char *zDb, 1666 | int eMode, 1667 | int *pnLog, 1668 | int *pnCkpt 1669 | ); 1670 | 1671 | 1672 | #define SQLITE_CHECKPOINT_PASSIVE 0 1673 | #define SQLITE_CHECKPOINT_FULL 1 1674 | #define SQLITE_CHECKPOINT_RESTART 2 1675 | #define SQLITE_CHECKPOINT_TRUNCATE 3 1676 | 1677 | 1678 | SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); 1679 | 1680 | 1681 | #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 1682 | #define SQLITE_VTAB_INNOCUOUS 2 1683 | #define SQLITE_VTAB_DIRECTONLY 3 1684 | #define SQLITE_VTAB_USES_ALL_SCHEMAS 4 1685 | 1686 | 1687 | SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); 1688 | 1689 | 1690 | SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); 1691 | 1692 | 1693 | SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); 1694 | 1695 | 1696 | SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); 1697 | 1698 | 1699 | SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); 1700 | 1701 | 1702 | SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); 1703 | SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); 1704 | 1705 | 1706 | SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); 1707 | 1708 | 1709 | #define SQLITE_ROLLBACK 1 1710 | 1711 | #define SQLITE_FAIL 3 1712 | 1713 | #define SQLITE_REPLACE 5 1714 | 1715 | 1716 | #define SQLITE_SCANSTAT_NLOOP 0 1717 | #define SQLITE_SCANSTAT_NVISIT 1 1718 | #define SQLITE_SCANSTAT_EST 2 1719 | #define SQLITE_SCANSTAT_NAME 3 1720 | #define SQLITE_SCANSTAT_EXPLAIN 4 1721 | #define SQLITE_SCANSTAT_SELECTID 5 1722 | #define SQLITE_SCANSTAT_PARENTID 6 1723 | #define SQLITE_SCANSTAT_NCYCLE 7 1724 | 1725 | 1726 | SQLITE_API int sqlite3_stmt_scanstatus( 1727 | sqlite3_stmt *pStmt, 1728 | int idx, 1729 | int iScanStatusOp, 1730 | void *pOut 1731 | ); 1732 | SQLITE_API int sqlite3_stmt_scanstatus_v2( 1733 | sqlite3_stmt *pStmt, 1734 | int idx, 1735 | int iScanStatusOp, 1736 | int flags, 1737 | void *pOut 1738 | ); 1739 | 1740 | 1741 | #define SQLITE_SCANSTAT_COMPLEX 0x0001 1742 | 1743 | 1744 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); 1745 | 1746 | 1747 | SQLITE_API int sqlite3_db_cacheflush(sqlite3*); 1748 | 1749 | 1750 | #if defined(SQLITE_ENABLE_PREUPDATE_HOOK) 1751 | SQLITE_API void *sqlite3_preupdate_hook( 1752 | sqlite3 *db, 1753 | void(*xPreUpdate)( 1754 | void *pCtx, 1755 | sqlite3 *db, 1756 | int op, 1757 | char const *zDb, 1758 | char const *zName, 1759 | sqlite3_int64 iKey1, 1760 | sqlite3_int64 iKey2 1761 | ), 1762 | void* 1763 | ); 1764 | SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); 1765 | SQLITE_API int sqlite3_preupdate_count(sqlite3 *); 1766 | SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); 1767 | SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); 1768 | SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); 1769 | #endif 1770 | 1771 | 1772 | SQLITE_API int sqlite3_system_errno(sqlite3*); 1773 | 1774 | 1775 | typedef struct sqlite3_snapshot { 1776 | unsigned char hidden[48]; 1777 | } sqlite3_snapshot; 1778 | 1779 | 1780 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( 1781 | sqlite3 *db, 1782 | const char *zSchema, 1783 | sqlite3_snapshot **ppSnapshot 1784 | ); 1785 | 1786 | 1787 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( 1788 | sqlite3 *db, 1789 | const char *zSchema, 1790 | sqlite3_snapshot *pSnapshot 1791 | ); 1792 | 1793 | 1794 | SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); 1795 | 1796 | 1797 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( 1798 | sqlite3_snapshot *p1, 1799 | sqlite3_snapshot *p2 1800 | ); 1801 | 1802 | 1803 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); 1804 | 1805 | 1806 | SQLITE_API unsigned char *sqlite3_serialize( 1807 | sqlite3 *db, 1808 | const char *zSchema, 1809 | sqlite3_int64 *piSize, 1810 | unsigned int mFlags 1811 | ); 1812 | 1813 | 1814 | #define SQLITE_SERIALIZE_NOCOPY 0x001 1815 | 1816 | 1817 | SQLITE_API int sqlite3_deserialize( 1818 | sqlite3 *db, 1819 | const char *zSchema, 1820 | unsigned char *pData, 1821 | sqlite3_int64 szDb, 1822 | sqlite3_int64 szBuf, 1823 | unsigned mFlags 1824 | ); 1825 | 1826 | 1827 | #define SQLITE_DESERIALIZE_FREEONCLOSE 1 1828 | #define SQLITE_DESERIALIZE_RESIZEABLE 2 1829 | #define SQLITE_DESERIALIZE_READONLY 4 1830 | 1831 | 1832 | #ifdef SQLITE_OMIT_FLOATING_POINT 1833 | # undef double 1834 | #endif 1835 | 1836 | #if defined(__wasi__) 1837 | # undef SQLITE_WASI 1838 | # define SQLITE_WASI 1 1839 | # ifndef SQLITE_OMIT_LOAD_EXTENSION 1840 | # define SQLITE_OMIT_LOAD_EXTENSION 1841 | # endif 1842 | # ifndef SQLITE_THREADSAFE 1843 | # define SQLITE_THREADSAFE 0 1844 | # endif 1845 | #endif 1846 | 1847 | #ifdef __cplusplus 1848 | } 1849 | #endif 1850 | 1851 | 1852 | 1853 | 1854 | 1855 | #ifndef _SQLITE3RTREE_H_ 1856 | #define _SQLITE3RTREE_H_ 1857 | 1858 | 1859 | #ifdef __cplusplus 1860 | extern "C" { 1861 | #endif 1862 | 1863 | typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; 1864 | typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; 1865 | 1866 | 1867 | #ifdef SQLITE_RTREE_INT_ONLY 1868 | typedef sqlite3_int64 sqlite3_rtree_dbl; 1869 | #else 1870 | typedef double sqlite3_rtree_dbl; 1871 | #endif 1872 | 1873 | 1874 | SQLITE_API int sqlite3_rtree_geometry_callback( 1875 | sqlite3 *db, 1876 | const char *zGeom, 1877 | int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), 1878 | void *pContext 1879 | ); 1880 | 1881 | 1882 | 1883 | struct sqlite3_rtree_geometry { 1884 | void *pContext; 1885 | int nParam; 1886 | sqlite3_rtree_dbl *aParam; 1887 | void *pUser; 1888 | void (*xDelUser)(void *); 1889 | }; 1890 | 1891 | 1892 | SQLITE_API int sqlite3_rtree_query_callback( 1893 | sqlite3 *db, 1894 | const char *zQueryFunc, 1895 | int (*xQueryFunc)(sqlite3_rtree_query_info*), 1896 | void *pContext, 1897 | void (*xDestructor)(void*) 1898 | ); 1899 | 1900 | 1901 | 1902 | struct sqlite3_rtree_query_info { 1903 | void *pContext; 1904 | int nParam; 1905 | sqlite3_rtree_dbl *aParam; 1906 | void *pUser; 1907 | void (*xDelUser)(void*); 1908 | sqlite3_rtree_dbl *aCoord; 1909 | unsigned int *anQueue; 1910 | int nCoord; 1911 | int iLevel; 1912 | int mxLevel; 1913 | sqlite3_int64 iRowid; 1914 | sqlite3_rtree_dbl rParentScore; 1915 | int eParentWithin; 1916 | int eWithin; 1917 | sqlite3_rtree_dbl rScore; 1918 | 1919 | sqlite3_value **apSqlParam; 1920 | }; 1921 | 1922 | 1923 | #define NOT_WITHIN 0 1924 | #define PARTLY_WITHIN 1 1925 | #define FULLY_WITHIN 2 1926 | 1927 | 1928 | #ifdef __cplusplus 1929 | } 1930 | #endif 1931 | 1932 | #endif 1933 | 1934 | 1935 | 1936 | 1937 | #if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) 1938 | #define __SQLITESESSION_H_ 1 1939 | 1940 | 1941 | #ifdef __cplusplus 1942 | extern "C" { 1943 | #endif 1944 | 1945 | 1946 | 1947 | typedef struct sqlite3_session sqlite3_session; 1948 | 1949 | 1950 | typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; 1951 | 1952 | 1953 | SQLITE_API int sqlite3session_create( 1954 | sqlite3 *db, 1955 | const char *zDb, 1956 | sqlite3_session **ppSession 1957 | ); 1958 | 1959 | 1960 | SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); 1961 | 1962 | 1963 | SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); 1964 | 1965 | 1966 | #define SQLITE_SESSION_OBJCONFIG_SIZE 1 1967 | #define SQLITE_SESSION_OBJCONFIG_ROWID 2 1968 | 1969 | 1970 | SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); 1971 | 1972 | 1973 | SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); 1974 | 1975 | 1976 | SQLITE_API int sqlite3session_attach( 1977 | sqlite3_session *pSession, 1978 | const char *zTab 1979 | ); 1980 | 1981 | 1982 | SQLITE_API void sqlite3session_table_filter( 1983 | sqlite3_session *pSession, 1984 | int(*xFilter)( 1985 | void *pCtx, 1986 | const char *zTab 1987 | ), 1988 | void *pCtx 1989 | ); 1990 | 1991 | 1992 | SQLITE_API int sqlite3session_changeset( 1993 | sqlite3_session *pSession, 1994 | int *pnChangeset, 1995 | void **ppChangeset 1996 | ); 1997 | 1998 | 1999 | SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); 2000 | 2001 | 2002 | SQLITE_API int sqlite3session_diff( 2003 | sqlite3_session *pSession, 2004 | const char *zFromDb, 2005 | const char *zTbl, 2006 | char **pzErrMsg 2007 | ); 2008 | 2009 | 2010 | 2011 | SQLITE_API int sqlite3session_patchset( 2012 | sqlite3_session *pSession, 2013 | int *pnPatchset, 2014 | void **ppPatchset 2015 | ); 2016 | 2017 | 2018 | SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); 2019 | 2020 | 2021 | SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); 2022 | 2023 | 2024 | SQLITE_API int sqlite3changeset_start( 2025 | sqlite3_changeset_iter **pp, 2026 | int nChangeset, 2027 | void *pChangeset 2028 | ); 2029 | SQLITE_API int sqlite3changeset_start_v2( 2030 | sqlite3_changeset_iter **pp, 2031 | int nChangeset, 2032 | void *pChangeset, 2033 | int flags 2034 | ); 2035 | 2036 | 2037 | #define SQLITE_CHANGESETSTART_INVERT 0x0002 2038 | 2039 | 2040 | 2041 | SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); 2042 | 2043 | 2044 | SQLITE_API int sqlite3changeset_op( 2045 | sqlite3_changeset_iter *pIter, 2046 | const char **pzTab, 2047 | int *pnCol, 2048 | int *pOp, 2049 | int *pbIndirect 2050 | ); 2051 | 2052 | 2053 | SQLITE_API int sqlite3changeset_pk( 2054 | sqlite3_changeset_iter *pIter, 2055 | unsigned char **pabPK, 2056 | int *pnCol 2057 | ); 2058 | 2059 | 2060 | SQLITE_API int sqlite3changeset_old( 2061 | sqlite3_changeset_iter *pIter, 2062 | int iVal, 2063 | sqlite3_value **ppValue 2064 | ); 2065 | 2066 | 2067 | SQLITE_API int sqlite3changeset_new( 2068 | sqlite3_changeset_iter *pIter, 2069 | int iVal, 2070 | sqlite3_value **ppValue 2071 | ); 2072 | 2073 | 2074 | SQLITE_API int sqlite3changeset_conflict( 2075 | sqlite3_changeset_iter *pIter, 2076 | int iVal, 2077 | sqlite3_value **ppValue 2078 | ); 2079 | 2080 | 2081 | SQLITE_API int sqlite3changeset_fk_conflicts( 2082 | sqlite3_changeset_iter *pIter, 2083 | int *pnOut 2084 | ); 2085 | 2086 | 2087 | 2088 | SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); 2089 | 2090 | 2091 | SQLITE_API int sqlite3changeset_invert( 2092 | int nIn, const void *pIn, 2093 | int *pnOut, void **ppOut 2094 | ); 2095 | 2096 | 2097 | SQLITE_API int sqlite3changeset_concat( 2098 | int nA, 2099 | void *pA, 2100 | int nB, 2101 | void *pB, 2102 | int *pnOut, 2103 | void **ppOut 2104 | ); 2105 | 2106 | 2107 | 2108 | SQLITE_API int sqlite3changeset_upgrade( 2109 | sqlite3 *db, 2110 | const char *zDb, 2111 | int nIn, const void *pIn, 2112 | int *pnOut, void **ppOut 2113 | ); 2114 | 2115 | 2116 | 2117 | 2118 | typedef struct sqlite3_changegroup sqlite3_changegroup; 2119 | 2120 | 2121 | SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); 2122 | 2123 | 2124 | SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); 2125 | 2126 | 2127 | SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); 2128 | 2129 | 2130 | SQLITE_API int sqlite3changegroup_add_change( 2131 | sqlite3_changegroup*, 2132 | sqlite3_changeset_iter* 2133 | ); 2134 | 2135 | 2136 | 2137 | 2138 | SQLITE_API int sqlite3changegroup_output( 2139 | sqlite3_changegroup*, 2140 | int *pnData, 2141 | void **ppData 2142 | ); 2143 | 2144 | 2145 | SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); 2146 | 2147 | 2148 | SQLITE_API int sqlite3changeset_apply( 2149 | sqlite3 *db, 2150 | int nChangeset, 2151 | void *pChangeset, 2152 | int(*xFilter)( 2153 | void *pCtx, 2154 | const char *zTab 2155 | ), 2156 | int(*xConflict)( 2157 | void *pCtx, 2158 | int eConflict, 2159 | sqlite3_changeset_iter *p 2160 | ), 2161 | void *pCtx 2162 | ); 2163 | SQLITE_API int sqlite3changeset_apply_v2( 2164 | sqlite3 *db, 2165 | int nChangeset, 2166 | void *pChangeset, 2167 | int(*xFilter)( 2168 | void *pCtx, 2169 | const char *zTab 2170 | ), 2171 | int(*xConflict)( 2172 | void *pCtx, 2173 | int eConflict, 2174 | sqlite3_changeset_iter *p 2175 | ), 2176 | void *pCtx, 2177 | void **ppRebase, int *pnRebase, 2178 | int flags 2179 | ); 2180 | 2181 | 2182 | #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 2183 | #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 2184 | #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 2185 | #define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 2186 | 2187 | 2188 | #define SQLITE_CHANGESET_DATA 1 2189 | #define SQLITE_CHANGESET_NOTFOUND 2 2190 | #define SQLITE_CHANGESET_CONFLICT 3 2191 | #define SQLITE_CHANGESET_CONSTRAINT 4 2192 | #define SQLITE_CHANGESET_FOREIGN_KEY 5 2193 | 2194 | 2195 | #define SQLITE_CHANGESET_OMIT 0 2196 | #define SQLITE_CHANGESET_REPLACE 1 2197 | #define SQLITE_CHANGESET_ABORT 2 2198 | 2199 | 2200 | typedef struct sqlite3_rebaser sqlite3_rebaser; 2201 | 2202 | 2203 | SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew); 2204 | 2205 | 2206 | SQLITE_API int sqlite3rebaser_configure( 2207 | sqlite3_rebaser*, 2208 | int nRebase, const void *pRebase 2209 | ); 2210 | 2211 | 2212 | SQLITE_API int sqlite3rebaser_rebase( 2213 | sqlite3_rebaser*, 2214 | int nIn, const void *pIn, 2215 | int *pnOut, void **ppOut 2216 | ); 2217 | 2218 | 2219 | SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); 2220 | 2221 | 2222 | SQLITE_API int sqlite3changeset_apply_strm( 2223 | sqlite3 *db, 2224 | int (*xInput)(void *pIn, void *pData, int *pnData), 2225 | void *pIn, 2226 | int(*xFilter)( 2227 | void *pCtx, 2228 | const char *zTab 2229 | ), 2230 | int(*xConflict)( 2231 | void *pCtx, 2232 | int eConflict, 2233 | sqlite3_changeset_iter *p 2234 | ), 2235 | void *pCtx 2236 | ); 2237 | SQLITE_API int sqlite3changeset_apply_v2_strm( 2238 | sqlite3 *db, 2239 | int (*xInput)(void *pIn, void *pData, int *pnData), 2240 | void *pIn, 2241 | int(*xFilter)( 2242 | void *pCtx, 2243 | const char *zTab 2244 | ), 2245 | int(*xConflict)( 2246 | void *pCtx, 2247 | int eConflict, 2248 | sqlite3_changeset_iter *p 2249 | ), 2250 | void *pCtx, 2251 | void **ppRebase, int *pnRebase, 2252 | int flags 2253 | ); 2254 | SQLITE_API int sqlite3changeset_concat_strm( 2255 | int (*xInputA)(void *pIn, void *pData, int *pnData), 2256 | void *pInA, 2257 | int (*xInputB)(void *pIn, void *pData, int *pnData), 2258 | void *pInB, 2259 | int (*xOutput)(void *pOut, const void *pData, int nData), 2260 | void *pOut 2261 | ); 2262 | SQLITE_API int sqlite3changeset_invert_strm( 2263 | int (*xInput)(void *pIn, void *pData, int *pnData), 2264 | void *pIn, 2265 | int (*xOutput)(void *pOut, const void *pData, int nData), 2266 | void *pOut 2267 | ); 2268 | SQLITE_API int sqlite3changeset_start_strm( 2269 | sqlite3_changeset_iter **pp, 2270 | int (*xInput)(void *pIn, void *pData, int *pnData), 2271 | void *pIn 2272 | ); 2273 | SQLITE_API int sqlite3changeset_start_v2_strm( 2274 | sqlite3_changeset_iter **pp, 2275 | int (*xInput)(void *pIn, void *pData, int *pnData), 2276 | void *pIn, 2277 | int flags 2278 | ); 2279 | SQLITE_API int sqlite3session_changeset_strm( 2280 | sqlite3_session *pSession, 2281 | int (*xOutput)(void *pOut, const void *pData, int nData), 2282 | void *pOut 2283 | ); 2284 | SQLITE_API int sqlite3session_patchset_strm( 2285 | sqlite3_session *pSession, 2286 | int (*xOutput)(void *pOut, const void *pData, int nData), 2287 | void *pOut 2288 | ); 2289 | SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, 2290 | int (*xInput)(void *pIn, void *pData, int *pnData), 2291 | void *pIn 2292 | ); 2293 | SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*, 2294 | int (*xOutput)(void *pOut, const void *pData, int nData), 2295 | void *pOut 2296 | ); 2297 | SQLITE_API int sqlite3rebaser_rebase_strm( 2298 | sqlite3_rebaser *pRebaser, 2299 | int (*xInput)(void *pIn, void *pData, int *pnData), 2300 | void *pIn, 2301 | int (*xOutput)(void *pOut, const void *pData, int nData), 2302 | void *pOut 2303 | ); 2304 | 2305 | 2306 | SQLITE_API int sqlite3session_config(int op, void *pArg); 2307 | 2308 | 2309 | #define SQLITE_SESSION_CONFIG_STRMSIZE 1 2310 | 2311 | 2312 | #ifdef __cplusplus 2313 | } 2314 | #endif 2315 | 2316 | #endif 2317 | 2318 | 2319 | 2320 | 2321 | 2322 | 2323 | #ifndef _FTS5_H 2324 | #define _FTS5_H 2325 | 2326 | 2327 | #ifdef __cplusplus 2328 | extern "C" { 2329 | #endif 2330 | 2331 | 2332 | 2333 | typedef struct Fts5ExtensionApi Fts5ExtensionApi; 2334 | typedef struct Fts5Context Fts5Context; 2335 | typedef struct Fts5PhraseIter Fts5PhraseIter; 2336 | 2337 | typedef void (*fts5_extension_function)( 2338 | const Fts5ExtensionApi *pApi, 2339 | Fts5Context *pFts, 2340 | sqlite3_context *pCtx, 2341 | int nVal, 2342 | sqlite3_value **apVal 2343 | ); 2344 | 2345 | struct Fts5PhraseIter { 2346 | const unsigned char *a; 2347 | const unsigned char *b; 2348 | }; 2349 | 2350 | 2351 | struct Fts5ExtensionApi { 2352 | int iVersion; 2353 | 2354 | void *(*xUserData)(Fts5Context*); 2355 | 2356 | int (*xColumnCount)(Fts5Context*); 2357 | int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); 2358 | int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); 2359 | 2360 | int (*xTokenize)(Fts5Context*, 2361 | const char *pText, int nText, 2362 | void *pCtx, 2363 | int (*xToken)(void*, int, const char*, int, int, int) 2364 | ); 2365 | 2366 | int (*xPhraseCount)(Fts5Context*); 2367 | int (*xPhraseSize)(Fts5Context*, int iPhrase); 2368 | 2369 | int (*xInstCount)(Fts5Context*, int *pnInst); 2370 | int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); 2371 | 2372 | sqlite3_int64 (*xRowid)(Fts5Context*); 2373 | int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); 2374 | int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); 2375 | 2376 | int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData, 2377 | int(*)(const Fts5ExtensionApi*,Fts5Context*,void*) 2378 | ); 2379 | int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*)); 2380 | void *(*xGetAuxdata)(Fts5Context*, int bClear); 2381 | 2382 | int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*); 2383 | void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff); 2384 | 2385 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); 2386 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); 2387 | 2388 | 2389 | int (*xQueryToken)(Fts5Context*, 2390 | int iPhrase, int iToken, 2391 | const char **ppToken, int *pnToken 2392 | ); 2393 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); 2394 | 2395 | 2396 | int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); 2397 | int (*xTokenize_v2)(Fts5Context*, 2398 | const char *pText, int nText, 2399 | const char *pLocale, int nLocale, 2400 | void *pCtx, 2401 | int (*xToken)(void*, int, const char*, int, int, int) 2402 | ); 2403 | }; 2404 | 2405 | 2406 | 2407 | 2408 | typedef struct Fts5Tokenizer Fts5Tokenizer; 2409 | typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; 2410 | struct fts5_tokenizer_v2 { 2411 | int iVersion; 2412 | 2413 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); 2414 | void (*xDelete)(Fts5Tokenizer*); 2415 | int (*xTokenize)(Fts5Tokenizer*, 2416 | void *pCtx, 2417 | int flags, 2418 | const char *pText, int nText, 2419 | const char *pLocale, int nLocale, 2420 | int (*xToken)( 2421 | void *pCtx, 2422 | int tflags, 2423 | const char *pToken, 2424 | int nToken, 2425 | int iStart, 2426 | int iEnd 2427 | ) 2428 | ); 2429 | }; 2430 | 2431 | 2432 | typedef struct fts5_tokenizer fts5_tokenizer; 2433 | struct fts5_tokenizer { 2434 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); 2435 | void (*xDelete)(Fts5Tokenizer*); 2436 | int (*xTokenize)(Fts5Tokenizer*, 2437 | void *pCtx, 2438 | int flags, 2439 | const char *pText, int nText, 2440 | int (*xToken)( 2441 | void *pCtx, 2442 | int tflags, 2443 | const char *pToken, 2444 | int nToken, 2445 | int iStart, 2446 | int iEnd 2447 | ) 2448 | ); 2449 | }; 2450 | 2451 | 2452 | 2453 | #define FTS5_TOKENIZE_QUERY 0x0001 2454 | #define FTS5_TOKENIZE_PREFIX 0x0002 2455 | #define FTS5_TOKENIZE_DOCUMENT 0x0004 2456 | #define FTS5_TOKENIZE_AUX 0x0008 2457 | 2458 | 2459 | #define FTS5_TOKEN_COLOCATED 0x0001 2460 | 2461 | 2462 | 2463 | 2464 | typedef struct fts5_api fts5_api; 2465 | struct fts5_api { 2466 | int iVersion; 2467 | 2468 | 2469 | int (*xCreateTokenizer)( 2470 | fts5_api *pApi, 2471 | const char *zName, 2472 | void *pUserData, 2473 | fts5_tokenizer *pTokenizer, 2474 | void (*xDestroy)(void*) 2475 | ); 2476 | 2477 | 2478 | int (*xFindTokenizer)( 2479 | fts5_api *pApi, 2480 | const char *zName, 2481 | void **ppUserData, 2482 | fts5_tokenizer *pTokenizer 2483 | ); 2484 | 2485 | 2486 | int (*xCreateFunction)( 2487 | fts5_api *pApi, 2488 | const char *zName, 2489 | void *pUserData, 2490 | fts5_extension_function xFunction, 2491 | void (*xDestroy)(void*) 2492 | ); 2493 | 2494 | 2495 | 2496 | 2497 | int (*xCreateTokenizer_v2)( 2498 | fts5_api *pApi, 2499 | const char *zName, 2500 | void *pUserData, 2501 | fts5_tokenizer_v2 *pTokenizer, 2502 | void (*xDestroy)(void*) 2503 | ); 2504 | 2505 | 2506 | int (*xFindTokenizer_v2)( 2507 | fts5_api *pApi, 2508 | const char *zName, 2509 | void **ppUserData, 2510 | fts5_tokenizer_v2 **ppTokenizer 2511 | ); 2512 | }; 2513 | 2514 | 2515 | 2516 | #ifdef __cplusplus 2517 | } 2518 | #endif 2519 | 2520 | #endif 2521 | 2522 | 2523 | #endif 2524 | 2525 | 2526 | 2527 | #ifdef SQLITE_USER_AUTHENTICATION 2528 | #undef SQLITE_USER_AUTHENTICATION 2529 | #endif 2530 | 2531 | 2532 | #define CODEC_TYPE_UNKNOWN 0 2533 | #define CODEC_TYPE_AES128 1 2534 | #define CODEC_TYPE_AES256 2 2535 | #define CODEC_TYPE_CHACHA20 3 2536 | #define CODEC_TYPE_SQLCIPHER 4 2537 | #define CODEC_TYPE_RC4 5 2538 | #define CODEC_TYPE_ASCON128 6 2539 | #define CODEC_TYPE_AEGIS 7 2540 | #define CODEC_TYPE_MAX_BUILTIN 7 2541 | 2542 | 2543 | 2544 | 2545 | #if SQLITE_OS_WIN == 1 2546 | 2547 | #ifdef __cplusplus 2548 | extern "C" { 2549 | #endif 2550 | 2551 | SQLITE_API int sqlite3_win32_set_directory(unsigned long type, void* zValue); 2552 | 2553 | #ifdef __cplusplus 2554 | } 2555 | #endif 2556 | 2557 | #endif 2558 | 2559 | #ifdef __cplusplus 2560 | extern "C" { 2561 | #endif 2562 | 2563 | 2564 | SQLITE_API int sqlite3_key(sqlite3* db, const void* pKey, int nKey); 2565 | SQLITE_API int sqlite3_key_v2(sqlite3* db, const char* zDbName, const void* pKey, int nKey); 2566 | 2567 | 2568 | SQLITE_API int sqlite3_rekey(sqlite3* db, const void* pKey, int nKey); 2569 | SQLITE_API int sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* pKey, int nKey); 2570 | 2571 | 2572 | SQLITE_API void sqlite3_activate_see(const char* zPassPhrase); 2573 | 2574 | 2575 | SQLITE_API int sqlite3mc_cipher_count(); 2576 | SQLITE_API int sqlite3mc_cipher_index(const char* cipherName); 2577 | SQLITE_API const char* sqlite3mc_cipher_name(int cipherIndex); 2578 | SQLITE_API int sqlite3mc_config(sqlite3* db, const char* paramName, int newValue); 2579 | SQLITE_API int sqlite3mc_config_cipher(sqlite3* db, const char* cipherName, const char* paramName, int newValue); 2580 | SQLITE_API unsigned char* sqlite3mc_codec_data(sqlite3* db, const char* zDbName, const char* paramName); 2581 | SQLITE_API const char* sqlite3mc_version(); 2582 | 2583 | #ifdef SQLITE3MC_WXSQLITE3_COMPATIBLE 2584 | SQLITE_API int wxsqlite3_config(sqlite3* db, const char* paramName, int newValue); 2585 | SQLITE_API int wxsqlite3_config_cipher(sqlite3* db, const char* cipherName, const char* paramName, int newValue); 2586 | SQLITE_API unsigned char* wxsqlite3_codec_data(sqlite3* db, const char* zDbName, const char* paramName); 2587 | #endif 2588 | 2589 | 2590 | 2591 | 2592 | typedef struct _CipherParams 2593 | { 2594 | const char* m_name; 2595 | int m_value; 2596 | int m_default; 2597 | int m_minValue; 2598 | int m_maxValue; 2599 | } CipherParams; 2600 | 2601 | 2602 | 2603 | typedef struct BtShared BtSharedMC; 2604 | 2605 | typedef void* (*AllocateCipher_t)(sqlite3* db); 2606 | typedef void (*FreeCipher_t)(void* cipher); 2607 | typedef void (*CloneCipher_t)(void* cipherTo, void* cipherFrom); 2608 | typedef int (*GetLegacy_t)(void* cipher); 2609 | typedef int (*GetPageSize_t)(void* cipher); 2610 | typedef int (*GetReserved_t)(void* cipher); 2611 | typedef unsigned char* (*GetSalt_t)(void* cipher); 2612 | typedef void (*GenerateKey_t)(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt); 2613 | typedef int (*EncryptPage_t)(void* cipher, int page, unsigned char* data, int len, int reserved); 2614 | typedef int (*DecryptPage_t)(void* cipher, int page, unsigned char* data, int len, int reserved, int hmacCheck); 2615 | 2616 | typedef struct _CipherDescriptor 2617 | { 2618 | const char* m_name; 2619 | AllocateCipher_t m_allocateCipher; 2620 | FreeCipher_t m_freeCipher; 2621 | CloneCipher_t m_cloneCipher; 2622 | GetLegacy_t m_getLegacy; 2623 | GetPageSize_t m_getPageSize; 2624 | GetReserved_t m_getReserved; 2625 | GetSalt_t m_getSalt; 2626 | GenerateKey_t m_generateKey; 2627 | EncryptPage_t m_encryptPage; 2628 | DecryptPage_t m_decryptPage; 2629 | } CipherDescriptor; 2630 | 2631 | 2632 | SQLITE_API int sqlite3mc_register_cipher(const CipherDescriptor* desc, const CipherParams* params, int makeDefault); 2633 | 2634 | #ifdef __cplusplus 2635 | } 2636 | #endif 2637 | 2638 | 2639 | 2640 | 2641 | 2642 | 2643 | #ifndef SQLITE3MC_VFS_H_ 2644 | 2645 | #ifdef __cplusplus 2646 | extern "C" { 2647 | #endif 2648 | 2649 | #ifndef SQLITE_PRIVATE 2650 | #define SQLITE_PRIVATE 2651 | #endif 2652 | 2653 | SQLITE_PRIVATE int sqlite3mcCheckVfs(const char* zVfs); 2654 | 2655 | SQLITE_API int sqlite3mc_vfs_create(const char* zVfsReal, int makeDefault); 2656 | SQLITE_API void sqlite3mc_vfs_destroy(const char* zName); 2657 | SQLITE_API void sqlite3mc_vfs_shutdown(); 2658 | 2659 | #ifdef __cplusplus 2660 | } 2661 | #endif 2662 | 2663 | #endif 2664 | 2665 | 2666 | 2667 | #endif 2668 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { DBHandle, version } = require('../build/Release/esqlite3.node'); 4 | 5 | const OPEN_FLAGS = { 6 | READONLY: 0x00000001, 7 | READWRITE: 0x00000002, 8 | CREATE: 0x00000004, 9 | MEMORY: 0x00000080, 10 | SHAREDCACHE: 0x00020000, 11 | PRIVATECACHE: 0x00040000, 12 | NOFOLLOW: 0x01000000, 13 | }; 14 | const DEFAULT_OPEN_FLAGS = (OPEN_FLAGS.READWRITE | OPEN_FLAGS.CREATE); 15 | const OPEN_FLAGS_MASK = Object.values(OPEN_FLAGS).reduce((prev, cur) => { 16 | return (prev | cur); 17 | }); 18 | 19 | const PREPARE_FLAGS = { 20 | NO_VTAB: 0x04, 21 | }; 22 | const DEFAULT_PREPARE_FLAGS = 0x00; 23 | const PREPARE_FLAGS_MASK = Object.values(PREPARE_FLAGS).reduce((prev, cur) => { 24 | return (prev | cur); 25 | }); 26 | 27 | const QUERY_FLAG_SINGLE = 0x01; 28 | const QUERY_FLAG_NAMED_PARAMS = 0x02; 29 | 30 | const kPath = Symbol('Database path'); 31 | const kHandle = Symbol('Database handle'); 32 | const kQueue = Symbol('Database query queue'); 33 | const kAutoClose = Symbol('Database auto closing'); 34 | 35 | class Database { 36 | constructor(path) { 37 | if (typeof path !== 'string') 38 | throw new Error('Invalid path value'); 39 | this[kPath] = path; 40 | this[kAutoClose] = false; 41 | this[kHandle] = new DBHandle(makeRow, makeRowObjFn); 42 | const queue = []; 43 | queue.busy = false; 44 | this[kQueue] = queue; 45 | } 46 | 47 | open(flags) { 48 | if (typeof flags !== 'number') 49 | flags = DEFAULT_OPEN_FLAGS; 50 | else 51 | flags &= OPEN_FLAGS_MASK; 52 | this[kHandle].open(this[kPath], flags); 53 | this[kAutoClose] = false; 54 | } 55 | 56 | query(sql, opts, vals, cb) { 57 | if (typeof sql !== 'string') 58 | throw new TypeError('Invalid sql value'); 59 | 60 | let prepareFlags = DEFAULT_PREPARE_FLAGS; 61 | let flags = QUERY_FLAG_SINGLE; 62 | if (typeof opts === 'function') { 63 | // query(sql, cb) 64 | cb = opts; 65 | opts = undefined; 66 | vals = undefined; 67 | } else if (Array.isArray(opts)) { 68 | // query(sql, vals, cb) 69 | cb = vals; 70 | vals = opts; 71 | opts = undefined; 72 | } else if (typeof opts === 'object' && opts !== null) { 73 | // query(sql, opts, cb) 74 | if (typeof opts.prepareFlags === 'number') 75 | prepareFlags = (opts.prepareFlags & PREPARE_FLAGS_MASK); 76 | if (opts.single === false) 77 | flags &= ~QUERY_FLAG_SINGLE; 78 | if (typeof vals === 'function') { 79 | cb = vals; 80 | vals = undefined; 81 | } 82 | if (opts.values !== undefined) 83 | vals = opts.values; 84 | } 85 | if (vals && !Array.isArray(vals)) { 86 | if (typeof vals === 'object' && vals !== null) { 87 | flags |= QUERY_FLAG_NAMED_PARAMS; 88 | const keys = Object.keys(vals); 89 | const valsKV = new Array(keys.length * 2); 90 | for (let k = 0, p = 0; k < keys.length; ++k, p += 2) { 91 | const key = keys[k]; 92 | valsKV[p] = `:${key}`; 93 | valsKV[p + 1] = vals[key]; 94 | } 95 | vals = valsKV; 96 | } else { 97 | vals = undefined; 98 | } 99 | } 100 | 101 | if (typeof cb !== 'function') 102 | cb = null; 103 | 104 | const queue = this[kQueue]; 105 | if (queue.busy) 106 | queue.push([sql, prepareFlags, flags, vals, cb]); 107 | else 108 | tryQuery(this, sql, prepareFlags, flags, vals, cb); 109 | } 110 | 111 | interrupt(cb) { 112 | this[kHandle].interrupt(() => { 113 | if (typeof cb === 'function') 114 | cb(); 115 | }); 116 | } 117 | 118 | autoCommitEnabled() { 119 | return this[kHandle].autoCommitEnabled(); 120 | } 121 | 122 | end() { 123 | const queue = this[kQueue]; 124 | if (queue.busy || queue.length) 125 | this[kAutoClose] = true; 126 | else 127 | this[kHandle].close(); 128 | } 129 | 130 | close() { 131 | this[kHandle].close(); 132 | } 133 | } 134 | 135 | function tryQuery(self, sql, prepareFlags, flags, vals, cb) { 136 | const queue = self[kQueue]; 137 | try { 138 | queue.busy = true; 139 | self[kHandle].query(sql, prepareFlags, flags, vals, (err, results) => { 140 | if (cb) { 141 | if (err) { 142 | cb(err.length === 1 ? err[0] : err, 143 | results && results.length === 1 ? results[0] : results); 144 | } else { 145 | cb(null, results.length === 1 ? results[0] : results); 146 | } 147 | } 148 | if (queue.length) { 149 | const entry = queue.shift(); 150 | tryQuery( 151 | self, entry[0], entry[1], entry[2], entry[3], entry[4] 152 | ); 153 | } else { 154 | queue.busy = false; 155 | if (self[kAutoClose]) 156 | self[kHandle].close(); 157 | } 158 | }); 159 | } catch (ex) { 160 | if (queue.length) { 161 | const entry = queue.shift(); 162 | process.nextTick( 163 | tryQuery, self, entry[0], entry[1], entry[2], entry[3], entry[4] 164 | ); 165 | } else { 166 | queue.busy = false; 167 | if (self[kAutoClose]) 168 | self[kHandle].close(); 169 | } 170 | if (cb) 171 | cb(ex); 172 | } 173 | } 174 | 175 | function makeRowObjFn() { 176 | let code = 'return {'; 177 | for (let i = 0; i < arguments.length; ++i) 178 | code += `${JSON.stringify(arguments[i])}:v[idx+${i}],`; 179 | const fn = new Function('v,idx', code + '}'); 180 | fn.ncols = arguments.length; 181 | return fn; 182 | } 183 | 184 | function makeRow(pos, rowFn, ...data) { 185 | const ncols = rowFn.ncols; 186 | for (let i = 0; i < data.length; i += ncols) 187 | this[pos++] = rowFn(data, i); 188 | } 189 | 190 | module.exports = { 191 | Database, 192 | OPEN_FLAGS: { ...OPEN_FLAGS }, 193 | PREPARE_FLAGS: { ...PREPARE_FLAGS }, 194 | version: version(), 195 | }; 196 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esqlite", 3 | "version": "0.0.20", 4 | "author": "Brian White ", 5 | "description": "An SQLite binding for node.js with built-in encryption, focused on simplicity and (async) performance", 6 | "main": "./lib/index", 7 | "dependencies": { 8 | "buildcheck": "~0.0.6", 9 | "nan": "^2.22.2" 10 | }, 11 | "devDependencies": { 12 | "@mscdex/eslint-config": "^1.1.0", 13 | "eslint": "^7.0.0" 14 | }, 15 | "scripts": { 16 | "install": "node buildcheck.js > buildcheck.gypi && node-gyp rebuild", 17 | "test": "node test/test.js", 18 | "lint": "eslint --cache --report-unused-disable-directives --ext=.js .eslintrc.js lib test", 19 | "lint:fix": "npm run lint -- --fix" 20 | }, 21 | "engines": { 22 | "node": ">=10.7.0" 23 | }, 24 | "keywords": [ 25 | "sqlite", 26 | "sqlite3", 27 | "database" 28 | ], 29 | "licenses": [ 30 | { 31 | "type": "MIT", 32 | "url": "https://github.com/mscdex/esqlite/raw/master/LICENSE" 33 | } 34 | ], 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/mscdex/esqlite.git" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/binding.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #ifdef _MSC_VER 6 | # include 7 | #endif 8 | 9 | #include 10 | 11 | using namespace node; 12 | using namespace v8; 13 | using namespace std; 14 | 15 | enum QueryFlag : uint32_t { 16 | SingleStatement = 0x01, 17 | NamedParams = 0x02, 18 | }; 19 | 20 | enum class BindParamsType : uint8_t { 21 | None, 22 | Numeric, 23 | Named 24 | }; 25 | 26 | enum class ValueType : uint8_t { 27 | Null, 28 | StringEmpty, 29 | String, 30 | BlobEmpty, 31 | Blob, 32 | Int32Internal, 33 | Int64, 34 | Int64Internal, 35 | Int64Internal4, 36 | Double, 37 | DoubleInternal 38 | }; 39 | 40 | typedef struct { 41 | ValueType type; 42 | void* val; 43 | } BindValue; 44 | 45 | typedef unordered_map NamedParamsMap; 46 | 47 | typedef struct { 48 | ValueType type; 49 | int len; 50 | void* val; 51 | } RowValue; 52 | 53 | class BindValueBlob { 54 | public: 55 | BindValueBlob(Local& buf_) { 56 | ref.Reset(buf_); 57 | data = Buffer::Data(buf_); 58 | len = Buffer::Length(buf_); 59 | } 60 | ~BindValueBlob() { 61 | ref.Reset(); 62 | } 63 | 64 | Nan::Persistent ref; 65 | char* data; 66 | size_t len; 67 | }; 68 | 69 | // When creating strings >= this length V8's GC spins up and consumes 70 | // most of the execution time. For these cases it's more performant to 71 | // use external string resources. 72 | // This value comes from node.js core. 73 | #define EXTERN_APEX 0xFBEE9 74 | class ExtString : public String::ExternalOneByteStringResource { 75 | public: 76 | explicit ExtString(char* data, size_t len) : data_(data), len_(len) { 77 | Nan::AdjustExternalMemory(len); 78 | } 79 | ~ExtString() override { 80 | if (data_) { 81 | free(data_); 82 | Nan::AdjustExternalMemory(-len_); 83 | } 84 | } 85 | const char* data() const override { return data_; } 86 | size_t length() const override { return len_; } 87 | 88 | char* data_; 89 | size_t len_; 90 | }; 91 | 92 | class DBHandle : public Nan::ObjectWrap { 93 | public: 94 | explicit DBHandle(); 95 | ~DBHandle(); 96 | 97 | static NAN_METHOD(New); 98 | static NAN_METHOD(Open); 99 | static NAN_METHOD(Query); 100 | static NAN_METHOD(AutoCommit); 101 | static NAN_METHOD(Interrupt); 102 | static NAN_METHOD(Close); 103 | static inline Nan::Persistent & constructor() { 104 | static Nan::Persistent my_constructor; 105 | return my_constructor; 106 | } 107 | 108 | sqlite3* db_; 109 | size_t working_; 110 | Nan::Persistent makeRowFn; 111 | Nan::Persistent makeObjectRowFn; 112 | }; 113 | 114 | class QueryRequest : public Nan::AsyncResource { 115 | public: 116 | QueryRequest(Local handle_, 117 | DBHandle* handle_ptr_, 118 | Local sql_str_, 119 | BindParamsType params_type_, 120 | void* params_, 121 | unsigned int prepare_flags_, 122 | bool single_query_, 123 | Local callback_) 124 | : Nan::AsyncResource("esqlite:QueryRequest"), 125 | handle_ptr(handle_ptr_), 126 | sql_utf8str(sql_str_), 127 | params_type(params_type_), 128 | params(params_), 129 | prepare_flags(prepare_flags_), 130 | single_query(single_query_), 131 | error_count(0) { 132 | sql_len = sql_utf8str.length(); 133 | sql_str.Reset(sql_str_); 134 | handle.Reset(handle_); 135 | callback.Reset(callback_); 136 | request.data = this; 137 | } 138 | 139 | ~QueryRequest() { 140 | handle.Reset(); 141 | callback.Reset(); 142 | sql_str.Reset(); 143 | } 144 | 145 | uv_work_t request; 146 | 147 | Nan::Persistent handle; 148 | DBHandle* handle_ptr; 149 | 150 | Nan::Persistent sql_str; 151 | Nan::Utf8String sql_utf8str; 152 | size_t sql_len; 153 | 154 | BindParamsType params_type; 155 | void* params; 156 | 157 | unsigned int prepare_flags; 158 | Nan::Callback callback; 159 | bool single_query; 160 | 161 | vector>> results; 162 | vector errors; 163 | size_t error_count; 164 | 165 | /*sqlite3_int64 last_insert_id; 166 | int total_changes; 167 | int changes;*/ 168 | }; 169 | 170 | bool bind_value(sqlite3_stmt* stmt, int index, BindValue& bv, int* res) { 171 | switch (bv.type) { 172 | case ValueType::Null: 173 | *res = sqlite3_bind_null(stmt, index); 174 | break; 175 | case ValueType::Int32Internal: { 176 | int32_t intval; 177 | memcpy(&intval, &bv.val, 4); 178 | *res = sqlite3_bind_int(stmt, index, intval); 179 | break; 180 | } 181 | case ValueType::Int64: { 182 | *res = sqlite3_bind_int64(stmt, index, *(static_cast(bv.val))); 183 | break; 184 | } 185 | case ValueType::Int64Internal: { 186 | int64_t int64val; 187 | memcpy(&int64val, &bv.val, 8); 188 | *res = sqlite3_bind_int64(stmt, index, int64val); 189 | break; 190 | } 191 | case ValueType::Int64Internal4: { 192 | uint32_t uintval; 193 | memcpy(&uintval, &bv.val, 4); 194 | *res = sqlite3_bind_int64(stmt, index, uintval); 195 | break; 196 | } 197 | case ValueType::StringEmpty: 198 | // XXX: hack to get an actual empty string instead of a NULL value 199 | *res = sqlite3_bind_text(stmt, 200 | index, 201 | reinterpret_cast(1), 202 | 0, 203 | SQLITE_STATIC); 204 | break; 205 | case ValueType::String: { 206 | Nan::Utf8String* str = static_cast(bv.val); 207 | *res = 208 | sqlite3_bind_text(stmt, index, **str, str->length(), SQLITE_STATIC); 209 | break; 210 | } 211 | case ValueType::BlobEmpty: 212 | // XXX: hack to get an actual empty blob instead of a NULL value 213 | *res = sqlite3_bind_blob(stmt, 214 | index, 215 | reinterpret_cast(1), 216 | 0, 217 | SQLITE_STATIC); 218 | break; 219 | case ValueType::Blob: { 220 | BindValueBlob* blob = static_cast(bv.val); 221 | *res = sqlite3_bind_blob64(stmt, 222 | index, 223 | blob->data, 224 | blob->len, 225 | SQLITE_STATIC); 226 | break; 227 | } 228 | case ValueType::Double: 229 | *res = sqlite3_bind_double(stmt, index, *(static_cast(bv.val))); 230 | break; 231 | case ValueType::DoubleInternal: { 232 | double doubleval; 233 | memcpy(&doubleval, &bv.val, 8); 234 | *res = sqlite3_bind_double(stmt, index, doubleval); 235 | break; 236 | } 237 | default: 238 | return false; 239 | } 240 | return true; 241 | } 242 | 243 | void bind_value_cleanup(BindValue& bv) { 244 | switch (bv.type) { 245 | case ValueType::String: { 246 | Nan::Utf8String* str = static_cast(bv.val); 247 | delete str; 248 | break; 249 | } 250 | case ValueType::Blob: { 251 | BindValueBlob* blob = static_cast(bv.val); 252 | delete blob; 253 | break; 254 | } 255 | case ValueType::Double: { 256 | double* doubleval = static_cast(bv.val); 257 | delete doubleval; 258 | break; 259 | } 260 | case ValueType::Int64: { 261 | int64_t* int64val = static_cast(bv.val); 262 | delete int64val; 263 | break; 264 | } 265 | default: 266 | return; 267 | } 268 | bv.val = nullptr; 269 | } 270 | 271 | bool set_bind_value(BindValue& bv, Local& val) { 272 | if (val->IsNullOrUndefined()) { 273 | bv.type = ValueType::Null; 274 | } else if (val->IsInt32()) { 275 | int32_t intval = Nan::To(val).FromJust(); 276 | bv.type = ValueType::Int32Internal; 277 | memcpy(&bv.val, &intval, 4); 278 | } else if (val->IsUint32() || val->IsBoolean()) { 279 | uint32_t uintval = Nan::To(val).FromJust(); 280 | memcpy(&bv.val, &uintval, 4); 281 | if (uintval <= 2147483647) 282 | bv.type = ValueType::Int32Internal; 283 | else 284 | bv.type = ValueType::Int64Internal4; 285 | } else if (val->IsString()) { 286 | Local str = Local::Cast(val); 287 | if (str->Length() == 0) { 288 | bv.type = ValueType::StringEmpty; 289 | } else { 290 | bv.type = ValueType::String; 291 | bv.val = new Nan::Utf8String(val); 292 | } 293 | } else if (val->IsNumber()) { 294 | double doubleval = Nan::To(val).FromJust(); 295 | if (sizeof(void*) == 4) { 296 | bv.type = ValueType::Double; 297 | double* val_ptr = new double; 298 | *val_ptr = doubleval; 299 | bv.val = val_ptr; 300 | } else { 301 | bv.type = ValueType::DoubleInternal; 302 | memcpy(&bv.val, &doubleval, 8); 303 | } 304 | } else if (val->IsBigInt()) { 305 | Local bi = val->ToBigInt(Nan::GetCurrentContext()).ToLocalChecked(); 306 | bool lossless; 307 | int64_t int64val = bi->Int64Value(&lossless); 308 | if (!lossless) 309 | return false; // Value too large for SQLite's API 310 | if (int64val >= -2147483648 && int64val <= 2147483647) { 311 | int32_t intval = int64val; 312 | bv.type = ValueType::Int32Internal; 313 | memcpy(&bv.val, &intval, 4); 314 | } else if (sizeof(void*) == 4) { 315 | bv.type = ValueType::Int64; 316 | int64_t* val_ptr = new int64_t; 317 | *val_ptr = int64val; 318 | bv.val = val_ptr; 319 | } else { 320 | bv.type = ValueType::Int64Internal; 321 | memcpy(&bv.val, &int64val, 8); 322 | } 323 | } else if (Buffer::HasInstance(val)) { 324 | // Assume Blob 325 | if (Buffer::Length(val) == 0) { 326 | bv.type = ValueType::BlobEmpty; 327 | } else { 328 | bv.type = ValueType::Blob; 329 | bv.val = new BindValueBlob(val); 330 | } 331 | } else { 332 | return false; 333 | } 334 | return true; 335 | } 336 | 337 | void QueryWork(uv_work_t* req) { 338 | QueryRequest* query_req = static_cast(req->data); 339 | 340 | const char* sql = *(query_req->sql_utf8str); 341 | const char* sql_pos = sql; 342 | size_t sql_len = query_req->sql_len; 343 | 344 | size_t bind_list_pos = 0; 345 | while (sql_len) { 346 | sqlite3_stmt* stmt; 347 | const char* new_pos; 348 | int res = sqlite3_prepare_v3(query_req->handle_ptr->db_, 349 | sql_pos, 350 | sql_len, 351 | query_req->prepare_flags, 352 | &stmt, 353 | &new_pos); 354 | vector> result_set; 355 | if (res != SQLITE_OK) { 356 | ++query_req->error_count; 357 | query_req->errors.push_back( 358 | strdup(sqlite3_errmsg(query_req->handle_ptr->db_)) 359 | ); 360 | query_req->results.push_back(std::move(result_set)); 361 | if (stmt) 362 | sqlite3_finalize(stmt); 363 | break; 364 | } 365 | 366 | if (stmt) { 367 | // Bind any parameters 368 | int nbinds = sqlite3_bind_parameter_count(stmt); 369 | if (nbinds > 0) { 370 | switch (query_req->params_type) { 371 | case BindParamsType::Named: { 372 | NamedParamsMap* map = 373 | static_cast(query_req->params); 374 | for (int index = 1; index <= nbinds; ++index) { 375 | const char* name = sqlite3_bind_parameter_name(stmt, index); 376 | if (name == nullptr) 377 | continue; 378 | 379 | // TODO: switch to map keyed on C string instead to avoid copying 380 | // of parameter name? 381 | auto it = map->find(string(name)); 382 | 383 | if (it == map->end()) 384 | continue; 385 | 386 | if (!bind_value(stmt, index, it->second, &res)) { 387 | ++query_req->error_count; 388 | query_req->errors.push_back(strdup("Invalid bind param type")); 389 | query_req->results.push_back(std::move(result_set)); 390 | sqlite3_finalize(stmt); 391 | return; 392 | } 393 | if (res != SQLITE_OK) { 394 | ++query_req->error_count; 395 | query_req->errors.push_back( 396 | strdup(sqlite3_errmsg(query_req->handle_ptr->db_)) 397 | ); 398 | query_req->results.push_back(std::move(result_set)); 399 | sqlite3_finalize(stmt); 400 | return; 401 | } 402 | } 403 | break; 404 | } 405 | case BindParamsType::Numeric: { 406 | vector* list = 407 | static_cast*>(query_req->params); 408 | for (int index = 1; 409 | index <= nbinds && bind_list_pos < list->size(); 410 | ++index) { 411 | if (!bind_value(stmt, index, list->at(bind_list_pos++), &res)) { 412 | ++query_req->error_count; 413 | query_req->errors.push_back( 414 | strdup("Invalid bind param type") 415 | ); 416 | query_req->results.push_back(std::move(result_set)); 417 | sqlite3_finalize(stmt); 418 | return; 419 | } 420 | if (res != SQLITE_OK) { 421 | ++query_req->error_count; 422 | query_req->errors.push_back( 423 | strdup(sqlite3_errmsg(query_req->handle_ptr->db_)) 424 | ); 425 | query_req->results.push_back(std::move(result_set)); 426 | sqlite3_finalize(stmt); 427 | return; 428 | } 429 | } 430 | break; 431 | } 432 | default: 433 | // Appease the compiler 434 | break; 435 | } 436 | } 437 | 438 | res = sqlite3_step(stmt); 439 | if (res == SQLITE_ROW) { 440 | int col_count = sqlite3_data_count(stmt); 441 | vector cols(col_count); 442 | if (col_count) { 443 | // Add the column names to the result set 444 | for (int i = 0; i < col_count; ++i) { 445 | const char* name = sqlite3_column_name(stmt, i); 446 | int len = -1; 447 | while (name[++len]); 448 | if (len > 0) { 449 | cols[i].type = ValueType::String; 450 | cols[i].val = malloc(len); 451 | assert(cols[i].val != nullptr); 452 | memcpy(cols[i].val, name, len); 453 | cols[i].len = len; 454 | } else { 455 | cols[i].type = ValueType::StringEmpty; 456 | } 457 | } 458 | result_set.push_back(std::move(cols)); 459 | 460 | // Add the rows to the result set 461 | do { 462 | vector row(col_count); 463 | for (int i = 0; i < col_count; ++i) { 464 | switch (sqlite3_column_type(stmt, i)) { 465 | case SQLITE_NULL: 466 | row[i].type = ValueType::Null; 467 | break; 468 | case SQLITE_BLOB: { 469 | const void* data = sqlite3_column_blob(stmt, i); 470 | int len = sqlite3_column_bytes(stmt, i); 471 | if (len == 0) { 472 | row[i].type = ValueType::BlobEmpty; 473 | } else { 474 | row[i].type = ValueType::Blob; 475 | row[i].len = len; 476 | row[i].val = malloc(len); 477 | assert(row[i].val != nullptr); 478 | memcpy(row[i].val, data, len); 479 | } 480 | break; 481 | } 482 | default: { 483 | const char* text = reinterpret_cast( 484 | sqlite3_column_text(stmt, i) 485 | ); 486 | int len = sqlite3_column_bytes(stmt, i); 487 | if (len == 0) { 488 | row[i].type = ValueType::StringEmpty; 489 | } else { 490 | row[i].type = ValueType::String; 491 | row[i].val = malloc(len); 492 | assert(row[i].val != nullptr); 493 | memcpy(row[i].val, text, len); 494 | row[i].len = len; 495 | } 496 | } 497 | } 498 | } 499 | result_set.push_back(std::move(row)); 500 | } while ((res = sqlite3_step(stmt)) == SQLITE_ROW); 501 | } else { 502 | result_set.push_back(std::move(cols)); 503 | // No columns thus no row data, so just step until done 504 | while ((res = sqlite3_step(stmt)) == SQLITE_ROW); 505 | } 506 | } 507 | } else { 508 | res = SQLITE_DONE; 509 | } 510 | 511 | if (res == SQLITE_DONE) { 512 | query_req->errors.push_back(nullptr); 513 | } else { 514 | ++query_req->error_count; 515 | query_req->errors.push_back( 516 | strdup(sqlite3_errmsg(query_req->handle_ptr->db_)) 517 | ); 518 | } 519 | query_req->results.push_back(std::move(result_set)); 520 | if (stmt) 521 | sqlite3_finalize(stmt); 522 | else 523 | break; 524 | 525 | if (query_req->single_query) 526 | break; 527 | 528 | // Move to the next query in the sql string 529 | sql_len -= (new_pos - sql_pos); 530 | sql_pos = new_pos; 531 | } 532 | 533 | // TODO: store these per result set? opt-in only? 534 | /*query_req->last_insert_id = 535 | sqlite3_last_insert_rowid(query_req->handle_ptr->db_); 536 | query_req->total_changes = 537 | sqlite3_total_changes(query_req->handle_ptr->db_); 538 | query_req->changes = sqlite3_changes(query_req->handle_ptr->db_);*/ 539 | } 540 | 541 | void QueryAfter(uv_work_t* req, int status) { 542 | Nan::HandleScope scope; 543 | QueryRequest* query_req = static_cast(req->data); 544 | Local handle = Nan::New(query_req->handle); 545 | Local callback = query_req->callback.GetFunction(); 546 | Local makeRowFn = Nan::New(query_req->handle_ptr->makeRowFn); 547 | Local makeObjectRowFn = 548 | Nan::New(query_req->handle_ptr->makeObjectRowFn); 549 | --query_req->handle_ptr->working_; 550 | 551 | switch (query_req->params_type) { 552 | case BindParamsType::Named: { 553 | NamedParamsMap* map = static_cast(query_req->params); 554 | NamedParamsMap::iterator it = map->begin(); 555 | while (it != map->end()) { 556 | bind_value_cleanup(it->second); 557 | ++it; 558 | } 559 | delete map; 560 | break; 561 | } 562 | case BindParamsType::Numeric: { 563 | vector* list = 564 | static_cast*>(query_req->params); 565 | for (size_t i = 0; i < list->size(); ++i) 566 | bind_value_cleanup(list->at(i)); 567 | delete list; 568 | break; 569 | } 570 | default: 571 | // Appease compiler 572 | break; 573 | } 574 | 575 | Local cb_argv[2]; 576 | 577 | Local errs; 578 | if (query_req->error_count) 579 | errs = Nan::New(query_req->errors.size()); 580 | 581 | Local results; 582 | if (query_req->error_count == query_req->errors.size()) { 583 | // All errors, no results 584 | for (size_t i = 0; i < query_req->errors.size(); ++i) { 585 | // TODO: attach code name/value to error object 586 | Local err = Nan::Error(query_req->errors[i]); 587 | free(query_req->errors[i]); 588 | Nan::Set(errs, i, err); 589 | } 590 | cb_argv[0] = errs; 591 | cb_argv[1] = Nan::Null(); 592 | } else { 593 | results = Nan::New(query_req->results.size()); 594 | for (size_t i = 0; i < query_req->results.size(); ++i) { 595 | if (query_req->errors[i]) { 596 | // TODO: attach code name/value to error object 597 | Local err = Nan::Error(query_req->errors[i]); 598 | free(query_req->errors[i]); 599 | Nan::Set(errs, i, err); 600 | Nan::Set(results, i, Nan::Null()); 601 | continue; 602 | } 603 | 604 | if (query_req->results[i].size() < 2) { 605 | Nan::Set(results, i, Nan::New(0)); 606 | continue; 607 | } 608 | int ncols = query_req->results[i][0].size(); 609 | if (ncols == 0) { 610 | Nan::Set(results, i, Nan::New(0)); 611 | continue; 612 | } 613 | size_t nrows = query_req->results[i].size() - 1; 614 | Local rows = Nan::New(nrows); 615 | 616 | // Create row generator from column names 617 | Local rowFn; 618 | { 619 | int argc = ncols; 620 | #ifdef _MSC_VER 621 | Local* argv = 622 | static_cast*>(_malloca(argc * sizeof(Local))); 623 | #else 624 | Local argv[argc]; 625 | #endif 626 | for (int k = 0; k < ncols; ++k) { 627 | Local val; 628 | switch (query_req->results[i][0][k].type) { 629 | case ValueType::String: { 630 | char* raw = static_cast(query_req->results[i][0][k].val); 631 | size_t len = query_req->results[i][0][k].len; 632 | if (len < EXTERN_APEX) { 633 | // Makes copy 634 | val = Nan::New(raw, len).ToLocalChecked(); 635 | free(raw); 636 | } else { 637 | // Uses reference to existing memory 638 | val = Nan::New(new ExtString(raw, len)).ToLocalChecked(); 639 | } 640 | } 641 | break; 642 | case ValueType::StringEmpty: 643 | val = Nan::EmptyString(); 644 | break; 645 | default: 646 | // Appease compiler 647 | break; 648 | } 649 | argv[k] = val; 650 | } 651 | rowFn = Local::Cast( 652 | query_req->runInAsyncScope(rows, makeObjectRowFn, argc, argv) 653 | .ToLocalChecked() 654 | ); 655 | #ifdef _MSC_VER 656 | _freea(argv); 657 | #endif 658 | } 659 | 660 | // Create rows 661 | { 662 | size_t j = 1; 663 | while (true) { 664 | #define CHUNK_SIZE 30 665 | size_t chunk_size = 666 | min(nrows - (j - 1), static_cast(CHUNK_SIZE)); 667 | if (chunk_size == 0) 668 | break; 669 | size_t end = j + chunk_size; 670 | 671 | int offset = 2; 672 | int argc = 2 + (ncols * chunk_size); 673 | #ifdef _MSC_VER 674 | Local* argv = 675 | static_cast*>(_malloca(argc * sizeof(Local))); 676 | #else 677 | Local argv[argc]; 678 | #endif 679 | argv[0] = Nan::New(static_cast(j - 1)); 680 | argv[1] = rowFn; 681 | for (; j < end; ++j) { 682 | for (int k = 0; k < ncols; ++k) { 683 | Local val; 684 | switch (query_req->results[i][j][k].type) { 685 | case ValueType::Null: 686 | val = Nan::Null(); 687 | break; 688 | case ValueType::StringEmpty: 689 | val = Nan::EmptyString(); 690 | break; 691 | case ValueType::BlobEmpty: 692 | val = Nan::NewBuffer(0).ToLocalChecked(); 693 | break; 694 | case ValueType::Blob: { 695 | // Transfers ownership 696 | val = Nan::NewBuffer( 697 | static_cast(query_req->results[i][j][k].val), 698 | query_req->results[i][j][k].len 699 | ).ToLocalChecked(); 700 | break; 701 | } 702 | default: { 703 | char* raw = 704 | static_cast(query_req->results[i][j][k].val); 705 | size_t len = query_req->results[i][j][k].len; 706 | if (len < EXTERN_APEX) { 707 | // Makes copy 708 | val = Nan::New(raw, len).ToLocalChecked(); 709 | free(raw); 710 | } else { 711 | // Uses reference to existing memory 712 | val = Nan::New(new ExtString(raw, len)).ToLocalChecked(); 713 | } 714 | } 715 | } 716 | argv[offset++] = val; 717 | } 718 | } 719 | query_req->runInAsyncScope(rows, makeRowFn, argc, argv); 720 | #ifdef _MSC_VER 721 | _freea(argv); 722 | #endif 723 | } 724 | } 725 | 726 | Nan::Set(results, i, rows); 727 | } 728 | 729 | if (query_req->error_count) 730 | cb_argv[0] = errs; 731 | else 732 | cb_argv[0] = Nan::Null(); 733 | cb_argv[1] = results; 734 | } 735 | 736 | query_req->runInAsyncScope(handle, callback, 2, cb_argv); 737 | 738 | delete query_req; 739 | } 740 | 741 | class InterruptRequest : public Nan::AsyncResource { 742 | public: 743 | InterruptRequest(Local handle_, 744 | DBHandle* handle_ptr_, 745 | Local callback_) 746 | : Nan::AsyncResource("esqlite:InterruptRequest"), 747 | handle_ptr(handle_ptr_) { 748 | handle.Reset(handle_); 749 | callback.Reset(callback_); 750 | request.data = this; 751 | } 752 | 753 | ~InterruptRequest() { 754 | handle.Reset(); 755 | callback.Reset(); 756 | } 757 | 758 | uv_work_t request; 759 | 760 | Nan::Persistent handle; 761 | DBHandle* handle_ptr; 762 | 763 | Nan::Callback callback; 764 | }; 765 | 766 | void InterruptWork(uv_work_t* req) { 767 | InterruptRequest* intr_req = static_cast(req->data); 768 | sqlite3_interrupt(intr_req->handle_ptr->db_); 769 | } 770 | 771 | void InterruptAfter(uv_work_t* req, int status) { 772 | Nan::HandleScope scope; 773 | InterruptRequest* intr_req = static_cast(req->data); 774 | Local handle = Nan::New(intr_req->handle); 775 | Local callback = intr_req->callback.GetFunction(); 776 | --intr_req->handle_ptr->working_; 777 | 778 | intr_req->runInAsyncScope(handle, callback, 0, nullptr); 779 | 780 | delete intr_req; 781 | } 782 | 783 | DBHandle::DBHandle() : db_(nullptr), working_(0) { 784 | } 785 | DBHandle::~DBHandle() { 786 | sqlite3_close_v2(db_); 787 | makeRowFn.Reset(); 788 | makeObjectRowFn.Reset(); 789 | } 790 | 791 | NAN_METHOD(DBHandle::New) { 792 | if (!info.IsConstructCall()) 793 | return Nan::ThrowError("Use `new` to create instances"); 794 | DBHandle* obj = new DBHandle(); 795 | obj->Wrap(info.This()); 796 | obj->makeRowFn.Reset(Local::Cast(info[0])); 797 | obj->makeObjectRowFn.Reset(Local::Cast(info[1])); 798 | info.GetReturnValue().Set(info.This()); 799 | } 800 | 801 | NAN_METHOD(DBHandle::Open) { 802 | DBHandle* self = Nan::ObjectWrap::Unwrap(info.Holder()); 803 | 804 | if (self->db_) 805 | return Nan::ThrowError("Database already open, close first"); 806 | 807 | Nan::Utf8String filename(info[0]); 808 | uint32_t flags = Nan::To(info[1]).FromJust(); 809 | flags |= SQLITE_OPEN_NOMUTEX; 810 | 811 | int res = sqlite3_open_v2(*filename, &self->db_, flags, nullptr); 812 | if (res != SQLITE_OK) 813 | return Nan::ThrowError(sqlite3_errstr(res)); 814 | 815 | res = sqlite3_extended_result_codes(self->db_, 1); 816 | if (res != SQLITE_OK) 817 | return Nan::ThrowError(sqlite3_errstr(res)); 818 | 819 | // Disable load_extension() SQL function, but leave C API enabled 820 | // TODO: is it safe to set to 0 and still have all extensions (including 821 | // cipher/crypto work properly?) 822 | res = sqlite3_db_config(self->db_, 823 | SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 824 | 1, 825 | nullptr); 826 | if (res != SQLITE_OK) 827 | return Nan::ThrowError(sqlite3_errstr(res)); 828 | 829 | // Disable language features that allow ordinary SQL to deliberately corrupt 830 | // the database 831 | res = sqlite3_db_config(self->db_, 832 | SQLITE_DBCONFIG_DEFENSIVE, 833 | 1, 834 | nullptr); 835 | if (res != SQLITE_OK) 836 | return Nan::ThrowError(sqlite3_errstr(res)); 837 | } 838 | 839 | NAN_METHOD(DBHandle::Query) { 840 | DBHandle* self = Nan::ObjectWrap::Unwrap(info.Holder()); 841 | 842 | if (!self->db_) 843 | return Nan::ThrowError("Database not open"); 844 | 845 | uint32_t prepare_flags = Nan::To(info[1]).FromJust(); 846 | uint32_t query_flags = Nan::To(info[2]).FromJust(); 847 | Local callback = Local::Cast(info[4]); 848 | 849 | BindParamsType params_type; 850 | void* params; 851 | if (info[3]->IsArray()) { 852 | Local param_list = Local::Cast(info[3]); 853 | if (query_flags & QueryFlag::NamedParams) { 854 | // [ key1, val1, key2, val2, ... ] 855 | params_type = BindParamsType::Named; 856 | NamedParamsMap* map = new NamedParamsMap(); 857 | for (uint32_t i = 0; i < param_list->Length(); i += 2) { 858 | BindValue bv; 859 | Local js_key = Nan::Get(param_list, i).ToLocalChecked(); 860 | Nan::Utf8String key_str(js_key); 861 | Local js_val = Nan::Get(param_list, i + 1).ToLocalChecked(); 862 | if (!set_bind_value(bv, js_val)) { 863 | delete map; 864 | string msg = "Unsupported value for bind parameter \""; 865 | msg += *key_str; 866 | msg += "\": "; 867 | Nan::Utf8String val_str(js_val); 868 | msg += *val_str; 869 | return Nan::ThrowError(Nan::New(msg).ToLocalChecked()); 870 | } 871 | map->emplace(make_pair(string(*key_str, key_str.length()), bv)); 872 | } 873 | params = map; 874 | } else { 875 | // [ val1, val2, .... ] 876 | params_type = BindParamsType::Numeric; 877 | vector* bind_values = 878 | new vector(param_list->Length()); 879 | for (uint32_t i = 0; i < param_list->Length(); ++i) { 880 | Local js_val = Nan::Get(param_list, i).ToLocalChecked(); 881 | if (!set_bind_value(bind_values->at(i), js_val)) { 882 | delete bind_values; 883 | string msg = "Unsupported value for bind parameter at position "; 884 | msg += to_string(i); 885 | msg += ": "; 886 | Nan::Utf8String val_str(js_val); 887 | msg += *val_str; 888 | return Nan::ThrowError(Nan::New(msg).ToLocalChecked()); 889 | } 890 | } 891 | params = bind_values; 892 | } 893 | } else { 894 | params_type = BindParamsType::None; 895 | params = nullptr; 896 | } 897 | 898 | bool single_stmt = ((query_flags & QueryFlag::SingleStatement) > 0); 899 | 900 | ++self->working_; 901 | QueryRequest* query_req = new QueryRequest(info.Holder(), 902 | self, 903 | info[0], 904 | params_type, 905 | params, 906 | prepare_flags, 907 | single_stmt, 908 | callback); 909 | 910 | int status = uv_queue_work( 911 | uv_default_loop(), 912 | &query_req->request, 913 | QueryWork, 914 | reinterpret_cast(QueryAfter) 915 | ); 916 | assert(status == 0); 917 | } 918 | 919 | NAN_METHOD(DBHandle::AutoCommit) { 920 | DBHandle* self = Nan::ObjectWrap::Unwrap(info.Holder()); 921 | 922 | if (!self->db_) 923 | return Nan::ThrowError("Database not open"); 924 | 925 | info.GetReturnValue().Set(Nan::New(!!sqlite3_get_autocommit(self->db_))); 926 | } 927 | 928 | NAN_METHOD(DBHandle::Interrupt) { 929 | DBHandle* self = Nan::ObjectWrap::Unwrap(info.Holder()); 930 | 931 | if (!self->db_) 932 | return Nan::ThrowError("Database not open"); 933 | 934 | Local callback = Local::Cast(info[0]); 935 | 936 | ++self->working_; 937 | InterruptRequest* intr_req = new InterruptRequest(info.Holder(), 938 | self, 939 | callback); 940 | 941 | int status = uv_queue_work( 942 | uv_default_loop(), 943 | &intr_req->request, 944 | InterruptWork, 945 | reinterpret_cast(InterruptAfter) 946 | ); 947 | assert(status == 0); 948 | } 949 | 950 | NAN_METHOD(DBHandle::Close) { 951 | DBHandle* self = Nan::ObjectWrap::Unwrap(info.Holder()); 952 | 953 | if (!self->db_) 954 | return; 955 | 956 | if (self->working_) 957 | return Nan::ThrowError("Cannot close database while executing queries"); 958 | 959 | int res = sqlite3_close_v2(self->db_); 960 | if (res != SQLITE_OK) 961 | return Nan::ThrowError(sqlite3_errstr(res)); 962 | 963 | self->db_ = nullptr; 964 | } 965 | 966 | NAN_METHOD(Version) { 967 | #define xstr(s) str(s) 968 | #define str(s) #s 969 | static const char* ver_str = SQLITE_VERSION " / MC " 970 | xstr(SQLITE3MC_VERSION_MAJOR) "." 971 | xstr(SQLITE3MC_VERSION_MINOR) "." 972 | xstr(SQLITE3MC_VERSION_RELEASE) "." 973 | xstr(SQLITE3MC_VERSION_SUBRELEASE) "-" 974 | xstr(SQLITE3MC_VERSION_REV); 975 | #undef str 976 | #undef xstr 977 | info.GetReturnValue().Set(Nan::New(ver_str).ToLocalChecked()); 978 | } 979 | 980 | 981 | 982 | 983 | NAN_MODULE_INIT(init) { 984 | static bool is_initialized = false; 985 | if (!is_initialized) { 986 | int res = sqlite3_initialize(); 987 | if (res != SQLITE_OK) 988 | return Nan::ThrowError("Unable to initialize SQLite"); 989 | is_initialized = true; 990 | } 991 | 992 | Local tpl = Nan::New(DBHandle::New); 993 | tpl->SetClassName(Nan::New("DBHandle").ToLocalChecked()); 994 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 995 | 996 | Nan::SetPrototypeMethod(tpl, "open", DBHandle::Open); 997 | Nan::SetPrototypeMethod(tpl, "query", DBHandle::Query); 998 | Nan::SetPrototypeMethod(tpl, "autoCommitEnabled", DBHandle::AutoCommit); 999 | Nan::SetPrototypeMethod(tpl, "interrupt", DBHandle::Interrupt); 1000 | Nan::SetPrototypeMethod(tpl, "close", DBHandle::Close); 1001 | 1002 | DBHandle::constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); 1003 | 1004 | Nan::Set(target, 1005 | Nan::New("DBHandle").ToLocalChecked(), 1006 | Nan::GetFunction(tpl).ToLocalChecked()); 1007 | 1008 | Nan::Export(target, "version", Version); 1009 | } 1010 | 1011 | NAN_MODULE_WORKER_ENABLED(esqlite3, init) 1012 | -------------------------------------------------------------------------------- /test/common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { inspect } = require('util'); 4 | 5 | function noop() {} 6 | 7 | const mustCallChecks = []; 8 | 9 | function runCallChecks(exitCode) { 10 | if (exitCode !== 0) return; 11 | 12 | const failed = mustCallChecks.filter((context) => { 13 | if ('minimum' in context) { 14 | context.messageSegment = `at least ${context.minimum}`; 15 | return context.actual < context.minimum; 16 | } 17 | context.messageSegment = `exactly ${context.exact}`; 18 | return context.actual !== context.exact; 19 | }); 20 | 21 | failed.forEach((context) => { 22 | console.error('Mismatched %s function calls. Expected %s, actual %d.', 23 | context.name, 24 | context.messageSegment, 25 | context.actual); 26 | console.error(context.stack.split('\n').slice(2).join('\n')); 27 | }); 28 | 29 | if (failed.length) 30 | process.exit(1); 31 | } 32 | 33 | function mustCall(fn, exact) { 34 | return _mustCallInner(fn, exact, 'exact'); 35 | } 36 | 37 | function mustCallAtLeast(fn, minimum) { 38 | return _mustCallInner(fn, minimum, 'minimum'); 39 | } 40 | 41 | function _mustCallInner(fn, criteria = 1, field) { 42 | if (process._exiting) 43 | throw new Error('Cannot use common.mustCall*() in process exit handler'); 44 | 45 | if (typeof fn === 'number') { 46 | criteria = fn; 47 | fn = noop; 48 | } else if (fn === undefined) { 49 | fn = noop; 50 | } 51 | 52 | if (typeof criteria !== 'number') 53 | throw new TypeError(`Invalid ${field} value: ${criteria}`); 54 | 55 | const context = { 56 | [field]: criteria, 57 | actual: 0, 58 | stack: inspect(new Error()), 59 | name: fn.name || '' 60 | }; 61 | 62 | // Add the exit listener only once to avoid listener leak warnings 63 | if (mustCallChecks.length === 0) 64 | process.on('exit', runCallChecks); 65 | 66 | mustCallChecks.push(context); 67 | 68 | function wrapped(...args) { 69 | ++context.actual; 70 | return fn.call(this, ...args); 71 | } 72 | 73 | wrapped.origFn = fn; 74 | 75 | return wrapped; 76 | } 77 | 78 | function once(fn) { 79 | if (typeof fn !== 'function') 80 | throw new TypeError('Missing function'); 81 | return (...args) => { 82 | if (!fn) 83 | return; 84 | const fn_ = fn; 85 | fn = undefined; 86 | fn_(...args); 87 | }; 88 | } 89 | 90 | function series(callbacks) { 91 | if (!Array.isArray(callbacks)) 92 | throw new Error('Missing callbacks array'); 93 | 94 | let p = -1; 95 | (function next(err) { 96 | if (err) 97 | throw err; 98 | if (++p === callbacks.length) 99 | return; 100 | const fn = callbacks[p]; 101 | fn(once(mustCall(next))); 102 | })(); 103 | } 104 | 105 | module.exports = { 106 | mustCall, 107 | mustCallAtLeast, 108 | once, 109 | series, 110 | }; 111 | -------------------------------------------------------------------------------- /test/test-basic.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const { mkdirSync, rmdirSync, unlinkSync } = require('fs'); 5 | const { join } = require('path'); 6 | 7 | const { Database, version } = require(join(__dirname, '..', 'lib')); 8 | 9 | const { series } = require(join(__dirname, 'common.js')); 10 | 11 | assert(/^[0-9.]+ \/ MC [0-9.]+-[a-f0-9]+$/.test(version)); 12 | 13 | let db; 14 | series([ 15 | (cb) => { 16 | db = new Database(':memory:'); 17 | db.open(); 18 | db.query(` 19 | CREATE TABLE data ( 20 | id INTEGER PRIMARY KEY AUTOINCREMENT, 21 | emailAddress VARCHAR(254), 22 | firstName VARCHAR(50), 23 | lastName VARCHAR(50), 24 | age INT, 25 | secret BLOB 26 | ) 27 | `, cb); 28 | assert.throws(() => db.close()); 29 | }, 30 | (cb) => { 31 | assert.strictEqual(db.autoCommitEnabled(), true); 32 | const values = [ 33 | 'foo@example.org', 'Foo', 'Bar', null, Buffer.from('abcd'), 34 | 'baz@example.com', 'Baz', 'Quux', 66, Buffer.from('efgh'), 35 | 'quuy@example.net', 'Quuy', 'Quuz', 33, Buffer.from('ijkl'), 36 | 'utf8@example.net', 'テスト', 'test', 99, Buffer.from('1'), 37 | ]; 38 | db.query(` 39 | INSERT INTO data (emailAddress, firstName, lastName, age, secret) 40 | VALUES (?, ?, ?, ?, ?), 41 | (?, ?, ?, ?, ?), 42 | (?, ?, ?, ?, ?), 43 | (?, ?, ?, ?, ?) 44 | `, values, cb); 45 | }, 46 | (cb) => { 47 | const values = { age: 50 }; 48 | db.query('SELECT * FROM data WHERE age < :age', { values }, (err, rows) => { 49 | if (err) 50 | return cb(err); 51 | assert.strictEqual(rows.length, 1); 52 | assert.deepStrictEqual(rows[0], { 53 | id: '3', 54 | emailAddress: 'quuy@example.net', 55 | firstName: 'Quuy', 56 | lastName: 'Quuz', 57 | age: '33', 58 | secret: Buffer.from('ijkl'), 59 | }); 60 | cb(); 61 | }); 62 | }, 63 | (cb) => { 64 | db.query('SELECT * FROM data ORDER BY id', (err, rows) => { 65 | if (err) 66 | return cb(err); 67 | assert.strictEqual(rows.length, 4); 68 | assert.deepStrictEqual(rows, [{ 69 | id: '1', 70 | emailAddress: 'foo@example.org', 71 | firstName: 'Foo', 72 | lastName: 'Bar', 73 | age: null, 74 | secret: Buffer.from('abcd'), 75 | }, { 76 | id: '2', 77 | emailAddress: 'baz@example.com', 78 | firstName: 'Baz', 79 | lastName: 'Quux', 80 | age: '66', 81 | secret: Buffer.from('efgh'), 82 | }, { 83 | id: '3', 84 | emailAddress: 'quuy@example.net', 85 | firstName: 'Quuy', 86 | lastName: 'Quuz', 87 | age: '33', 88 | secret: Buffer.from('ijkl'), 89 | }, { 90 | id: '4', 91 | emailAddress: 'utf8@example.net', 92 | firstName: 'テスト', 93 | lastName: 'test', 94 | age: '99', 95 | secret: Buffer.from('1'), 96 | }]); 97 | cb(); 98 | }); 99 | }, 100 | (cb) => { 101 | db.query(` 102 | SELECT 'hello' msg1; 103 | SELECT 'world' msg2 104 | `, { single: false }, (err, rows) => { 105 | if (err) 106 | return cb(err); 107 | assert.deepStrictEqual(rows, [ 108 | [ { msg1: 'hello' } ], 109 | [ { msg2: 'world' } ], 110 | ]); 111 | cb(); 112 | }); 113 | }, 114 | (cb) => { 115 | db.query('THISISNOTVALIDSYNTAX', (err, rows) => { 116 | assert(err instanceof Error); 117 | assert(!rows); 118 | cb(); 119 | }); 120 | }, 121 | (cb) => { 122 | db.query(` 123 | SELECT 'hello' msg; 124 | THISISNOTVALIDSYNTAX 125 | `, { single: false }, (err, rows) => { 126 | assert(Array.isArray(err)); 127 | assert.strictEqual(err.length, 2); 128 | assert(!err[0]); 129 | assert(err[1] instanceof Error); 130 | assert.strictEqual(rows.length, 2); 131 | assert.deepStrictEqual(rows[0], [ { msg: 'hello' } ]); 132 | assert(!rows[1]); 133 | cb(); 134 | }); 135 | }, 136 | (cb) => { 137 | db.query(` 138 | THISISNOTVALIDSYNTAX; 139 | SELECT 'hello' msg 140 | `, { single: false }, (err, rows) => { 141 | assert(err instanceof Error); 142 | assert(!rows); 143 | db.close(); 144 | cb(); 145 | }); 146 | }, 147 | (cb) => { 148 | const basePath = join(__dirname, 'tmp'); 149 | const dbPath = join(basePath, 'encrypted.db'); 150 | try { 151 | mkdirSync(basePath); 152 | } catch (ex) { 153 | if (ex.code !== 'EEXIST') 154 | return cb(ex); 155 | } 156 | try { 157 | unlinkSync(dbPath); 158 | } catch (ex) { 159 | if (ex.code !== 'ENOENT') 160 | return cb(ex); 161 | } 162 | 163 | series([ 164 | (cb) => { 165 | // Create an encrypted database 166 | db = new Database(dbPath); 167 | db.open(); 168 | db.query(`PRAGMA key = 'foobarbaz'`, cb); 169 | }, 170 | (cb) => { 171 | db.query(` 172 | CREATE TABLE data ( 173 | id INTEGER PRIMARY KEY AUTOINCREMENT, 174 | name VARCHAR(50) 175 | ); 176 | INSERT INTO data (name) VALUES ('Mr. Anderson') 177 | `, { single: false }, (err) => { 178 | if (err) 179 | return cb(err); 180 | 181 | db.close(); 182 | cb(); 183 | }); 184 | }, 185 | (cb) => { 186 | // Re-open and querying without key set should fail 187 | db = new Database(dbPath); 188 | db.open(); 189 | db.query('SELECT * FROM data', (err) => { 190 | assert(err instanceof Error); 191 | db.close(); 192 | cb(); 193 | }); 194 | }, 195 | (cb) => { 196 | // Re-open and querying with wrong key set should fail 197 | db = new Database(dbPath); 198 | db.open(); 199 | db.query(`PRAGMA key = 'bazbarfoo'`, cb); 200 | }, 201 | (cb) => { 202 | db.query('SELECT * FROM data', (err) => { 203 | assert(err instanceof Error); 204 | db.close(); 205 | cb(); 206 | }); 207 | }, 208 | (cb) => { 209 | // Re-opening with wrong cipher set should fail 210 | db = new Database(dbPath); 211 | db.open(); 212 | db.query(`PRAGMA cipher = 'sqlcipher'`, (err) => { 213 | assert(err instanceof Error); 214 | db.close(); 215 | cb(); 216 | }); 217 | }, 218 | (cb) => { 219 | // Re-open and querying with correct key set should succeed 220 | db = new Database(dbPath); 221 | db.open(); 222 | db.query(`PRAGMA key = 'foobarbaz'`, cb); 223 | }, 224 | (cb) => { 225 | db.query('SELECT * FROM data', (err, rows) => { 226 | if (err) 227 | return cb(err); 228 | assert.strictEqual(rows.length, 1); 229 | db.close(); 230 | cb(); 231 | }); 232 | }, 233 | (cb) => { 234 | // Re-opening with cipher set explicitly and querying with correct key 235 | // set should succeed 236 | db = new Database(dbPath); 237 | db.open(); 238 | db.query(`PRAGMA cipher = 'chacha20'`, cb); 239 | }, 240 | (cb) => { 241 | db.query(`PRAGMA key = 'foobarbaz'`, cb); 242 | }, 243 | (cb) => { 244 | db.query('SELECT * FROM data', (err, rows) => { 245 | if (err) 246 | return cb(err); 247 | assert.strictEqual(rows.length, 1); 248 | db.close(); 249 | cb(); 250 | }); 251 | }, 252 | (cb_) => { 253 | unlinkSync(dbPath); 254 | rmdirSync(basePath); 255 | cb_(); 256 | cb(); 257 | }, 258 | ]); 259 | }, 260 | ]); 261 | -------------------------------------------------------------------------------- /test/test-end.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const { join } = require('path'); 5 | 6 | const { Database } = require(join(__dirname, '..', 'lib')); 7 | 8 | process.on('exit', () => { 9 | assert.deepStrictEqual(result, [1, 2, 3]); 10 | }); 11 | 12 | const result = []; 13 | const db = new Database(':memory:'); 14 | db.open(); 15 | 16 | db.query(` 17 | CREATE TABLE data ( 18 | id INTEGER PRIMARY KEY AUTOINCREMENT, 19 | emailAddress VARCHAR(254), 20 | firstName VARCHAR(50), 21 | lastName VARCHAR(50), 22 | age INT, 23 | secret BLOB 24 | ) 25 | `, (err) => { 26 | assert.ifError(err); 27 | result.push(1); 28 | }); 29 | 30 | { 31 | const values = [ 32 | 'foo@example.org', 'Foo', 'Bar', null, Buffer.from('abcd'), 33 | ]; 34 | db.query(` 35 | INSERT INTO data (emailAddress, firstName, lastName, age, secret) 36 | VALUES (?, ?, ?, ?, ?) 37 | `, values, (err) => { 38 | assert.ifError(err); 39 | result.push(2); 40 | }); 41 | } 42 | 43 | db.query('SELECT * FROM data', (err, rows) => { 44 | assert.ifError(err); 45 | assert.strictEqual(rows.length, 1); 46 | assert.deepStrictEqual(rows[0], { 47 | id: '1', 48 | emailAddress: 'foo@example.org', 49 | firstName: 'Foo', 50 | lastName: 'Bar', 51 | age: null, 52 | secret: Buffer.from('abcd'), 53 | }); 54 | result.push(3); 55 | }); 56 | 57 | db.end(); 58 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { spawnSync } = require('child_process'); 4 | const { readdirSync } = require('fs'); 5 | const { join } = require('path'); 6 | 7 | const spawnOpts = { 8 | stdio: ['ignore', 'inherit', 'inherit'], 9 | windowsHide: true, 10 | }; 11 | let hadError = false; 12 | for (const filename of readdirSync(__dirname)) { 13 | if (!/^test-.+[.]js$/i.test(filename)) 14 | continue; 15 | const spawnArgs = [join(__dirname, filename)]; 16 | const { status: exitCode, signal } = 17 | spawnSync(process.execPath, spawnArgs, spawnOpts); 18 | if (exitCode !== 0) { 19 | hadError = true; 20 | console.error( 21 | `${filename} failed with exit code ${exitCode}, signal ${signal}` 22 | ); 23 | } 24 | } 25 | 26 | if (hadError) 27 | process.exit(1); 28 | --------------------------------------------------------------------------------