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.keytype+": "+store.keyname+")");
30 store.os=idb.handle.createObjectStore(sn,key);
32 if(store.idx!==undefined) {
33 var idx=store.idx[nv];
35 cl('idb: missing version '+nv);
37 for(var iname in idx) {
38 cl("idb: creating index '"+
42 store.os.createIndex(iname,
49 if(store.content!==undefined) {
52 if(vc===null) continue;
54 cl("idb: put content to store '"+
63 cl("idb: upgrade success! ("+ov+" -> "+nv+")");
65 onsuccess: function(event) {
66 idb.handle=event.target.result;
67 cl("idb: initialized successfuly ...");
70 onerror: function(event) {
71 cl("idb: error - "+this.error.message);
73 onblocked: function(event) {
76 init: function(name,successcb,version,stores,upgradecb) {
78 cl("idb: indexed db not supported");
83 if(version!==undefined)
85 if(stores!==undefined)
87 if(successcb!==undefined)
88 idb.successcb=successcb;
89 if(upgradecb!==undefined)
90 idb.onupgradeneeded=upgradecb;
91 cl("idb: init database '"+idb.name+"'");
92 var req=indexedDB.open(idb.name,idb.version);
93 req.onsuccess=idb.onsuccess;
94 req.onupgradeneeded=idb.onupgradeneeded;
95 req.onerror=idb.onerror;
96 req.onblocked=idb.onblocked;
98 del_store: function(sname,callback) {
99 var tx=db.handle.transaction(sname,'readwrite');
100 var store=tx.objectStore(sname);
101 var req=store.clear();
102 req.onsuccess=function() {
103 cl("db: store "+store.name+" deleted");
107 add_store_item: function(sname,item,callback) {
108 var tx=idb.handle.transaction(sname,'readwrite');
109 var store=tx.objectStore(sname);
110 var req=store.add(item);
111 req.onsuccess=function(event) {
114 req.onerror=function(error) {
115 cl("idb: add item error, "+error);
118 del_store_item: function(sname,num,callback) {
119 var tx=db.handle.transaction(sname,'readwrite');
120 var store=tx.objectStore(sname);
122 var kr=IDBKeyRange.bound(num,num,false,false);
123 var req=store.openCursor(kr);
125 req.onsuccess=function(event) {
126 var cursor=event.target.result;
128 var res=cursor.delete();
129 res.onsuccess=function(event) {
132 res.onerror=function(error) {
133 cl("db: delete error");
139 cl("db: nothing to delete");
144 update_store_item: function(sname,num,nitem,callback) {
145 var tx=idb.handle.transaction(sname,'readwrite');
146 var store=tx.objectStore(sname);
148 var kr=IDBKeyRange.bound(num,num,false,false);
149 var req=store.openCursor(kr);
151 req.onsuccess=function(event) {
152 var cursor=event.target.result;
154 var oitem=cursor.value;
156 for(var k in oitem) {
157 if(JSON.stringify(oitem[k])!=
158 JSON.stringify(nitem[k])) {
160 cl("idb: modified "+k);
167 var res=cursor.update(nitem);
168 res.onsuccess=function(event) {
169 cl("idb: updated cursor");
170 if(callback!==undefined)
173 res.onerror=function(error) {
174 cl("idb: cursor update error");
180 var addreq=store.add(nitem,num);
181 addreq.onsuccess=function(event) {
182 cl("idb: added (update mode) key "+num);
183 if(callback!==undefined)
186 addreq.onerror=function(error) {
187 cl("idb: error add (update mode)");
193 get_store_items: function(sname,callback,low,up) {
194 // if low and up are undefined, all items are considered
198 if((low!==undefined)&&(up!==undefined)) {
199 if((low===0)&&(up<0)) {
203 else if((low===0)&&(up===0)) {
204 // get all items in reversed order
205 // no key range, no stop criteria required!
209 // get items in range
210 kr=IDBKeyRange.bound(low,up,true,true);
213 else if (low!==undefined) {
214 // get items from low to current
215 kr=IDBKeyRange.lowerBound(low,true);
217 else if (up!==undefined) {
218 // get items from first to up
219 kr=IDBKeyRange.upperBound(up,true);
222 var tx=idb.handle.transaction(sname,'readonly');
223 var store=tx.objectStore(sname);
229 var req=store.openCursor(null,"prev");
233 var req=store.openCursor(kr);
236 var req=store.openCursor();
239 req.onerror=function(error) {
240 cl("idb: cursor error - "+error);
242 req.onsuccess=function(event) {
243 var cursor=event.target.result;
244 if(cursor&&(!(last&&(obj.cnt_objs==-up)))) {
245 obj[cursor.key]=cursor.value;
254 get_item_by_key: function(sname,key,callback) {
255 var tx=idb.handle.transaction(sname,'readonly')
256 var store=tx.objectStore(sname);
257 var req=store.get(key);
258 req.onerror=function(event) {
259 cl("idb: get key error - "+event.target.errorCode);
261 req.onsuccess=function(event) {
262 if(event.target.result!=null) {
263 callback(event.target.result);
267 get_item_by_index: function(sname,index,val,callback) {
268 var tx=db.handle.transaction(sname,'readonly')
269 var store=tx.objectStore(sname);
270 var idx=store.index(index);
271 var req=idx.get(val);
272 req.onerror=function(event) {
273 cl("db: error! "+event.target.errorCode);
275 req.onsuccess=function(event) {
276 if(event.target.result!=null) {
277 callback(event.target.result);
281 del_item_by_key: function(sname,key,callback) {
282 var tx=idb.handle.transaction(sname,'readwrite');
283 var store=tx.objectStore(sname);
285 var kr=IDBKeyRange.bound(key,key,false,false);
286 var req=store.openCursor(kr);
288 req.onsuccess=function(event) {
289 var cursor=event.target.result;
291 var res=cursor.delete();
292 res.onsuccess=function(event) {
293 cl("idb: deleted key "+key);
296 res.onerror=function(error) {
297 cl("idb: cursor delete error");
301 cl('idb: nothing to delete');
306 del: function(callback) {
307 var req=indexedDB.deleteDatabase(idb.name);
308 req.onsuccess=function() {
309 cl("idb: deleted database '"+idb.name+"'");
312 req.onblocked=function() {
313 cl("idb: database delete blocked");
315 req.onerror=function() {
316 cl("idb: delete database error");