Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | 3x 3x 3x 3x 3x 15x 15x 1x 1x 16x 16x 16x 16x 16x 16x 16x 16x 16x 14x 14x 14x 14x 1x 64x 64x 64x 64x 64x 7x 7x 7x 7x 7x 1x 1x 1x 1x 1x 1x 1x 1x 1x 25x 25x 25x 25x 25x 27x 27x 27x 27x 27x 7x 7x 7x 7x 7x 4x | import * as sqlite from 'sqlite3' import { Sqlite3 } from '../interfaces/Sqlite3.interfaces' import { Sqlite3Statement } from './Sqlite3Statement' import { Migrate } from '../interfaces/migrate.interfaces' import { migrate } from '../utils/migrate' import { toSqlParams } from '../utils/strings' import MigrationParams = Migrate.MigrationParams export class Sqlite3Database { config: Sqlite3.DatabaseConfigParams db: sqlite.Database constructor (config: Sqlite3.DatabaseConfigParams) { this.config = config this.db = null } /** * Event handler when verbose mode is enabled. * @see https://github.com/mapbox/node-sqlite3/wiki/Debugging */ on (event: string, listener) { this.db.on(event, listener) } /** * Returns the underlying sqlite3 Database instance */ getDatabaseInstance () { return this.db } /** * Opens the database */ open (): Promise<void> { return new Promise((resolve, reject) => { let { filename, mode, driver } = this.config Iif (!filename) { throw new Error('filename is not defined') } Iif (!driver) { throw new Error('driver is not defined') } Eif (!mode) { mode = Sqlite3.OpenDatabaseEnum.OPEN_READWRITE | Sqlite3.OpenDatabaseEnum.OPEN_CREATE } this.db = new driver(filename, mode, err => { Iif (err) { return reject(err) } resolve() }) }) } /** * Closes the database. */ close (): Promise<void> { return new Promise((resolve, reject) => { this.db.close(err => { Iif (err) { return reject(err) } resolve() }) }) } /** * @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseconfigureoption-value */ configure (option: Sqlite3.ConfigureOption, value: any): any { this.db.configure(option as any, value) } /** * Runs the SQL query with the specified parameters. It does not retrieve any result data. * The function returns the Database object for which it was called to allow for function chaining. * * @param {string} sql The SQL query to run. * * @param {any} [params, ...] When the SQL statement contains placeholders, you * can pass them in here. They will be bound to the statement before it is * executed. There are three ways of passing bind parameters: directly in * the function's arguments, as an array, and as an object for named * parameters. This automatically sanitizes inputs. * * @see https://github.com/mapbox/node-sqlite3/wiki/API#databaserunsql-param--callback */ run (sql: Sqlite3.SqlType, ...params: any[]): Promise<Sqlite3.RunResult> { return new Promise((resolve, reject) => { const sqlObj = toSqlParams(sql, params) this.db.run(sqlObj.sql, ...sqlObj.params, function (err) { Iif (err) { return reject(err) } resolve({ stmt: new Sqlite3Statement(this.stmt), lastID: this.lastID, changes: this.changes }) }) }) } /** * Runs the SQL query with the specified parameters and resolves with * with the first result row afterwards. If the result set is empty, returns undefined. * * The property names correspond to the column names of the result set. * It is impossible to access them by column index; the only supported way is by column name. * * @param {string} sql The SQL query to run. * * @param {any} [params, ...] When the SQL statement contains placeholders, you * can pass them in here. They will be bound to the statement before it is * executed. There are three ways of passing bind parameters: directly in * the function's arguments, as an array, and as an object for named * parameters. This automatically sanitizes inputs. * * @see https://github.com/mapbox/node-sqlite3/wiki/API#databasegetsql-param--callback */ get<T = any> ( sql: Sqlite3.SqlType, ...params: any[] ): Promise<T | undefined> { return new Promise((resolve, reject) => { const sqlObj = toSqlParams(sql, params) this.db.get(sqlObj.sql, ...sqlObj.params, (err, row?: T) => { Iif (err) { return reject(err) } resolve(row) }) }) } /** * Runs the SQL query with the specified parameters and calls the callback once for each result * row. The parameters are the same as the Database#run function, with the following differences: * * If the result set succeeds but is empty, the callback is never called. * In all other cases, the callback is called once for every retrieved row. * The order of calls correspond exactly to the order of rows in the result set. * * There is currently no way to abort execution! * * The last parameter to each() *must* be a callback function. * * @example await db.each('SELECT * FROM x WHERE y = ?', 'z', (err, row) => { * // row contains the row data * // each() resolves when there are no more rows to fetch * }) * * @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseeachsql-param--callback-complete * @returns Promise<number> Number of rows returned */ each<T = any> (sql: Sqlite3.SqlType, ...params: any[]): Promise<number> { return new Promise((resolve, reject) => { const callback: (err, row: T) => void = params.pop() Iif (!callback || typeof callback !== 'function') { throw new Error( 'Last param of Sqlite3Database#each() must be a callback( function' ) } const sqlObj = toSqlParams(sql, params) this.db.each( sqlObj.sql, ...sqlObj.params, (err, row) => { Iif (err) { return callback(err, null) } callback(null, row) }, (err, count) => { Iif (err) { return reject(err) } resolve(count) } ) }) } /** * Runs the SQL query with the specified parameters. The parameters are the same as the * Database#run function, with the following differences: * * If the result set is empty, it will be an empty array, otherwise it will * have an object for each result row which * in turn contains the values of that row, like the Database#get function. * * Note that it first retrieves all result rows and stores them in memory. * For queries that have potentially large result sets, use the Database#each * function to retrieve all rows or Database#prepare followed by multiple * Statement#get calls to retrieve a previously unknown amount of rows. * * @param {string} sql The SQL query to run. * * @param {any} [params, ...] When the SQL statement contains placeholders, you * can pass them in here. They will be bound to the statement before it is * executed. There are three ways of passing bind parameters: directly in * the function's arguments, as an array, and as an object for named * parameters. This automatically sanitizes inputs. * * @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseallsql-param--callback */ all<T = any[]> (sql: Sqlite3.SqlType, ...params: any[]): Promise<T> { return new Promise((resolve, reject) => { const sqlObj = toSqlParams(sql, params) this.db.all(sqlObj.sql, ...sqlObj.params, (err, rows?: T) => { Iif (err) { return reject(err) } resolve(rows) }) }) } /** * Runs all SQL queries in the supplied string. No result rows are retrieved. If a query fails, * no subsequent statements will be executed (wrap it in a transaction if you want all * or none to be executed). * * Note: This function will only execute statements up to the first NULL byte. * Comments are not allowed and will lead to runtime errors. * * @param {string} sql The SQL query to run. * @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseexecsql-callback */ exec (sql: Sqlite3.SqlType): Promise<void> { return new Promise((resolve, reject) => { const sqlObj = toSqlParams(sql) this.db.exec(sqlObj.sql, err => { Iif (err) { return reject(err) } resolve() }) }) } /** * Prepares the SQL statement and optionally binds the specified parameters. * When bind parameters are supplied, they are bound to the prepared statement. * * @param {string} sql The SQL query to run. * @param {any} [params, ...] When the SQL statement contains placeholders, you * can pass them in here. They will be bound to the statement before it is * executed. There are three ways of passing bind parameters: directly in * the function's arguments, as an array, and as an object for named * parameters. This automatically sanitizes inputs. * @returns Promise<Statement> Statement object */ prepare (sql: Sqlite3.SqlType, ...params: any[]): Promise<Sqlite3Statement> { return new Promise((resolve, reject) => { const sqlObj = toSqlParams(sql, params) const stmt = this.db.prepare(sqlObj.sql, ...sqlObj.params, err => { Iif (err) { return reject(err) } resolve(new Sqlite3Statement(stmt)) }) }) } /** * Loads a compiled SQLite extension into the database connection object. * * @param {string} path Filename of the extension to load */ loadExtension (path: string) { return new Promise((resolve, reject) => { this.db.loadExtension(path, err => { if (err) { return reject(err) } resolve() }) }) } /** * Performs a database migration. */ async migrate (config?: MigrationParams) { await migrate(this, config) } /** * The methods underneath requires creative work to implement. PRs / proposals accepted! */ /* * Unsure if serialize can be made into a promise. */ serialize () { throw new Error( 'Currently not implemented. Use getDatabaseInstance().serialize() instead.' ) } /* * Unsure if parallelize can be made into a promise. */ parallelize () { throw new Error( 'Currently not implemented. Use getDatabaseInstance().parallelize() instead.' ) } } |