Commit 77749537 authored by Romain Courteaud's avatar Romain Courteaud

Update erp5 storage implementation.

parent a8ced060
...@@ -144,6 +144,8 @@ module.exports = function (grunt) { ...@@ -144,6 +144,8 @@ module.exports = function (grunt) {
jio: { jio: {
// duplicate files are ignored // duplicate files are ignored
src: [ src: [
'lib/uri/URI.js',
'node_modules/uritemplate/bin/uritemplate.js',
// 'node_modules/moment/moment.js', // 'node_modules/moment/moment.js',
'lib/moment/moment-2.5.0.js', 'lib/moment/moment-2.5.0.js',
// 'src/*.js', // 'src/*.js',
...@@ -173,6 +175,7 @@ module.exports = function (grunt) { ...@@ -173,6 +175,7 @@ module.exports = function (grunt) {
'src/jio.storage/davstorage.js', 'src/jio.storage/davstorage.js',
'src/jio.storage/indexeddbstorage.js', 'src/jio.storage/indexeddbstorage.js',
'src/jio.storage/unionstorage.js', 'src/jio.storage/unionstorage.js',
'src/jio.storage/erp5storage.js',
'src/jio.storage/querystorage.js', 'src/jio.storage/querystorage.js',
'src/jio.storage/drivetojiomapping.js', 'src/jio.storage/drivetojiomapping.js',
'src/jio.storage/cachestorage.js' 'src/jio.storage/cachestorage.js'
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
], ],
"dependencies": { "dependencies": {
"rsvp": "git+http://git.erp5.org/repos/rsvp.js.git", "rsvp": "git+http://git.erp5.org/repos/rsvp.js.git",
"uritemplate": "git+http://git.erp5.org/repos/uritemplate-js.git",
"moment": "2.8.3" "moment": "2.8.3"
}, },
"devDependencies": { "devDependencies": {
......
...@@ -10,229 +10,42 @@ ...@@ -10,229 +10,42 @@
// default_view: {string} (optional) // default_view: {string} (optional)
// } // }
/*jslint indent: 2, nomen: true, unparam: true */ /*jslint nomen: true */
/*global jIO, UriTemplate, FormData, RSVP, URI, DOMParser, Blob, /*global jIO, UriTemplate, FormData, RSVP, URI,
ProgressEvent, define */ module */
(function (root, dependencies, module) { (function (jIO, UriTemplate, FormData, RSVP, URI) {
"use strict"; "use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
var namespace = module(RSVP, jIO, URI, UriTemplate);
if (namespace !== undefined) { root.ERP5Storage = namespace; }
}(this, [
"rsvp",
"jio",
"uri",
"uritemplate"
], function (RSVP, jIO, URI, UriTemplate) {
"use strict";
var hasOwnProperty = Function.prototype.call.bind(
Object.prototype.hasOwnProperty
), constant = {};
constant.method_notification_message_obj = {
"get": "Getting document.",
"post": "Posting document.",
"put": "Putting document.",
"remove": "Removing document.",
"getAttachment": "Getting attachment.",
"putAttachment": "Putting attachment.",
"removeAttacment": "Removing attachment.",
"allDocs": "Getting document list."
};
// XXX docstring
function formatGetSuccessAnswer(answer) {
if (answer === undefined || answer === null) { throw answer; }
var result;
if (typeof answer.data === "object" && answer.data) {
return answer;
}
if (answer.target &&
typeof answer.target.status === "number" &&
typeof answer.target.statusText === "string") {
result = {
"status": answer.target.status
};
if (typeof answer.target.response === "object" &&
answer.target.response !== null) {
if (typeof answer.target.response.toJSON === "function") {
result.data = answer.target.response.toJSON();
} else {
result.data = answer.target.response;
}
} else if (answer.target.response instanceof Blob) {
return jIO.util.readBlobAsText(answer.target.response).
then(function (text) {
result.data = JSON.parse(text);
return result;
});
}
return result;
}
return answer;
}
// XXX docstring
function formatUpdateSuccessAnswer(answer) {
if (answer === undefined || answer === null) { throw answer; }
var result;
if (typeof answer.target === "object" && answer.target !== null &&
typeof answer.target.status === "number") {
result = {
"status": answer.target.status
};
return result;
}
return answer;
}
// XXX docstring
function formatErrorAnswer(answer) {
if (answer === undefined || answer === null) { throw answer; }
var result, dom;
if (answer.target &&
typeof answer.target.status === "number" &&
typeof answer.target.statusText === "string") {
// seams to be a ProgressEvent
result = {
"status": answer.target.status
};
if (typeof answer.target.response === "object" &&
answer.target.response !== null) {
if (typeof answer.target.response.toJSON === "function") {
result.data = answer.target.response.toJSON();
} else {
result.data = answer.target.response;
}
} else if (typeof answer.target.responseText === "string") {
dom = new DOMParser().parseFromString(
answer.target.responseText,
"text/html"
);
result.message = (dom.querySelector('#master') ||
dom.firstElementChild).textContent;
if (!result.message) { delete result.message; }
}
throw result;
}
throw answer;
}
// XXX docstring
function formatNotification(method, notif) {
var result;
if (notif) {
if (typeof notif.loaded === "number" &&
typeof notif.total === "number") {
result = {};
// can be a ProgressEvent or a jIO notification
if (notif.method !== method) {
result = {
"method": method,
"loaded": notif.loaded,
"total": notif.total
};
if (typeof notif.percentage === "number") {
result.percentage = notif.percentage;
}
}
if (typeof notif.message === "string") {
result.message = notif.message;
} else {
result.message = constant.method_notification_message_obj[method];
}
return result;
}
}
throw null; // stop propagation
}
constant.formatSuccessAnswerFor = {
"post": formatUpdateSuccessAnswer,
"put": formatUpdateSuccessAnswer,
"get": formatGetSuccessAnswer
};
//////////////////////////////////////////////////////////////////////
// XXX docstring
function ERP5Storage(spec) {
if (typeof spec.url !== "string" || !spec.url) {
throw new TypeError("ERP5 'url' must be a string " +
"which contains more than one character.");
}
this._url = spec.url;
this._default_view = spec.default_view;
}
// XXX docstring function getSiteDocument(storage) {
function methodGenerator(method) { return new RSVP.Queue()
return function (command, param, options) { .push(function () {
RSVP.resolve(). return jIO.util.ajax({
then(function () { "type": "GET",
var view = ERP5Storage.onView[options._view || this._default_view] || "url": storage._url,
ERP5Storage.onView["default"]; "xhrFields": {
if (typeof view[method] !== "function") { withCredentials: true
view = ERP5Storage.onView["default"];
} }
return view[method].call(this, param, options); });
}.bind(this)). })
then(constant.formatSuccessAnswerFor[method]). .push(function (event) {
then(null, formatErrorAnswer, formatNotification.bind(null, method)). return JSON.parse(event.target.responseText);
then(command.success, command.error, command.progress); });
};
} }
// XXX docstring function getDocumentAndHateoas(storage, param, options) {
[ if (options === undefined) {
"post", options = {};
"put",
"get",
"remove",
"putAttachment",
"getAttachment",
"removeAttachment",
"allDocs",
"check",
"repair"
].forEach(function (method) {
ERP5Storage.prototype[method] = methodGenerator(method);
});
// XXX docstring
function getSiteDocument(url) {
if (typeof url !== "string" &&
typeof (this && this._url) !== "string") {
throw new TypeError("ERP5Storage.getSiteDocument(): Argument 1 `url` " +
"or `this._url` are not of type string.");
} }
return jIO.util.ajax({ return getSiteDocument(storage)
"type": "GET", .push(function (site_hal) {
"url": url || this._url,
"xhrFields": {
withCredentials: true
}
}).then(function (event) {
return JSON.parse(event.target.responseText);
});
}
ERP5Storage.getSiteDocument = getSiteDocument;
// XXX docstring
function getDocumentAndHatoas(param, options) {
var this_ = this;
return ERP5Storage.getSiteDocument(this._url).
then(function (site_hal) {
// XXX need to get modified metadata // XXX need to get modified metadata
return jIO.util.ajax({ return jIO.util.ajax({
"type": "GET", "type": "GET",
"url": UriTemplate.parse(site_hal._links.traverse.href) "url": UriTemplate.parse(site_hal._links.traverse.href)
.expand({ .expand({
relative_url: param._id, relative_url: param._id,
view: options._view || this_._default_view || "view" view: options._view || storage._default_view
}), }),
"xhrFields": { "xhrFields": {
withCredentials: true withCredentials: true
...@@ -241,30 +54,34 @@ ...@@ -241,30 +54,34 @@
}); });
} }
ERP5Storage.onView = {};
ERP5Storage.onView["default"] = {};
// XXX docstring // XXX docstring
ERP5Storage.onView["default"].get = function (param, options) { function ERP5Storage(spec) {
return getDocumentAndHatoas.call(this, param, options). if (typeof spec.url !== "string" || !spec.url) {
then(function (response) { throw new TypeError("ERP5 'url' must be a string " +
"which contains more than one character.");
}
this._url = spec.url;
this._default_view = spec.default_view || "view";
}
ERP5Storage.prototype.get = function (param, options) {
return getDocumentAndHateoas(this, param, options)
.push(function (response) {
var result = JSON.parse(response.target.responseText); var result = JSON.parse(response.target.responseText);
result._id = param._id; result._id = param._id;
result.portal_type = result._links.type.name; result.portal_type = result._links.type.name;
delete result._embedded; // delete result._embedded;
delete result._links; // delete result._links;
delete result._debug; // delete result._debug;
new jIO.Metadata(result).format(); return result;
return {"data": result};
}); });
}; };
// XXX docstring ERP5Storage.prototype.post = function (metadata, options) {
ERP5Storage.onView["default"].post = function (metadata, options) { var final_response,
var final_response; context = this;
return getSiteDocument(this._url) return getSiteDocument(this)
.then(function (site_hal) { .push(function (site_hal) {
/*jslint forin: true */
var post_action = site_hal._actions.add, var post_action = site_hal._actions.add,
data = new FormData(); data = new FormData();
...@@ -278,24 +95,26 @@ ...@@ -278,24 +95,26 @@
withCredentials: true withCredentials: true
} }
}); });
}).then(function (event) { })
final_response = {"status": event.target.status}; .push(function (event) {
if (!metadata._id) { if (!metadata._id) {
// XXX Really depend on server response... // XXX Really depend on server response...
var uri = new URI(event.target.getResponseHeader("X-Location")); var uri = new URI(event.target.getResponseHeader("X-Location"));
final_response.id = uri.segment(2); final_response = uri.segment(2);
metadata._id = final_response.id; metadata._id = final_response;
} }
}). })
then(ERP5Storage.onView["default"].put.bind(this, metadata, options)). .push(function () {
then(function () { return final_response; }); return context.put(metadata, options);
})
.push(function () {
return final_response;
});
}; };
// XXX docstring ERP5Storage.prototype.put = function (metadata, options) {
ERP5Storage.onView["default"].put = function (metadata, options) { return getDocumentAndHateoas(this, metadata, options)
return getDocumentAndHatoas.call(this, metadata, options). .push(function (result) {
then(function (result) {
/*jslint forin: true */
result = JSON.parse(result.target.responseText); result = JSON.parse(result.target.responseText);
var put_action = result._embedded._view._actions.put, var put_action = result._embedded._view._actions.put,
renderer_form = result._embedded._view, renderer_form = result._embedded._view,
...@@ -304,10 +123,10 @@ ...@@ -304,10 +123,10 @@
data.append(renderer_form.form_id.key, data.append(renderer_form.form_id.key,
renderer_form.form_id['default']); renderer_form.form_id['default']);
for (key in metadata) { for (key in metadata) {
if (hasOwnProperty(metadata, key)) { if (metadata.hasOwnProperty(key)) {
if (key !== "_id") { if (key !== "_id") {
// Hardcoded my_ ERP5 behaviour // Hardcoded my_ ERP5 behaviour
if (hasOwnProperty(renderer_form, "my_" + key)) { if (renderer_form.hasOwnProperty("my_" + key)) {
data.append(renderer_form["my_" + key].key, metadata[key]); data.append(renderer_form["my_" + key].key, metadata[key]);
} }
} }
...@@ -324,18 +143,19 @@ ...@@ -324,18 +143,19 @@
}); });
}; };
ERP5Storage.onView["default"].remove = function () { ERP5Storage.prototype.hasCapacity = function (name) {
return; return ((name === "list") || (name === "query") ||
(name === "select") || (name === "limit"));
}; };
ERP5Storage.onView["default"].allDocs = function (param, options) { ERP5Storage.prototype.buildQuery = function (options) {
if (typeof options.query !== "string") { // if (typeof options.query !== "string") {
options.query = (options.query ? // options.query = (options.query ?
jIO.Query.objectToSearchText(options.query) : // jIO.Query.objectToSearchText(options.query) :
undefined); // undefined);
} // }
return getSiteDocument(this._url) return getSiteDocument(this)
.then(function (site_hal) { .push(function (site_hal) {
return jIO.util.ajax({ return jIO.util.ajax({
"type": "GET", "type": "GET",
"url": UriTemplate.parse(site_hal._links.raw_search.href) "url": UriTemplate.parse(site_hal._links.raw_search.href)
...@@ -350,50 +170,30 @@ ...@@ -350,50 +170,30 @@
} }
}); });
}) })
.then(function (response) { .push(function (response) {
return JSON.parse(response.target.responseText); return JSON.parse(response.target.responseText);
}) })
.then(function (catalog_json) { .push(function (catalog_json) {
var data = catalog_json._embedded.contents, var data = catalog_json._embedded.contents,
count = data.length, count = data.length,
i, i,
uri, uri,
item, item,
result = [], result = [];
promise_list = [result];
for (i = 0; i < count; i += 1) { for (i = 0; i < count; i += 1) {
item = data[i]; item = data[i];
uri = new URI(item._links.self.href); uri = new URI(item._links.self.href);
delete item._links;
result.push({ result.push({
id: uri.segment(2), id: uri.segment(2),
key: uri.segment(2),
doc: {}, doc: {},
value: item value: item
}); });
// if (options.include_docs) {
// promise_list.push(RSVP.Queue().push(function () {
// return this._get({_id: item.name}, {_view: "View"});
// }).push
// }
} }
return RSVP.all(promise_list); return result;
})
.then(function (promise_list) {
var result = promise_list[0];
return {"data": {"rows": result, "total_rows": result.length}};
}); });
}; };
ERP5Storage.onView["default"].check = function () {
return;
};
ERP5Storage.onView["default"].repair = function () {
return;
};
jIO.addStorage("erp5", ERP5Storage); jIO.addStorage("erp5", ERP5Storage);
return ERP5Storage; }(jIO, UriTemplate, FormData, RSVP, URI));
}));
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