axemclion / jquery-indexeddb

An IndexedDB Plugin for Jquery.
Other
195 stars 70 forks source link

Provide getAll method for objectStore and index #9

Closed puppe closed 12 years ago

puppe commented 12 years ago

I think it would be really useful, if there was a straight-forward way to get an array of all the items in an objectStore. Here is the interface I have in mind:

var getAllPromise = objectStore.getAll(/*Optional*/ range, /*Optional*/direction);

getAllPromise.done(function(allItems, event){
  allItems; // Array of all the items in the objectStore (that are withing range)
  event ; // Success event
}

getAllPromise.fail(function(error, event){
  error; // Error during iteration
  event; // Error event, can be exception or event
}

And here is a "static" implementation of it:

function getAll(iterable, range, direction){
  var allItems = [];
  var defer = $.Deferred();
  iterable.each(function(item){
    allItems.push(item.value);
  }, range, direction).then(function(result, event){
    defer.resolve(allItems, event);
  }, function(error, event){
    defer.reject(error, event);
  });
  return defer.promise();
}

I tried to implement this (in an object-oriented way) into jquery-indexeddb myself. But I could not quite figure out where it would need to go.

axemclion commented 12 years ago

Can you explain your implementation in more detail ? I presume that getAll would be on an objectStore. Also, is getAll(iterable), not similar to objectStore.each(iterable) ? The plugin already has an objectStore.each.

puppe commented 12 years ago

Yes, getAll would be a method on an objectStore (or an index).

By iterable I mean an objectStore or an index, because they are iterable (via their each method).

With the above "static" implementation you can do this

var objectStore = $.indexedDB("database_name").objectStore("objectStoreName");

getAll(objectStore).done(function(allItems) {
    // do something with allItems
})

(At least I hope so, because a few days ago I did not know anything about indexeddb or jquery promises)

But I would actually like to be able to do that

var objectStore = $.indexedDB("database_name").objectStore("objectStoreName");

objectStore.getAll().done(function(allItems) {
    // do something with allItems
})
axemclion commented 12 years ago

Not sure if getting all the data from the database into one single array would be scalable - with large data, I tested that the memory consumption grows a lot. Is there a specific use case that you would like to address where the each method does not work?

An alternate implementation could be something like objectStore("objectStoreName").getItem(item_index) which returns a promise or can take a second callback argument - this would still get you one item at a time, using cursors. Will that work?

puppe commented 12 years ago

I am trying to build a todo app and I don't think I will have to handle large data. I want to separate the code that accesses the db (or a server) from the rest of my application. It makes the interface to the data storage simpler, if I just return (a promise of) an array. So I often push all tasks or projects (in a certain range) into one array anyway, in order to pass that to more front facing code. That is why I think it would be convenient for me and other people, if there was a getAll method. I got the idea from Mozilla: https://developer.mozilla.org/en-US/docs/IndexedDB/Using_IndexedDB#Using_a_cursor.

axemclion commented 12 years ago

Can you add this getAll method and send me a pull request ? I could merge it after that.

axemclion commented 12 years ago

Closing this issue, waiting for a pull request from you.