diff --git a/CHANGES.md b/CHANGES.md index 8d723cf..2023641 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,11 +45,12 @@ - Validation: Tighter checking on argument to `modify` method (ensure is an object) and on index creation objects (issue #149) - Docs: Badges, CHANGES, clarify `add`, `update`, `delete`, `filter` and - `modify` methods and `schema` property behavior + `modify` methods, `schema` property behavior, and querying with ranges. - Testing improvements: Travis/Karma/PhantomJS/Grunt (including allowing override of Saucekey env var., overcoming PhantomJS issues with workers, testing `versionchange` events in another window, testing bad args, - ensure Firefox is passing as well as Chrome) + testing array and nested `keyPath`'s and indexes, ensure Firefox is + passing as well as Chrome) ## 0.14.0 (March 8, 2016) diff --git a/README.md b/README.md index 56e8b17..dc119db 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,40 @@ server.people.query('answer') }); ``` +Note that IndexedDB allows you to use array keys within ranges (and +other methods where a key is accepted) as long as you have created +your store with an array `keyPath` (and optionally with an index +`keyPath`). + +```js + +// The definition: +schema: { + people: { + key: { + keyPath: ['lastName', 'firstName'] + }, + indexes: { + name: { + keyPath: ['lastName', 'firstName'] + }, + lastName: {}, + firstName: {} + } + } +} + +// ...elsewhere... + +// The query: +s.test.query('name') + .only(['Zamir', 'Brett']) + .execute() + .then(function (results) { + // do something with the results + }); +``` + ##### Limiting cursor range Unlike key ranges which filter by the range of present values, diff --git a/tests/specs/bad-args.js b/tests/specs/bad-args.js index 81e0573..66a2ac9 100644 --- a/tests/specs/bad-args.js +++ b/tests/specs/bad-args.js @@ -76,6 +76,30 @@ done(); }); }); + it('should catch when keyPath is an array and multiEntry=true', function (done) { + db.open({ + server: this.dbName, + version: 2, + schema: { + test: { + key: { + keyPath: ['lastName', 'firstName'] + }, + indexes: { + name: { + keyPath: ['lastName', 'firstName'], + multiEntry: true + }, + lastName: {}, + firstName: {} + } + } + } + }).catch(function (err) { + expect(err.name).to.equal('InvalidAccessError'); + done(); + }); + }); }); describe('open: createSchema', function () { diff --git a/tests/specs/indexes.js b/tests/specs/indexes.js index ac87653..91fa0f3 100644 --- a/tests/specs/indexes.js +++ b/tests/specs/indexes.js @@ -70,6 +70,78 @@ }); }); + it('should allow defining (and querying) array keyPaths and multi-segment indexes', function (done) { + db.open({ + server: this.dbName, + version: 1, + schema: { + test: { + key: { + keyPath: ['lastName', 'firstName'] + }, + indexes: { + name: { + keyPath: ['lastName', 'firstName'] + }, + lastName: {}, + firstName: {} + } + } + } + }).then(function (s) { + s.test.add( + {lastName: 'Zamir', firstName: 'Brett'}, + {lastName: 'Favre', firstName: 'Brett'}, + {lastName: 'Brett', firstName: 'George'}, + {lastName: 'Powell', firstName: 'Aaron'} + ).then(function () { + return s.test.query() + .only(['Zamir', 'Brett']) + .execute(); + }).then(function (results) { + expect(results[0].lastName).to.equal('Zamir'); + expect(results.length).to.equal(1); + s.close(); + done(); + }); + }); + }); + + it('should allow defining (and querying) nested (dot-separated) keyPaths and indexes', function (done) { + db.open({ + server: this.dbName, + version: 1, + schema: { + test: { + key: { + keyPath: 'person.name.lastName' + }, + indexes: { + personName: { + keyPath: 'person.name.lastName' + } + } + } + } + }).then(function (s) { + s.test.add( + {person: {name: {lastName: 'Zamir', firstName: 'Brett'}}}, + {person: {name: {lastName: 'Favre', firstName: 'Brett'}}}, + {person: {name: {lastName: 'Brett', firstName: 'George'}}}, + {person: {name: {lastName: 'Powell', firstName: 'Aaron'}}} + ).then(function () { + return s.test.query('personName') + .only('Zamir') + .execute(); + }).then(function (results) { + expect(results.length).to.equal(1); + expect(results[0].person.name.lastName).to.equal('Zamir'); + s.close(); + done(); + }); + }); + }); + it('should allow adding indexes to an existing object store', function (done) { var spec = this; db.open({ diff --git a/tests/specs/query.js b/tests/specs/query.js index adadb1b..c944b6c 100644 --- a/tests/specs/query.js +++ b/tests/specs/query.js @@ -762,7 +762,14 @@ age: 40, tags: ['one', 'two', 'three', 'four'] }; - spec.server.add('test', item1, item2, item3).then(function () { + var item4 = { + id: 4, + firstName: 'Brett', + lastName: 'Zamir', + age: 43, + tags: ['two', 'three', 'four'] + }; + spec.server.add('test', item1, item2, item3, item4).then(function () { done(); }); }); @@ -800,7 +807,7 @@ .all() .execute() .then(function (data) { - expect(data.length).to.equal(10); + expect(data.length).to.equal(13); done(); }); });