diff --git a/.eslintrc.json b/.eslintrc.json
index 5ee807d06..b45eb6759 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -23,6 +23,7 @@
"prefer-const": "error",
"space-infix-ops": "error",
"no-useless-escape": "off",
- "no-var": "error"
+ "no-var": "error",
+ "no-console": 0
}
}
diff --git a/integration/test/ParseLocalDatastoreTest.js b/integration/test/ParseLocalDatastoreTest.js
index 9b01139b5..cbf9c2428 100644
--- a/integration/test/ParseLocalDatastoreTest.js
+++ b/integration/test/ParseLocalDatastoreTest.js
@@ -8,18 +8,64 @@ const Item = Parse.Object.extend('Item');
global.localStorage = require('./mockLocalStorage');
const mockRNStorage = require('./mockRNStorage');
+const LocalDatastoreUtils = require('../../lib/node/LocalDatastoreUtils');
-const DEFAULT_PIN = Parse.LocalDatastore.DEFAULT_PIN;
-const PIN_PREFIX = Parse.LocalDatastore.PIN_PREFIX;
+const DEFAULT_PIN = LocalDatastoreUtils.DEFAULT_PIN;
+const PIN_PREFIX = LocalDatastoreUtils.PIN_PREFIX;
+
+function LDS_KEY(object) {
+ return Parse.LocalDatastore.getKeyForObject(object);
+}
function runTest(controller) {
describe(`Parse Object Pinning (${controller.name})`, () => {
- beforeEach(() => {
+ beforeEach(async () => {
const StorageController = require(controller.file);
Parse.CoreManager.setAsyncStorage(mockRNStorage);
Parse.CoreManager.setLocalDatastoreController(StorageController);
Parse.enableLocalDatastore();
- Parse.LocalDatastore._clear();
+ await Parse.LocalDatastore._clear();
+ });
+
+ it(`${controller.name} can clear localDatastore`, async () => {
+ const obj1 = new TestObject();
+ const obj2 = new TestObject();
+ const obj3 = new TestObject();
+ const objects = [obj1, obj2, obj3];
+ await Parse.Object.pinAll(objects);
+ await Parse.Object.pinAllWithName('test_pin', objects);
+ await Parse.Object.saveAll(objects);
+
+ await Parse.LocalDatastore.pinWithName('DO_NOT_CLEAR', {});
+
+ let storage = await Parse.LocalDatastore._getRawStorage();
+ assert.equal(Object.keys(storage).length, 6);
+
+ await Parse.LocalDatastore._clear();
+
+ storage = await Parse.LocalDatastore._getRawStorage();
+ assert.equal(Object.keys(storage).length, 1);
+ assert.equal(storage['DO_NOT_CLEAR'], '{}');
+ await Parse.LocalDatastore.unPinWithName('DO_NOT_CLEAR');
+ });
+
+ it(`${controller.name} can getAllContents localDatastore`, async () => {
+ const obj1 = new TestObject();
+ const obj2 = new TestObject();
+ const obj3 = new TestObject();
+ const objects = [obj1, obj2, obj3];
+ await Parse.Object.pinAll(objects);
+ await Parse.Object.pinAllWithName('test_pin', objects);
+ await Parse.Object.saveAll(objects);
+
+ await Parse.LocalDatastore.pinWithName('DO_NOT_FETCH', {});
+
+ const storage = await Parse.LocalDatastore._getRawStorage();
+ assert.equal(Object.keys(storage).length, 6);
+
+ const LDS = await Parse.LocalDatastore._getAllContents();
+ assert.equal(Object.keys(LDS).length, 5);
+ assert.equal(LDS['DO_NOT_FETCH'], null);
});
it(`${controller.name} can pin (unsaved)`, async () => {
@@ -28,14 +74,14 @@ function runTest(controller) {
// Since object not saved check localId
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${object.className}_${object._localId}`]);
- assert.deepEqual(localDatastore[`${object.className}_${object._localId}`], object._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(object)]);
+ assert.deepEqual(localDatastore[LDS_KEY(object)], [object._toFullJSON()]);
await object.save();
// Check if localDatastore updated localId to objectId
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${object.className}_${object.id}`]);
- assert.deepEqual(localDatastore[`${object.className}_${object.id}`], object._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(object)]);
+ assert.deepEqual(localDatastore[LDS_KEY(object)], [object._toFullJSON()]);
});
it(`${controller.name} cannot pin unsaved pointer`, async () => {
@@ -55,10 +101,10 @@ function runTest(controller) {
await object.save();
await object.pin();
const localDatastore = await Parse.LocalDatastore._getAllContents();
- const cachedObject = localDatastore[`${object.className}_${object.id}`];
+ const cachedObject = localDatastore[LDS_KEY(object)][0];
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${object.className}_${object.id}`]);
- assert.deepEqual(localDatastore[`${object.className}_${object.id}`], object._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(object)]);
+ assert.deepEqual(localDatastore[LDS_KEY(object)], [object._toFullJSON()]);
assert.equal(cachedObject.objectId, object.id);
assert.equal(cachedObject.field, 'test');
});
@@ -73,10 +119,10 @@ function runTest(controller) {
await object.save();
const localDatastore = await Parse.LocalDatastore._getAllContents();
- const cachedObject = localDatastore[`${object.className}_${object.id}`];
+ const cachedObject = localDatastore[LDS_KEY(object)][0];
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${object.className}_${object.id}`]);
- assert.deepEqual(localDatastore[`${object.className}_${object.id}`], object._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(object)]);
+ assert.deepEqual(localDatastore[LDS_KEY(object)], [object._toFullJSON()]);
assert.equal(cachedObject.objectId, object.id);
assert.equal(cachedObject.field, 'new info');
});
@@ -109,12 +155,12 @@ function runTest(controller) {
await parent.pin();
const localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${parent.className}_${parent.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${child.className}_${child.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${grandchild.className}_${grandchild.id}`), true);
- assert.deepEqual(localDatastore[`${parent.className}_${parent.id}`], parent._toFullJSON());
- assert.deepEqual(localDatastore[`${child.className}_${child.id}`], child._toFullJSON());
- assert.deepEqual(localDatastore[`${grandchild.className}_${grandchild.id}`], grandchild._toFullJSON());
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(parent)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(child)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(grandchild)), true);
+ assert.deepEqual(localDatastore[LDS_KEY(parent)], [parent._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(child)], [child._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(grandchild)], [grandchild._toFullJSON()]);
});
it(`${controller.name} can pinAll (unsaved)`, async () => {
@@ -127,19 +173,19 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1.id}`, `${obj2.className}_${obj2.id}`, `${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can pinAll (saved)`, async () => {
@@ -153,10 +199,10 @@ function runTest(controller) {
await Parse.Object.pinAll(objects);
const localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1.id}`, `${obj2.className}_${obj2.id}`, `${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can pinAllWithName (unsaved)`, async () => {
@@ -169,19 +215,19 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [`${obj1.className}_${obj1.id}`, `${obj2.className}_${obj2.id}`, `${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can pinAllWithName (saved)`, async () => {
@@ -194,10 +240,10 @@ function runTest(controller) {
await Parse.Object.pinAllWithName('test_pin', objects);
const localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [`${obj1.className}_${obj1.id}`, `${obj2.className}_${obj2.id}`, `${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPin on destroy`, async () => {
@@ -212,20 +258,20 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 4);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj2.className}_${obj2.id}`), true);
- assert(localDatastore[`${obj1.className}_${obj1.id}`]);
- assert(localDatastore[`${obj2.className}_${obj2.id}`]);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj2)), true);
+ assert(localDatastore[LDS_KEY(obj1)]);
+ assert(localDatastore[LDS_KEY(obj2)]);
await obj1.destroy();
localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 3);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj2.className}_${obj2.id}`]);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [`${obj2.className}_${obj2.id}`]);
- assert(localDatastore[`${obj2.className}_${obj2.id}`]);
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj2)]);
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [LDS_KEY(obj2)]);
+ assert(localDatastore[LDS_KEY(obj2)]);
});
it(`${controller.name} can unPin on destroyAll`, async () => {
@@ -239,23 +285,23 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 5);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj3.className}_${obj3.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj3.className}_${obj3.id}`), true);
- assert(localDatastore[`${obj1.className}_${obj1.id}`]);
- assert(localDatastore[`${obj2.className}_${obj2.id}`]);
- assert(localDatastore[`${obj3.className}_${obj3.id}`]);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj3)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj3)), true);
+ assert(localDatastore[LDS_KEY(obj1)]);
+ assert(localDatastore[LDS_KEY(obj2)]);
+ assert(localDatastore[LDS_KEY(obj3)]);
await Parse.Object.destroyAll([obj1, obj3]);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 3);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj2.className}_${obj2.id}`]);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [`${obj2.className}_${obj2.id}`]);
- assert(localDatastore[`${obj2.className}_${obj2.id}`]);
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj2)]);
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_pin'], [LDS_KEY(obj2)]);
+ assert(localDatastore[LDS_KEY(obj2)]);
});
it(`${controller.name} can unPin with pinAll (unsaved)`, async () => {
@@ -268,26 +314,26 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await obj2.unPin();
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1.id}`, `${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPin with pinAll (saved)`, async () => {
@@ -300,10 +346,10 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
@@ -311,9 +357,9 @@ function runTest(controller) {
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1.id}`, `${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPin / unPinAll without pin (unsaved)`, async () => {
@@ -360,24 +406,24 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.unPinAll([obj1, obj2]);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAll (saved)`, async () => {
@@ -390,18 +436,18 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
await Parse.Object.unPinAll([obj1, obj2]);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAllObjects (unsaved)`, async () => {
@@ -414,26 +460,26 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.unPinAllObjects();
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAllObjects (saved)`, async () => {
@@ -446,19 +492,19 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[DEFAULT_PIN], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[DEFAULT_PIN], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
Parse.Object.unPinAllObjects();
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAllWithName (unsaved)`, async () => {
@@ -471,24 +517,24 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.unPinAllWithName('test_unpin', [obj1, obj2]);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAllWithName (saved)`, async () => {
@@ -501,18 +547,18 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
await Parse.Object.unPinAllWithName('test_unpin', [obj1, obj2]);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 2);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj3.className}_${obj3.id}`]);
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAllObjectsWithName (unsaved)`, async () => {
@@ -525,26 +571,26 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.unPinAllObjectsWithName('test_unpin');
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPinAllObjectsWithName (saved)`, async () => {
@@ -557,19 +603,19 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 4);
- assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [`${obj1.className}_${obj1._localId}`, `${obj2.className}_${obj2._localId}`, `${obj3.className}_${obj3._localId}`]);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1._localId}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2._localId}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3._localId}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[PIN_PREFIX + 'test_unpin'], [LDS_KEY(obj1), LDS_KEY(obj2), LDS_KEY(obj3)]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
await Parse.Object.saveAll(objects);
await Parse.Object.unPinAllObjectsWithName('test_unpin');
localDatastore = await Parse.LocalDatastore._getAllContents();
assert.equal(Object.keys(localDatastore).length, 3);
- assert.deepEqual(localDatastore[`${obj1.className}_${obj1.id}`], obj1._toFullJSON());
- assert.deepEqual(localDatastore[`${obj2.className}_${obj2.id}`], obj2._toFullJSON());
- assert.deepEqual(localDatastore[`${obj3.className}_${obj3.id}`], obj3._toFullJSON());
+ assert.deepEqual(localDatastore[LDS_KEY(obj1)], [obj1._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj2)], [obj2._toFullJSON()]);
+ assert.deepEqual(localDatastore[LDS_KEY(obj3)], [obj3._toFullJSON()]);
});
it(`${controller.name} can unPin and save reference`, async () => {
@@ -583,20 +629,20 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 5);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj3.className}_${obj3.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj3.className}_${obj3.id}`), true);
- assert(localDatastore[`${obj1.className}_${obj1.id}`]);
- assert(localDatastore[`${obj2.className}_${obj2.id}`]);
- assert(localDatastore[`${obj3.className}_${obj3.id}`]);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj3)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj3)), true);
+ assert(localDatastore[LDS_KEY(obj1)]);
+ assert(localDatastore[LDS_KEY(obj2)]);
+ assert(localDatastore[LDS_KEY(obj3)]);
await obj1.unPin();
localDatastore = await Parse.LocalDatastore._getAllContents();
- assert(localDatastore[`${obj1.className}_${obj1.id}`]);
+ assert(localDatastore[LDS_KEY(obj1)]);
});
it(`${controller.name} can unPin and save reference with children`, async () => {
@@ -612,24 +658,24 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
assert(Object.keys(localDatastore).length === 6);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${obj3.className}_${obj3.id}`), true);
- assert.equal(localDatastore[DEFAULT_PIN].includes(`${child.className}_${child.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj1.className}_${obj1.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj2.className}_${obj2.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${obj3.className}_${obj3.id}`), true);
- assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(`${child.className}_${child.id}`), true);
- assert(localDatastore[`${obj1.className}_${obj1.id}`]);
- assert(localDatastore[`${obj2.className}_${obj2.id}`]);
- assert(localDatastore[`${obj3.className}_${obj3.id}`]);
- assert(localDatastore[`${child.className}_${child.id}`]);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(obj3)), true);
+ assert.equal(localDatastore[DEFAULT_PIN].includes(LDS_KEY(child)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj1)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj2)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(obj3)), true);
+ assert.equal(localDatastore[PIN_PREFIX + 'test_pin'].includes(LDS_KEY(child)), true);
+ assert(localDatastore[LDS_KEY(obj1)]);
+ assert(localDatastore[LDS_KEY(obj2)]);
+ assert(localDatastore[LDS_KEY(obj3)]);
+ assert(localDatastore[LDS_KEY(child)]);
await obj1.unPin();
localDatastore = await Parse.LocalDatastore._getAllContents();
- assert(localDatastore[`${obj1.className}_${obj1.id}`]);
- assert(localDatastore[`${child.className}_${child.id}`]);
+ assert(localDatastore[LDS_KEY(obj1)]);
+ assert(localDatastore[LDS_KEY(child)]);
});
it(`${controller.name} cannot fetchFromLocalDatastore (unsaved)`, async () => {
@@ -756,7 +802,7 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
- assert.equal(localDatastore[`Item_${item.id}`].foo, 'bar');
+ assert.equal(localDatastore[LDS_KEY(item)][0].foo, 'bar');
const itemAgain = new Item();
itemAgain.id = item.id;
@@ -766,7 +812,7 @@ function runTest(controller) {
assert.equal(itemAgain.get('foo'), 'changed');
assert.equal(fetchedItem.get('foo'), 'changed');
- assert.equal(localDatastore[`Item_${item.id}`].foo, 'changed');
+ assert.equal(localDatastore[LDS_KEY(item)][0].foo, 'changed');
});
it('fetchAll updates LocalDatastore', async () => {
@@ -783,8 +829,8 @@ function runTest(controller) {
let localDatastore = await Parse.LocalDatastore._getAllContents();
- assert.equal(localDatastore[`Item_${item1.id}`].foo, 'bar');
- assert.equal(localDatastore[`Item_${item2.id}`].foo, 'baz');
+ assert.equal(localDatastore[LDS_KEY(item1)][0].foo, 'bar');
+ assert.equal(localDatastore[LDS_KEY(item2)][0].foo, 'baz');
const item1Again = new Item();
item1Again.id = item1.id;
@@ -799,8 +845,8 @@ function runTest(controller) {
assert.equal(item2Again.get('foo'), 'changed');
assert.equal(fetchedItems[0].get('foo'), 'changed');
assert.equal(fetchedItems[1].get('foo'), 'changed');
- assert.equal(localDatastore[`Item_${fetchedItems[0].id}`].foo, 'changed');
- assert.equal(localDatastore[`Item_${fetchedItems[1].id}`].foo, 'changed');
+ assert.equal(localDatastore[LDS_KEY(fetchedItems[0])][0].foo, 'changed');
+ assert.equal(localDatastore[LDS_KEY(fetchedItems[1])][0].foo, 'changed');
});
it(`${controller.name} can update Local Datastore from network`, async () => {
@@ -822,7 +868,7 @@ function runTest(controller) {
await Parse.LocalDatastore.updateFromServer();
const updatedLDS = await Parse.LocalDatastore._getAllContents();
- const childJSON = updatedLDS[`${child.className}_${child.id}`];
+ const childJSON = updatedLDS[LDS_KEY(child)];
assert.equal(childJSON.foo, 'changed');
});
});
@@ -881,10 +927,14 @@ function runTest(controller) {
const obj1 = new TestObject({ field: 1 });
const obj2 = new TestObject({ field: 2 });
const obj3 = new TestObject({ field: 3 });
+ const obj4 = new TestObject({ field: 4 });
const objects = [obj1, obj2, obj3];
- await Parse.Object.saveAll(objects);
+ await Parse.Object.saveAll(objects);
await Parse.Object.pinAll(objects);
+ await obj4.save();
+ await obj4.pinWithName('DO_NOT_QUERY');
+
const query = new Parse.Query(TestObject);
query.fromPin();
const results = await query.find();
diff --git a/integration/test/mockRNStorage.js b/integration/test/mockRNStorage.js
index 4e09cfac8..9318d2451 100644
--- a/integration/test/mockRNStorage.js
+++ b/integration/test/mockRNStorage.js
@@ -27,6 +27,16 @@ const mockRNStorage = {
cb(undefined, Object.keys(mockStorage));
},
+ multiGet(keys, cb) {
+ const objects = keys.map((key) => [key, mockStorage[key]]);
+ cb(undefined, objects);
+ },
+
+ multiRemove(keys, cb) {
+ keys.map((key) => delete mockStorage[key]);
+ cb(undefined);
+ },
+
clear() {
mockStorage = {};
},
diff --git a/src/.flowconfig b/src/.flowconfig
index 3c28636fc..e36f40442 100644
--- a/src/.flowconfig
+++ b/src/.flowconfig
@@ -1,11 +1,10 @@
[ignore]
-.*/node_modules/.*
+.*/node_modules/
+.*/lib/
[include]
-../package.json
[libs]
-interfaces/
[options]
-unsafe.enable_getters_and_setters=true
+suppress_comment= \\(.\\|\n\\)*\\@flow-disable-next
diff --git a/src/LocalDatastore.js b/src/LocalDatastore.js
index 3c6e3a153..0afe3c6d3 100644
--- a/src/LocalDatastore.js
+++ b/src/LocalDatastore.js
@@ -13,10 +13,28 @@ import CoreManager from './CoreManager';
import type ParseObject from './ParseObject';
import ParseQuery from './ParseQuery';
+import { DEFAULT_PIN, PIN_PREFIX, OBJECT_PREFIX } from './LocalDatastoreUtils';
-const DEFAULT_PIN = '_default';
-const PIN_PREFIX = 'parsePin_';
-
+/**
+ * Provides a local datastore which can be used to store and retrieve Parse.Object
.
+ * To enable this functionality, call Parse.enableLocalDatastore()
.
+ *
+ * Pin object to add to local datastore
+ *
+ *
await object.pin();
+ * await object.pinWithName('pinName');
+ *
+ * Query pinned objects
+ *
+ * query.fromLocalDatastore();
+ * query.fromPin();
+ * query.fromPinWithName();
+ *
+ * const localObjects = await query.find();
+ *
+ * @class Parse.LocalDatastore
+ * @static
+ */
const LocalDatastore = {
fromPinWithName(name: string): Promise {
const controller = CoreManager.getLocalDatastoreController();
@@ -38,6 +56,12 @@ const LocalDatastore = {
return controller.getAllContents();
},
+ // Use for testing
+ _getRawStorage(): Promise {
+ const controller = CoreManager.getLocalDatastoreController();
+ return controller.getRawStorage();
+ },
+
_clear(): Promise {
const controller = CoreManager.getLocalDatastoreController();
return controller.clear();
@@ -45,37 +69,49 @@ const LocalDatastore = {
// Pin the object and children recursively
// Saves the object and children key to Pin Name
- async _handlePinWithName(name: string, object: ParseObject): Promise {
+ async _handlePinAllWithName(name: string, objects: Array): Promise {
const pinName = this.getPinName(name);
- const objects = this._getChildren(object);
- objects[this.getKeyForObject(object)] = object._toFullJSON();
- for (const objectKey in objects) {
- await this.pinWithName(objectKey, objects[objectKey]);
+ const toPinPromises = [];
+ const objectKeys = [];
+ for (const parent of objects) {
+ const children = this._getChildren(parent);
+ const parentKey = this.getKeyForObject(parent);
+ children[parentKey] = parent._toFullJSON();
+ for (const objectKey in children) {
+ objectKeys.push(objectKey);
+ toPinPromises.push(this.pinWithName(objectKey, [children[objectKey]]));
+ }
}
- const pinned = await this.fromPinWithName(pinName) || [];
- const objectIds = Object.keys(objects);
- const toPin = [...new Set([...pinned, ...objectIds])];
- await this.pinWithName(pinName, toPin);
+ const fromPinPromise = this.fromPinWithName(pinName);
+ const [pinned] = await Promise.all([fromPinPromise, toPinPromises]);
+ const toPin = [...new Set([...(pinned || []), ...objectKeys])];
+ return this.pinWithName(pinName, toPin);
},
// Removes object and children keys from pin name
// Keeps the object and children pinned
- async _handleUnPinWithName(name: string, object: ParseObject) {
+ async _handleUnPinAllWithName(name: string, objects: Array) {
const localDatastore = await this._getAllContents();
const pinName = this.getPinName(name);
- const objects = this._getChildren(object);
- const objectIds = Object.keys(objects);
- objectIds.push(this.getKeyForObject(object));
+ const promises = [];
+ let objectKeys = [];
+ for (const parent of objects) {
+ const children = this._getChildren(parent);
+ const parentKey = this.getKeyForObject(parent);
+ objectKeys.push(parentKey, ...Object.keys(children));
+ }
+ objectKeys = [...new Set(objectKeys)];
+
let pinned = localDatastore[pinName] || [];
- pinned = pinned.filter(item => !objectIds.includes(item));
+ pinned = pinned.filter(item => !objectKeys.includes(item));
if (pinned.length == 0) {
- await this.unPinWithName(pinName);
+ promises.push(this.unPinWithName(pinName));
delete localDatastore[pinName];
} else {
- await this.pinWithName(pinName, pinned);
+ promises.push(this.pinWithName(pinName, pinned));
localDatastore[pinName] = pinned;
}
- for (const objectKey of objectIds) {
+ for (const objectKey of objectKeys) {
let hasReference = false;
for (const key in localDatastore) {
if (key === DEFAULT_PIN || key.startsWith(PIN_PREFIX)) {
@@ -87,9 +123,10 @@ const LocalDatastore = {
}
}
if (!hasReference) {
- await this.unPinWithName(objectKey);
+ promises.push(this.unPinWithName(objectKey));
}
}
+ return Promise.all(promises);
},
// Retrieve all pointer fields from object recursively
@@ -130,20 +167,22 @@ const LocalDatastore = {
const localDatastore = await this._getAllContents();
const allObjects = [];
for (const key in localDatastore) {
- if (key !== DEFAULT_PIN && !key.startsWith(PIN_PREFIX)) {
- allObjects.push(localDatastore[key]);
+ if (key.startsWith(OBJECT_PREFIX)) {
+ allObjects.push(localDatastore[key][0]);
}
}
if (!name) {
- return Promise.resolve(allObjects);
+ return allObjects;
}
- const pinName = await this.getPinName(name);
- const pinned = await this.fromPinWithName(pinName);
+ const pinName = this.getPinName(name);
+ const pinned = localDatastore[pinName];
if (!Array.isArray(pinned)) {
- return Promise.resolve([]);
+ return [];
}
- const objects = pinned.map(async (objectKey) => await this.fromPinWithName(objectKey));
- return Promise.all(objects);
+ const promises = pinned.map((objectKey) => this.fromPinWithName(objectKey));
+ let objects = await Promise.all(promises);
+ objects = [].concat(...objects);
+ return objects.filter(object => object != null);
},
// Replaces object pointers with pinned pointers
@@ -154,10 +193,10 @@ const LocalDatastore = {
if (!LDS) {
LDS = await this._getAllContents();
}
- const root = LDS[objectKey];
- if (!root) {
+ if (!LDS[objectKey] || LDS[objectKey].length === 0) {
return null;
}
+ const root = LDS[objectKey][0];
const queue = [];
const meta = {};
@@ -172,8 +211,8 @@ const LocalDatastore = {
const value = subTreeRoot[field];
if (value.__type && value.__type === 'Object') {
const key = this.getKeyForObject(value);
- const pointer = LDS[key];
- if (pointer) {
+ if (LDS[key] && LDS[key].length > 0) {
+ const pointer = LDS[key][0];
uniqueId++;
meta[uniqueId] = pointer;
subTreeRoot[field] = pointer;
@@ -187,15 +226,16 @@ const LocalDatastore = {
// Called when an object is save / fetched
// Update object pin value
- async _updateObjectIfPinned(object: ParseObject) {
+ async _updateObjectIfPinned(object: ParseObject): Promise {
if (!this.isEnabled) {
return;
}
const objectKey = this.getKeyForObject(object);
const pinned = await this.fromPinWithName(objectKey);
- if (pinned) {
- await this.pinWithName(objectKey, object._toFullJSON());
+ if (!pinned || pinned.length === 0) {
+ return;
}
+ return this.pinWithName(objectKey, [object._toFullJSON()]);
},
// Called when object is destroyed
@@ -211,7 +251,9 @@ const LocalDatastore = {
if (!pin) {
return;
}
- await this.unPinWithName(objectKey);
+ const promises = [
+ this.unPinWithName(objectKey)
+ ];
delete localDatastore[objectKey];
for (const key in localDatastore) {
@@ -220,15 +262,16 @@ const LocalDatastore = {
if (pinned.includes(objectKey)) {
pinned = pinned.filter(item => item !== objectKey);
if (pinned.length == 0) {
- await this.unPinWithName(key);
+ promises.push(this.unPinWithName(key));
delete localDatastore[key];
} else {
- await this.pinWithName(key, pinned);
+ promises.push(this.pinWithName(key, pinned));
localDatastore[key] = pinned;
}
}
}
}
+ return Promise.all(promises);
},
// Update pin and references of the unsaved object
@@ -236,15 +279,17 @@ const LocalDatastore = {
if (!this.isEnabled) {
return;
}
- const localKey = `${object.className}_${localId}`;
+ const localKey = `${OBJECT_PREFIX}${object.className}_${localId}`;
const objectKey = this.getKeyForObject(object);
const unsaved = await this.fromPinWithName(localKey);
- if (!unsaved) {
+ if (!unsaved || unsaved.length === 0) {
return;
}
- await this.unPinWithName(localKey);
- await this.pinWithName(objectKey, unsaved);
+ const promises = [
+ this.unPinWithName(localKey),
+ this.pinWithName(objectKey, unsaved),
+ ];
const localDatastore = await this._getAllContents();
for (const key in localDatastore) {
@@ -253,11 +298,12 @@ const LocalDatastore = {
if (pinned.includes(localKey)) {
pinned = pinned.filter(item => item !== localKey);
pinned.push(objectKey);
- await this.pinWithName(key, pinned);
+ promises.push(this.pinWithName(key, pinned));
localDatastore[key] = pinned;
}
}
}
+ return Promise.all(promises);
},
/**
@@ -266,7 +312,8 @@ const LocalDatastore = {
*
* await Parse.LocalDatastore.updateFromServer();
*
- *
+ * @method updateFromServer
+ * @name Parse.LocalDatastore.updateFromServer
* @static
*/
async updateFromServer() {
@@ -276,7 +323,7 @@ const LocalDatastore = {
const localDatastore = await this._getAllContents();
const keys = [];
for (const key in localDatastore) {
- if (key !== DEFAULT_PIN && !key.startsWith(PIN_PREFIX)) {
+ if (key.startsWith(OBJECT_PREFIX)) {
keys.push(key);
}
}
@@ -286,7 +333,8 @@ const LocalDatastore = {
this.isSyncing = true;
const pointersHash = {};
for (const key of keys) {
- const [className, objectId] = key.split('_');
+ // Ignore the OBJECT_PREFIX
+ const [ , , className, objectId] = key.split('_');
if (!(className in pointersHash)) {
pointersHash[className] = new Set();
}
@@ -313,15 +361,14 @@ const LocalDatastore = {
await Promise.all(pinPromises);
this.isSyncing = false;
} catch(error) {
- console.log('Error syncing LocalDatastore'); // eslint-disable-line
- console.log(error); // eslint-disable-line
+ console.error('Error syncing LocalDatastore: ', error);
this.isSyncing = false;
}
},
getKeyForObject(object: any) {
const objectId = object.objectId || object._getId();
- return `${object.className}_${objectId}`;
+ return `${OBJECT_PREFIX}${object.className}_${objectId}`;
},
getPinName(pinName: ?string) {
@@ -333,14 +380,12 @@ const LocalDatastore = {
checkIfEnabled() {
if (!this.isEnabled) {
- console.log('Parse.enableLocalDatastore() must be called first'); // eslint-disable-line no-console
+ console.error('Parse.enableLocalDatastore() must be called first');
}
return this.isEnabled;
}
};
-LocalDatastore.DEFAULT_PIN = DEFAULT_PIN;
-LocalDatastore.PIN_PREFIX = PIN_PREFIX;
LocalDatastore.isEnabled = false;
LocalDatastore.isSyncing = false;
diff --git a/src/LocalDatastoreController.browser.js b/src/LocalDatastoreController.browser.js
index 3212fdceb..5b7333386 100644
--- a/src/LocalDatastoreController.browser.js
+++ b/src/LocalDatastoreController.browser.js
@@ -10,44 +10,64 @@
*/
/* global localStorage */
+import { isLocalDatastoreKey } from './LocalDatastoreUtils';
const LocalDatastoreController = {
- fromPinWithName(name: string): Promise {
+ fromPinWithName(name: string): Array