A common question with db.js is how to merge data from a remote store into the local store. When doing so you need to think about how you’re handling an add vs an update statement.
Say you have some records that you’re syncing between the two instances and they have a common key that you use to identify on both the client and the server. When a user hits the site you pull down the records and want to work out if they are to be inserted or just updated against what you already have.
Well db.js exposes two methods,
update which take an item and well, do what it sounds like. But this can make your code seem a bit confusing, do you need to perform a
get first and find out if the record exists, and if it does then do an
update otherwise do an
add? That’d make it quite intensive a process as you have two operations for every record.
I decided to crack open the IndexedDB spec and do some digging to see if I could work out the best way to go about this. The logical starting place for this is with the Object Store Storage Operation for you see there are two methods for adding items into an IndexedDB store, there is the
add method and there is the
So what’s the difference between the two? Well it comes down to point #4 of the Object Store Storage Operation:
If the no-overwrite flag was passed to these steps and is set, and a record already exists in store with its key equal to key, then this operation failed with a ConstraintError. Abort this algorithm without taking any further steps.
The difference is that
add sets the
no-overwrite flag to
true where as
put sets it to
false, meaning that if you provide a “new” item to
put it will perform an insert on the record.
Now let’s get back to db.js, how does this fit into the picture? Well with db.js I don’t have a
put method (at least not as of today), instead
put is what the
update method uses.
If you want to perform an add-or-update but don’t want to go through the overhead of doing a check if the record exists then you can just call the
update method on your db.js store. Although it probably makes sense to rename the
update method to
put so it’s more consistent with the IndexedDB API, maybe I’ll just backlog that one.