From 1a0a6c3c2fb6de7330e4ae2dbf14e6640177c06c Mon Sep 17 00:00:00 2001 From: Javier Abadia Date: Sat, 5 Apr 2014 01:27:41 +0200 Subject: [PATCH] low level functions in attachmentsStore.js --- lib/edit/attachmentsStore.js | 182 ++++++++++++++++++++++++++--- lib/edit/offlineFeaturesManager.js | 24 ++-- samples/attachments-editor.html | 7 +- 3 files changed, 180 insertions(+), 33 deletions(-) diff --git a/lib/edit/attachmentsStore.js b/lib/edit/attachmentsStore.js index aaff0a3..348accd 100644 --- a/lib/edit/attachmentsStore.js +++ b/lib/edit/attachmentsStore.js @@ -4,36 +4,190 @@ define([], function() { var AttachmentsStore = function() { + this._db = null; + + var DB_NAME = "attachments_store"; + var OBJECT_STORE_NAME = "attachments"; this.isSupported = function() { - return true; + if(!window.indexedDB){ + return false; + } + return true; } - this.init = function() + this.store = function(attachmentId, featureId, attachmentFile, callback) { - console.log("init AttachmentStore"); + try + { + var transaction = this._db.transaction([OBJECT_STORE_NAME],"readwrite"); + + transaction.oncomplete = function(event) + { + callback(true); + }; + + transaction.onerror = function(event) + { + callback(false,event.target.error.message) + }; + + var objectStore = transaction.objectStore(OBJECT_STORE_NAME); + var request = objectStore.put( + { + attachmentId: attachmentId, + featureId: featureId, + attachmentFile: attachmentFile + }); + request.onsuccess = function(event) + { + //console.log("item added to db " + event.target.result); + }; + } + catch(err) + { + console.log("AttachmentsStore: " + err.stack); + callback(false,err.stack); + } } - /* what should the API be? */ - - // add new attachment to new feature - // add new attachment to existing feature - // delete new attachment from feature - // delete existing attachment (how do we know about it if we are offline?) - // get attachments of a feature (only those that we know about it) - - this.add = function(attachmentId, attachmentFile) + this.retrieve = function(attachmentId, callback) { + if(this._db != null) + { + var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME); + var request = objectStore.get(attachmentId); + request.onsuccess = function(event) + { + var result = event.target.result; + if(result == null){ + callback(false,"not found"); + } + else{ + callback(true,result); + } + } + request.onerror = function(err) + { + console.log(err); + callback(false,err); + } + } } - this.get = function(attachmentId) + this.getAttachmentsByFeatureId = function(featureId,callback) { + var attachments = []; + + var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME); + var index = objectStore.index("featureId"); + var keyRange = IDBKeyRange.only(featureId); + index.openCursor(keyRange).onsuccess = function(evt) + { + var cursor = evt.target.result; + if(cursor) + { + attachments.push( cursor.value ); + cursor.continue(); + } + else + { + callback(attachments); + } + } } this.delete = function(attachmentId) { + console.assert(false, "not implemented"); } + + this.deleteAll = function(callback) + { + if(this._db != null) + { + var request = this._db.transaction([OBJECT_STORE_NAME],"readwrite") + .objectStore(OBJECT_STORE_NAME) + .clear(); + request.onsuccess = function(event) + { + callback(true); + } + request.onerror = function(err) + { + callback(false,err); + } + } + else + { + callback(false,null); + } + } + + this.getUsage = function(callback){ + if(this._db != null){ + var usage = { sizeBytes: 0, attachmentCount: 0 }; + + var transaction = this._db.transaction([OBJECT_STORE_NAME]) + .objectStore(OBJECT_STORE_NAME) + .openCursor(); + + transaction.onsuccess = function(event){ + var cursor = event.target.result; + if(cursor){ + var storedObject = cursor.value; + var json = JSON.stringify(storedObject); + usage.sizeBytes += json.length; + usage.attachmentCount += 1; + cursor.continue(); + } + else{ + callback(usage,null); + } + }.bind(this); + transaction.onerror = function(err){ + callback(null,err); + } + } + else{ + callback(null,null); + } + } + + this.init = function(callback) + { + console.log("init AttachmentStore"); + + var request = indexedDB.open(DB_NAME, 9); + callback = callback? callback : function(success) { console.log("AttachmentsStore::init() success:", success)}.bind(this); + + request.onerror = function(event) + { + console.log("indexedDB error: " + event.target.errorCode); + callback(false,event.target.errorCode); + }.bind(this); + + request.onupgradeneeded = function(event) + { + var db = event.target.result; + + if( db.objectStoreNames.contains(OBJECT_STORE_NAME)) + { + db.deleteObjectStore(OBJECT_STORE_NAME); + } + + var objectStore = db.createObjectStore(OBJECT_STORE_NAME, { keyPath: "attachmentId" }); + objectStore.createIndex("featureId","featureId", {unique: false}); + }.bind(this); + + request.onsuccess = function(event) + { + this._db = event.target.result; + console.log("database opened successfully"); + callback(true); + }.bind(this); + } }; - return AttachmentStore; + return AttachmentsStore; }) diff --git a/lib/edit/offlineFeaturesManager.js b/lib/edit/offlineFeaturesManager.js index 664da40..6522dcf 100644 --- a/lib/edit/offlineFeaturesManager.js +++ b/lib/edit/offlineFeaturesManager.js @@ -47,7 +47,7 @@ define([ * @param layer * @returns deferred */ - extend: function(layer,callback) + extend: function(layer, callback) { var self = this; @@ -63,19 +63,17 @@ define([ layer._queryAttachmentInfos = layer.queryAttachmentInfos; layer._deleteAttachments = layer.deleteAttachments; - try{ - layer.offline = { - online: true, - store: new AttachmentsStore(), - proxyPath: window.proxyPath - }; + try + { + layer.attachmentsStore = new AttachmentsStore(); - if( /*false &&*/ layer.offline.store.isSupported() ) - layer.offline.store.init(callback); + if( /*false &&*/ layer.attachmentsStore.isSupported() ) + layer.attachmentsStore.init(callback); else return callback(false, "indexedDB not supported"); } - catch(err){ + catch(err) + { console.log("problem! " + err.toString()) } @@ -106,6 +104,7 @@ define([ var def = this._queryAttachmentInfos(objectId, function() { + console.log(arguments); self.emit(self.events.ATTACHMENTS_INFO,arguments); callback && callback.apply(this,arguments); }, @@ -116,11 +115,8 @@ define([ { // NEEDS TESTING var deferred = new Deferred(); - this.store.get(objectId, function(found,objectIdAttachmentPair) + this.attachmentsStore.getAttachmentsByFeatureId(objectId, function(found,attachments) { - var attachments = [] - if(found) - attachments.push(objectIdAttachmentPair.attachment); callback && callback.apply(this,attachments); deferred.resolve(attachments); }); diff --git a/samples/attachments-editor.html b/samples/attachments-editor.html index 89c0744..b3de502 100644 --- a/samples/attachments-editor.html +++ b/samples/attachments-editor.html @@ -167,11 +167,8 @@ { var layer = evt.layer; var test = featureLayer.allowGeometryUpdates; console.log("type " + test) - offlineFeaturesManager.extend(featureLayer,function(success){ - console.log("extend "); - if(success){ - - } + offlineFeaturesManager.extend(featureLayer, function(success){ + console.log("layer extended", success? "successfully" : "without success"); }); layer.on('update-end', logCurrentObjectIds);