controlling QuotaError when localStorage is full

This commit is contained in:
Javier Abadia 2014-01-27 23:27:24 +01:00
parent 2918f449e8
commit 35ca131086
3 changed files with 87 additions and 17 deletions

View File

@ -3,12 +3,13 @@
- adds: OK
- deletes: OK
- change pushEdit() to pushEdits(), NO
- control QuotaError error gracefully, ONGOING
- try and fill localStorage to see what happens... OK, localStorage.setItem() throws error
- goOnline()/goOffline() automatically
- prevent attributeEditor to appear after replaying the stored edits
- be careful with updates for features added offline (replace tmp id by final id)
- goOnline()/goOffline() automatically
- unit tests
- feedback graphics layer
- add timestamp to edits

View File

@ -52,9 +52,10 @@ define(["esri/graphic"], function(Graphic)
else
{
edits.push(edit);
this._storeEditsQueue(edits);
this._storeRedoStack([]);
return true; // success
var success =
this._storeRedoStack([]) &&
this._storeEditsQueue(edits);
return success;
}
},
@ -166,16 +167,16 @@ define(["esri/graphic"], function(Graphic)
var redoStack = this._retrieveRedoStack();
var editToRedo = redoStack.pop();
edits.push(editToRedo);
this._storeEditsQueue(edits);
this._storeRedoStack(redoStack);
this._storeEditsQueue(edits);
return editToRedo;
},
getEditsStoreSizeBytes: function()
{
return window.localStorage.getItem(EDITS_QUEUE_KEY).length +
window.localStorage.getItem(REDO_STACK_KEY).length;
return EDITS_QUEUE_KEY.length + window.localStorage.getItem(EDITS_QUEUE_KEY).length +
REDO_STACK_KEY.length + window.localStorage.getItem(REDO_STACK_KEY).length;
},
@ -185,7 +186,7 @@ define(["esri/graphic"], function(Graphic)
for( var key in window.localStorage )
{
var value = window.localStorage.getItem(key);
bytes += value.length;
bytes += key.length + value.length;
}
return bytes;
},
@ -225,9 +226,16 @@ define(["esri/graphic"], function(Graphic)
_storeEditsQueue: function(edits)
{
// jabadia: handle the QuotaExceeded error gracefully
var serializedEdits = this._packArrayOfEdits(edits);
window.localStorage.setItem(EDITS_QUEUE_KEY, serializedEdits);
try
{
var serializedEdits = this._packArrayOfEdits(edits);
window.localStorage.setItem(EDITS_QUEUE_KEY, serializedEdits);
return true;
}
catch(err)
{
return false;
}
},
_retrieveRedoStack: function()
@ -238,9 +246,16 @@ define(["esri/graphic"], function(Graphic)
_storeRedoStack: function(edits)
{
// jabadia: handle the QuotaExceeded error gracefully
var serializedEdits = this._packArrayOfEdits(edits);
window.localStorage.setItem(REDO_STACK_KEY, serializedEdits);
try
{
var serializedEdits = this._packArrayOfEdits(edits);
window.localStorage.setItem(REDO_STACK_KEY, serializedEdits);
return true;
}
catch(err)
{
return false;
}
},
_packArrayOfEdits: function(edits)

View File

@ -1,5 +1,8 @@
"use strict"
var KEY_PREFIX = "__LOCAL_STORAGE_TEST__";
var EXECUTE_LONG_TESTS = true;
describe("Internal Methods", function()
{
describe("Serialize/Deserialize Graphics", function()
@ -204,6 +207,12 @@ describe("Public Interface", function()
{
it("reset edits queue", function()
{
for( var key in window.localStorage )
{
if( key.indexOf(KEY_PREFIX)==0 )
window.localStorage.removeItem(key);
}
g_editsStore.resetEditsQueue();
expect(g_editsStore.pendingEditsCount()).toBe(0);
});
@ -436,14 +445,59 @@ describe("Public Interface", function()
it("report edit store size", function()
{
usedBytes = g_editsStore.getEditsStoreSizeBytes();
expect(usedBytes).toBe(678);
expect(usedBytes).toBe(705);
});
it("report total local storage size", function()
{
totalBytes = g_editsStore.getLocalStorageSizeBytes();
expect(usedBytes).not.toBeGreaterThan(totalBytes);
})
});
it("exhaust localStorage capacity", function()
{
if( EXECUTE_LONG_TESTS )
{
console.log("this will take some time");
var sizeBefore = g_editsStore.getLocalStorageSizeBytes();
// first, fill localStorage up to max capacity
try
{
var index = 0;
var value = "0123456789";
var value8 = value + value + value + value + value + value + value + value;
while(true)
{
var key = KEY_PREFIX + index;
window.localStorage.setItem(key, value8 + value8 + value8 + value8);
index += 1;
if( index % 1000 == 0)
console.log(index, g_editsStore.getLocalStorageSizeBytes());
}
}
catch(err)
{
console.log(err);
}
// now, try to push one edit
var success = g_editsStore.pushEdit(g_editsStore.ADD, 20, g_test.polygonFeature);
expect(success).toBeFalsy();
// clean everything
for( var key in window.localStorage )
{
if( key.indexOf(KEY_PREFIX)==0 )
window.localStorage.removeItem(key);
}
var sizeAfter = g_editsStore.getLocalStorageSizeBytes();
expect(sizeBefore).toEqual(sizeAfter);
}
});
})
});