Skip to content

Commit

Permalink
Allow empty string index;
Browse files Browse the repository at this point in the history
reject cursor.update errors (and test);
const/let grouping;
validate limit() arguments (and test);
add tests for bad query indexes, bad ranges with other cursor types;
move query tests to that section
  • Loading branch information
brettz9 committed Mar 27, 2016
1 parent 5c65252 commit 699e9db
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 61 deletions.
6 changes: 4 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
- Deprecated: on `schema.indexes`, in place of the index `key` property,
`keyPath` should be used.
- API addition: Add Server aliases, `put` and `delete`.
- Fix: Ensure there is a promise rejection for a bad schema callback or
bad IDBKeyRange-related call.
- Fix: Ensure limit() arguments are numeric
- Fix: Ensure there is a promise rejection for a bad schema callback,
bad IDBKeyRange-related call, or bad `modify` result;.
- Fix: Error reporting with `Server.query().range()`.
- Fix: Actually implement documented chaining of (short) event handlers
- Fix: Allow empty string index in `Server.query()`.
- Validation: Tighter checking on argument to `modify` method
- Docs: Badges, CHANGES, clarify `delete` behavior
- Testing improvements: Travis/Karma/PhantomJS/Grunt (including allowing
Expand Down
83 changes: 44 additions & 39 deletions dist/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
reject(e);
return;
}
filters = filters || [];
limitRange = limitRange || null;

var results = [];
var counter = 0;
var indexArgs = [keyRange];
Expand All @@ -109,10 +112,8 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
};

var store = transaction.objectStore(table); // if bad, db.transaction will reject first
var index = indexName ? store.index(indexName) : store;
var index = typeof indexName === 'string' ? store.index(indexName) : store;

limitRange = limitRange || null;
filters = filters || [];
if (cursorType !== 'count') {
indexArgs.push(direction || 'next');
}
Expand All @@ -133,67 +134,68 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
};

index[cursorType].apply(index, indexArgs).onsuccess = function (e) {
// indexArgs are already validated
var cursor = e.target.result;
if (typeof cursor === 'number') {
results = cursor;
} else if (cursor) {
if (limitRange !== null && limitRange[0] > counter) {
counter = limitRange[0];
cursor.advance(limitRange[0]);
cursor.advance(limitRange[0]); // Will throw on 0, but condition above prevents since counter always 0+
} else if (limitRange !== null && counter >= limitRange[0] + limitRange[1]) {
// Out of limit range... skip
} else {
var _ret = function () {
var matchFilter = true;
var result = 'value' in cursor ? cursor.value : cursor.key;

filters.forEach(function (filter) {
if (!filter || !filter.length) {
// Invalid filter do nothing
} else if (filter.length === 2) {
matchFilter = matchFilter && result[filter[0]] === filter[1];
} else {
matchFilter = matchFilter && filter[0](result);
// Out of limit range... skip
} else {
var _ret = function () {
var matchFilter = true;
var result = 'value' in cursor ? cursor.value : cursor.key;

filters.forEach(function (filter) {
if (!filter || !filter.length) {
// Invalid filter do nothing
} else if (filter.length === 2) {
matchFilter = matchFilter && result[filter[0]] === filter[1];
} else {
matchFilter = matchFilter && filter[0](result);
}
});

if (matchFilter) {
counter++;
// If we're doing a modify, run it now
if (modifyObj) {
try {
result = modifyRecord(result);
cursor.update(result); // `result` should only be a "structured clone"-able object
} catch (err) {
reject(err);
return {
v: void 0
};
}
}
});

if (matchFilter) {
counter++;
// If we're doing a modify, run it now
if (modifyObj) {
try {
result = modifyRecord(result);
results.push(mapper(result));
} catch (err) {
reject(err);
return {
v: void 0
};
}
cursor.update(result);
}
try {
results.push(mapper(result));
} catch (err) {
reject(err);
return {
v: void 0
};
}
}
cursor.continue();
}();
cursor.continue();
}();

if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
}
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
}
}
};
});
};

var Query = function Query(type, args, queuedError) {
var filters = [];
var direction = 'next';
var cursorType = 'openCursor';
var filters = [];
var limitRange = null;
var mapper = defaultMapper;
var unique = false;
Expand All @@ -212,6 +214,9 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
}

limitRange = args.slice(0, 2);
error = limitRange.some(function (val) {
return typeof val !== 'number';
}) ? new Error('limit() arguments must be numeric') : error;
if (limitRange.length === 1) {
limitRange.unshift(0);
}
Expand Down
2 changes: 1 addition & 1 deletion dist/db.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/db.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/db.min.js.map

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions src/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
reject(e);
return;
}
filters = filters || [];
limitRange = limitRange || null;

let results = [];
let counter = 0;
const indexArgs = [keyRange];
Expand All @@ -82,10 +85,8 @@
transaction.onabort = e => reject(e);

const store = transaction.objectStore(table); // if bad, db.transaction will reject first
const index = indexName ? store.index(indexName) : store;
const index = typeof indexName === 'string' ? store.index(indexName) : store;

limitRange = limitRange || null;
filters = filters || [];
if (cursorType !== 'count') {
indexArgs.push(direction || 'next');
}
Expand All @@ -103,14 +104,14 @@
return record;
};

index[cursorType](...indexArgs).onsuccess = function (e) {
index[cursorType](...indexArgs).onsuccess = function (e) { // indexArgs are already validated
const cursor = e.target.result;
if (typeof cursor === 'number') {
results = cursor;
} else if (cursor) {
if (limitRange !== null && limitRange[0] > counter) {
counter = limitRange[0];
cursor.advance(limitRange[0]);
cursor.advance(limitRange[0]); // Will throw on 0, but condition above prevents since counter always 0+
} else if (limitRange !== null && counter >= (limitRange[0] + limitRange[1])) {
// Out of limit range... skip
} else {
Expand All @@ -133,11 +134,11 @@
if (modifyObj) {
try {
result = modifyRecord(result);
cursor.update(result); // `result` should only be a "structured clone"-able object
} catch (err) {
reject(err);
return;
}
cursor.update(result);
}
try {
results.push(mapper(result));
Expand All @@ -154,13 +155,13 @@
};

const Query = function (type, args, queuedError) {
const filters = [];
let direction = 'next';
let cursorType = 'openCursor';
const filters = [];
let limitRange = null;
let mapper = defaultMapper;
let unique = false;
const error = preexistingError || queuedError;
let error = preexistingError || queuedError;

const execute = function () {
if (error) {
Expand All @@ -171,6 +172,7 @@

const limit = function (...args) {
limitRange = args.slice(0, 2);
error = limitRange.some(val => typeof val !== 'number') ? new Error('limit() arguments must be numeric') : error;
if (limitRange.length === 1) {
limitRange.unshift(0);
}
Expand Down
59 changes: 50 additions & 9 deletions tests/specs/bad-args.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,6 @@
}).catch(function (err) {
expect(err.message).to.have.string('is not a valid key');
ct++;
return s.names.query().range({badKey: ''}).execute();
}).catch(function (err) {
expect(err.message).to.have.string('is not a valid key');
ct++;
return s.names.query().only(null).execute();
}).catch(function (err) {
expect(err.name).to.equal('DataError');
ct++;
return s.names.delete({badKey: ''});
}).catch(function (err) {
expect(err.name).to.equal('DataError');
Expand All @@ -229,7 +221,7 @@
return s.names.update({key: {badKey: ''}, item: item});
}).catch(function (err) {
expect(err.name).to.equal('DataError');
expect(ct).to.equal(6);
expect(ct).to.equal(4);
s.close();
done();
});
Expand Down Expand Up @@ -301,6 +293,55 @@
});
});
});
it('should catch bad indexes', function (done) {
db.open({server: this.dbName}).then(function (s) {
s.names.query('nonexistentIndex').all().execute().catch(function (err) {
expect(err.name).to.equal('NotFoundError');
done();
});
});
});
it('should catch bad limit arguments', function (done) {
db.open({server: this.dbName}).then(function (s) {
s.names.query().all().limit('bad', 'limit', 'args').execute().catch(function (err) {
expect(err.message).to.equal('limit() arguments must be numeric');
done();
});
});
});
it('should catch bad modify() arguments', function (done) {
db.open({server: this.dbName}).then(function (s) {
s.names.query().all().modify({badModifier: function () {
return function badModifiedResult () {};
}}).execute().catch(function (err) {
expect(err.name).to.equal('DataCloneError');
done();
});
});
});
it('should catch bad range keys (on cursor)', function (done) {
var ct = 0;
db.open({server: this.dbName}).then(function (s) {
s.names.query().range({badKey: ''}).execute().catch(function (err) {
expect(err.message).to.have.string('is not a valid key');
ct++;
return s.names.query().only(null).execute();
}).catch(function (err) {
expect(err.name).to.equal('DataError');
ct++;
return s.names.query().only(null).keys().execute();
}).catch(function (err) {
expect(err.name).to.equal('DataError');
ct++;
return s.names.query().only(null).count().execute();
}).catch(function (err) {
expect(err.name).to.equal('DataError');
expect(ct).to.equal(3);
s.close();
done();
});
});
});
});

describe('delete', function () {
Expand Down

0 comments on commit 699e9db

Please sign in to comment.