express-sqlite3
Advanced tools
Comparing version 0.0.3 to 0.0.4
const { isFunc, isEmpty, isObject } = require('tm-is'); | ||
const StoreDb = require('./storedb'); | ||
const { buildOptions, extractSessExpires, extractSessMaxAge } = require('./utils'); | ||
const { | ||
buildOptions, extractSessExpires, extractSessMaxAge, processCallback, | ||
} = require('./utils'); | ||
@@ -39,4 +41,3 @@ const DEFAULT_OPTS = { | ||
return this[DB].client.all(query, (e, rows) => { | ||
if (e) return cb(e); | ||
return cb(null, rows | ||
processCallback(e, rows, cb, (res) => res | ||
.filter((r) => r.sess) | ||
@@ -54,7 +55,8 @@ .map((r) => JSON.parse(r.sess))); | ||
if (isEmpty(sid)) return cb(null); | ||
const data = [sid, Date.now()]; | ||
const query = `SELECT sess FROM ${this[DB].table} WHERE sid = ? AND ? <= expired`; | ||
return this[DB].client.get(query, [sid, Date.now()], (e, row) => (e | ||
? cb(e) | ||
: cb(null, row ? JSON.parse(row.sess) : undefined) | ||
)); | ||
return this[DB].client.get(query, data, (e, row) => processCallback(e, row, cb, (r) => (r | ||
? JSON.parse(r.sess) | ||
: undefined | ||
))); | ||
} | ||
@@ -115,7 +117,5 @@ | ||
const query = `UPDATE ${this[DB].table} SET expired=? WHERE sid = ? AND ? <= expired`; | ||
this[DB].client.run(query, [expires, sid, Date.now()], (err) => { | ||
if (!isFunc(cb)) return; | ||
cb(err || null, !err); | ||
}); | ||
const data = [expires, sid, Date.now()]; | ||
this[DB].client.run(query, data, (err) => processCallback(err, true, cb)); | ||
} | ||
}; |
const { join } = require('path'); | ||
const sqlite3 = require('sqlite3'); | ||
const { isFunc } = require('tm-is'); | ||
const { buildOptions } = require('./utils'); | ||
const { buildOptions, processCallback } = require('./utils'); | ||
@@ -65,12 +65,7 @@ const DEFAULT_OPTS = { | ||
* Creates a table for sessions if it is not exist. | ||
* @param {Function} cb | ||
*/ | ||
create(cb) { | ||
const query = this.concurrentDb ? `PRAGMA journal_mode = wal;${this.schema()}` : this.schema(); | ||
this.client.run(query, (err) => { | ||
if (isFunc(cb)) { | ||
cb(err); | ||
} else if (err) { | ||
throw err; | ||
} | ||
}); | ||
this.client.run(query, (err) => processCallback(err, null, cb)); | ||
} | ||
@@ -83,6 +78,4 @@ | ||
cleanup(cb) { | ||
this.client.run(`DELETE FROM ${this.table} WHERE ? > expired`, Date.now(), (err) => { | ||
if (!isFunc(cb)) return; | ||
cb(err, err ? undefined : true); | ||
}); | ||
const query = `DELETE FROM ${this.table} WHERE ? > expired`; | ||
this.client.run(query, Date.now(), (err) => processCallback(err, true, cb)); | ||
} | ||
@@ -95,6 +88,3 @@ | ||
clear(cb) { | ||
this.client.run(`DELETE FROM ${this.table}`, (err) => { | ||
if (!isFunc(cb)) return; | ||
cb(err, err ? undefined : true); | ||
}); | ||
this.client.run(`DELETE FROM ${this.table}`, (err) => processCallback(err, true, cb)); | ||
} | ||
@@ -109,4 +99,4 @@ | ||
const query = `SELECT COUNT(*) AS count FROM ${this.table}`; | ||
this.client.get(query, (err, row) => cb(err, err ? undefined : row.count)); | ||
this.client.get(query, (e, row) => processCallback(e, row, cb, (r) => r.count)); | ||
} | ||
}; |
@@ -1,4 +0,19 @@ | ||
const { isObject } = require('tm-is'); | ||
const { isObj, isFunc } = require('tm-is'); | ||
/** | ||
* Process very basic callback logic. | ||
* @param {Object} err Error object o null. | ||
* @param {*} res Result data. | ||
* @param {Function} cb Callback. | ||
* @param {Function} action Function to process result. | ||
*/ | ||
exports.processCallback = (err, res, cb, action) => { | ||
if (!isFunc(cb)) { | ||
if (err) throw err; | ||
return isFunc(action) ? action(res) : res; | ||
} | ||
return err ? cb(err) : cb(null, isFunc(action) ? action(res) : res); | ||
}; | ||
/** | ||
* Takes passed in args object and merges it into one. | ||
@@ -10,3 +25,3 @@ * Argumets order matter. Arg with greater index overrides existed properties. | ||
exports.buildOptions = (...args) => args | ||
.filter((a) => isObject(a)) | ||
.filter((a) => isObj(a)) | ||
.reduce((res, opts) => ({ ...res, ...opts }), {}); | ||
@@ -19,3 +34,3 @@ | ||
*/ | ||
exports.extractSessExpires = (s) => (isObject(s) && isObject(s.cookie) && s.cookie.expires | ||
exports.extractSessExpires = (s) => (isObj(s) && isObj(s.cookie) && s.cookie.expires | ||
? new Date(s.cookie.expires).getTime() | ||
@@ -31,3 +46,3 @@ : false); | ||
exports.extractSessMaxAge = (s, defMaxAge) => { | ||
if (!isObject(s) || !isObject(s.cookie)) { | ||
if (!isObj(s) || !isObj(s.cookie)) { | ||
return defMaxAge; | ||
@@ -34,0 +49,0 @@ } |
{ | ||
"name": "express-sqlite3", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "SQLite3 session store for express-session", | ||
@@ -5,0 +5,0 @@ "main": "lib/express-sqlite3", |
@@ -14,8 +14,44 @@ # express-sqlite3 | ||
- db | ||
- dir | ||
- mode | ||
- table | ||
- maxAge | ||
- concurentDb | ||
- cleanupInterval | ||
| name | description | default value| | ||
| ------ | ----------- |:--------:| | ||
| db | Database file name | sessions | | ||
| dir | Database file directory | ./ | | ||
| mode | SQLite3 client [mode option](https://github.com/mapbox/node-sqlite3/wiki/API#new-sqlite3databasefilename-mode-callback) | | | ||
| table | Database table name | sessions | | ||
| maxAge | Sessions maximum age in msecs| 86400000 (One day) | | ||
| concurentDb | Enables [WAL](https://www.sqlite.org/wal.html) mode | false | | ||
| cleanupInterval | Interval for expired sessions cleanup in msecs | 3600000 (One hour)| | ||
### Example | ||
For Express 4.xx | ||
```js | ||
const express = require('express'); | ||
const session = require('express-session'); | ||
const Store = require('express-sqlite3')(session); | ||
const app = express(); | ||
const storeOptions = { | ||
db: ':memory:', // Use SQLite3 in memory db. | ||
concurentDb: true, // Enable SQLite3 WAL. | ||
}; | ||
app.use(session({ | ||
store: new Store(storeOptions), | ||
secret: 'qwerty', | ||
resave: false, | ||
saveUninitialized: true, | ||
})); | ||
``` | ||
### Test | ||
Install dev dependencies. | ||
`npm i -D express-sqlite3` | ||
Then run | ||
`npm test` or `npm run test:coverage` |
@@ -5,2 +5,32 @@ const { isObject } = require('tm-is'); | ||
describe('Test utils functions', () => { | ||
describe('Test processCallback function', () => { | ||
const err = 'Test processCallback error'; | ||
const action = (res) => res * 100; | ||
test('Should throw an error if error passed without a callback', () => { | ||
expect(() => utils.processCallback(new Error('Error!'))).toThrow(); | ||
}); | ||
test('Should return result if callded without callback', () => { | ||
expect(utils.processCallback(null, 1)).toBe(1); | ||
}); | ||
test('Should run action and return result if callded without callback', () => { | ||
expect(utils.processCallback(null, 1, null, action)).toBe(100); | ||
}); | ||
test('Should call a callback with an error if error given', () => { | ||
utils.processCallback(err, 1, (cbErr) => { | ||
expect(cbErr).toBe(err); | ||
}, action); | ||
}); | ||
test('Should run action and pass results to callback if there is no errors', () => { | ||
utils.processCallback(null, 1, (cbErr, res) => { | ||
expect(cbErr).toBeFalsy(); | ||
expect(res).toBe(100); | ||
}, action); | ||
}); | ||
}); | ||
describe('Test buildOptions function', () => { | ||
@@ -7,0 +37,0 @@ test('Should return an empty object if nothing passed', () => { |
25154
605
57