Commit 5affdcda authored by Vincent Bechu's avatar Vincent Bechu

mapping storage: create this storage

parent 6c040d84
......@@ -180,7 +180,8 @@ module.exports = function (grunt) {
'src/jio.storage/localstorage.js',
'src/jio.storage/indexeddbstorage.js',
'src/jio.storage/cryptstorage.js',
'src/jio.storage/websqlstorage.js'
'src/jio.storage/websqlstorage.js',
'src/jio.storage/mappingstorage.js'
],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
// dest: 'jio.js'
......
/*jslint indent:2, maxlen: 80, nomen: true */
/*global jIO */
(function (jIO) {
"use strict";
function MappingStorage(spec) {
this._mapping_dict = spec.mapping_dict || {};
this._default_dict = spec.default_dict || {};
this._sub_storage = jIO.createJIO(spec.sub_storage);
}
MappingStorage.prototype._getSubStorageId = function (index) {
var option = {};
option.query = this._mapping_dict.id.equal + ': "' + index + '"';
return this._sub_storage.allDocs(option)
.push(function (data) {
return data.data.rows[0].id;
});
};
MappingStorage.prototype._mapDocFromStorage = function (object) {
var result = {},
that = this,
prop;
for (prop in that._mapping_dict) {
if (that._mapping_dict.hasOwnProperty(prop)) {
if (prop !== "id") {
result[prop] = object[that._mapping_dict[prop].equal];
}
}
}
return result;
};
MappingStorage.prototype.get = function (index) {
var that = this;
if (this._mapping_dict.id === undefined ||
this._mapping_dict.id.equal === "id") {
return this._sub_storage.get(index)
.push(function (result) {
return that._mapDocFromStorage(result);
});
}
return this._getSubStorageId(index)
.push(function (id) {
return that._sub_storage.get(id);
})
.push(function (result) {
return that._mapDocFromStorage(result);
});
};
MappingStorage.prototype.put = function (index, doc) {
var prop,
doc_mapped = JSON.parse(JSON.stringify(this._default_dict));
for (prop in doc) {
if (doc.hasOwnProperty(prop)) {
doc_mapped[this._mapping_dict[prop].equal] = doc[prop];
}
}
if (this._mapping_dict.id === undefined ||
this._mapping_dict.id.equal === "id") {
return this._sub_storage.put(index, doc_mapped);
}
doc_mapped[this._mapping_dict.id.equal] = index;
return this._sub_storage.post(doc_mapped)
.push(function () {
return index;
});
};
MappingStorage.prototype.remove = function (index) {
var that = this;
if (this._mapping_dict.id === undefined
|| this._mapping_dict.id.equal === "id") {
return this._sub_storage.remove.apply(this._sub_storage,
arguments);
}
return this._getSubStorageId(index)
.push(function (id) {
return that._sub_storage.remove(id);
})
.push(function () {
return index;
});
};
MappingStorage.prototype.putAttachment = function (doc_id) {
var that = this;
if (this._mapping_dict.id === undefined
|| this._mapping_dict.id.equal === "id") {
return this._sub_storage.putAttachment.apply(this._sub_storage,
arguments);
}
return this._getSubStorageId(doc_id)
.push(function (id) {
doc_id = id;
return that._sub_storage.putAttachment.apply(that._sub_storage,
arguments);
});
};
MappingStorage.prototype.getAttachment = function (doc_id) {
var that = this;
if (this._mapping_dict.id === undefined
|| this._mapping_dict.id.equal === "id") {
return this._sub_storage.getAttachment.apply(this._sub_storage,
arguments);
}
return this._getSubStorageId(doc_id)
.push(function (id) {
doc_id = id;
return that._sub_storage.getAttachment.apply(that._sub_storage,
arguments);
});
};
MappingStorage.prototype.removeAttachment = function (doc_id) {
var that = this;
if (this._mapping_dict.id === undefined
|| this._mapping_dict.id.equal === "id") {
return this._sub_storage.removeAttachment.apply(this._sub_storage,
arguments);
}
return this._getSubStorageId(doc_id)
.push(function (id) {
doc_id = id;
return that._sub_storage.removeAttachment.apply(that._sub_storage,
arguments);
});
};
MappingStorage.prototype.hasCapacity = function () {
return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
};
MappingStorage.prototype.buildQuery = function (option) {
var that = this, i, select_list = [], sort_on = [], query;
function mapQuery(one_query) {
var i, query_list = [];
if (one_query.type === "complex") {
for (i = 0; i < one_query.query_list.length; i += 1) {
query_list.push(mapQuery(one_query.query_list[i]));
}
return {
operator: one_query.operator,
query_list: query_list,
type: "complex"
};
}
return {
key: that._mapping_dict[one_query.key].equal,
type: "simple",
value: one_query.value
};
}
if (option.sort_on !== undefined) {
for (i = 0; i < option.sort_on.length; i += 1) {
sort_on.push([this._mapping_dict[option.sort_on[i][0]].equal,
option.sort_on[i][1]]);
}
}
if (option.select_list !== undefined) {
for (i = 0; i < option.select_list.length; i += 1) {
select_list.push(this._mapping_dict[option.select_list[i]].equal);
}
}
if (this._mapping_dict.id !== undefined
&& this._mapping_dict.id.equal !== "id") {
select_list.push(this._mapping_dict.id.equal);
}
query = jIO.Query.parseStringToObject(option.query);
return this._sub_storage.allDocs(
{
query: mapQuery(query),
select_list: select_list,
sort_on: sort_on,
limit: option.limit,
include_docs: option.include_docs || false
}
)
.push(function (result) {
for (i = 0; i < result.data.total_rows; i += 1) {
if (that._mapping_dict.id !== undefined
&& that._mapping_dict.id.equal !== "id") {
result.data.rows[i].id =
result.data.rows[i].value[that._mapping_dict.id.equal];
delete result.data.rows[i].value[that._mapping_dict.id.equal];
}
result.data.rows[i].value =
that._mapDocFromStorage(result.data.rows[i].value);
}
return result.data.rows;
});
};
jIO.addStorage('mapping', MappingStorage);
}(jIO));
\ No newline at end of file
/*jslint indent:2, maxlen: 80, nomen: true */
/*global jIO, QUnit, Blob*/
(function (jIO, QUnit, Blob) {
"use strict";
var test = QUnit.test,
stop = QUnit.stop,
start = QUnit.start,
ok = QUnit.ok,
expect = QUnit.expect,
deepEqual = QUnit.deepEqual,
equal = QUnit.equal,
module = QUnit.module;
/////////////////////////////////////////////////////////////////
// Custom test substorage definition
/////////////////////////////////////////////////////////////////
function Storage2713() {
return this;
}
jIO.addStorage('mappingstorage2713', Storage2713);
/////////////////////////////////////////////////////////////////
// mappingStorage.constructor
/////////////////////////////////////////////////////////////////
module("mappingStorage.constructor");
test("create substorage", function () {
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
}
});
ok(jio.__storage._sub_storage instanceof jio.constructor);
equal(jio.__storage._sub_storage.__type, "mappingstorage2713");
deepEqual(jio.__storage._mapping_dict, {});
deepEqual(jio.__storage._default_dict, {});
});
test("accept parameters", function () {
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: { "bar": {"equal": "foo"}},
default_dict: { "foo": {"equal": "bar"}}
});
deepEqual(jio.__storage._mapping_dict, {"bar": {"equal": "foo"}});
deepEqual(jio.__storage._default_dict, {"foo": {"equal": "bar"}});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.get
/////////////////////////////////////////////////////////////////
module("mappingStorage.get");
test("get called substorage get", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {"title": {"equal": "title"}}
});
Storage2713.prototype.get = function (id) {
equal(id, "bar", "get 2713 called");
return {title: "foo"};
};
jio.get("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
}, "Check document");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get with props mapped", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {"title": {"equal": "otherTitle"}}
});
Storage2713.prototype.get = function (id) {
equal(id, "bar", "get 2713 called");
return {otherTitle: "foo"};
};
jio.get("bar")
.then(function (result) {
deepEqual(result, {
"title": "foo"
});
}).fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get with id and props mapped", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {
"title": {"equal": "otherTitle"},
"id": {"equal": "otherId"}
}
});
Storage2713.prototype.hasCapacity = function () {
return true;
};
Storage2713.prototype.buildQuery = function (options) {
deepEqual(options, {query: 'otherId: "42"'}, "allDoc 2713 called");
return [{id: "2713"}];
};
Storage2713.prototype.get = function (id) {
equal(id, "2713", "get 2713 called");
return {"otherTitle": "foo"};
};
jio.get("42")
.then(function (result) {
deepEqual(result, {
"title": "foo"
});
}).fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.put
/////////////////////////////////////////////////////////////////
module("mappingStorage.put");
test("put with substorage put", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {"title": {"equal": "title"}}
});
Storage2713.prototype.put = function (id, param) {
equal(id, "bar", "put 2713 called");
deepEqual(param, {"title": "foo"}, "put 2713 called");
return id;
};
jio.put("bar", {"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("put with default values", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
default_dict: {"title": "foobar"}
});
Storage2713.prototype.put = function (id, param) {
equal(id, "bar", "put 2713 called");
deepEqual(param, {"title": "foobar"}, "put 2713 called");
return id;
};
jio.put("bar", {})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("put with id and prop mapped", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {
"title": {"equal": "otherTitle"},
"id": {"equal": "otherId"}
}
});
Storage2713.prototype.post = function (doc) {
deepEqual(doc,
{"otherId": "42", "otherTitle": "foo"}, "post 2713 called");
return "bar";
};
jio.put("42", {"title": "foo"})
.then(function (result) {
equal(result, "42");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.remove
/////////////////////////////////////////////////////////////////
module("mappingStorage.remove");
test("remove with substorage remove", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
}
});
Storage2713.prototype.remove = function (id) {
equal(id, "bar", "remove 2713 called");
return id;
};
jio.remove("bar", {"title": "foo"})
.then(function (result) {
equal(result, "bar");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("remove with id mapped", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {
"id": {"equal": "otherId"}
}
});
Storage2713.prototype.hasCapacity = function () {
return true;
};
Storage2713.prototype.buildQuery = function (options) {
deepEqual(options, {query: 'otherId: "42"'}, "allDoc 2713 called");
return [{id: "2713"}];
};
Storage2713.prototype.remove = function (id) {
equal(id, "2713", "get 2713 called");
return "foo";
};
jio.remove("42")
.then(function (result) {
equal(result, "42");
}).fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.putAttachment
/////////////////////////////////////////////////////////////////
module("mappingStorage.putAttachment");
test("putAttachment use sub_storage one's", function () {
stop();
expect(4);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
}
}),
blob = new Blob([""]);
Storage2713.prototype.putAttachment = function (doc_id,
attachment_id, attachment) {
equal(doc_id, "42", "putAttachment 2713 called");
equal(attachment_id, "2713", "putAttachment 2713 called");
deepEqual(attachment, blob, "putAttachment 2713 called");
return doc_id;
};
jio.putAttachment("42", "2713", blob)
.then(function (result) {
equal(result, "42");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.getAttachment
/////////////////////////////////////////////////////////////////
module("mappingStorage.getAttachment");
test("getAttachment use sub_storage one's", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
}
}),
blob = new Blob([""]);
Storage2713.prototype.getAttachment = function (doc_id, attachment) {
equal(doc_id, "42", "getAttachment 2713 called");
equal(attachment, "2713", "getAttachment 2713 called");
return blob;
};
jio.getAttachment("42", "2713")
.then(function (result) {
deepEqual(result, blob);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.removeAttachment
/////////////////////////////////////////////////////////////////
module("mappingStorage.removeAttachment");
test("putAttachment use sub_storage one's", function () {
stop();
expect(3);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
}
});
Storage2713.prototype.removeAttachment = function (doc_id, attachment) {
equal(doc_id, "42", "putAttachment 2713 called");
equal(attachment, "2713", "getAttachment 2713 called");
return attachment;
};
jio.removeAttachment("42", "2713")
.then(function (result) {
deepEqual(result, "2713");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// mappingStorage.buildQuery
/////////////////////////////////////////////////////////////////
module("mappingStorage.buildQuery");
test("buildQuery with id and prop mapped", function () {
stop();
expect(2);
var jio = jIO.createJIO({
type: "mapping",
sub_storage: {
type: "mappingstorage2713"
},
mapping_dict: {
"id": {"equal": "otherId"},
"title": {"equal": "otherTitle"},
"smth": {"equal": "otherSmth"}
}
});
Storage2713.prototype.hasCapacity = function () {
return true;
};
Storage2713.prototype.buildQuery = function (options) {
deepEqual(options,
{
"include_docs": false,
"limit": undefined,
"query": {
"operator": "AND",
"query_list": [
{
"key": "otherTitle",
"type": "simple",
"value": "foo"
},
{
"key": "otherSmth",
"type": "simple",
"value": "bar"
}
],
"type": "complex"
},
"select_list": [
"otherTitle",
"otherId"
],
"sort_on": [
[
"otherSmth",
"descending"
]
]
}, "allDocs 2713 called");
return [{
id: "2713",
value: {"otherId": "42", "otherTitle": "foo", "otherSmth": "bar"}
}];
};
jio.allDocs({
query: '(title: "foo") AND (smth: "bar")',
sort_on: [["smth", "descending"]],
select_list: ["title"],
include_docs: false
})
.then(function (result) {
deepEqual(result,
{
"data": {
"rows": [
{
"id": "42",
"value": {
"smth": "bar",
"title": "foo"
}
}
],
"total_rows": 1
}
}, "allDocs check");
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, Blob));
\ No newline at end of file
......@@ -28,7 +28,6 @@
<script src="queries/key-jiodate.tests.js"></script>
<!--script src="queries/key-localstorage.tests.js"></script-->
<script src="jio.storage/memorystorage.tests.js"></script>
<script src="jio.storage/querystorage.tests.js"></script>
<script src="jio.storage/localstorage.tests.js"></script>
......@@ -45,7 +44,7 @@
<script src="jio.storage/replicatestorage_fastrepair.tests.js"></script>
<script src="jio.storage/replicatestorage_fastrepairattachment.tests.js"></script>
<script src="jio.storage/shastorage.tests.js"></script>
<script src="jio.storage/mappingstorage.tests.js"></script>
<!--script src="jio.storage/qiniustorage.tests.js"></script-->
<!--script src="jio.storage/indexstorage.tests.js"></script-->
<script src="jio.storage/cryptstorage.tests.js"></script>
......
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