-
Notifications
You must be signed in to change notification settings - Fork 1
Running queries
Indexed-db.es6 comes with a built-in query engine allowing you to run complex queries on your database instead of having to resolve to using only the low-level APIs. The query engine uses a cost-based query optimizer to run the queries at the best possible performance.
The database
variable in all code examples is an opened database connection created using the DBFactory.open(...)
method as described in the Defining database schema page.
Probably the easiest way to fetch records usign a query is as follows:
database.getObjectStore("fooBar").query().then((records) => {
// do something with the array of fetched records
// note that the out-of-line primary keys cannot be accessed like this
}).catch((error) => {
// something went wrong, see the description of the error for
// details
})
The query can be filtered (filtering is, due to its many options, described on a separate page here):
database.getObjectStore("fooBar").query(someFilter).then((records) => {
// do something with the records
})
...and sorted:
database.getObjectStore("fooBar").query(someFilter, [
"mainCategory",
"!meta.lastUpdate"
]).then((records) => {
// do something with the records
})
The !
prefix is used to reverse the order of the records. The sorting can also be specified as a string if the records should be sorted by a single field path. Another option for sorting the records is providing a comparator function compatible with the Array.prototype.sort()
method:
database.getObjectStore("fooBar").query(null, (record1, record2) => {
return record2.age - record1.age
}).then((records) => {
// do something with the records
})
Here we used null
to specify that no filtering should be applied. Notice that the comparator cannot access out-of-line primary keys.
Finally, there are some short-hands for sorting the records by their primary keys:
-
CursorDirection.NEXT
orNEXT
from theobject-store/CursorDirection
module,null
or "next" for the ascending order. -
CursorDirection.PREVIOUS
orPREVIOUS
from theobject-store/CursorDirection
module, "prev" or "previous" for the descending order.
Note that because of these shorthands you need to wrap the sorting field path in an array if you need to sort by the next
, prev
or previous
field of your records, like this:
database.getObjectStore("fooBar").query(
null,
["next"]
).then((records) => {
// records will be sorted by the field named "next"
})
Last but not least, you can specify the starting (0-based) offset of the first record to be matched by the query:
database.getObjectStore("fooBar").query(
null,
null,
5
).then((records) => {
// the first 5 records have been skipped
})
...and you can specify the maximum number of records the query should match:
database.getObjectStore("fooBar").query(
null,
null,
0,
3
).then((records) => {
// at most 3 records will be in the records array
})
Queries can also be used to modify multiple records easily. Update queries can only be executed within a read-write transaction. An example update query is show below:
database.runTransaction("fooBar", (fooBar) => {
return fooBar.updateQuery()((record, primaryKey) => {
// modify the record here
return modifiedRecord
})
}).then((recordCount) => {
// the recordCount is the number of modified records
}).catch((error) => {
// something went wrong, check the error details
})
Notice that the updateQuery()
method returns a function that accepts the record modification callback and then executes the query. This allows us to skip the default values of parameters.
Just like with the record fetching queries, it is possible to specify filtering, sorting, starting record offset and the maximum number of records to match:
database.runTransaction("fooBar", (fooBar) => {
return fooBar.updateQuery(
filter,
sorting,
startOffset,
maxRecords
)((record, primaryKey) => {
// modify the record here
return modifiedRecord
})
})
The default values of the arguments for filtering, sorting, and limiting the query are the same as in case of the query()
method.
Finally, queries can be used to delete records in read-write transactions:
database.runTransaction("fooBar", (fooBar) => {
return fooBar.deleteQuery(
filter,
sorting,
startOffset,
maxRecords
)
}).then((recordCount) => {
// the recordCount is the number of modified records
}).catch((error) => {
// something went wrong, check the error details
})
All of the arguments of the deleteQuery()
method are optional. The default values of the arguments for filtering, sorting, and limiting the query are the same as in case of the query()
method.