Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexed DB cursor ranges on multiple properties

I have a composite index of two properties on an indexeddb objectstore and wish to retrieve a cursor based on the range of both of these properties.

Here's an example object in the store :

{species: 'Oak',xcoord: 123456, ycoord: 654321}

and index :

treeStore.createIndex("treelocation", ["xcoord","ycoord"], { unique: false });

The index creation is succesful and I can see it in the Chrome developer tools, however now I'd like to open a cursor with a keyrange on both the x and y co-ordinates (which will be the extent of a map).

Searching online I can't see how to do this, and opening an index with an array of key ranges doesn't seem to work.

like image 828
kes Avatar asked May 13 '13 12:05

kes


People also ask

What is cursor in IndexedDB?

The IDBCursor interface of the IndexedDB API represents a cursor for traversing or iterating over multiple records in a database. The cursor has a source that indicates which index or object store it is iterating over.

Is IndexedDB asynchronous?

Operations performed using IndexedDB are done asynchronously, so as not to block applications.

Is IndexedDB a relational database?

IndexedDB is not a relational database with tables representing collections of rows and columns. This important and fundamental difference affects the way you design and build your applications.


1 Answers

The range suggestion is part of the answer, but even with array keys it really is just a 1-dimensional range, not a 2- (or N-) dimensional selection of the data. With your current schema you'll need to do something like this:

index.openCursor([lowX, lowY], [highX, highY]).onsuccess = function(e) {
    var cursor = e.target.result;
    if (!cursor) return; // done!

    var x = cursor.key[0], y = cursor.key[1];
    // assert(lowX <= x && x <= highX);
    if (y < lowY) {
        cursor.continue([x, lowY]);
    } else if (y > highY) {
        cursor.continue([x + 1, lowY]);
    } else {
        processRecord(cursor.value); // we got one!
        cursor.continue();
    }
};

(if coordinates are not integral, replace + 1 with an appropriate epsilon)

I've posted an example of a generalized solution to:

https://gist.github.com/inexorabletash/704e9688f99ac12dd336

like image 86
Joshua Bell Avatar answered Oct 26 '22 22:10

Joshua Bell