better-sqlite-pool
Advanced tools
Comparing version 0.3.1 to 0.3.2
@@ -0,17 +1,15 @@ | ||
/// <reference types="node" /> | ||
import { EventEmitter } from "events"; | ||
import BetterSqlite3 = require("better-sqlite3"); | ||
import * as BetterSqlite3 from "better-sqlite3"; | ||
export interface PoolConnection extends BetterSqlite3.Database { | ||
/** Wheter the connection is available and can be acquired. */ | ||
/** Whether the connection is available and can be acquired. */ | ||
readonly available: boolean; | ||
/** Releases the connection. */ | ||
release(): void; | ||
} | ||
export interface PoolOptions extends BetterSqlite3.Options { | ||
/** | ||
* The number of milliseconds to wait when executing queries on a locked | ||
* The number of milliseconds to wait when executing queries on a locked | ||
* database, before throwing a SQLITE_BUSY error. Also, this option is used | ||
* to determine how long it'd be waited before throwing timeout error when | ||
* to determine how long it'd be waited before throwing timeout error when | ||
* acquiring the connection. (default: 5000). | ||
@@ -21,3 +19,3 @@ */ | ||
/** | ||
* A function that gets called with every SQL string executed by the | ||
* A function that gets called with every SQL string executed by the | ||
* database connection (default: `null`). | ||
@@ -28,25 +26,26 @@ */ | ||
max?: number; | ||
onConnectionCreated?: (conn: PoolConnection) => void; | ||
} | ||
export class Pool extends EventEmitter implements PoolOptions { | ||
export declare class Pool extends EventEmitter implements PoolOptions { | ||
readonly path: string; | ||
readonly memory: boolean; | ||
readonly readonly: boolean; | ||
readonly fileMustExist: boolean; | ||
readonly timeout: number; | ||
readonly verbose: Function; | ||
readonly verbose: (...args: any[]) => any; | ||
onConnectionCreated?: (conn: PoolConnection) => void; | ||
readonly max: number; | ||
protected connections: PoolConnection[]; | ||
private _closed; | ||
/** | ||
* Creates a new pool to store database connections. | ||
* | ||
* @param path A SQLite database file path, can be set to | ||
* | ||
* @param path A SQLite database file path, can be set to | ||
* `:memory` to open a memory based database. | ||
* @param options If this argument is set to a boolean, it's equivalent to | ||
* `readonly`, if set to a number, it's equivalent to `max`. | ||
* | ||
* | ||
* @see https://github.com/JoshuaWise/better-sqlite3/wiki/API#new-databasepath-options | ||
*/ | ||
constructor(path: string, options?: number | boolean | PoolOptions); | ||
/** | ||
@@ -57,4 +56,11 @@ * Acquires a connection from the pool. | ||
acquire(): Promise<PoolConnection>; | ||
private _getAvailableConnection; | ||
private _createConnection; | ||
/** | ||
* low level create connection | ||
* TODO: this should be abstract method for universal Database Pool | ||
*/ | ||
private _rawCreateConnection; | ||
private _waitConnection; | ||
/** | ||
* Closes all connections in the pool. | ||
@@ -65,3 +71,2 @@ * @see https://github.com/JoshuaWise/better-sqlite3/wiki/API#close---this | ||
} | ||
export default Pool; |
113
index.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const EventEmitter = require("events").EventEmitter; | ||
exports.Pool = void 0; | ||
const events_1 = require("events"); | ||
const BetterSqlite3 = require("better-sqlite3"); | ||
const isV7 = parseInt(require("better-sqlite3/package.json").version) >= 7; | ||
const releaseEvent = "release"; | ||
/** | ||
* A connection pool for the module `better-sqlite3`. | ||
* | ||
* Using this module to open pools and acquire connections, and `release` the | ||
* connection once it has done its work. | ||
*/ | ||
class Pool extends EventEmitter { | ||
class Pool extends events_1.EventEmitter { | ||
/** | ||
* Creates a new pool to store database connections. | ||
* | ||
* @param {string} path A SQLite database file path, can be set to | ||
* | ||
* @param path A SQLite database file path, can be set to | ||
* `:memory` to open a memory based database. | ||
* @param {object|boolean|number} options May contain any of these: | ||
* - `readonly` Default is `false`. | ||
* - `memory` Default is `false`. | ||
* - `fileMustExist` Default is `false`. | ||
* - `max` Max connections in the pool, default is `5`. | ||
* - `timeout` | ||
* - `verbose` | ||
* | ||
* If this argument is set to a boolean, it's equivalent to `readonly`, | ||
* if set to a number, it's equivalent to `max`. | ||
* | ||
* @param options If this argument is set to a boolean, it's equivalent to | ||
* `readonly`, if set to a number, it's equivalent to `max`. | ||
* | ||
* @see https://github.com/JoshuaWise/better-sqlite3/wiki/API#new-databasepath-options | ||
@@ -36,29 +21,26 @@ */ | ||
super(); | ||
this.readonly = false; | ||
this.fileMustExist = false; | ||
this.timeout = 5000; | ||
this.max = 5; | ||
this.connections = []; | ||
this._closed = false; | ||
if (options === undefined || options === null) { | ||
options = {}; | ||
} else if (typeof options === "boolean") { | ||
} | ||
else if (typeof options === "boolean") { | ||
options = { readonly: options }; | ||
} else if (typeof options === "number") { | ||
} | ||
else if (typeof options === "number") { | ||
options = { max: options }; | ||
} | ||
this._closed = false; | ||
this.path = path; | ||
/** @type {BetterSqlite3.Database[]} */ | ||
this.connections = []; | ||
Object.assign(this, { | ||
readonly: false, | ||
path, | ||
memory: path === ":memory", | ||
fileMustExist: false, | ||
timeout: 5000, | ||
verbose: null, | ||
max: 5 | ||
}, options); | ||
} | ||
/** | ||
* Acquires a connection from the pool. | ||
* @see https://github.com/JoshuaWise/better-sqlite3/wiki/API#class-database | ||
* @returns {Promise<BetterSqlite3.Database>} | ||
*/ | ||
@@ -69,26 +51,31 @@ acquire() { | ||
} | ||
return this._getAvailableConnection() | ||
|| this._createConnection() | ||
|| this._waitConnection(); | ||
const conn = this._getAvailableConnection() | ||
|| this._createConnection(); | ||
if (conn) { | ||
return Promise.resolve(conn); | ||
} | ||
else { | ||
return this._waitConnection(); | ||
} | ||
} | ||
_getAvailableConnection() { | ||
for (let conn of this.connections) { | ||
if (conn.available && conn.open) { | ||
conn.available = false; | ||
return Promise.resolve(conn); | ||
Object.assign(conn, { | ||
available: false, | ||
}); | ||
return conn; | ||
} | ||
} | ||
return false; | ||
return null; | ||
} | ||
_createConnection() { | ||
if (this.connections.length < this.max) { | ||
let conn = this._rawCreateConnection(); | ||
conn.available = false; | ||
Object.assign(conn, { | ||
available: false, | ||
}); | ||
conn.release = () => { | ||
if (conn.open && conn.inTransaction) | ||
conn.exec("rollback"); | ||
if (this._closed) { | ||
@@ -98,17 +85,16 @@ conn.close(); | ||
else { | ||
conn.available = conn.open && true; | ||
Object.assign(conn, { | ||
available: conn.open && true, | ||
}); | ||
this.emit(releaseEvent); | ||
} | ||
}; | ||
if (this.onConnectionCreated) { | ||
this.onConnectionCreated(conn); | ||
} | ||
this.connections.push(conn); | ||
return Promise.resolve(conn); | ||
return conn; | ||
} | ||
return false; | ||
return null; | ||
} | ||
/** | ||
@@ -125,27 +111,23 @@ * low level create connection | ||
}; | ||
if (isV7) { | ||
options[":memory"] = this.memory; | ||
} else { | ||
options["memory"] = this.memory; | ||
Object.assign(options, { [":memory"]: this.memory }); | ||
} | ||
else { | ||
Object.assign(options, { memory: this.memory }); | ||
} | ||
return new BetterSqlite3(this.path, options); | ||
} | ||
_waitConnection() { | ||
return new Promise((resolve, reject) => { | ||
let handler = () => { | ||
const handler = () => { | ||
clearTimeout(timer); | ||
resolve(this.acquire()); | ||
}; | ||
let timer = setTimeout(() => { | ||
const timer = setTimeout(() => { | ||
this.removeListener(releaseEvent, handler); | ||
reject(new Error("Timeout to acquire the connection.")); | ||
}, this.timeout); | ||
this.once(releaseEvent, handler); | ||
}); | ||
} | ||
/** | ||
@@ -165,2 +147,3 @@ * Closes all connections in the pool. | ||
} | ||
exports.default = exports.Pool = Pool; | ||
exports.Pool = Pool; | ||
exports.default = Pool; |
{ | ||
"name": "better-sqlite-pool", | ||
"version": "0.3.1", | ||
"version": "0.3.2", | ||
"description": "A connection pool for better-sqlite3.", | ||
@@ -8,25 +8,25 @@ "main": "index.js", | ||
"scripts": { | ||
"prepublishOnly": "tsc --module commonjs --target es2015 --declaration true --noImplicitThis true --noImplicitAny true index.ts", | ||
"postpublish": "ls index.* | grep -v index.ts | xargs rm -f", | ||
"pretest": "tsc --module commonjs --target es2015 test.ts", | ||
"posttest": "rm -f test.js && rm -f *.db && ls index.js* | xargs rm -f", | ||
"test": "node test" | ||
}, | ||
"author": { | ||
"name": "A-yon Lee", | ||
"email": "i@hyurl.com", | ||
"url": "https://github.com/hyurl" | ||
}, | ||
"author": "A-yon Lee <the@ayon.li>", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/hyurl/better-sqlite-pool.git" | ||
"url": "git+https://github.com/ayonli/better-sqlite-pool.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Hyurl/better-sqlite-pool/issues", | ||
"email": "i@hyurl.com" | ||
"url": "https://github.com/ayonli/better-sqlite-pool/issues" | ||
}, | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">=8.0" | ||
"node": ">=10.0" | ||
}, | ||
"devDependencies": { | ||
"@types/better-sqlite3": "^5.4.1", | ||
"better-sqlite3": "^7.4.0" | ||
"@types/better-sqlite3": "^7.6.4", | ||
"better-sqlite3": "^8.4.0", | ||
"typescript": "^4.9.5" | ||
} | ||
} |
# Better-SQLite-Pool | ||
**A connection pool for the module** | ||
**[better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).** | ||
**[better-sqlite3](https://github.com/WiseLibs/better-sqlite3).** | ||
@@ -9,4 +9,4 @@ Using this module to open pools and acquire connections, and `release` the | ||
NOTE: Since v0.3.1, this package no longer includes `better-sqlite3` by default, | ||
you have to install it explicitly. | ||
NOTE: Since v0.3.1, this package no longer includes **better-sqlite3** by | ||
default, you have to install it explicitly. | ||
@@ -84,4 +84,5 @@ ## Install | ||
If you have any problem of downloading and installing this module, it's most | ||
likely that you don't have a `node-gyp` installed, which is used to compile | ||
`better-sqlite3` binary files. so please install `node-gyp` first if this | ||
likely that you're running an old version Node.js which doesn't include prebuilt | ||
**better-sqlite3** binary files, and don't have a `node-gyp` installed, which is | ||
used to compile **better-sqlite3**. so please install `node-gyp` first if this | ||
situation occurs to you. | ||
@@ -97,6 +98,7 @@ | ||
These error will happen when compiling **better-sqlite3** with GCC 7+, which is | ||
issued in [Many "statement may fall through" while installing #3](https://github.com/hyurl/better-sqlite-pool/issues/3) | ||
and [Many "statement may fall through" while installing #239](https://github.com/JoshuaWise/better-sqlite3/issues/239), | ||
These error may happen when compiling **better-sqlite3** (version under v7.0) | ||
with GCC 7+, which is issued | ||
in [Many "statement may fall through" while installing #3](https://github.com/ayonli/better-sqlite-pool/issues/3) | ||
and [Ignore compilation warnings from SQLite3 itself #239](https://github.com/WiseLibs/better-sqlite3/issues/239), | ||
you can still run the driver though, if it's not so much important, just leave | ||
the error alone. |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
102
0
12511
3
5
212
1