Well, things are moving fast… We have now a new version for handling updating schema in IndexedDB. As you can see both MDN (mozilla) and Chrome/Chromium are aligned with the new way.
Here is a short example that show you the new way to work with upgrades to your schema:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <script> | |
| var indexedDB = window.indexedDB || window.webkitIndexedDB | |
| || window.mozIndexedDB || window.msIndexedDB; | |
| var request = indexedDB.open("testUpgrade",1); | |
| var customerData=[ | |
| {tel:"540-343-3334", name:"Monk", age:35, email:"mock@example.com"}, | |
| {tel:"650-450-5555", name:"Jack", age:32, email:"jack-2@example.com"} | |
| ]; | |
| request.onerror = function(e){ | |
| console.log("Oppss… we got into problems and errors. e:" + e); | |
| }; | |
| request.onupgradeneeded = function(event) { | |
| console.log("UPGRADE our nice example DB") ; | |
| var objectStore = db.createObjectStore("customers",{keyPath:"tel"}); | |
| objectStore.createIndex("name","name",{unique:false}); | |
| objectStore.createIndex("email","email",{unique:true}); | |
| for(var i in customerData){ | |
| objectStore.add(customerData[i]); | |
| } | |
| }; | |
| request.onsuccess = function(e) { | |
| console.log("life is good with indexedDB e:" + e) ; | |
| }; | |
| </script> | |
| </head> | |
| </html> |
The full example I have on github that show the differences between WebSQL and indexedDB still uses the setVersion syntax. However, in Firefox 10 (and in Chrome 21) you should change your code to work with the new API. Good luck!
=====
[Update Sep 2012]
In case you wish to see a code that will work fine both on Chrome (that still need to update according to the spec on onupgrade) and Firefox you can check this example of jQuery mobile and indexedDB mobile app:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <meta name="description" content="Short example on using indexedDB with jquery mobile – last updated: May 2012"> | |
| <meta name="author" content="Ido Green"> | |
| <title>IndexedDB with JQM</title> | |
| <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" /> | |
| <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> | |
| <script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script> | |
| <script> | |
| var dbName = "jqm-todo"; | |
| var dbVersion = 1.0; | |
| var todoDB = {}; | |
| var indexedDB = window.indexedDB || window.webkitIndexedDB || | |
| window.mozIndexedDB; | |
| if ('webkitIndexedDB' in window) { | |
| window.IDBTransaction = window.webkitIDBTransaction; | |
| window.IDBKeyRange = window.webkitIDBKeyRange; | |
| } | |
| todoDB.indexedDB = {}; | |
| todoDB.indexedDB.db = null; | |
| $(document).bind('pageinit', function() { | |
| console.log("– lets start the party –"); | |
| todoDB.indexedDB.open(); | |
| $("#addItem").click(function() { | |
| addTodo(); | |
| }); | |
| }); | |
| todoDB.indexedDB.onerror = function(e) { | |
| console.log(e); | |
| }; | |
| todoDB.indexedDB.open = function() { | |
| var request = indexedDB.open(dbName, dbVersion); | |
| request.onsuccess = function(e) { | |
| console.log ("success our DB: " + dbName + " is open and ready for work"); | |
| todoDB.indexedDB.db = e.target.result; | |
| var db = todoDB.indexedDB.db; | |
| if (db.setVersion) { | |
| console.log("in old setVersion: "+ db.setVersion); | |
| if (db.version != dbVersion) { | |
| var req = db.setVersion(dbVersion); | |
| req.onsuccess = function () { | |
| if(db.objectStoreNames.contains("todo")) { | |
| db.deleteObjectStore("todo"); | |
| } | |
| var store = db.createObjectStore("todo", {keyPath: "timeStamp"}); | |
| var trans = req.result; | |
| trans.oncomplete = function(e) { | |
| console.log("== oncomplete transaction =="); | |
| todoDB.indexedDB.getAllTodoItems(); | |
| } | |
| }; | |
| } | |
| else { | |
| todoDB.indexedDB.getAllTodoItems(); | |
| } | |
| } | |
| else { | |
| todoDB.indexedDB.getAllTodoItems(); | |
| } | |
| } | |
| request.onupgradeneeded = function(e) { | |
| console.log ("Going to upgrade our DB"); | |
| todoDB.indexedDB.db = e.target.result; | |
| var db = todoDB.indexedDB.db; | |
| if(db.objectStoreNames.contains("todo")) { | |
| db.deleteObjectStore("todo"); | |
| } | |
| var store = db.createObjectStore("todo", | |
| {keyPath: "timeStamp"}); | |
| todoDB.indexedDB.getAllTodoItems(); | |
| } | |
| request.onfailure = todoDB.indexedDB.onerror; | |
| request.onerror = function(e) { | |
| console.error("Well… How should I put it? We have some issues with our DB! Err:"+e); | |
| } | |
| }; | |
| todoDB.indexedDB.addTodo = function(todoText) { | |
| var db = todoDB.indexedDB.db; | |
| var trans = db.transaction(['todo'], "readwrite"); | |
| var store = trans.objectStore("todo"); | |
| var data = { | |
| "text": todoText, | |
| "timeStamp": new Date().getTime() | |
| }; | |
| var request = store.put(data); | |
| request.onsuccess = function(e) { | |
| todoDB.indexedDB.getAllTodoItems(); | |
| }; | |
| request.onerror = function(e) { | |
| console.error("Error Adding an item: ", e); | |
| }; | |
| }; | |
| todoDB.indexedDB.deleteTodo = function(id) { | |
| var db = todoDB.indexedDB.db; | |
| var trans = db.transaction(["todo"], "readwrite"); | |
| var store = trans.objectStore("todo"); | |
| var request = store.delete(id); | |
| request.onsuccess = function(e) { | |
| todoDB.indexedDB.getAllTodoItems(); | |
| }; | |
| request.onerror = function(e) { | |
| console.error("Error deleteing: ", e); | |
| }; | |
| }; | |
| todoDB.indexedDB.getAllTodoItems = function() { | |
| var todos = document.getElementById("todoItems"); | |
| todos.innerHTML = ""; | |
| var db = todoDB.indexedDB.db; | |
| var trans = db.transaction(["todo"], "readwrite"); | |
| var store = trans.objectStore("todo"); | |
| // Get everything in the store; | |
| var keyRange = IDBKeyRange.lowerBound(0); | |
| var cursorRequest = store.openCursor(keyRange); | |
| cursorRequest.onsuccess = function(e) { | |
| var result = e.target.result; | |
| if(!!result == false) | |
| return; | |
| renderTodo(result.value); | |
| result.continue(); | |
| }; | |
| cursorRequest.onerror = todoDB.indexedDB.onerror; | |
| }; | |
| function renderTodo(row) { | |
| var todos = document.getElementById("todoItems"); | |
| var li = document.createElement("li"); | |
| var a = document.createElement("a"); | |
| var t = document.createTextNode(row.text); | |
| a.addEventListener("click", function() { | |
| todoDB.indexedDB.deleteTodo(row.timeStamp); | |
| }, false); | |
| // some fun with jquery mobile data attributes | |
| a.setAttribute("href", "#"); | |
| a.setAttribute("data-iconpos", "notext"); | |
| a.setAttribute("data-role", "button"); | |
| a.setAttribute("data-icon", "delete"); | |
| a.setAttribute("data-inline", "true"); | |
| li.appendChild(a); | |
| li.appendChild(t); | |
| todos.appendChild(li) | |
| // And lets create the new il item with its markup | |
| $("#todoItems").trigger('create'); | |
| } | |
| // Add an item only if we have more then zero letters | |
| function addTodo() { | |
| var todo = document.getElementById("todo"); | |
| if (todo.value.length > 0) { | |
| todoDB.indexedDB.addTodo(todo.value); | |
| todo.value = ""; | |
| } | |
| } | |
| // use it in case you wish to work on specific 'set' of data | |
| function showAll() { | |
| document.getElementById("ourList").innerHTML = "" ; | |
| var request = window.indexedDB.open(dbName); | |
| request.onsuccess = function(event) { | |
| // Enumerate the entire object store. | |
| var db = todoDB.indexedDB.db; | |
| var trans = db.transaction(["todo"], IDBTransaction.READ_ONLY); | |
| var request = trans.objectStore("todo").openCursor(); | |
| var ul = document.createElement("ul"); | |
| request.onsuccess = function(event) { | |
| var cursor = request.result || event.result; | |
| // If cursor is null then we've completed the enumeration. | |
| if (!cursor) { | |
| document.getElementById("ourList").appendChild(ul); | |
| return; | |
| } | |
| var li = document.createElement("li"); | |
| li.textContent = "key: " + cursor.key + " => Todo text: " + cursor.value.text; | |
| ul.appendChild(li); | |
| cursor.continue(); | |
| } | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body> | |
| <div data-role="page"> | |
| <div data-role="header"> | |
| <h1>IndexedDB with JQM</h1> | |
| </div> | |
| <!– /header –> | |
| <div data-role="content"> | |
| <p> | |
| This is a short example of inexedDB with jQueryMobile on a todo list app. Please open Chrome DevTools and/or FireBug in order to see all the log message and understand what is the process. | |
| </p> | |
| <p> | |
| <input type="text" id="todo" name="todo" placeholder="What do you need to do?" /> | |
| <input type="submit" value="Add Todo Item" id="addItem" /> | |
| </p> | |
| <ul id="todoItems" data-role="listview" data-inset="true" data-filter="true"></ul> | |
| </div> | |
| <!– /content –> | |
| <div data-role="footer"> | |
| <p> | |
| <ul> | |
| <li> | |
| <a href="https://greenido.wordpress.com">Ido's blog</a> | |
| </li> | |
| <li> | |
| <a href="http://www.w3.org/TR/IndexedDB/">IndexedDB spec on w3c</a> | |
| </li> | |
| <li> | |
| <a href="https://github.com/greenido/WebSQL-to-IndexedDB-example">WebSQL to IndexedDB example on github</a> | |
| </li> | |
| </ul> | |
| </p> | |
| </div> <!– /footer –> | |
| </div> <!– /page –> | |
| </body> | |
| </html> |





Last Friday and Saturday we hosted a Dart Hackathon in Tel Aviv. When you have a group of people
Some thoughts for the future:



During the first day of Java posse roundup 2012 I’ve took some notes from all the interesting session I’ve been in. The first day was a great start to the conference with two session that were very interesting with lots of good stuff to start and checkout. Here are some of the notes I’ve took from the session about “Tools that make you more productive”.