Skip to content

Commit

Permalink
Added default options to createIndex function.
Browse files Browse the repository at this point in the history
  • Loading branch information
Parashuram committed Feb 24, 2012
1 parent 3f52040 commit d4e70b1
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 20 deletions.
23 changes: 16 additions & 7 deletions README.md
@@ -1,13 +1,20 @@
Jquery Plugin for the IndexedDB API
===================================

Summary
-------
IndexedDB Jquery plugin demo - http://nparashuram.com/trialtool/index.html#example=/IndexedDB/jquery/trialtool.html

Background
-----------
The IndexedDB API is in its draft state but is already available in Firefox 4 and Chrome 12 Canary Builds. Internet Explorer also has a version of it on their HTML5 prototypes site. In my previous posts, I have also written about IndexedDB API examples using TrialTool.

Problem
--------
I wrote a couple of "non-production" applications and noticed that I was frequently copying non-application-logic, IndexedDB-related code across applications. Should that code be a part of a library? In my opinion, the amount of boiler plate code written to perform simple tasks like persisting or fetching data is not little.

Code
----
A typical operation using the IndexedDB API would involve using the request model, creating transactions, checking for existence of object store using error responses and exceptions and then finally getting to the part where the data is actually iterated over.

var request = window.indexedDB.open("BookShop-1");
Expand All @@ -28,22 +35,24 @@ A typical operation using the IndexedDB API would involve using the request mode
The above code would increase if objects have to be created with version transaction, and error conditions are to be added.

Solution
--------
The IndexedDB Jquery plugin is an attempt to reduce this boiler plate code in addition to bring back concepts like method chaining and Deferred calls.

The philosophy followed in the library is the same as the $.ajax() call that is more than just a wrapper over the XMLHTTPRequest object.
The philosophy followed in the library is the same as the `$.ajax()` call that is more than just a wrapper over the XMLHTTPRequest object.
Some Jquery goodness that I wanted while I designed the API include

Method chaining, access to most probable next operation in a chain. For example, once an objectStore is referenced, the next operations usually are CRUD, cursors or indexes. These operations should be available in the chain.
APIs for most common functions. For example, most people would not want to care about transactions. They would simply like transactions to be implicit and hence, the API opens a READ_WRITE transaction. Alternatively, the user can also explicitly open transactions and use them.
Since the IndexedDB API is an asynchronous API, use of Deferreds() for completion. This model is much more familiar than the request and request.result model exposed in IndexedDB API.
Default error handling, taking advantage of error event propagation in IndexedDB. Error cases are not common and should not be required at every step. The promises in Deferreds() are easier to handle errors.
Falling back on smart defaults. For example, when a user accesses an object store and it does no exist, they would probably want to create on a version change transaction. This is done in the object store call by default. However, the user can explicitly specify that the call should fail if the objectStore does not exist.
1. Method chaining, access to most probable next operation in a chain. For example, once an objectStore is referenced, the next operations usually are CRUD, cursors or indexes. These operations should be available in the chain.
2. APIs for most common functions. For example, most people would not want to care about transactions. They would simply like transactions to be implicit and hence, the API opens a READ_WRITE transaction. Alternatively, the user can also explicitly open transactions and use them.
3. Since the IndexedDB API is an asynchronous API, use of `Deferreds()` for completion. This model is much more familiar than the request and request.result model exposed in IndexedDB API.
4. Default error handling, taking advantage of error event propagation in IndexedDB. Error cases are not common and should not be required at every step. The promises in `Deferreds()` are easier to handle errors.
5. Falling back on smart defaults. For example, when a user accesses an object store and it does no exist, they would probably want to create on a version change transaction. This is done in the object store call by default. However, the user can explicitly specify that the call should fail if the objectStore does not exist.

The equivalent code for the snippet above looks something like this

$.indexeddb("BookShop-1").objectStore("BookList").openCursor().each(write);
$.indexeddb("BookShop-1").objectStore("BookList").openCursor().each(write);

Code and Demo
--------------
The library is currently hosted here on GitHub and the examples illustrating the API are available at http://nparashuram.com/trialtool/index.html#example=/IndexedDB/jquery/trialtool.html.

Watch out this space for more updates on my experiments with IndexedDB.
8 changes: 7 additions & 1 deletion docs/README.md
@@ -1 +1,7 @@
Documentation for the IndexedDB APIs will go here
Jquery-IndexedDB API Reference
===============================

$.indexedDB
-----------


52 changes: 52 additions & 0 deletions example/index.html
@@ -0,0 +1,52 @@
<!doctype html>
<html>
<head>
<title>A self contained example for the Jquery-IndexedDB plugin</title>
</head>
<body>
<h1>Jquery IndexedDB API example</h1>
<div id = "controls">
<a href = "javascript:loaddata()">Load Data from Database</a>
<a href = "javascript:()"></a>
</div>
<table id = "content">
<tr class = "sample">
<td class = "key">
</td>
<td class = "value">
</td>
</tr>
</table>
<div id = "console">
</div>
<!-- Main IndexedDB Example functions -->
<script type = "text/javascript">
var key = null;
var dbConnection = $.indexedDB("ECommerceSite", {
"schema": {
"1": function(versionTransaction){
var catalog = versionTransaction.createObjectStore("catalog", {
"keyPath": "itemId"
});
catalog.createIndex("")
}
}
});

function loaddata(){
dbConnection.objectStore("objectStore1").each(function(elem){
var row = document.getElementsByClassName("sample")[0].innerHTML;
});
}
</script>
<!-- End of Main IndexedDB Example functions -->
<!-- Helper functions -->
<script tyoe = "text/javascript">
var console = {
"log": function(msg){

}
};
</script>
</body>
</html>
9 changes: 8 additions & 1 deletion jquery.indexeddb.new.js
Expand Up @@ -114,7 +114,14 @@
});
};

result.createIndex = function(prop, indexName, options){
result.createIndex = function(prop, options, indexName){
if (arguments.length === 2 && typeof options === "string") {
indexName = arguments[1]
options = null;
}
if (!indexName) {
indexName = prop;
}
return wrap.index(function(){
return idbObjectStore.createIndex(indexName, prop, options);
});
Expand Down
13 changes: 8 additions & 5 deletions package.json
Expand Up @@ -5,18 +5,21 @@
"description" : "An easy to use Jquery API over the HTML5 IndexedDB API with smart defaults and support for promises, ",
"keywords" : "IndexedDB, storage, database, data",
"homepage" : "http://nparashuram.com/jquery-indexeddb/",
"docs" : "",
"demo" : "",
"docs" : "https://github.com/axemclion/jquery-indexeddb/blob/gh-pages/docs/README.md",
"demo" : "http://nparashuram.com/jquery-indexeddb/example/index.html",
"files" : "jquery.indexeddb.js"
"author" : {
"name" : "Parashuram Narasimhan",
"email" : "contact@nparashuram.com",
"url" : "http://nparashuram.com"
},
"licenses": [{
"type": "GPLv2",
"url": "http://www.example.com/licenses/gpl.html"
}],
"type": "GPLv2",
"url": "http://www.gnu.org/copyleft/gpl.html"
}, {
"type" : "Apache License, Version 2.0",
"url" : "http://www.apache.org/licenses/LICENSE-2.0"
}],
"dependencies" : {
"jquery" : ">=1.5.x"
}
Expand Down
12 changes: 6 additions & 6 deletions test/index.html
Expand Up @@ -89,7 +89,7 @@
versionTransaction.objectStore(DB.OBJECT_STORE_1).each(function(elem){
objectStore2.add(elem.value);
});
versionTransaction.objectStore(DB.OBJECT_STORE_1).createIndex("Int", DB.INDEX1_ON_OBJECT_STORE_1);
versionTransaction.objectStore(DB.OBJECT_STORE_1).createIndex("Int");
},
"3": function(versionTransaction){
versionTransaction.deleteObjectStore(DB.OBJECT_STORE_3);
Expand Down Expand Up @@ -390,15 +390,15 @@
var key = sample.integer();
var value = sample.obj();
var objectStore = $.indexedDB(DB.NAME).objectStore(DB.OBJECT_STORE_1);
objectStore.index(DB.INDEX1_ON_OBJECT_STORE_1).each(function(elem){
objectStore.index("Int").each(function(elem){
ok(true, "Iterating on " + elem.key + ":" + elem.value);
start();
stop();
}).then(function(res, e){
ok(true, "Index Iteration completed");
start();
}, function(err, e){
ok(true, "Index Iteration NOT completed");
ok(false, "Index Iteration NOT completed");
_("Index Iteration NOT completed");
start();
});
Expand All @@ -407,16 +407,16 @@
asyncTest("Index iteration with keyCursor", function(){
var key = sample.integer();
var value = sample.obj();
var objectStore = $.indexedDB(DB.NAME).objectStore(DB.OBJECT_STORE_1);
objectStore.index(DB.INDEX1_ON_OBJECT_STORE_1).eachKey(function(elem){
var objectStore = $.indexedDB(DB.NAME).objectStore(DB.OBJECT_STORE_2);
objectStore.index(DB.INDEX1_ON_OBJECT_STORE_2).eachKey(function(elem){
ok(true, "Iterating on " + elem.key + ":" + elem.value);
start();
stop();
}).then(function(res, e){
ok(true, "Index Iteration completed");
start();
}, function(err, e){
ok(true, "Index Iteration NOT completed");
ok(false, "Index Iteration NOT completed");
_("Index Iteration NOT completed");
start();
});
Expand Down

0 comments on commit d4e70b1

Please sign in to comment.