Commit 9bbcbeb5 authored by Bryan Kaperick's avatar Bryan Kaperick

Updated bryanstorage to retain all versions of documents and only retrieve the...

Updated bryanstorage to retain all versions of documents and only retrieve the most recent copy when get(id) is called.
parent 6f693094
......@@ -13,37 +13,76 @@
this._sub_storage = jIO.createJIO(spec.sub_storage);
}
BryanStorage.prototype.get = function () {
return this._sub_storage.get.apply(this._sub_storage, arguments);
BryanStorage.prototype.get = function (id_in) {
var options = {
//query: 'id: "' + id_in + '"',
//sort_on: [['_revision', 'descending']],
//id: "tmp",
include_docs: true
};
return this._sub_storage.allDocs(options)
// Return document with most recent revision
.push(function (results) {
//<0 => a < b
var sorted_results = results.data.rows.sort(function (a, b) {
if (b.doc.id !== id_in || !b) {return -1; }
if (a.doc.id !== id_in || !a) {return 1; }
return b.doc._revision - a.doc._revision;
});
if (sorted_results.length > 0 && sorted_results[0].doc.id === id_in) {
return sorted_results[0].doc;
}
return [];
});
};
BryanStorage.prototype.allAttachments = function () {
return this._sub_storage.allAttachments.apply(this._sub_storage, arguments);
};
// Not implemented for IndexedDB
BryanStorage.prototype.post = function () {
return this._sub_storage.post.apply(this._sub_storage, arguments);
BryanStorage.prototype.post = function (metadata) {
function S4() {
return ('0000' + Math.floor(
Math.random() * 0x10000 // 65536
).toString(16)).slice(-4);
}
var id = S4() + S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + S4() + S4();
return this._sub_storage.put(id, metadata);
};
BryanStorage.prototype.put = function (id, new_metadata) {
var substorage = this._sub_storage;
return this.get(id)
var storage = this;
new_metadata.id = id;
return storage.get(id)
.push(
function (metadata) {
// Increments existing "_revision" attribute
new_metadata._revision = metadata._revision + 1;
return substorage.put(id, new_metadata);
if (metadata.hasOwnProperty('_revision')) {
new_metadata._revision = metadata._revision + 1;
} else {
new_metadata._revision = 0;
}
//return storage.post.apply(substorage, new_metadata);
return storage.post(new_metadata);
},
function () {
// Creates new attribute "_revision" = 0
new_metadata._revision = 0;
return substorage.put(id, new_metadata);
return storage.post(new_metadata);
}
);
};
BryanStorage.prototype.allAttachments = function () {
return this._sub_storage.allAttachments.apply(this._sub_storage, arguments);
};
BryanStorage.prototype.remove = function () {
return this._sub_storage.remove.apply(this._sub_storage, arguments);
};
......@@ -103,8 +142,8 @@
BryanStorage.prototype.hasCapacity = function (name) {
return this._sub_storage.removeAttachment.apply(this._sub_storage, name);
};
BryanStorage.prototype.buildQuery = function (options) {
return this._sub_storage.removeAttachment.apply(this._sub_storage, options);
BryanStorage.prototype.buildQuery = function () {
return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
};
jIO.addStorage('bryan', BryanStorage);
......
......@@ -9,8 +9,7 @@
expect = QUnit.expect,
deepEqual = QUnit.deepEqual,
equal = QUnit.equal,
module = QUnit.module,
throws = QUnit.throws;
module = QUnit.module;
/////////////////////////////////////////////////////////////////
......@@ -225,6 +224,32 @@
}
);
/////////////////////////////////////////////////////////////////
// _revision parameter updating with RSVP all
/////////////////////////////////////////////////////////////////
module("bryanStorage _revision with RSVP all");
test("verifying _revision updates correctly when puts are done in parallel",
function () {
stop();
expect(1);
// create storage of type "bryan" with memory as substorage
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {type: "memory"}
});
jio.put("bar", {"title": "foo"});
RSVP.all(
jio.put("bar", {"title2": "foo2"}),
jio.put("bar", {"title3": "foo3"})
)
.push(function () {return jio.get("bar"); })
.push(function (result) {equal(result._revision, 3, "parallel exec"); })
.fail(function (error) {ok(false, error); })
.always(function () {start(); });
});
/////////////////////////////////////////////////////////////////
// bryanStorage.allAttachments
/////////////////////////////////////////////////////////////////
......@@ -423,140 +448,31 @@
});
/////////////////////////////////////////////////////////////////
// bryanStorage.hasCapacity
// bryanStorage revision history
/////////////////////////////////////////////////////////////////
module("bryanStorage.hasCapacity");
test("hasCapacity is false by default", function () {
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "memory"
}
});
throws(
function () {
jio.hasCapacity("foo");
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message,
"Capacity 'foo' is not implemented on 'bryan'");
return true;
}
);
});
test("hasCapacity list return substorage value", function () {
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "memory"
}
});
throws(
function () {
jio.hasCapacity("list");
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message,
"Capacity 'list' is not implemented on 'memory'");
return true;
}
);
});
/////////////////////////////////////////////////////////////////
// bryanStorage.buildbryan
/////////////////////////////////////////////////////////////////
module("bryanStorage.buildbryan");
test("substorage should have 'list' capacity", function () {
module("bryanStorage revision history");
test("put and get the correct version", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "memory"
}
});
jio.allDocs({
include_docs: true,
bryan: 'title: "two"'
})
.then(function () {
ok(false);
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 501);
equal(error.message,
"Capacity 'list' is not implemented on 'memory'");
})
.always(function () {
start();
});
});
test("no manual bryan if substorage handle everything", function () {
stop();
expect(2);
function StorageAllDocsNoGet() {
return this;
}
StorageAllDocsNoGet.prototype.get = function () {
throw new Error("Unexpected get call");
};
StorageAllDocsNoGet.prototype.hasCapacity = function (capacity) {
if ((capacity === "list") ||
(capacity === "sort") ||
(capacity === "select") ||
(capacity === "limit") ||
(capacity === "bryan")) {
return true;
}
throw new Error("Unexpected " + capacity + " capacity check");
};
StorageAllDocsNoGet.prototype.buildbryan = function (options) {
deepEqual(options, {
sort_on: [["title", "ascending"]],
limit: [5],
select_list: ["title", "id"],
bryan: 'title: "two"'
},
"buildbryan called");
return "taboulet";
};
jIO.addStorage('bryanStoragealldocsnoget', StorageAllDocsNoGet);
expect(1);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "bryanStoragealldocsnoget"
type: "indexeddb",
database: "db_test1"
}
});
jio.allDocs({
sort_on: [["title", "ascending"]],
limit: [5],
select_list: ["title", "id"],
bryan: 'title: "two"'
jio.put("doc1", {
"title": "rev0",
"subtitle": "subrev0"
})
.then(function (result) {
.push(function () {return jio.get("doc1"); })
.push(function (result) {
deepEqual(result, {
data: {
rows: "taboulet",
total_rows: 8
}
});
"title": "rev0",
"subtitle": "subrev0",
"_revision": 0,
"id": "doc1"
}, "Retrieve document correctly");
})
.fail(function (error) {
ok(false, error);
......@@ -566,467 +482,62 @@
});
});
test("manual bryan used if substorage does not handle sort", function () {
module("bryanStorage revision history multiple edits");
test("modify first version but save both", function () {
stop();
expect(4);
function StorageNoSortCapacity() {
return this;
}
StorageNoSortCapacity.prototype.get = function (id) {
if (id === "foo") {
equal(id, "foo", "Get foo");
} else {
equal(id, "bar", "Get bar");
}
return {title: id, id: "ID " + id,
"another": "property"};
};
StorageNoSortCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list") ||
(capacity === "select") ||
(capacity === "limit") ||
(capacity === "bryan")) {
return true;
}
return false;
};
StorageNoSortCapacity.prototype.buildbryan = function (options) {
deepEqual(options, {}, "No bryan parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage('bryanStoragenosortcapacity', StorageNoSortCapacity);
expect(2);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "bryanStoragenosortcapacity"
type: "indexeddb",
database: "db_test2"
}
});
jio.allDocs({
sort_on: [["title", "ascending"]],
limit: [0, 5],
select_list: ["title", "id"],
bryan: 'title: "foo"'
jio.put("other_doc", {
"attr": "version0",
"subattr": "subversion0"
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: "foo",
doc: {},
value: {
title: "foo",
id: "ID foo"
}
}],
total_rows: 1
}
.push(function () {
return jio.put("other_doc", {
"attr": "version1",
"subattr": "subversion1"
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("manual bryan used if substorage does not handle select", function () {
stop();
expect(4);
function StorageNoSelectCapacity() {
return this;
}
StorageNoSelectCapacity.prototype.get = function (id) {
if (id === "foo") {
equal(id, "foo", "Get foo");
} else {
equal(id, "bar", "Get bar");
}
return {title: id, id: "ID " + id,
"another": "property"};
};
StorageNoSelectCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list") ||
(capacity === "sort") ||
(capacity === "limit") ||
(capacity === "bryan")) {
return true;
}
return false;
};
StorageNoSelectCapacity.prototype.buildbryan = function (options) {
deepEqual(options, {}, "No bryan parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage('bryanStoragenoselectcapacity', StorageNoSelectCapacity);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "bryanStoragenoselectcapacity"
}
});
jio.allDocs({
sort_on: [["title", "ascending"]],
limit: [0, 5],
select_list: ["title", "id"],
bryan: 'title: "foo"'
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: "foo",
doc: {},
value: {
title: "foo",
id: "ID foo"
}
}],
total_rows: 1
}
.push(function () {
return jio.put("main_doc", {
"title": "rev0",
"subtitle": "subrev0"
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("manual bryan used if substorage does not handle limit", function () {
stop();
expect(4);
function StorageNoLimitCapacity() {
return this;
}
StorageNoLimitCapacity.prototype.get = function (id) {
if (id === "foo") {
equal(id, "foo", "Get foo");
} else {
equal(id, "bar", "Get bar");
}
return {title: id, id: "ID " + id,
"another": "property"};
};
StorageNoLimitCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list") ||
(capacity === "select") ||
(capacity === "sort") ||
(capacity === "bryan")) {
return true;
}
return false;
};
StorageNoLimitCapacity.prototype.buildbryan = function (options) {
deepEqual(options, {}, "No bryan parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage('bryanStoragenolimitcapacity', StorageNoLimitCapacity);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "bryanStoragenolimitcapacity"
}
});
jio.allDocs({
sort_on: [["title", "ascending"]],
limit: [0, 5],
select_list: ["title", "id"],
bryan: 'title: "foo"'
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: "foo",
doc: {},
value: {
title: "foo",
id: "ID foo"
}
}],
total_rows: 1
}
.push(function () {
return jio.put("main_doc", {
"title": "rev1",
"subtitle": "subrev1"
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("manual bryan used if substorage does not handle bryan", function () {
stop();
expect(4);
function StorageNobryanCapacity() {
return this;
}
StorageNobryanCapacity.prototype.get = function (id) {
if (id === "foo") {
equal(id, "foo", "Get foo");
} else {
equal(id, "bar", "Get bar");
}
return {title: id, id: "ID " + id,
"another": "property"};
};
StorageNobryanCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list") ||
(capacity === "select") ||
(capacity === "limit") ||
(capacity === "sort")) {
return true;
}
return false;
};
StorageNobryanCapacity.prototype.buildbryan = function (options) {
deepEqual(options, {}, "No bryan parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage('bryanStoragenobryancapacity', StorageNobryanCapacity);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "bryanStoragenobryancapacity"
}
});
jio.allDocs({
sort_on: [["title", "ascending"]],
limit: [0, 5],
select_list: ["title", "id"],
bryan: 'title: "foo"'
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: "foo",
doc: {},
value: {
title: "foo",
id: "ID foo"
}
}],
total_rows: 1
}
.push(function () {
return jio.put("main_doc", {
"title": "rev2",
"subtitle": "subrev2"
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("does not fetch doc one by one if substorage handle include_docs",
function () {
stop();
expect(2);
function StorageIncludeDocsCapacity() {
return this;
}
StorageIncludeDocsCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list") ||
(capacity === "include")) {
return true;
}
return false;
};
StorageIncludeDocsCapacity.prototype.buildbryan = function (options) {
deepEqual(options, {include_docs: true}, "Include docs parameter");
var result2 = [{
id: "foo",
value: {},
doc: {
title: "foo",
id: "ID foo",
another: "property"
}
}, {
id: "bar",
value: {},
doc: {
title: "bar",
id: "ID bar",
another: "property"
}
}];
return result2;
};
jIO.addStorage('bryanStorageincludedocscapacity',
StorageIncludeDocsCapacity);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "bryanStorageincludedocscapacity"
}
});
jio.allDocs({
sort_on: [["title", "ascending"]],
limit: [0, 5],
select_list: ["title", "id"],
bryan: 'title: "foo"'
.push(function () {return jio.get("main_doc"); })
.push(function (result) {
deepEqual(result, {
"title": "rev2",
"subtitle": "subrev2",
"_revision": 2,
"id": "main_doc"
}, "Retrieve main document correctly");
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [{
id: "foo",
doc: {},
value: {
title: "foo",
id: "ID foo"
}
}],
total_rows: 1
}
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("manual bryan used and use schema", function () {
stop();
expect(4);
function StorageSchemaCapacity() {
return this;
}
StorageSchemaCapacity.prototype.get = function (id) {
var doc = {
title: id,
id: "ID " + id,
"another": "property"
};
if (id === "foo") {
equal(id, "foo", "Get foo");
doc.modification_date = "Fri, 08 Sep 2017 07:46:27 +0000";
} else {
equal(id, "bar", "Get bar");
doc.modification_date = "Thu, 07 Sep 2017 18:59:23 +0000";
}
return doc;
};
StorageSchemaCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list")) {
return true;
}
return false;
};
StorageSchemaCapacity.prototype.buildbryan = function (options) {
deepEqual(options, {}, "No bryan parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage(
'bryanStoragenoschemacapacity',
StorageSchemaCapacity
);
var jio = jIO.createJIO({
type: "bryan",
schema: {
"modification_date": {
"type": "string",
"format": "date-time"
}
},
sub_storage: {
type: "bryanStoragenoschemacapacity"
}
});
jio.allDocs({
sort_on: [["modification_date", "descending"]],
limit: [0, 5],
select_list: ['modification_date']
})
.then(function (result) {
.push(function () {return jio.get("other_doc"); })
.push(function (result) {
deepEqual(result, {
data: {
rows: [
{
id: "foo",
doc: {},
value: {
modification_date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
}, {
id: "bar",
doc: {},
value: {
modification_date: "Thu, 07 Sep 2017 18:59:23 +0000"
}
}
],
total_rows: 2
}
});
"attr": "version1",
"subattr": "subversion1",
"_revision": 1,
"id": "other_doc"
}, "Retrieve other document correctly");
})
.fail(function (error) {
ok(false, error);
......@@ -1035,32 +546,7 @@
start();
});
});
/////////////////////////////////////////////////////////////////
// bryanStorage.repair
/////////////////////////////////////////////////////////////////
module("bryanStorage.repair");
test("repair called substorage repair", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "bryan",
sub_storage: {
type: "memory"
}
}),
expected_options = {foo: "bar"};
}(jIO, QUnit, Blob));
jio.repair(expected_options)
.then(function (result) {
equal(result, "OK");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, Blob));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment