2 * idb.js - indexed db interface
4 * author: hackbard@hackdaworld.org
13 onupgradeneeded: function(event) {
14 idb.handle=event.target.result;
15 idb.handle.onerror=function(event) {
16 cl("idb: handle error - "+event.target.errorCode);
18 var ov=event.oldVersion;
19 var nv=event.newVersion;
21 cl("idb: version upgrade ("+ov+" -> "+nv+')!');
23 for(var sn in idb.stores) {
25 var store=idb.stores[sn]
27 key[store['keytype']]=store['keyname'];
28 cl("idb: creating store '"+sn+"'");
29 store.os=idb.handle.createObjectStore(sn,key);
31 if(store.idx!==undefined) {
32 var idx=store.idx[nv];
34 cl('idb: missing version '+nv);
36 for(var iname in idx) {
37 cl("idb: creating index '"+
41 store.os.createIndex(iname,
48 if(store.content!==undefined) {
51 if(vc===null) continue;
53 cl("idb: put content to store '"+
62 cl("idb: upgrade success! ("+ov+"->"+nv+")");
64 onsuccess: function(event) {
65 idb.handle=event.target.result;
66 cl("idb: initialized successfuly ...");
69 onerror: function(event) {
70 cl("idb: error - "+this.error.message);
72 onblocked: function(event) {
75 init: function(name,successcb,version,stores,upgradecb) {
77 cl("idb: indexed db not supported");
82 if(version!==undefined)
84 if(stores!==undefined)
86 if(successcb!==undefined)
87 idb.successcb=successcb;
88 if(upgradecb!==undefined)
89 idb.onupgradeneeded=upgradecb;
90 var req=indexedDB.open(idb.name,idb.version);
91 req.onsuccess=idb.onsuccess;
92 req.onupgradeneeded=idb.onupgradeneeded;
93 req.onerror=idb.onerror;
94 req.onblocked=idb.onblocked;
96 add_store_item: function(store,item,callback) {
97 var tx=idb.handle.transaction(store,'readwrite');
98 var store=tx.objectStore(store);
99 var req=store.add(item);
100 req.onsuccess=function(event) {
103 req.onerror=function(error) {
104 cl("idb: add item error, "+error);
107 del_store: function(store,callback) {
108 var tx=db.handle.transaction(store,'readwrite');
109 var store=tx.objectStore(store);
110 var req=store.clear();
111 req.onsuccess=function() {
112 cl("db: store "+store.name+" deleted");
116 del_store_item: function(store,num,callback) {
117 var tx=db.handle.transaction(store,'readwrite');
118 var store=tx.objectStore(store);
120 var kr=IDBKeyRange.bound(num,num,false,false);
121 var req=store.openCursor(kr);
123 req.onsuccess=function(event) {
124 var cursor=event.target.result;
126 var res=cursor.delete();
127 res.onsuccess=function(event) {
130 res.onerror=function(error) {
131 cl("db: delete error");
137 cl("db: nothing to delete");
142 update_store_item: function(store,num,nitem,callback) {
143 var tx=idb.handle.transaction(store,'readwrite');
144 var store=tx.objectStore(store);
146 var kr=IDBKeyRange.bound(num,num,false,false);
147 var req=store.openCursor(kr);
149 req.onsuccess=function(event) {
150 var cursor=event.target.result;
152 var oitem=cursor.value;
154 for(var k in oitem) {
155 if(JSON.stringify(oitem[k])!=
156 JSON.stringify(nitem[k])) {
158 cl("idb: modified "+k);
165 var res=cursor.update(nitem);
166 res.onsuccess=function(event) {
167 cl("idb: updated cursor");
170 res.onerror=function(error) {
171 cl("idb: cursor update error");
177 var addreq=store.add(nitem,num);
178 addreq.onsuccess=function(event) {
179 cl("idb: added (update mode) key "+num);
182 addreq.onerror=function(error) {
183 cl("idb: error add (update mode)");
189 get_store_items: function(store,callback,low,up) {
190 // if low and up are undefined, all items are considered
194 if((low!==undefined)&&(up!==undefined)) {
195 if((low===0)&&(up<0)) {
199 else if((low===0)&&(up===0)) {
200 // get all items in reversed order
201 // no key range, no stop criteria required!
205 // get items in range
206 kr=IDBKeyRange.bound(low,up,true,true);
209 else if (low!==undefined) {
210 // get items from low to current
211 kr=IDBKeyRange.lowerBound(low,true);
213 else if (up!==undefined) {
214 // get items from first to up
215 kr=IDBKeyRange.upperBound(up,true);
218 var tx=idb.handle.transaction(store,'readonly');
219 var store=tx.objectStore(store);
225 var req=store.openCursor(null,"prev");
229 var req=store.openCursor(kr);
232 var req=store.openCursor();
235 req.onerror=function(error) {
236 cl("idb: cursor error - "+error);
238 req.onsuccess=function(event) {
239 var cursor=event.target.result;
240 if(cursor&&(!(last&&(obj.cnt_objs==-up)))) {
241 obj[cursor.key]=cursor.value;
250 get_item_by_key: function(store,key,callback) {
251 var tx=idb.handle.transaction(store,'readonly')
252 var store=tx.objectStore(store);
253 var req=store.get(key);
254 req.onerror=function(event) {
255 cl("idb: get key error - "+event.target.errorCode);
257 req.onsuccess=function(event) {
258 if(event.target.result!=null) {
259 callback(event.target.result);
263 get_item_by_index: function(store,index,val,callback) {
264 var tx=db.handle.transaction(store,'readonly')
265 var store=tx.objectStore(store);
266 var idx=store.index(index);
267 var req=idx.get(val);
268 req.onerror=function(event) {
269 cl("db: error! "+event.target.errorCode);
271 req.onsuccess=function(event) {
272 if(event.target.result!=null) {
273 callback(event.target.result);
277 del_item_by_key: function(store,key,callback) {
278 var tx=idb.handle.transaction(store,'readwrite');
279 var store=tx.objectStore(store);
281 var kr=IDBKeyRange.bound(key,key,false,false);
282 var req=store.openCursor(kr);
284 req.onsuccess=function(event) {
285 var cursor=event.target.result;
287 var res=cursor.delete();
288 res.onsuccess=function(event) {
289 cl("idb: deleted key "+key);
292 res.onerror=function(error) {
293 cl("idb: cursor delete error");
297 cl('idb: nothing to delete');
303 var req=indexedDB.deleteDatabase(idb.name);
304 req.onsuccess=function() {
305 cl("idb: deleted database '"+idb.name+"'");
307 req.onblocked=function() {
308 cl("idb: database delete blocked");
310 req.onerror=function() {
311 cl("idb: delete database error");