mirror of
https://github.com/Esri/offline-editor-js.git
synced 2025-12-15 15:20:05 +00:00
added delete, getAllEdits + unit tests
This commit is contained in:
parent
702387f7a3
commit
7c3baa2753
@ -34,37 +34,64 @@ O.esri.Edit.EditStore = function()
|
||||
*/
|
||||
this.pushEdit = function(operation,layer,graphic, callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
var edit = {
|
||||
id: graphic.attributes.objectid,
|
||||
operation: operation,
|
||||
layer: layer,
|
||||
graphic: graphic.toJson()
|
||||
};
|
||||
|
||||
var transaction = this._db.transaction([objectStoreName],"readwrite");
|
||||
|
||||
transaction.oncomplete = function(event){
|
||||
callback(true);
|
||||
var edit = {
|
||||
id: layer + "/" + graphic.attributes.objectid,
|
||||
operation: operation,
|
||||
layer: layer,
|
||||
graphic: graphic.toJson()
|
||||
};
|
||||
|
||||
transaction.onerror = function(event){
|
||||
callback(false,event.target.error.message);
|
||||
var transaction = this._db.transaction([objectStoreName],"readwrite");
|
||||
|
||||
transaction.oncomplete = function(event){
|
||||
callback(true);
|
||||
};
|
||||
|
||||
transaction.onerror = function(event){
|
||||
callback(false,event.target.error.message);
|
||||
};
|
||||
|
||||
var objectStore = transaction.objectStore(objectStoreName);
|
||||
var request = objectStore.put(edit);
|
||||
request.onsuccess = function(event){
|
||||
//console.log("item added to db " + event.target.result);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all the edits recursively via the callback
|
||||
* @param callback {value, message}
|
||||
*/
|
||||
this.getAllEdits = function(callback){
|
||||
|
||||
console.assert(this._db !== null, "indexeddb not initialized");
|
||||
|
||||
if(this._db !== null){
|
||||
var transaction = this._db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
.openCursor();
|
||||
|
||||
transaction.onsuccess = function(event)
|
||||
{
|
||||
var cursor = event.target.result;
|
||||
if(cursor){
|
||||
callback(cursor.value,null);
|
||||
cursor.continue();
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(null, "end");
|
||||
}
|
||||
}.bind(this);
|
||||
transaction.onerror = function(err)
|
||||
{
|
||||
callback(null, err);
|
||||
};
|
||||
|
||||
var objectStore = transaction.objectStore(objectStoreName);
|
||||
var request = objectStore.put(edit);
|
||||
request.onsuccess = function(event){
|
||||
//console.log("item added to db " + event.target.result);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
catch(err)
|
||||
else
|
||||
{
|
||||
console.log("AttachmentsStore: " + err.stack);
|
||||
callback(false,err.stack);
|
||||
callback(null, "no db");
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,7 +117,7 @@ O.esri.Edit.EditStore = function()
|
||||
|
||||
//Create a new update object
|
||||
var update = {
|
||||
id: graphic.attributes.objectid,
|
||||
id: layer + "/" + graphic.attributes.objectid,
|
||||
operation: operation,
|
||||
layer: layer,
|
||||
graphic: graphic.toJson()
|
||||
@ -109,6 +136,83 @@ O.esri.Edit.EditStore = function()
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a pending edit's record from the database.
|
||||
* IMPORTANT: Be aware of false negatives. See Step 4 in this function.
|
||||
*
|
||||
* @param layerUrl
|
||||
* @param graphic Graphic
|
||||
* @param callback {boolean}
|
||||
*/
|
||||
this.delete = function(layerUrl, graphic, callback){
|
||||
|
||||
// NOTE: the implementation of the IndexedDB spec has a major failure with respect to
|
||||
// handling deletes. The result of the operation is specified as undefined.
|
||||
// What this means is that there is no way to tell if an operation was successful or not.
|
||||
//
|
||||
// In order to get around this we have to verify if after the attempted deletion operation
|
||||
// if the record is or is not in the database. Kinda dumb, but that's how IndexedDB works.
|
||||
//http://stackoverflow.com/questions/17137879/is-there-a-way-to-get-information-on-deleted-record-when-calling-indexeddbs-obj
|
||||
|
||||
var db = this._db;
|
||||
var deferred = null;
|
||||
var self = this;
|
||||
|
||||
var edit = {
|
||||
id: layerUrl + "/" + graphic.attributes.objectid,
|
||||
operation: null,
|
||||
layer: layerUrl,
|
||||
graphic: graphic.toJson()
|
||||
};
|
||||
|
||||
require(["dojo/Deferred"], function(Deferred){
|
||||
deferred = new Deferred();
|
||||
|
||||
// Step 1 - lets see if record exits. If it does then return callback.
|
||||
self.editExists(edit).then(function(result){
|
||||
if(result.success){
|
||||
// Step 4 - Then we check to see if the record actually exists or not.
|
||||
deferred.then(function(edit){
|
||||
self.editExists(edit).then(function(results){
|
||||
results.success == false ? callback(true) : callback(false);
|
||||
},
|
||||
function(){
|
||||
callback(true); //because we want this test to throw an error. That means item deleted.
|
||||
})
|
||||
},
|
||||
// There was a problem with the delete operation on the database
|
||||
function(err){
|
||||
callback(err);
|
||||
});
|
||||
|
||||
var objectStore = db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);
|
||||
|
||||
// Step 2 - go ahead and delete graphic
|
||||
var objectStoreDeleteRequest = objectStore.delete(edit.id);
|
||||
|
||||
// Step 3 - We know that the onsuccess will always fire unless something serious goes wrong.
|
||||
// So we go ahead and resolve the deferred here.
|
||||
objectStoreDeleteRequest.onsuccess = function() {
|
||||
deferred.resolve(edit);
|
||||
|
||||
};
|
||||
|
||||
objectStoreDeleteRequest.onerror = function(msg){
|
||||
deferred.reject({success:false,error:msg});
|
||||
}
|
||||
}
|
||||
},
|
||||
// If there is an error in editExists()
|
||||
function(){
|
||||
callback(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//We return a deferred object so that when calling this function you can chain it with a then() statement.
|
||||
//return deferred;
|
||||
};
|
||||
|
||||
this.resetEditsQueue = function(callback)
|
||||
{
|
||||
console.assert(this._db !== null, "indexeddb not initialized");
|
||||
@ -163,11 +267,11 @@ O.esri.Edit.EditStore = function()
|
||||
var objectStore = db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);
|
||||
|
||||
//Get the entry associated with the graphic
|
||||
var objectStoreGraphicRequest = objectStore.get(newEdit.graphic.attributes.objectid);
|
||||
var objectStoreGraphicRequest = objectStore.get(newEdit.id);
|
||||
|
||||
objectStoreGraphicRequest.onsuccess = function() {
|
||||
var graphic = objectStoreGraphicRequest.result;
|
||||
if(graphic.layer == newEdit.layer){
|
||||
if(graphic && (graphic.layer == newEdit.layer)){
|
||||
deferred.resolve({success:true,error:null});
|
||||
}
|
||||
else{
|
||||
@ -184,11 +288,15 @@ O.esri.Edit.EditStore = function()
|
||||
return deferred;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the approximate size of the database in bytes
|
||||
* @param callback {usage, error} Whereas, the usage Object is {sizeBytes: number, editCount: number}
|
||||
*/
|
||||
this.getUsage = function(callback)
|
||||
{
|
||||
console.assert(this._db !== null, "indexeddb not initialized");
|
||||
|
||||
var usage = { sizeBytes: 0, attachmentCount: 0 };
|
||||
var usage = { sizeBytes: 0, editCount: 0 };
|
||||
|
||||
var transaction = this._db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName)
|
||||
@ -201,18 +309,17 @@ O.esri.Edit.EditStore = function()
|
||||
var cursor = event.target.result;
|
||||
if(cursor)
|
||||
{
|
||||
console.log(cursor.value.id, cursor.value.featureId, cursor.value.objectId);
|
||||
var storedObject = cursor.value;
|
||||
var json = JSON.stringify(storedObject);
|
||||
usage.sizeBytes += json.length;
|
||||
usage.attachmentCount += 1;
|
||||
usage.editCount += 1;
|
||||
cursor.continue();
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(usage,null);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
transaction.onerror = function(err)
|
||||
{
|
||||
callback(null,err);
|
||||
@ -292,14 +399,14 @@ O.esri.Edit.EditStore = function()
|
||||
*/
|
||||
this.hasPendingEdits = function()
|
||||
{
|
||||
// DEPRECATED at v2.5!
|
||||
return "DEPRECATED at v2.5!";
|
||||
};
|
||||
|
||||
/**
|
||||
* Deprecated @ v2.5. Use public function editExists() instead.
|
||||
*/
|
||||
this._isEditDuplicated = function(newEdit,edits){
|
||||
// DEPRECATED at v2.5!
|
||||
return "DEPRECATED at v2.5!";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -277,23 +277,92 @@ describe("Public Interface", function()
|
||||
});
|
||||
});
|
||||
|
||||
async.it("does edit already exist", function(done)
|
||||
async.it("check yes edit already exists", function(done)
|
||||
{
|
||||
|
||||
var edit = {
|
||||
id: g_test.lineFeature.attributes.objectid,
|
||||
operation: g_editsStore.DELETE,
|
||||
layer: 2,
|
||||
graphic: g_test.lineFeature.toJson()
|
||||
id: 6 + "/" + g_test.pointFeature.attributes.objectid,
|
||||
operation: g_editsStore.ADD,
|
||||
layer: 6,
|
||||
graphic: g_test.pointFeature.toJson()
|
||||
};
|
||||
|
||||
g_editsStore.editExists(edit).then(function(result){
|
||||
console.log("RESULT " + JSON.stringify(result));
|
||||
console.log("RESULT does edit exist " + JSON.stringify(result));
|
||||
expect(result.success).toBe(true);
|
||||
done();
|
||||
},function(err){
|
||||
expect(err.success).toBe(true);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
async.it("check no edit does not exist", function(done)
|
||||
{
|
||||
|
||||
var edit = {
|
||||
id: 62 + "/" + g_test.pointFeature.attributes.objectid,
|
||||
operation: g_editsStore.ADD,
|
||||
layer: 62,
|
||||
graphic: g_test.pointFeature.toJson()
|
||||
};
|
||||
|
||||
g_editsStore.editExists(edit).then(function(result){
|
||||
console.log("RESULT does edit exist " + JSON.stringify(result));
|
||||
expect(result.success).toBe(false);
|
||||
done();
|
||||
},function(err){
|
||||
expect(err.success).toBe(false);
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
async.it("get all edits recursively", function(done)
|
||||
{
|
||||
g_editsStore.getAllEdits(function(value,message){
|
||||
if(message ==="end")
|
||||
{
|
||||
expect(value).toBe(null);
|
||||
done();
|
||||
}
|
||||
else{
|
||||
console.log("VALUE: " + JSON.stringify(value));
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
async.it("delete an non-existing record from the database", function(done){
|
||||
|
||||
//Then let's delete that new entry
|
||||
g_editsStore.delete(21,g_test.pointFeature,function(result){
|
||||
expect(result).toBe(false); console.log("LKJ:LKJ " + result)
|
||||
|
||||
g_editsStore.pendingEditsCount(function(counts){
|
||||
expect(counts).toBe(3);
|
||||
done();
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
async.it("delete an existing record from the database", function(done){
|
||||
|
||||
//First we add a new entry
|
||||
g_editsStore.pushEdit(g_editsStore.ADD, 22, g_test.pointFeature, function(result){
|
||||
expect(result).toEqual(true);
|
||||
|
||||
//Then let's delete that new entry
|
||||
g_editsStore.delete(22,g_test.pointFeature,function(result){
|
||||
expect(result).toBe(true);
|
||||
|
||||
g_editsStore.pendingEditsCount(function(counts){
|
||||
expect(counts).toBe(3);
|
||||
done();
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// it("pending edits", function()
|
||||
// {
|
||||
// expect(g_editsStore.hasPendingEdits()).toBeTruthy();
|
||||
@ -343,8 +412,18 @@ describe("Public Interface", function()
|
||||
//
|
||||
});
|
||||
//
|
||||
// describe("Local Storage size", function()
|
||||
// {
|
||||
describe("Database storage size", function()
|
||||
{
|
||||
async.it("get size", function(done){
|
||||
g_editsStore.getUsage(function(result,error){
|
||||
console.log("RESULT IS " + result.sizeBytes);
|
||||
expect(result).toEqual(jasmine.any(Object));
|
||||
expect(result.sizeBytes).toEqual(1142);
|
||||
expect(result.editCount).toEqual(3);
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
// var usedBytes, totalBytes;
|
||||
//
|
||||
// it("reset edits queue", function()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user