better-sqlite3
Advanced tools
Comparing version 2.3.3 to 3.0.0
@@ -64,3 +64,3 @@ 'use strict'; | ||
var table = this === largeData ? 'large' : 'small'; | ||
throw new TypeError('No data defined for column "' + table + '.' + column + '".'); | ||
throw new TypeError('No data defined for column "' + table + '.' + column + '"'); | ||
} | ||
@@ -67,0 +67,0 @@ return this[column]; |
'use strict'; | ||
module.exports = require('./lib/database'); | ||
module.exports.Int64 = require('./lib/int64'); | ||
module.exports.Integer = require('integer'); | ||
module.exports.SqliteError = require('./lib/sqlite-error'); |
'use strict'; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var toDescriptor = require('to-descriptor'); | ||
var util = require('./util'); | ||
var CPPDatabase = require('bindings')({ | ||
bindings: 'better_sqlite3.node', | ||
module_root: path.resolve(__dirname, '..'), | ||
module_root: path.resolve(__dirname, '..') | ||
}).Database; | ||
@@ -12,13 +12,13 @@ | ||
if (typeof filenameGiven !== 'string') { | ||
throw new TypeError('Expected argument 0 to be a string filename.'); | ||
throw new TypeError('Expected first argument to be a string'); | ||
} | ||
var filename = filenameGiven.trim(); | ||
if (!filename) { | ||
throw new TypeError('A database filename cannot be an empty string.'); | ||
throw new TypeError('A database filename cannot be an empty string'); | ||
} | ||
if (/^file:/i.test(filename)) { | ||
throw new TypeError('URI filenames are reserved for internal use only.'); | ||
throw new TypeError('URI filenames are reserved for internal use only'); | ||
} | ||
if (/^(:memory:)?$/i.test(filename)) { | ||
throw new TypeError('To create an in-memory database, specify a normal filename and use the "memory" option.'); | ||
throw new TypeError('To create an in-memory database, specify a normal filename and use the "memory" option'); | ||
} | ||
@@ -29,4 +29,4 @@ | ||
} | ||
var memory = getBoolean(options, 'memory'); | ||
var readonly = getBoolean(options, 'readonly'); | ||
var memory = util.getBooleanOption(options, 'memory'); | ||
var readonly = util.getBooleanOption(options, 'readonly'); | ||
@@ -43,4 +43,4 @@ if (memory) { | ||
+ '?mode=memory&cache=shared'; | ||
} else if (!pathExists(path.dirname(filename))) { | ||
throw new TypeError('Cannot open database because the directory does not exist.'); | ||
} else if (!util.pathExists(path.dirname(filename))) { | ||
throw new TypeError('Cannot open database because the directory does not exist'); | ||
} | ||
@@ -51,40 +51,4 @@ | ||
var createFunction = CPPDatabase.prototype.register; | ||
CPPDatabase.prototype.register = function register(options, func) { | ||
if (typeof options === 'function') { | ||
func = options; | ||
} | ||
if (typeof options !== 'object' || options === null) { | ||
options = {}; | ||
} | ||
if (typeof func !== 'function') { | ||
throw new TypeError('Expected argument 2 to be a function.'); | ||
} | ||
var name = 'name' in options ? options.name : func.name; | ||
var defaultSafeIntegers = !('safeIntegers' in options); | ||
var deterministic = getBoolean(options, 'deterministic'); | ||
var safeIntegers = getBoolean(options, 'safeIntegers'); | ||
var varargs = getBoolean(options, 'varargs'); | ||
var argCount = func.length; | ||
if (typeof name !== 'string') { | ||
throw new TypeError('Expected the "name" option to be a string.'); | ||
} | ||
if (!varargs && typeof argCount !== 'number') { | ||
throw new TypeError('Expected function.length to be a number.'); | ||
} | ||
return createFunction.call(this, func, name, deterministic, defaultSafeIntegers, varargs, safeIntegers, argCount); | ||
}; | ||
function pathExists(path) { | ||
try {fs.accessSync(path); return true;} | ||
catch (ex) {return false;} | ||
} | ||
function getBoolean(options, key) { | ||
if (key in options && typeof options[key] !== 'boolean') { | ||
throw new TypeError('Expected the "' + key + '" option to be a boolean.'); | ||
} | ||
return !!options[key]; | ||
} | ||
util.wrap(CPPDatabase, 'pragma', require('./pragma')); | ||
util.wrap(CPPDatabase, 'register', require('./register')); | ||
CPPDatabase.prototype.constructor = Database; | ||
@@ -91,0 +55,0 @@ Database.prototype = Object.create(Object.prototype, toDescriptor(CPPDatabase.prototype)); |
{ | ||
"name": "better-sqlite3", | ||
"version": "2.3.3", | ||
"version": "3.0.0", | ||
"description": "The fastest and simplest library for SQLite3 in Node.js.", | ||
@@ -14,3 +14,4 @@ "homepage": "http://github.com/JoshuaWise/better-sqlite3", | ||
"bindings": "^1.2.1", | ||
"nan": "^2.5.1", | ||
"integer": "^1.0.1", | ||
"lzz-gyp": "^0.3.3", | ||
"to-descriptor": "^1.0.1" | ||
@@ -27,3 +28,4 @@ }, | ||
"scripts": { | ||
"install": "node install", | ||
"install": "node tools/install", | ||
"install-debug": "CI=true node tools/install", | ||
"test": "$(npm bin)/mocha --bail --timeout 5000 --slow 5000", | ||
@@ -39,3 +41,4 @@ "pretest": "rm -r ./temp/ || true && mkdir ./temp/", | ||
"sqlite3", | ||
"int64", | ||
"custom", | ||
"aggregate", | ||
"database", | ||
@@ -42,0 +45,0 @@ "transactions" |
@@ -16,3 +16,3 @@ # better-sqlite3 [![Build Status](https://travis-ci.org/JoshuaWise/better-sqlite3.svg?branch=master)](https://travis-ci.org/JoshuaWise/better-sqlite3) | ||
|better-sqlite3|1x|1x|1x|1x|1x| | ||
|[sqlite](https://www.npmjs.com/package/sqlite) and [sqlite3](https://www.npmjs.com/package/sqlite3)|7.8x slower|3.3x slower|3.2x slower|3.6x slower|6.2x slower| | ||
|[sqlite](https://www.npmjs.com/package/sqlite) and [sqlite3](https://www.npmjs.com/package/sqlite3)|7.8x slower|3.4x slower|3.4x slower|3.5x slower|6.2x slower| | ||
@@ -19,0 +19,0 @@ > You can verify these results by [running the benchmark yourself](https://github.com/JoshuaWise/better-sqlite3/wiki/Benchmark). |
@@ -38,3 +38,3 @@ var expect = require('chai').expect; | ||
expect(function () {fs.accessSync(util.next());}).to.throw(Error); | ||
var db = new Database(util.current()); | ||
var db = Database(util.current()); | ||
expect(db.name).to.equal(util.current()); | ||
@@ -57,2 +57,5 @@ expect(db.memory).to.be.false; | ||
expect(function () {fs.accessSync(util.next());}).to.throw(Error); | ||
expect(function () {new Database(util.current(), {readonly: true});}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CANTOPEN');; | ||
(new Database(util.current())).close(); | ||
fs.accessSync(util.current()); | ||
var db = new Database(util.current(), {readonly: true}); | ||
@@ -76,3 +79,3 @@ expect(db.name).to.equal(util.current()); | ||
expect(function () {fs.accessSync(util.next());}).to.throw(Error); | ||
expect(function () {new Database('temp/nonexistent/abcfoobar123/' + util.current());}) | ||
expect(function () {new Database('temp/nonexistent/abcfoobar123/' + util.current());}).to.throw(TypeError); | ||
expect(function () {fs.accessSync(util.current());}).to.throw(Error); | ||
@@ -79,0 +82,0 @@ }) |
@@ -26,9 +26,10 @@ var expect = require('chai').expect; | ||
var db = new Database(util.next()); | ||
expect(function () {db.pragma('PRAGMA cache_size');}).to.throw(Error); | ||
expect(function () {db.pragma('PRAGMA cache_size');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {db.pragma('cache_size; PRAGMA cache_size');}).to.throw(RangeError); | ||
}); | ||
it('should execute the pragma, returning rows of strings', function () { | ||
it('should execute the pragma, returning rows of results', function () { | ||
var db = new Database(util.next()); | ||
var rows = db.pragma('cache_size'); | ||
expect(rows[0].cache_size).to.be.a('string'); | ||
expect(rows[0].cache_size).to.equal('-16000'); | ||
expect(rows[0].cache_size).to.be.a('number'); | ||
expect(rows[0].cache_size).to.equal(-16000); | ||
}); | ||
@@ -38,23 +39,29 @@ it('should optionally return simpler results', function () { | ||
var cache_size = db.pragma('cache_size', true); | ||
expect(cache_size).to.be.a('string'); | ||
expect(cache_size).to.equal('-16000'); | ||
expect(cache_size).to.be.a('number'); | ||
expect(cache_size).to.equal(-16000); | ||
expect(function () {db.pragma('cache_size', undefined)}).to.throw(TypeError); | ||
expect(function () {db.pragma('cache_size', null)}).to.throw(TypeError); | ||
expect(function () {db.pragma('cache_size', 123)}).to.throw(TypeError); | ||
expect(function () {db.pragma('cache_size', function () {})}).to.throw(TypeError); | ||
expect(function () {db.pragma('cache_size', NaN)}).to.throw(TypeError); | ||
expect(function () {db.pragma('cache_size', 'true')}).to.throw(TypeError); | ||
}); | ||
it('should accept any truthy value to simplify results', function () { | ||
var db = new Database(util.next()); | ||
expect(db.pragma('cache_size', {})).to.equal('-16000'); | ||
expect(db.pragma('cache_size', 123)).to.equal('-16000'); | ||
expect(db.pragma('cache_size', function () {})).to.equal('-16000'); | ||
expect(db.pragma('cache_size', NaN)).to.deep.equal([{cache_size: '-16000'}]); | ||
}); | ||
it('should obey PRAGMA changes', function () { | ||
var db = new Database(util.next()); | ||
expect(db.pragma('cache_size', true)).to.equal('-16000'); | ||
expect(db.pragma('cache_size', true)).to.equal(-16000); | ||
db.pragma('cache_size = -8000'); | ||
expect(db.pragma('cache_size', true)).to.equal('-8000'); | ||
expect(db.pragma('cache_size', true)).to.equal(-8000); | ||
expect(db.pragma('journal_mode', true)).to.equal('delete'); | ||
db.pragma('journal_mode = wal'); | ||
expect(db.pragma('journal_mode', true)).to.equal('wal'); | ||
}); | ||
it('should be available to readonly connections', function () { | ||
var db = new Database(util.next(), {readonly: true}); | ||
expect(db.pragma('cache_size', true)).to.equal('-16000'); | ||
it('should respect readonly connections', function () { | ||
(new Database(util.next())).close(); | ||
var db = new Database(util.current(), {readonly: true}); | ||
expect(db.pragma('cache_size', true)).to.equal(-16000); | ||
db.pragma('cache_size = -8000'); | ||
expect(db.pragma('cache_size', true)).to.equal('-8000'); | ||
expect(db.pragma('cache_size', true)).to.equal(-8000); | ||
expect(db.pragma('journal_mode', true)).to.equal('delete'); | ||
expect(function () {db.pragma('journal_mode = wal');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_READONLY'); | ||
expect(db.pragma('journal_mode', true)).to.equal('delete'); | ||
}); | ||
@@ -61,0 +68,0 @@ it('should return undefined if no rows exist and simpler results are desired', function () { |
@@ -35,15 +35,15 @@ var expect = require('chai').expect; | ||
var db = new Database(util.next()); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT');}).to.throw(Error); | ||
expect(function () {db.prepare('INSERT INTO people VALUES (?)');}).to.throw(Error); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {db.prepare('INSERT INTO people VALUES (?)');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
}); | ||
it('should throw an exception if no statements are provided', function () { | ||
var db = new Database(util.next()); | ||
expect(function () {db.prepare('');}).to.throw(TypeError); | ||
expect(function () {db.prepare(';');}).to.throw(TypeError); | ||
expect(function () {db.prepare('');}).to.throw(RangeError); | ||
expect(function () {db.prepare(';');}).to.throw(RangeError); | ||
}); | ||
it('should throw an exception if more than one statement is provided', function () { | ||
var db = new Database(util.next()); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT);CREATE TABLE animals (name TEXT)');}).to.throw(TypeError); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT); ');}).to.throw(TypeError); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT);;');}).to.throw(TypeError); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT);CREATE TABLE animals (name TEXT)');}).to.throw(RangeError); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT); ');}).to.throw(RangeError); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT);;');}).to.throw(RangeError); | ||
}); | ||
@@ -64,8 +64,2 @@ it('should create a prepared Statement object', function () { | ||
}); | ||
it('should obey the restrictions of readonly mode', function () { | ||
var db = new Database(util.next(), {readonly: true}); | ||
expect(function () {db.prepare('CREATE TABLE people (name TEXT)');}).to.throw(TypeError); | ||
var stmt = db.prepare('SELECT 555'); | ||
assertStmt(stmt, 'SELECT 555', db, true); | ||
}); | ||
}); |
@@ -31,3 +31,3 @@ var expect = require('chai').expect; | ||
var db = new Database(util.next()); | ||
expect(function () {db.transaction([]);}).to.throw(TypeError); | ||
expect(function () {db.transaction([]);}).to.throw(RangeError); | ||
}); | ||
@@ -43,17 +43,17 @@ it('should propagate exceptions thrown from array accessors', function () { | ||
var db = new Database(util.next()); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT']);}).to.throw(Error); | ||
expect(function () {db.transaction(['INSERT INTO people VALUES (?)']);}).to.throw(Error); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT']);}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {db.transaction(['INSERT INTO people VALUES (?)']);}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
}); | ||
it('should throw an exception if a string contains no statements', function () { | ||
var db = new Database(util.next()); | ||
expect(function () {db.transaction(['']);}).to.throw(TypeError); | ||
expect(function () {db.transaction([';']);}).to.throw(TypeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT)', '']);}).to.throw(TypeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT)', ';']);}).to.throw(TypeError); | ||
expect(function () {db.transaction(['']);}).to.throw(RangeError); | ||
expect(function () {db.transaction([';']);}).to.throw(RangeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT)', '']);}).to.throw(RangeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT)', ';']);}).to.throw(RangeError); | ||
}); | ||
it('should throw an exception if multiple statements exist in one string', function () { | ||
var db = new Database(util.next()); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT);CREATE TABLE animals (name TEXT)']);}).to.throw(TypeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT); ']);}).to.throw(TypeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT);;']);}).to.throw(TypeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT);CREATE TABLE animals (name TEXT)']);}).to.throw(RangeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT); ']);}).to.throw(RangeError); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT);;']);}).to.throw(RangeError); | ||
}); | ||
@@ -72,6 +72,2 @@ it('should throw an exception if any read-only statements are provided', function () { | ||
}); | ||
it('should throw an exception if used on a readonly database connection', function () { | ||
var db = new Database(util.next(), {readonly: true}); | ||
expect(function () {db.transaction(['CREATE TABLE people (name TEXT)']);}).to.throw(TypeError); | ||
}); | ||
it('should create a prepared Transaction object', function () { | ||
@@ -78,0 +74,0 @@ var db = new Database(util.next()); |
@@ -18,7 +18,8 @@ var expect = require('chai').expect; | ||
it('should throw an exception if invalid SQL is provided', function () { | ||
expect(function () {db.exec('CREATE TABLE entries (a TEXT, b INTEGER');}).to.throw(Error); | ||
expect(function () {db.exec('CREATE TABLE entries (a TEXT, b INTEGER');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
}); | ||
it('should throw an exception if used on a readonly database connection', function () { | ||
var readonly = new Database(db.name, {readonly: true}); | ||
expect(function () {readonly.exec('CREATE TABLE entries (a TEXT, b INTEGER)');}).to.throw(TypeError); | ||
it('should obey the restrictions of readonly mode', function () { | ||
var db2 = new Database(db.name, {readonly: true}); | ||
expect(function () {db2.exec('CREATE TABLE people (name TEXT)');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_READONLY'); | ||
db2.exec('SELECT 555'); | ||
}); | ||
@@ -25,0 +26,0 @@ it('should execute the SQL, returning the database object itself', function () { |
@@ -75,5 +75,5 @@ 'use strict'; | ||
var stmt = db.prepare("INSERT INTO ages VALUES (30, 3)"); | ||
expect(function () {stmt.run();}).to.throw(Error); | ||
expect(function () {stmt.run();}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_FOREIGNKEY'); | ||
stmt = db.prepare("INSERT INTO ages VALUES (30, NULL)"); | ||
expect(function () {stmt.run();}).to.throw(Error); | ||
expect(function () {stmt.run();}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_NOTNULL'); | ||
}); | ||
@@ -84,3 +84,3 @@ it('should allow ad-hoc transactions', function () { | ||
var stmt = db.prepare("INSERT INTO ages VALUES (30, 3)"); | ||
expect(function () {stmt.run()}).to.throw(Error); | ||
expect(function () {stmt.run()}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_FOREIGNKEY'); | ||
expect(db.prepare("ROLLBACK TRANSACTION").run().changes).to.equal(0); | ||
@@ -96,2 +96,7 @@ }); | ||
}); | ||
it('should obey the restrictions of readonly mode', function () { | ||
var db2 = new Database(db.name, {readonly: true}); | ||
var stmt = db2.prepare('CREATE TABLE people (name TEXT)'); | ||
expect(function () {stmt.run()}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_READONLY'); | ||
}); | ||
it('should accept bind parameters', function () { | ||
@@ -108,13 +113,13 @@ db.prepare("CREATE TABLE entries (a TEXT CHECK(typeof(a)=='text'), b INTEGER CHECK(typeof(b)=='integer' OR typeof(b)=='real'), c REAL CHECK(typeof(c)=='real' OR typeof(c)=='integer'), d BLOB CHECK(typeof(d)=='blob'))").run(); | ||
db.prepare('INSERT INTO entries VALUES (?, @a, @a, ?)').run({a: 25}, ['foo'], bufferOfSize(8).fill(0xdd), bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, @a, @a, ?)').run({a: 25}, ['foo']); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
db.prepare('INSERT INTO entries VALUES (?, @a, @a, ?)').run({a: 25, c: 25}, ['foo'], bufferOfSize(8).fill(0xdd)); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, @a, @a, ?)').run({}, ['foo'], bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run(25, 'foo', 25, bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_CHECK'); | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run('foo', 25, 25, bufferOfSize(8).fill(0xdd), {}); | ||
@@ -124,15 +129,15 @@ db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run('foo', 25, 25, bufferOfSize(8).fill(0xdd), {foo: 'foo'}); | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run('foo', 25, 25, {4: bufferOfSize(8).fill(0xdd)}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run(); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run({length: 4, 0: 'foo', 1: 25, 2: 25, 3: bufferOfSize(8).fill(0xdd)}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run('foo', 25, new Number(25), bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(TypeError); | ||
expect(function () { | ||
db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?)').run('foo', {low: 25, high: 25}, 25, bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
function Foo() { | ||
@@ -146,3 +151,3 @@ this.a = 'foo'; | ||
db.prepare('INSERT INTO entries VALUES (@a, @b, @c, @d)').run(new Foo); | ||
}).to.throw(Error); | ||
}).to.throw(TypeError); | ||
@@ -149,0 +154,0 @@ // This part of the test may fail is Statement#get() does not work. |
@@ -73,11 +73,11 @@ 'use strict'; | ||
db.prepare(SQL2).get({a: 'foo', b: 1, c: 3.14, d: bufferOfSize(4).fill(0xdd)}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare(SQL1).get(); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare(SQL2).get({}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
}); | ||
@@ -84,0 +84,0 @@ }); |
@@ -82,11 +82,11 @@ 'use strict'; | ||
db.prepare(SQL2).all({a: 'foo', b: 1, c: 3.14, d: bufferOfSize(4).fill(0xdd)}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare(SQL1).all(); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
db.prepare(SQL2).all({}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
}); | ||
@@ -93,0 +93,0 @@ }); |
@@ -108,6 +108,6 @@ 'use strict'; | ||
stmt.each(function () { | ||
throw new Error('This callback should not have been invoked.') | ||
throw new Error('This callback should not have been invoked') | ||
}); | ||
stmt.pluck().each(function () { | ||
throw new Error('This callback should not have been invoked.') | ||
throw new Error('This callback should not have been invoked') | ||
}); | ||
@@ -166,3 +166,3 @@ }); | ||
db.prepare(SQL2).each({a: 'foo', b: 1, c: 3.14, d: bufferOfSize(4).fill(0xaa), e: undefined}, function () { | ||
throw new Error('This callback should not have been invoked.'); | ||
throw new Error('This callback should not have been invoked'); | ||
}); | ||
@@ -172,3 +172,3 @@ | ||
db.prepare(SQL2).each({a: 'foo', b: 1, c: 3.14, d: bufferOfSize(4).fill(0xdd)}, function () {}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -181,3 +181,3 @@ expect(function () { | ||
db.prepare(SQL1).each(function () {}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -190,3 +190,3 @@ expect(function () { | ||
db.prepare(SQL2).each({}, function () {}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -193,0 +193,0 @@ function shouldHave(SQL, desiredData, args) { |
@@ -43,25 +43,2 @@ 'use strict'; | ||
}); | ||
it('should throw an exception when invoked after the first execution', function () { | ||
var stmt = db.prepare('SELECT * FROM entries'); | ||
stmt.get(); | ||
expect(function () {stmt.bind();}).to.throw(TypeError); | ||
stmt = db.prepare('SELECT * FROM entries'); | ||
stmt.all(); | ||
expect(function () {stmt.bind();}).to.throw(TypeError); | ||
stmt = db.prepare('SELECT * FROM entries'); | ||
stmt.each(function () {}); | ||
expect(function () {stmt.bind();}).to.throw(TypeError); | ||
stmt = db.prepare("INSERT INTO entries VALUES ('foobar', 25, NULL)"); | ||
stmt.run(); | ||
expect(function () {stmt.bind();}).to.throw(TypeError); | ||
stmt = db.prepare('SELECT * FROM entries'); | ||
stmt.bind(); | ||
stmt = db.prepare("INSERT INTO entries VALUES ('foobar', 25, NULL)"); | ||
stmt.bind(); | ||
}); | ||
it('should throw an exception when invalid parameters are given', function () { | ||
@@ -72,15 +49,15 @@ var stmt = db.prepare('INSERT INTO entries VALUES (?, ?, ?)'); | ||
stmt.bind('foo', 25); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
stmt.bind('foo', 25, null, null); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
stmt.bind('foo', new Number(25), null); | ||
}).to.throw(Error); | ||
}).to.throw(TypeError); | ||
expect(function () { | ||
stmt.bind(); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -93,11 +70,11 @@ stmt.bind('foo', 25, null); | ||
stmt.bind({a: '123'}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
stmt.bind({a: '123', 1: null}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
stmt.bind({a: '123'}, null, null); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -104,0 +81,0 @@ stmt.bind({a: '123'}, null); |
@@ -65,3 +65,3 @@ 'use strict'; | ||
]); | ||
expect(function () {trans.run();}).to.throw(Error); | ||
expect(function () {trans.run();}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_FOREIGNKEY'); | ||
trans = db.transaction([ | ||
@@ -71,3 +71,3 @@ "INSERT INTO ages VALUES (40, 1)", | ||
]); | ||
expect(function () {trans.run();}).to.throw(Error); | ||
expect(function () {trans.run();}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_NOTNULL'); | ||
expect(db.prepare('SELECT * FROM ages WHERE age==35').get()).to.not.be.undefined; | ||
@@ -89,2 +89,7 @@ expect(db.prepare('SELECT * FROM ages WHERE age==40').get()).to.be.undefined; | ||
}); | ||
it('should obey the restrictions of readonly mode', function () { | ||
var db2 = new Database(db.name, {readonly: true}); | ||
var trans = db2.transaction(['CREATE TABLE people (name TEXT)']); | ||
expect(function () {trans.run()}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_READONLY'); | ||
}); | ||
it('should accept bind parameters', function () { | ||
@@ -117,3 +122,3 @@ db.transaction(["CREATE TABLE entries (a TEXT CHECK(typeof(a)=='text'), b INTEGER CHECK(typeof(b)=='integer' OR typeof(b)=='real'), c REAL CHECK(typeof(c)=='real' OR typeof(c)=='integer'), d BLOB CHECK(typeof(d)=='blob'))"]).run(); | ||
.run({a: 25}, ['foo'], bufferOfSize(8).fill(0xdd), 'foo', bufferOfSize(8).fill(0xdd), bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -123,3 +128,3 @@ expect(function () { | ||
.run({a: 25}, ['foo'], bufferOfSize(8).fill(0xdd), 'foo'); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -132,3 +137,3 @@ db.transaction(['INSERT INTO entries VALUES (?, @a, @a, ?)', 'INSERT INTO entries VALUES (?, @a, @a, ?)']) | ||
.run({}, ['foo'], bufferOfSize(8).fill(0xdd), ['foo'], bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -138,3 +143,3 @@ expect(function () { | ||
.run(25, 'foo', 25, bufferOfSize(8).fill(0xdd), 'foo', 25, 25, bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_CONSTRAINT_CHECK'); | ||
@@ -150,3 +155,3 @@ db.transaction(['INSERT INTO entries VALUES (?, ?, ?, ?)', 'INSERT INTO entries VALUES (?, ?, ?, ?)']) | ||
.run('foo', 25, 25, {4: bufferOfSize(8).fill(0xdd)}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -156,3 +161,3 @@ expect(function () { | ||
.run(); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -162,3 +167,3 @@ expect(function () { | ||
.run({length: 4, 0: 'foo', 1: 25, 2: 25, 3: bufferOfSize(8).fill(0xdd)}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -168,3 +173,3 @@ expect(function () { | ||
.run('foo', 25, new Number(25), bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(TypeError); | ||
@@ -174,3 +179,3 @@ expect(function () { | ||
.run('foo', {low: 25, high: 25}, 25, bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -180,3 +185,3 @@ expect(function () { | ||
.run('foo', 25, 25, bufferOfSize(8).fill(0xdd)); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -191,3 +196,3 @@ function Foo() { | ||
db.transaction(['INSERT INTO entries VALUES (@a, @b, @c, @d)', 'INSERT INTO entries VALUES (@a, @b, @c, @d)']).run(new Foo); | ||
}).to.throw(Error); | ||
}).to.throw(TypeError); | ||
@@ -194,0 +199,0 @@ var i = 0; |
@@ -43,10 +43,2 @@ 'use strict'; | ||
}); | ||
it('should throw an exception when invoked after the first execution', function () { | ||
var trans = db.transaction(["INSERT INTO entries VALUES ('foobar', 25, NULL)"]); | ||
trans.run(); | ||
expect(function () {trans.bind();}).to.throw(TypeError); | ||
trans = db.transaction(["INSERT INTO entries VALUES ('foobar', 25, NULL)"]); | ||
trans.bind(); | ||
}); | ||
it('should throw an exception when invalid parameters are given', function () { | ||
@@ -57,15 +49,15 @@ var trans = db.transaction(['INSERT INTO entries VALUES (?, ?, ?)']); | ||
trans.bind('foo', 25); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
trans.bind('foo', 25, null, null); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
trans.bind('foo', new Number(25), null); | ||
}).to.throw(Error); | ||
}).to.throw(TypeError); | ||
expect(function () { | ||
trans.bind(); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -78,11 +70,11 @@ trans.bind('foo', 25, null); | ||
trans.bind({a: '123'}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
trans.bind({a: '123', 1: null}); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
expect(function () { | ||
trans.bind({a: '123'}, null, null); | ||
}).to.throw(Error); | ||
}).to.throw(RangeError); | ||
@@ -89,0 +81,0 @@ trans.bind({a: '123'}, null); |
var expect = require('chai').expect; | ||
var fs = require('fs'); | ||
var Database = require('../.'); | ||
var db; | ||
var db1, db2; | ||
before(function () { | ||
db = new Database('temp/' + require('path').basename(__filename).split('.')[0] + '.db'); | ||
db.pragma('journal_mode = WAL'); | ||
db.prepare('CREATE TABLE entries (a TEXT, b INTEGER)').run(); | ||
db1 = new Database('temp/' + require('path').basename(__filename).split('.')[0] + '.db'); | ||
db1.pragma('journal_mode = WAL'); | ||
db1.prepare('CREATE TABLE entries (a TEXT, b INTEGER)').run(); | ||
db2 = new Database('temp/' + require('path').basename(__filename).split('.')[0] + '2.db'); | ||
db2.pragma('journal_mode = WAL'); | ||
db2.prepare('CREATE TABLE entries (a TEXT, b INTEGER)').run(); | ||
}); | ||
function fillWall(count, expectation) { | ||
[db1, db2].forEach(function (db) { | ||
var size1, size2; | ||
for (var i=0; i<count; ++i) { | ||
size1 = fs.statSync(db.name + '-wal').size; | ||
db.prepare('INSERT INTO entries VALUES (?, ?)').run('bar', 999); | ||
size2 = fs.statSync(db.name + '-wal').size; | ||
expectation(size2, size1, db); | ||
} | ||
}); | ||
} | ||
describe('Database#checkpoint()', function () { | ||
describe('before a checkpoint', function () { | ||
it('every insert should increase the size of the WAL file', function () { | ||
var size1, size2; | ||
for (var i=0; i<10; ++i) { | ||
size1 = fs.statSync(db.name + '-wal').size; | ||
db.prepare('INSERT INTO entries VALUES (?, ?)').run('bar', 999); | ||
size2 = fs.statSync(db.name + '-wal').size; | ||
expect(size2).to.be.above(size1); | ||
} | ||
describe('when used without a specified database', function () { | ||
specify('every insert should increase the size of the WAL file', function () { | ||
fillWall(10, function (b, a) {expect(b).to.be.above(a);}); | ||
}); | ||
specify('inserts after a checkpoint should NOT increase the size of the WAL file', function () { | ||
db1.prepare('ATTACH \'' + db2.name + '\' AS foobar').run(); | ||
expect(db1.checkpoint()).to.deep.equal(db1); | ||
fillWall(10, function (b, a) {expect(b).to.equal(a);}); | ||
}); | ||
}); | ||
describe('after a checkpoint', function () { | ||
it('inserts should NOT increase the size of the WAL file', function () { | ||
expect(db.checkpoint()).to.equal(1); | ||
var size1, size2; | ||
for (var i=0; i<10; ++i) { | ||
size1 = fs.statSync(db.name + '-wal').size; | ||
db.prepare('INSERT INTO entries VALUES (?, ?)').run('bar', 999); | ||
size2 = fs.statSync(db.name + '-wal').size; | ||
expect(size2).to.be.equal(size1); | ||
} | ||
describe('when used on a specific database', function () { | ||
specify('every insert should increase the size of the WAL file', function () { | ||
db1.prepare('DETACH foobar').run(); | ||
db1.close(); | ||
db2.close(); | ||
db1 = new Database(db1.name); | ||
db2 = new Database(db2.name); | ||
db1.prepare('CREATE TABLE _unused (a TEXT, b INTEGER)').run(); | ||
db2.prepare('CREATE TABLE _unused (a TEXT, b INTEGER)').run(); | ||
fillWall(10, function (b, a) {expect(b).to.be.above(a);}); | ||
}); | ||
specify('inserts after a checkpoint should NOT increase the size of the WAL file', function () { | ||
db1.prepare('ATTACH \'' + db2.name + '\' AS bazqux').run(); | ||
expect(db1.checkpoint('bazqux')).to.equal(db1); | ||
fillWall(10, function (b, a, db) { | ||
if (db === db1) { | ||
expect(b).to.be.above(a); | ||
} else { | ||
expect(b).to.be.equal(a); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -7,2 +7,11 @@ var expect = require('chai').expect; | ||
db = new Database('temp/' + require('path').basename(__filename).split('.')[0] + '.db'); | ||
db.prepare('CREATE TABLE data (x)').run(); | ||
db.prepare('CREATE TABLE empty (x)').run(); | ||
db.prepare('INSERT INTO data VALUES (?)').run(3); | ||
db.prepare('INSERT INTO data VALUES (?)').run(5); | ||
db.prepare('INSERT INTO data VALUES (?)').run(7); | ||
db.prepare('INSERT INTO data VALUES (?)').run(11); | ||
db.prepare('INSERT INTO data VALUES (?)').run(13); | ||
db.prepare('INSERT INTO data VALUES (?)').run(17); | ||
db.prepare('INSERT INTO data VALUES (?)').run(19); | ||
}); | ||
@@ -18,3 +27,3 @@ | ||
describe('Database#register()', function () { | ||
it('should throw an exception if a function is not provided', function () { | ||
it('should throw if a function is not provided', function () { | ||
expect(function () {db.register()}).to.throw(TypeError); | ||
@@ -25,3 +34,3 @@ expect(function () {db.register(null)}).to.throw(TypeError); | ||
}); | ||
it('should throw an exception if the function name is empty', function () { | ||
it('should throw if the function name is empty', function () { | ||
expect(function () {db.register(function () {})}).to.throw(TypeError); | ||
@@ -40,19 +49,21 @@ }); | ||
// undefined is interpreted as null | ||
register(function b2(a, b) {}); | ||
register(function b2(a, b) {return null;}); | ||
register(function b3(a, b) {}); | ||
expect(exec('b2(?, ?)', 2, 10)).to.equal(null); | ||
expect(exec('b3(?, ?)', 2, 10)).to.equal(null); | ||
// buffers | ||
register(function b3(a) {return a;}); | ||
var buffer = exec('b3(?)', Buffer.alloc(8).fill(0xdd)); | ||
expect(buffer.equals(Buffer.alloc(8).fill(0xdd))).to.be.ok; | ||
register(function b4(a) {return a;}); | ||
var buffer = exec('b4(?)', bufferOfSize(8).fill(0xdd)); | ||
expect(buffer.equals(bufferOfSize(8).fill(0xdd))).to.be.ok; | ||
// zero arguments | ||
register(function b4() {return 12;}); | ||
expect(exec('b4()')).to.equal(12); | ||
register(function b5() {return 12;}); | ||
expect(exec('b5()')).to.equal(12); | ||
}); | ||
it('should have a strict number of arguments by default', function () { | ||
register(function c1(a, b) {}); | ||
expect(function () {exec('c1()');}).to.throw(Error); | ||
expect(function () {exec('c1(?)', 4);}).to.throw(Error); | ||
expect(function () {exec('c1(?, ?, ?)', 4, 8, 3);}).to.throw(Error); | ||
expect(function () {exec('c1()');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {exec('c1(?)', 4);}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {exec('c1(?, ?, ?)', 4, 8, 3);}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
exec('c1(?, ?)', 4, 8); | ||
@@ -65,3 +76,3 @@ }); | ||
expect(exec('d2(?, ?)', 2, 10)).to.equal(20); | ||
expect(function () {exec('sdnfjlsd(?, ?)', 2, 10);}).to.throw(Error); | ||
expect(function () {exec('sdnfjlsd(?, ?)', 2, 10);}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
}); | ||
@@ -77,3 +88,3 @@ it('should accept a "varargs" option', function () { | ||
}); | ||
it('should throw an exception if name is not a valid string', function () { | ||
it('should throw if name is not a valid string', function () { | ||
expect(function () {db.register({name: ''}, function () {})}).to.throw(TypeError); | ||
@@ -84,3 +95,3 @@ expect(function () {db.register({name: 123}, function () {})}).to.throw(TypeError); | ||
}); | ||
it('should throw an exception if function.length is not a positive integer', function () { | ||
it('should throw if function.length is not a positive integer', function () { | ||
function length(n, fn) { | ||
@@ -96,3 +107,3 @@ Object.defineProperty(fn, 'length', {value: n}); | ||
}); | ||
it('should throw an exception if function.length is larger than 127', function () { | ||
it('should throw if function.length is larger than 127', function () { | ||
function length(n, fn) { | ||
@@ -102,7 +113,7 @@ Object.defineProperty(fn, 'length', {value: n}); | ||
} | ||
expect(function () {db.register(length(128, function xc1() {}))}).to.throw(TypeError); | ||
expect(function () {db.register(length(0xe0000000f, function xc2() {}))}).to.throw(TypeError); | ||
expect(function () {db.register(length(128, function xc1() {}))}).to.throw(RangeError); | ||
expect(function () {db.register(length(0xe0000000f, function xc2() {}))}).to.throw(RangeError); | ||
db.register(length(127, function ya1() {})); | ||
}); | ||
it('should throw an exception if the database is busy', function () { | ||
it('should throw if the database is busy', function () { | ||
var ranOnce = false; | ||
@@ -131,5 +142,5 @@ db.prepare('SELECT 2').pluck().each(function (a) { | ||
}); | ||
it('should throw an exception if the function returns an invalid value', function () { | ||
it('should throw if the function returns an invalid value', function () { | ||
register(function h1(a) {return {};}); | ||
expect(function () {exec('h1(?)', 42);}).to.throw(Error); | ||
expect(function () {exec('h1(?)', 42);}).to.throw(TypeError); | ||
}); | ||
@@ -145,3 +156,3 @@ it('should propagate exceptions thrown in the registered function', function () { | ||
} | ||
throw new TypeError('Expected registered function to throw an exception.'); | ||
throw new TypeError('Expected registered function to throw an exception'); | ||
} | ||
@@ -156,4 +167,22 @@ expectError('i1', new TypeError('foobar')); | ||
}); | ||
it('should be able to register multiple functions with the same name', function () { | ||
register(function ia1() {return 0;}); | ||
register(function ia1(a) {return 1;}); | ||
register(function ia1(a, b) {return 2;}); | ||
register(function ia1(a, b, c) {return 3;}); | ||
register(function ia1(a, b, c, d) {return 4;}); | ||
expect(exec('ia1()')).to.equal(0); | ||
expect(exec('ia1(555)')).to.equal(1); | ||
expect(exec('ia1(555, 555)')).to.equal(2); | ||
expect(exec('ia1(555, 555, 555)')).to.equal(3); | ||
expect(exec('ia1(555, 555, 555, 555)')).to.equal(4); | ||
register(function ia1(a, b) {return 'foobar';}); | ||
expect(exec('ia1()')).to.equal(0); | ||
expect(exec('ia1(555)')).to.equal(1); | ||
expect(exec('ia1(555, 555)')).to.equal('foobar'); | ||
expect(exec('ia1(555, 555, 555)')).to.equal(3); | ||
expect(exec('ia1(555, 555, 555, 555)')).to.equal(4); | ||
}); | ||
it('should not be able to affect bound buffers mid-query', function () { | ||
var buffer = Buffer.alloc(1024 * 8).fill(0xbb); | ||
var buffer = bufferOfSize(1024 * 8).fill(0xbb); | ||
var ranOnce = false; | ||
@@ -166,3 +195,3 @@ register(function j1() { | ||
expect(ranOnce).to.be.true; | ||
expect(returned.equals(Buffer.alloc(1024 * 8).fill(0xbb))).to.be.ok; | ||
expect(returned.equals(bufferOfSize(1024 * 8).fill(0xbb))).to.be.ok; | ||
}); | ||
@@ -195,8 +224,288 @@ describe('should not affect external environment', function () { | ||
expect(ex.message).to.not.equal(err.message); | ||
expect(ex.message.indexOf('SQLite: ')).to.equal(0); | ||
expect(ex).to.be.an.instanceof(Database.SqliteError); | ||
return; | ||
} | ||
throw new TypeError('Expected the statement to throw an exception.'); | ||
throw new TypeError('Expected the statement to throw an exception'); | ||
}); | ||
}); | ||
describe('should be able to register aggregate functions', function () { | ||
describe('while registering', function () { | ||
it('should register the given generator function', function () { | ||
register(function* zb1() { | ||
yield function () {}; | ||
}); | ||
}); | ||
it('should throw if the yielded function.length is not a positive integer', function () { | ||
function length(n) { | ||
var fn = function () {}; | ||
Object.defineProperty(fn, 'length', {value: n}); | ||
return fn; | ||
} | ||
expect(function () {register(function* zc1() { | ||
yield length(-1); | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zc2() { | ||
yield length(1.2); | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zc3() { | ||
yield length(Infinity); | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zc4() { | ||
yield length(NaN); | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zc5() { | ||
yield length('2'); | ||
})}).to.throw(TypeError); | ||
}); | ||
it('should throw if the yielded function.length is larger than 127', function () { | ||
function length(n) { | ||
var fn = function () {}; | ||
Object.defineProperty(fn, 'length', {value: n}); | ||
return fn; | ||
} | ||
expect(function () {register(function* zd1() { | ||
yield length(128); | ||
})}).to.throw(RangeError); | ||
expect(function () {register(function* zd2() { | ||
yield length(0xe0000000f); | ||
})}).to.throw(RangeError); | ||
register(function* zd3() {yield length(127);}) | ||
}); | ||
it('should propagate exceptions thrown while getting function.length', function () { | ||
var err = new Error('foobar'); | ||
expect(function () { | ||
register(function* ze1() { | ||
var fn = function () {}; | ||
Object.defineProperty(fn, 'length', {get: function () { | ||
throw err; | ||
}}); | ||
yield fn; | ||
}); | ||
}).to.throw(err); | ||
}); | ||
it('should throw if the generator function never yields', function () { | ||
expect(function () {register(function* zf1() { | ||
// no yield | ||
})}).to.throw(TypeError); | ||
}); | ||
it('should throw if a non-function is yielded', function () { | ||
expect(function () {register(function* zf1() { | ||
yield; | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zf1() { | ||
yield 123; | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zf1() { | ||
yield 'foobar'; | ||
})}).to.throw(TypeError); | ||
expect(function () {register(function* zf1() { | ||
yield {length: 0, name: ''}; | ||
})}).to.throw(TypeError); | ||
}); | ||
it('should throw if the generator function yields twice', function () { | ||
expect(function () {register(function* zg1() { | ||
var fn = function () {}; | ||
yield fn; | ||
yield fn; | ||
})}).to.throw(TypeError); | ||
}); | ||
it('should propagate exceptions thrown before yielding', function () { | ||
var err = new Error('foobar'); | ||
expect(function () { | ||
register(function* zh1() { | ||
throw err; | ||
yield function () {}; | ||
}); | ||
}).to.throw(err); | ||
}); | ||
it('should propagate exceptions thrown after yielding', function () { | ||
var err = new Error('foobar'); | ||
expect(function () { | ||
register(function* zi1() { | ||
yield function () {}; | ||
throw err; | ||
}); | ||
}).to.throw(err); | ||
}); | ||
}); | ||
describe('before executing', function () { | ||
it('should throw if the generator function never yields', function () { | ||
var first = true; | ||
register(function* zj1() { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} | ||
}); | ||
expect(function () {exec('zj1(x) FROM data');}).to.throw(TypeError); | ||
}); | ||
it('should throw if a non-function is yielded', function () { | ||
function registerAggregate(name, value) { | ||
var first = true; | ||
register({name: name}, function* () { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} else { | ||
yield value; | ||
} | ||
}); | ||
} | ||
registerAggregate('zk1'); | ||
registerAggregate('zk2', 123); | ||
registerAggregate('zk3', 'foobar'); | ||
registerAggregate('zk4', {length: 0, name: ''}); | ||
registerAggregate('zk5', function (x) {}); | ||
expect(function () {exec('zk1(x) FROM data');}).to.throw(TypeError); | ||
expect(function () {exec('zk2(x) FROM data');}).to.throw(TypeError); | ||
expect(function () {exec('zk3(x) FROM data');}).to.throw(TypeError); | ||
expect(function () {exec('zk4(x) FROM data');}).to.throw(TypeError); | ||
exec('zk5(x) FROM data'); | ||
}); | ||
it('should throw if the generator function yields twice', function () { | ||
var first = true; | ||
register(function* zl1() { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} else { | ||
yield function (x) {}; | ||
yield function (x) {}; | ||
} | ||
}); | ||
expect(function () {exec('zl1(x) FROM data');}).to.throw(TypeError); | ||
}); | ||
it('should propagate exceptions thrown before yielding', function () { | ||
var first = true; | ||
var err = new Error('foobar'); | ||
register(function* zm1() { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} else { | ||
throw err; | ||
yield function (x) {}; | ||
} | ||
}); | ||
expect(function () {exec('zm1(x) FROM data');}).to.throw(err); | ||
}); | ||
it('should propagate exceptions thrown after yielding', function () { | ||
var first = true; | ||
var err = new Error('foobar'); | ||
register(function* zma1() { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} else { | ||
yield function (x) {}; | ||
throw err; | ||
} | ||
}); | ||
expect(function () {exec('zma1(x) FROM data');}).to.throw(err); | ||
}); | ||
it('should propagate exceptions thrown while getting function.length', function () { | ||
var first = true; | ||
var err = new Error('foobar'); | ||
register(function* zn1() { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} else { | ||
var fn = function (x) {}; | ||
Object.defineProperty(fn, 'length', {get: function () { | ||
throw err; | ||
}}); | ||
yield fn; | ||
} | ||
}); | ||
expect(function () {exec('zn1(x) FROM data');}).to.throw(err); | ||
}); | ||
it('should throw if the yielded function.length is inconsistent', function () { | ||
var first = true; | ||
register(function* zo1() { | ||
if (first) { | ||
first = false; | ||
yield function (x) {}; | ||
} else { | ||
yield function (x, y) {}; | ||
} | ||
}); | ||
expect(function () {exec('zo1(x) FROM data');}).to.throw(TypeError); | ||
}); | ||
}); | ||
describe('while executing', function () { | ||
it('should propagate exceptions thrown in the yielded callback', function () { | ||
var err = new Error('foobar'); | ||
register(function* zp1() { | ||
yield function (x) {throw err;}; | ||
}); | ||
expect(function () {exec('zp1(x) FROM data');}).to.throw(err); | ||
}); | ||
it('should throw if the generator function returns an invalid value', function () { | ||
var err = new Error('foobar'); | ||
register(function* zq1() {yield function (x) {}; return {};}); | ||
register(function* zq2() {yield function (x) {}; return 123;}); | ||
expect(function () {exec('zq1(x) FROM data');}).to.throw(TypeError); | ||
exec('zq2(x) FROM data'); | ||
}); | ||
it('should be invoked for each row', function () { | ||
register(function* zr1() { | ||
var result = 1; | ||
yield function (x) {result *= x;}; | ||
return result + 5; | ||
}); | ||
expect(exec('zr1(x) FROM data')).to.equal(4849850); | ||
}) | ||
it('should result in the correct value when no rows are passed through', function () { | ||
register(function* zra1() { | ||
var result = 5; | ||
yield function (x) {result = 999;}; | ||
return result + 2; | ||
}); | ||
expect(exec('zra1(x) FROM empty')).to.equal(7); | ||
}); | ||
it('should have a strict number of arguments by default', function () { | ||
register(function* zs1() { | ||
var result = 0; | ||
yield function (x, y) {result += x + y}; | ||
return result; | ||
}); | ||
expect(function () {exec('zs1() FROM data');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {exec('zs1(x) FROM data');}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(function () {exec('zs1(x, ?, ?) FROM data', 8, 3);}).to.throw(Database.SqliteError).with.property('code', 'SQLITE_ERROR'); | ||
expect(exec('zs1(x, ?) FROM data', 2)).to.equal(89); | ||
}); | ||
it('should accept a "varargs" option', function () { | ||
register({varargs: true}, function* zt1() { | ||
var result = 0; | ||
yield function () { | ||
result += [].slice.call(arguments).reduce(function (a, b) {return a + b;}, 0); | ||
}; | ||
return result; | ||
}); | ||
expect(exec('zt1() FROM data')).to.equal(0); | ||
expect(exec('zt1(x) FROM data')).to.equal(75); | ||
expect(exec('zt1(x, x) FROM data')).to.equal(150); | ||
expect(exec('zt1(x, ?, ?, ?, ?, ?, ?) FROM data', 2, 3, 4, 5, 6, 7)).to.equal(264); | ||
}); | ||
it('should result in the correct value when * is used as the argument', function () { | ||
register(function* zu1() { | ||
var result = 1; | ||
yield function () { | ||
expect(arguments.length).to.equal(0); | ||
result += 2; | ||
}; | ||
return result + 1000; | ||
}); | ||
expect(exec('zu1(*) FROM data')).to.equal(1015); | ||
expect(exec('zu1() FROM data')).to.equal(1015); | ||
expect(exec('zu1(*) FROM empty')).to.equal(1001); | ||
expect(exec('zu1() FROM empty')).to.equal(1001); | ||
}); | ||
}); | ||
}); | ||
}); | ||
function bufferOfSize(size) { | ||
return Buffer.alloc ? Buffer.alloc(+size) : new Buffer(+size); | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
2744890
2546
6
2
4
67
+ Addedinteger@^1.0.1
+ Addedlzz-gyp@^0.3.3
+ Addedinteger@1.0.7(transitive)
+ Addedlzz-gyp@0.3.5(transitive)
- Removednan@^2.5.1
- Removednan@2.22.0(transitive)