Commit 7eebc25c authored by Tristan Cavelier's avatar Tristan Cavelier Committed by Romain Courteaud

[erp5_core/erp5_web_renderjs_ui] Update jIO 3.37.0

parent c2a52c61
...@@ -6092,11 +6092,11 @@ var arrayExtend = function () { ...@@ -6092,11 +6092,11 @@ var arrayExtend = function () {
} }
return {type:"complex",operator:operator,query_list:query_list2}; return {type:"complex",operator:operator,query_list:query_list2};
}, simpleQuerySetKey = function (query, key) { }, querySetKey = function (query, key) {
var i; var i;
if (query.type === "complex") { if (query.type === "complex") {
for (i = 0; i < query.query_list.length; ++i) { for (i = 0; i < query.query_list.length; ++i) {
simpleQuerySetKey (query.query_list[i],key); querySetKey(query.query_list[i], key);
} }
return true; return true;
} }
...@@ -6217,7 +6217,7 @@ case 12: ...@@ -6217,7 +6217,7 @@ case 12:
this.$ = $$[$0-1]; this.$ = $$[$0-1];
break; break;
case 13: case 13:
simpleQuerySetKey($$[$0], $$[$0-2]); this.$ = $$[$0]; querySetKey($$[$0], $$[$0-2]); this.$ = $$[$0];
break; break;
case 15: case 15:
$$[$0].operator = $$[$0-1] ; this.$ = $$[$0]; $$[$0].operator = $$[$0-1] ; this.$ = $$[$0];
...@@ -7346,21 +7346,8 @@ return new Parser; ...@@ -7346,21 +7346,8 @@ return new Parser;
* #crossLink "Query/toString:method" * #crossLink "Query/toString:method"
*/ */
ComplexQuery.prototype.toString = function () { ComplexQuery.prototype.toString = function () {
var str_list = [], this_operator = this.operator; /*global objectToSearchText */
if (this.operator === "NOT") { return objectToSearchText(this.toJSON());
str_list.push("NOT (");
str_list.push(this.query_list[0].toString());
str_list.push(")");
return str_list.join(" ");
}
this.query_list.forEach(function (query) {
str_list.push("(");
str_list.push(query.toString());
str_list.push(")");
str_list.push(this_operator);
});
str_list.length -= 1;
return str_list.join(" ");
}; };
/** /**
...@@ -7459,21 +7446,60 @@ return new Parser; ...@@ -7459,21 +7446,60 @@ return new Parser;
}; };
function objectToSearchText(query) { function objectToSearchText(query) {
var str_list = []; var i = 0,
if (query.type === "complex") { query_list = null,
str_list.push("("); string_list = null,
(query.query_list || []).forEach(function (sub_query) { operator = "",
str_list.push(objectToSearchText(sub_query)); common_key = "";
str_list.push(query.operator);
});
str_list.length -= 1;
str_list.push(")");
return str_list.join(" ");
}
if (query.type === "simple") { if (query.type === "simple") {
return (query.key ? query.key + ": " : "") + return (query.key ? query.key + ": " : "") +
(query.operator || "") + ' "' + query.value + '"'; (query.operator || "") + ' "' + query.value + '"';
} }
if (query.type === "complex") {
query_list = query.query_list;
if (!query_list || query_list.length === 0) {
return "";
}
operator = query.operator || "";
if (operator === "NOT") {
// fallback to AND operator if several queries are given
// i.e. `NOT ( a AND b )`
return "NOT ( " + objectToSearchText(
{type: "complex", operator: "AND", query_list: query_list}
) + " )";
}
if (query_list.length === 1) {
return objectToSearchText(query_list[0]);
}
common_key = query_list[i].key;
for (i = 1; i < query_list.length; i += 1) {
if (query_list[i].type !== "simple" ||
query_list[i].key !== common_key) {
break;
}
}
string_list = [];
if (i === query_list.length) {
for (i = 0; i < query_list.length; i += 1) {
string_list.push(
(query_list[i].operator || "") +
' "' + query_list[i].value + '"'
);
}
} else {
common_key = "";
for (i = 0; i < query_list.length; i += 1) {
string_list.push(objectToSearchText(query_list[i]));
}
}
if (string_list.length > 1) {
return (common_key ? common_key + ": " : "") +
"( " + string_list.join(" " + operator + " ") + " )";
}
return (common_key ? common_key + ": " : "") +
string_list[0];
}
throw new TypeError("This object is not a query"); throw new TypeError("This object is not a query");
} }
...@@ -7641,8 +7667,7 @@ return new Parser; ...@@ -7641,8 +7667,7 @@ return new Parser;
* #crossLink "Query/toString:method" * #crossLink "Query/toString:method"
*/ */
SimpleQuery.prototype.toString = function () { SimpleQuery.prototype.toString = function () {
return (this.key ? this.key + ":" : "") + return objectToSearchText(this.toJSON());
(this.operator ? " " + this.operator : "") + ' "' + this.value + '"';
}; };
/** /**
...@@ -8080,17 +8105,11 @@ return new Parser; ...@@ -8080,17 +8105,11 @@ return new Parser;
* See https://www.nexedi.com/licensing for rationale and options. * See https://www.nexedi.com/licensing for rationale and options.
*/ */
/*global window, RSVP, Blob, XMLHttpRequest, QueryFactory, Query, atob, /*global window, RSVP, Blob, XMLHttpRequest, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator */ FileReader, ArrayBuffer, Uint8Array */
(function (window, RSVP, Blob, QueryFactory, Query, atob, (function (window, RSVP, Blob, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator) { FileReader, ArrayBuffer, Uint8Array) {
"use strict"; "use strict";
if (window.openDatabase === undefined) {
window.openDatabase = function () {
throw new Error('WebSQL is not supported by ' + navigator.userAgent);
};
}
/* Safari does not define DOMError */ /* Safari does not define DOMError */
if (window.DOMError === undefined) { if (window.DOMError === undefined) {
window.DOMError = {}; window.DOMError = {};
...@@ -8536,6 +8555,7 @@ return new Parser; ...@@ -8536,6 +8555,7 @@ return new Parser;
if (context.hasCapacity("list") && if (context.hasCapacity("list") &&
((options.query === undefined) || context.hasCapacity("query")) && ((options.query === undefined) || context.hasCapacity("query")) &&
((options.sort_on === undefined) || context.hasCapacity("sort")) && ((options.sort_on === undefined) || context.hasCapacity("sort")) &&
((options.group_by === undefined) || context.hasCapacity("group")) &&
((options.select_list === undefined) || ((options.select_list === undefined) ||
context.hasCapacity("select")) && context.hasCapacity("select")) &&
((options.include_docs === undefined) || ((options.include_docs === undefined) ||
...@@ -8622,7 +8642,7 @@ return new Parser; ...@@ -8622,7 +8642,7 @@ return new Parser;
window.jIO = jIO; window.jIO = jIO;
}(window, RSVP, Blob, QueryFactory, Query, atob, }(window, RSVP, Blob, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator)); FileReader, ArrayBuffer, Uint8Array));
/* /*
* Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1, * Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1,
* as defined in FIPS PUB 180-1, tuned for high performance with large inputs. * as defined in FIPS PUB 180-1, tuned for high performance with large inputs.
...@@ -13695,7 +13715,7 @@ return new Parser; ...@@ -13695,7 +13715,7 @@ return new Parser;
ERP5Storage.prototype.hasCapacity = function (name) { ERP5Storage.prototype.hasCapacity = function (name) {
return ((name === "list") || (name === "query") || return ((name === "list") || (name === "query") ||
(name === "select") || (name === "limit") || (name === "select") || (name === "limit") ||
(name === "sort")); (name === "sort") || (name === "group"));
}; };
function isSingleLocalRoles(parsed_query) { function isSingleLocalRoles(parsed_query) {
...@@ -13763,7 +13783,8 @@ return new Parser; ...@@ -13763,7 +13783,8 @@ return new Parser;
local_roles, local_roles,
local_role_found = false, local_role_found = false,
selection_domain, selection_domain,
sort_list = []; sort_list = [],
group_list = [];
if (options.query) { if (options.query) {
parsed_query = jIO.QueryFactory.create(options.query); parsed_query = jIO.QueryFactory.create(options.query);
result_list = isSingleLocalRoles(parsed_query); result_list = isSingleLocalRoles(parsed_query);
...@@ -13835,6 +13856,10 @@ return new Parser; ...@@ -13835,6 +13856,10 @@ return new Parser;
} }
} }
if (options.group_by) {
group_list = options.group_by;
}
if (selection_domain) { if (selection_domain) {
selection_domain = JSON.stringify(selection_domain); selection_domain = JSON.stringify(selection_domain);
} }
...@@ -13848,6 +13873,7 @@ return new Parser; ...@@ -13848,6 +13873,7 @@ return new Parser;
select_list: options.select_list || ["title", "reference"], select_list: options.select_list || ["title", "reference"],
limit: options.limit, limit: options.limit,
sort_on: sort_list, sort_on: sort_list,
group_by: group_list,
local_roles: local_roles, local_roles: local_roles,
selection_domain: selection_domain selection_domain: selection_domain
}) })
...@@ -15686,385 +15712,6 @@ return new Parser; ...@@ -15686,385 +15712,6 @@ return new Parser;
jIO.addStorage('crypt', CryptStorage); jIO.addStorage('crypt', CryptStorage);
}(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer)); }(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer));
/*
* Copyright 2013, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/**
* JIO Websql Storage. Type = "websql".
* websql "database" storage.
*/
/*global Blob, jIO, RSVP, openDatabase*/
/*jslint nomen: true*/
(function (jIO, RSVP, Blob, openDatabase) {
"use strict";
/**
* The JIO Websql Storage extension
*
* @class WebSQLStorage
* @constructor
*/
function queueSql(db, query_list, argument_list) {
return new RSVP.Promise(function (resolve, reject) {
/*jslint unparam: true*/
db.transaction(function (tx) {
var len = query_list.length,
result_list = [],
i;
function resolveTransaction(tx, result) {
result_list.push(result);
if (result_list.length === len) {
resolve(result_list);
}
}
function rejectTransaction(tx, error) {
reject(error);
return true;
}
for (i = 0; i < len; i += 1) {
tx.executeSql(query_list[i], argument_list[i], resolveTransaction,
rejectTransaction);
}
}, function (tx, error) {
reject(error);
});
/*jslint unparam: false*/
});
}
function initDatabase(db) {
var query_list = [
"CREATE TABLE IF NOT EXISTS document" +
"(id VARCHAR PRIMARY KEY NOT NULL, data TEXT)",
"CREATE TABLE IF NOT EXISTS attachment" +
"(id VARCHAR, attachment VARCHAR, part INT, blob TEXT)",
"CREATE TRIGGER IF NOT EXISTS removeAttachment " +
"BEFORE DELETE ON document FOR EACH ROW " +
"BEGIN DELETE from attachment WHERE id = OLD.id;END;",
"CREATE INDEX IF NOT EXISTS index_document ON document (id);",
"CREATE INDEX IF NOT EXISTS index_attachment " +
"ON attachment (id, attachment);"
];
return new RSVP.Queue()
.push(function () {
return queueSql(db, query_list, []);
});
}
function WebSQLStorage(spec) {
if (typeof spec.database !== 'string' || !spec.database) {
throw new TypeError("database must be a string " +
"which contains more than one character.");
}
this._database = openDatabase("jio:" + spec.database,
'1.0', '', 2 * 1024 * 1024);
if (spec.blob_length &&
(typeof spec.blob_length !== "number" ||
spec.blob_length < 20)) {
throw new TypeError("blob_len parameter must be a number >= 20");
}
this._blob_length = spec.blob_length || 2000000;
this._init_db_promise = initDatabase(this._database);
}
WebSQLStorage.prototype.put = function (id, param) {
var db = this._database,
that = this,
data_string = JSON.stringify(param);
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["INSERT OR REPLACE INTO " +
"document(id, data) VALUES(?,?)"],
[[id, data_string]]);
})
.push(function () {
return id;
});
};
WebSQLStorage.prototype.remove = function (id) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["DELETE FROM document WHERE id = ?"], [[id]]);
})
.push(function (result_list) {
if (result_list[0].rowsAffected === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return id;
});
};
WebSQLStorage.prototype.get = function (id) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["SELECT data FROM document WHERE id = ?"],
[[id]]);
})
.push(function (result_list) {
if (result_list[0].rows.length === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return JSON.parse(result_list[0].rows[0].data);
});
};
WebSQLStorage.prototype.allAttachments = function (id) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, [
"SELECT id FROM document WHERE id = ?",
"SELECT DISTINCT attachment FROM attachment WHERE id = ?"
], [[id], [id]]);
})
.push(function (result_list) {
if (result_list[0].rows.length === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
var len = result_list[1].rows.length,
obj = {},
i;
for (i = 0; i < len; i += 1) {
obj[result_list[1].rows[i].attachment] = {};
}
return obj;
});
};
function sendBlobPart(blob, argument_list, index, queue) {
queue.push(function () {
return jIO.util.readBlobAsDataURL(blob);
})
.push(function (strBlob) {
argument_list[index + 2].push(strBlob.target.result);
return;
});
}
WebSQLStorage.prototype.putAttachment = function (id, name, blob) {
var db = this._database,
that = this,
part_size = this._blob_length;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["SELECT id FROM document WHERE id = ?"], [[id]]);
})
.push(function (result) {
var query_list = [],
argument_list = [],
blob_size = blob.size,
queue = new RSVP.Queue(),
i,
index;
if (result[0].rows.length === 0) {
throw new jIO.util.jIOError("Cannot access subdocument", 404);
}
query_list.push("DELETE FROM attachment WHERE id = ? " +
"AND attachment = ?");
argument_list.push([id, name]);
query_list.push("INSERT INTO attachment(id, attachment, part, blob)" +
"VALUES(?, ?, ?, ?)");
argument_list.push([id, name, -1,
blob.type || "application/octet-stream"]);
for (i = 0, index = 0; i < blob_size; i += part_size, index += 1) {
query_list.push("INSERT INTO attachment(id, attachment, part, blob)" +
"VALUES(?, ?, ?, ?)");
argument_list.push([id, name, index]);
sendBlobPart(blob.slice(i, i + part_size), argument_list, index,
queue);
}
queue.push(function () {
return queueSql(db, query_list, argument_list);
});
return queue;
});
};
WebSQLStorage.prototype.getAttachment = function (id, name, options) {
var db = this._database,
that = this,
part_size = this._blob_length,
start,
end,
start_index,
end_index;
if (options === undefined) { options = {}; }
start = options.start || 0;
end = options.end || -1;
if (start < 0 || (options.end !== undefined && options.end < 0)) {
throw new jIO.util.jIOError("_start and _end must be positive",
400);
}
if (start > end && end !== -1) {
throw new jIO.util.jIOError("_start is greater than _end",
400);
}
start_index = Math.floor(start / part_size);
if (start === 0) { start_index -= 1; }
end_index = Math.floor(end / part_size);
if (end % part_size === 0) {
end_index -= 1;
}
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
var command = "SELECT part, blob FROM attachment WHERE id = ? AND " +
"attachment = ? AND part >= ?",
argument_list = [id, name, start_index];
if (end !== -1) {
command += " AND part <= ?";
argument_list.push(end_index);
}
return queueSql(db, [command], [argument_list]);
})
.push(function (response_list) {
var i,
response,
blob_array = [],
blob,
type;
response = response_list[0].rows;
if (response.length === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
for (i = 0; i < response.length; i += 1) {
if (response[i].part === -1) {
type = response[i].blob;
start_index += 1;
} else {
blob_array.push(jIO.util.dataURItoBlob(response[i].blob));
}
}
if ((start === 0) && (options.end === undefined)) {
return new Blob(blob_array, {type: type});
}
blob = new Blob(blob_array, {});
return blob.slice(start - (start_index * part_size),
end === -1 ? blob.size :
end - (start_index * part_size),
"application/octet-stream");
});
};
WebSQLStorage.prototype.removeAttachment = function (id, name) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["DELETE FROM attachment WHERE " +
"id = ? AND attachment = ?"], [[id, name]]);
})
.push(function (result) {
if (result[0].rowsAffected === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return name;
});
};
WebSQLStorage.prototype.hasCapacity = function (name) {
return (name === "list" || (name === "include"));
};
WebSQLStorage.prototype.buildQuery = function (options) {
var db = this._database,
that = this,
query = "SELECT id";
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
if (options === undefined) { options = {}; }
if (options.include_docs === true) {
query += ", data AS doc";
}
query += " FROM document";
return queueSql(db, [query], [[]]);
})
.push(function (result) {
var array = [],
len = result[0].rows.length,
i;
for (i = 0; i < len; i += 1) {
array.push(result[0].rows[i]);
array[i].value = {};
if (array[i].doc !== undefined) {
array[i].doc = JSON.parse(array[i].doc);
}
}
return array;
});
};
jIO.addStorage('websql', WebSQLStorage);
}(jIO, RSVP, Blob, openDatabase));
/* /*
* Copyright 2017, Nexedi SA * Copyright 2017, Nexedi SA
* *
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>973.43645.19782.57207</string> </value> <value> <string>974.4070.21826.50261</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1550160394.98</float> <float>1551694892.25</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -53,13 +53,13 @@ ...@@ -53,13 +53,13 @@
<tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_id', 'value': '1', 'index': 0}"> <tal:block tal:define="filter_section_configuration python: {'key': 'COLUMN_id', 'value': '1', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block> </tal:block>
<tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': '( id: &nbsp;&#34;2&#34; AND id: &nbsp;&#34;3&#34; )', 'index': 1}"> <tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': 'id: (&nbsp; &#34;2&#34; AND&nbsp; &#34;3&#34; )', 'index': 1}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block> </tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="parsed_query python: '( id: &nbsp;&#34;1&#34; OR ( id: &nbsp;&#34;2&#34; AND id: &nbsp;&#34;3&#34; ) )'; <tal:block tal:define="parsed_query python: '( id: &nbsp;&#34;1&#34; OR id: (&nbsp; &#34;2&#34; AND&nbsp; &#34;3&#34; ) )';
search_query python: ''"> search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block> </tal:block>
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="parsed_query python: '( id: &nbsp;&#34;1&#34; OR ( id: &nbsp;&#34;2&#34; AND id: &nbsp;&#34;3&#34; ) )'; <tal:block tal:define="parsed_query python: '( id: &nbsp;&#34;1&#34; OR id: (&nbsp; &#34;2&#34; AND&nbsp; &#34;3&#34; ) )';
search_query python: ''"> search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block> </tal:block>
......
...@@ -48,14 +48,14 @@ ...@@ -48,14 +48,14 @@
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/search_in_form_list" />
</tal:block> </tal:block>
<tal:block tal:define="parsed_query python: '( id: &nbsp;&#34;2&#34; OR id: &nbsp;&#34;3&#34; )'; <tal:block tal:define="parsed_query python: 'id: (&nbsp; &#34;2&#34; OR&nbsp; &#34;3&#34; )';
search_query python: 'title'"> search_query python: 'title'">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block> </tal:block>
<!-- Open the panel and submit it. Check that the new query string is not to much changed --> <!-- Open the panel and submit it. Check that the new query string is not to much changed -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/triggle_filter_and" />
<tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': '( id: &nbsp;&#34;2&#34; OR id: &nbsp;&#34;3&#34; )', 'index': 0}"> <tal:block tal:define="filter_section_configuration python: {'key': 'RAW', 'value': 'id: (&nbsp; &#34;2&#34; OR&nbsp; &#34;3&#34; )', 'index': 0}">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_filter_section" />
</tal:block> </tal:block>
<tal:block tal:define="filter_section_configuration python: {'key': 'TEXT', 'value': 'title', 'index': 1}"> <tal:block tal:define="filter_section_configuration python: {'key': 'TEXT', 'value': 'title', 'index': 1}">
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/submit_filter" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tal:block tal:define="parsed_query python: '( id: &nbsp;&#34;2&#34; OR id: &nbsp;&#34;3&#34; )'; <tal:block tal:define="parsed_query python: 'id: (&nbsp; &#34;2&#34; OR&nbsp; &#34;3&#34; )';
search_query python: 'title'"> search_query python: 'title'">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block> </tal:block>
......
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
<td></td> <td></td>
</tr> </tr>
<tal:block tal:define="parsed_query python: '( id:&nbsp; &#34;0&#34; OR id:&nbsp; &#34;1&#34; OR id:&nbsp; &#34;2&#34; OR id:&nbsp; &#34;3&#34; )'; <tal:block tal:define="parsed_query python: 'id: (&nbsp; &#34;0&#34; OR&nbsp; &#34;1&#34; OR&nbsp; &#34;2&#34; OR&nbsp; &#34;3&#34; )';
search_query python: ''"> search_query python: ''">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block> </tal:block>
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<td></td> <td></td>
</tr> </tr>
<tal:block tal:define="search_query python: ''; <tal:block tal:define="search_query python: '';
parsed_query python: '( ( portal_type:&nbsp; &#34;Bar&#34; OR portal_type:&nbsp; &#34;Foo&#34; ) AND simulation_state:&nbsp; &#34;draft&#34; )'"> parsed_query python: '( portal_type: (&nbsp; &#34;Bar&#34; OR&nbsp; &#34;Foo&#34; ) AND simulation_state:&nbsp; &#34;draft&#34; )'">
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" /> <tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/check_search_in_form_list" />
</tal:block> </tal:block>
......
...@@ -6092,11 +6092,11 @@ var arrayExtend = function () { ...@@ -6092,11 +6092,11 @@ var arrayExtend = function () {
} }
return {type:"complex",operator:operator,query_list:query_list2}; return {type:"complex",operator:operator,query_list:query_list2};
}, simpleQuerySetKey = function (query, key) { }, querySetKey = function (query, key) {
var i; var i;
if (query.type === "complex") { if (query.type === "complex") {
for (i = 0; i < query.query_list.length; ++i) { for (i = 0; i < query.query_list.length; ++i) {
simpleQuerySetKey (query.query_list[i],key); querySetKey(query.query_list[i], key);
} }
return true; return true;
} }
...@@ -6217,7 +6217,7 @@ case 12: ...@@ -6217,7 +6217,7 @@ case 12:
this.$ = $$[$0-1]; this.$ = $$[$0-1];
break; break;
case 13: case 13:
simpleQuerySetKey($$[$0], $$[$0-2]); this.$ = $$[$0]; querySetKey($$[$0], $$[$0-2]); this.$ = $$[$0];
break; break;
case 15: case 15:
$$[$0].operator = $$[$0-1] ; this.$ = $$[$0]; $$[$0].operator = $$[$0-1] ; this.$ = $$[$0];
...@@ -7346,21 +7346,8 @@ return new Parser; ...@@ -7346,21 +7346,8 @@ return new Parser;
* #crossLink "Query/toString:method" * #crossLink "Query/toString:method"
*/ */
ComplexQuery.prototype.toString = function () { ComplexQuery.prototype.toString = function () {
var str_list = [], this_operator = this.operator; /*global objectToSearchText */
if (this.operator === "NOT") { return objectToSearchText(this.toJSON());
str_list.push("NOT (");
str_list.push(this.query_list[0].toString());
str_list.push(")");
return str_list.join(" ");
}
this.query_list.forEach(function (query) {
str_list.push("(");
str_list.push(query.toString());
str_list.push(")");
str_list.push(this_operator);
});
str_list.length -= 1;
return str_list.join(" ");
}; };
/** /**
...@@ -7459,21 +7446,60 @@ return new Parser; ...@@ -7459,21 +7446,60 @@ return new Parser;
}; };
function objectToSearchText(query) { function objectToSearchText(query) {
var str_list = []; var i = 0,
if (query.type === "complex") { query_list = null,
str_list.push("("); string_list = null,
(query.query_list || []).forEach(function (sub_query) { operator = "",
str_list.push(objectToSearchText(sub_query)); common_key = "";
str_list.push(query.operator);
});
str_list.length -= 1;
str_list.push(")");
return str_list.join(" ");
}
if (query.type === "simple") { if (query.type === "simple") {
return (query.key ? query.key + ": " : "") + return (query.key ? query.key + ": " : "") +
(query.operator || "") + ' "' + query.value + '"'; (query.operator || "") + ' "' + query.value + '"';
} }
if (query.type === "complex") {
query_list = query.query_list;
if (!query_list || query_list.length === 0) {
return "";
}
operator = query.operator || "";
if (operator === "NOT") {
// fallback to AND operator if several queries are given
// i.e. `NOT ( a AND b )`
return "NOT ( " + objectToSearchText(
{type: "complex", operator: "AND", query_list: query_list}
) + " )";
}
if (query_list.length === 1) {
return objectToSearchText(query_list[0]);
}
common_key = query_list[i].key;
for (i = 1; i < query_list.length; i += 1) {
if (query_list[i].type !== "simple" ||
query_list[i].key !== common_key) {
break;
}
}
string_list = [];
if (i === query_list.length) {
for (i = 0; i < query_list.length; i += 1) {
string_list.push(
(query_list[i].operator || "") +
' "' + query_list[i].value + '"'
);
}
} else {
common_key = "";
for (i = 0; i < query_list.length; i += 1) {
string_list.push(objectToSearchText(query_list[i]));
}
}
if (string_list.length > 1) {
return (common_key ? common_key + ": " : "") +
"( " + string_list.join(" " + operator + " ") + " )";
}
return (common_key ? common_key + ": " : "") +
string_list[0];
}
throw new TypeError("This object is not a query"); throw new TypeError("This object is not a query");
} }
...@@ -7641,8 +7667,7 @@ return new Parser; ...@@ -7641,8 +7667,7 @@ return new Parser;
* #crossLink "Query/toString:method" * #crossLink "Query/toString:method"
*/ */
SimpleQuery.prototype.toString = function () { SimpleQuery.prototype.toString = function () {
return (this.key ? this.key + ":" : "") + return objectToSearchText(this.toJSON());
(this.operator ? " " + this.operator : "") + ' "' + this.value + '"';
}; };
/** /**
...@@ -8080,17 +8105,11 @@ return new Parser; ...@@ -8080,17 +8105,11 @@ return new Parser;
* See https://www.nexedi.com/licensing for rationale and options. * See https://www.nexedi.com/licensing for rationale and options.
*/ */
/*global window, RSVP, Blob, XMLHttpRequest, QueryFactory, Query, atob, /*global window, RSVP, Blob, XMLHttpRequest, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator */ FileReader, ArrayBuffer, Uint8Array */
(function (window, RSVP, Blob, QueryFactory, Query, atob, (function (window, RSVP, Blob, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator) { FileReader, ArrayBuffer, Uint8Array) {
"use strict"; "use strict";
if (window.openDatabase === undefined) {
window.openDatabase = function () {
throw new Error('WebSQL is not supported by ' + navigator.userAgent);
};
}
/* Safari does not define DOMError */ /* Safari does not define DOMError */
if (window.DOMError === undefined) { if (window.DOMError === undefined) {
window.DOMError = {}; window.DOMError = {};
...@@ -8536,6 +8555,7 @@ return new Parser; ...@@ -8536,6 +8555,7 @@ return new Parser;
if (context.hasCapacity("list") && if (context.hasCapacity("list") &&
((options.query === undefined) || context.hasCapacity("query")) && ((options.query === undefined) || context.hasCapacity("query")) &&
((options.sort_on === undefined) || context.hasCapacity("sort")) && ((options.sort_on === undefined) || context.hasCapacity("sort")) &&
((options.group_by === undefined) || context.hasCapacity("group")) &&
((options.select_list === undefined) || ((options.select_list === undefined) ||
context.hasCapacity("select")) && context.hasCapacity("select")) &&
((options.include_docs === undefined) || ((options.include_docs === undefined) ||
...@@ -8622,7 +8642,7 @@ return new Parser; ...@@ -8622,7 +8642,7 @@ return new Parser;
window.jIO = jIO; window.jIO = jIO;
}(window, RSVP, Blob, QueryFactory, Query, atob, }(window, RSVP, Blob, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator)); FileReader, ArrayBuffer, Uint8Array));
/* /*
* Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1, * Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1,
* as defined in FIPS PUB 180-1, tuned for high performance with large inputs. * as defined in FIPS PUB 180-1, tuned for high performance with large inputs.
...@@ -13695,7 +13715,7 @@ return new Parser; ...@@ -13695,7 +13715,7 @@ return new Parser;
ERP5Storage.prototype.hasCapacity = function (name) { ERP5Storage.prototype.hasCapacity = function (name) {
return ((name === "list") || (name === "query") || return ((name === "list") || (name === "query") ||
(name === "select") || (name === "limit") || (name === "select") || (name === "limit") ||
(name === "sort")); (name === "sort") || (name === "group"));
}; };
function isSingleLocalRoles(parsed_query) { function isSingleLocalRoles(parsed_query) {
...@@ -13763,7 +13783,8 @@ return new Parser; ...@@ -13763,7 +13783,8 @@ return new Parser;
local_roles, local_roles,
local_role_found = false, local_role_found = false,
selection_domain, selection_domain,
sort_list = []; sort_list = [],
group_list = [];
if (options.query) { if (options.query) {
parsed_query = jIO.QueryFactory.create(options.query); parsed_query = jIO.QueryFactory.create(options.query);
result_list = isSingleLocalRoles(parsed_query); result_list = isSingleLocalRoles(parsed_query);
...@@ -13835,6 +13856,10 @@ return new Parser; ...@@ -13835,6 +13856,10 @@ return new Parser;
} }
} }
if (options.group_by) {
group_list = options.group_by;
}
if (selection_domain) { if (selection_domain) {
selection_domain = JSON.stringify(selection_domain); selection_domain = JSON.stringify(selection_domain);
} }
...@@ -13848,6 +13873,7 @@ return new Parser; ...@@ -13848,6 +13873,7 @@ return new Parser;
select_list: options.select_list || ["title", "reference"], select_list: options.select_list || ["title", "reference"],
limit: options.limit, limit: options.limit,
sort_on: sort_list, sort_on: sort_list,
group_by: group_list,
local_roles: local_roles, local_roles: local_roles,
selection_domain: selection_domain selection_domain: selection_domain
}) })
...@@ -15686,385 +15712,6 @@ return new Parser; ...@@ -15686,385 +15712,6 @@ return new Parser;
jIO.addStorage('crypt', CryptStorage); jIO.addStorage('crypt', CryptStorage);
}(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer)); }(jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer));
/*
* Copyright 2013, Nexedi SA
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Free Software licenses or any of the Open Source
* Initiative approved licenses and Convey the resulting work. Corresponding
* source of such a combination shall include the source code for all other
* software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
* See https://www.nexedi.com/licensing for rationale and options.
*/
/**
* JIO Websql Storage. Type = "websql".
* websql "database" storage.
*/
/*global Blob, jIO, RSVP, openDatabase*/
/*jslint nomen: true*/
(function (jIO, RSVP, Blob, openDatabase) {
"use strict";
/**
* The JIO Websql Storage extension
*
* @class WebSQLStorage
* @constructor
*/
function queueSql(db, query_list, argument_list) {
return new RSVP.Promise(function (resolve, reject) {
/*jslint unparam: true*/
db.transaction(function (tx) {
var len = query_list.length,
result_list = [],
i;
function resolveTransaction(tx, result) {
result_list.push(result);
if (result_list.length === len) {
resolve(result_list);
}
}
function rejectTransaction(tx, error) {
reject(error);
return true;
}
for (i = 0; i < len; i += 1) {
tx.executeSql(query_list[i], argument_list[i], resolveTransaction,
rejectTransaction);
}
}, function (tx, error) {
reject(error);
});
/*jslint unparam: false*/
});
}
function initDatabase(db) {
var query_list = [
"CREATE TABLE IF NOT EXISTS document" +
"(id VARCHAR PRIMARY KEY NOT NULL, data TEXT)",
"CREATE TABLE IF NOT EXISTS attachment" +
"(id VARCHAR, attachment VARCHAR, part INT, blob TEXT)",
"CREATE TRIGGER IF NOT EXISTS removeAttachment " +
"BEFORE DELETE ON document FOR EACH ROW " +
"BEGIN DELETE from attachment WHERE id = OLD.id;END;",
"CREATE INDEX IF NOT EXISTS index_document ON document (id);",
"CREATE INDEX IF NOT EXISTS index_attachment " +
"ON attachment (id, attachment);"
];
return new RSVP.Queue()
.push(function () {
return queueSql(db, query_list, []);
});
}
function WebSQLStorage(spec) {
if (typeof spec.database !== 'string' || !spec.database) {
throw new TypeError("database must be a string " +
"which contains more than one character.");
}
this._database = openDatabase("jio:" + spec.database,
'1.0', '', 2 * 1024 * 1024);
if (spec.blob_length &&
(typeof spec.blob_length !== "number" ||
spec.blob_length < 20)) {
throw new TypeError("blob_len parameter must be a number >= 20");
}
this._blob_length = spec.blob_length || 2000000;
this._init_db_promise = initDatabase(this._database);
}
WebSQLStorage.prototype.put = function (id, param) {
var db = this._database,
that = this,
data_string = JSON.stringify(param);
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["INSERT OR REPLACE INTO " +
"document(id, data) VALUES(?,?)"],
[[id, data_string]]);
})
.push(function () {
return id;
});
};
WebSQLStorage.prototype.remove = function (id) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["DELETE FROM document WHERE id = ?"], [[id]]);
})
.push(function (result_list) {
if (result_list[0].rowsAffected === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return id;
});
};
WebSQLStorage.prototype.get = function (id) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["SELECT data FROM document WHERE id = ?"],
[[id]]);
})
.push(function (result_list) {
if (result_list[0].rows.length === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return JSON.parse(result_list[0].rows[0].data);
});
};
WebSQLStorage.prototype.allAttachments = function (id) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, [
"SELECT id FROM document WHERE id = ?",
"SELECT DISTINCT attachment FROM attachment WHERE id = ?"
], [[id], [id]]);
})
.push(function (result_list) {
if (result_list[0].rows.length === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
var len = result_list[1].rows.length,
obj = {},
i;
for (i = 0; i < len; i += 1) {
obj[result_list[1].rows[i].attachment] = {};
}
return obj;
});
};
function sendBlobPart(blob, argument_list, index, queue) {
queue.push(function () {
return jIO.util.readBlobAsDataURL(blob);
})
.push(function (strBlob) {
argument_list[index + 2].push(strBlob.target.result);
return;
});
}
WebSQLStorage.prototype.putAttachment = function (id, name, blob) {
var db = this._database,
that = this,
part_size = this._blob_length;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["SELECT id FROM document WHERE id = ?"], [[id]]);
})
.push(function (result) {
var query_list = [],
argument_list = [],
blob_size = blob.size,
queue = new RSVP.Queue(),
i,
index;
if (result[0].rows.length === 0) {
throw new jIO.util.jIOError("Cannot access subdocument", 404);
}
query_list.push("DELETE FROM attachment WHERE id = ? " +
"AND attachment = ?");
argument_list.push([id, name]);
query_list.push("INSERT INTO attachment(id, attachment, part, blob)" +
"VALUES(?, ?, ?, ?)");
argument_list.push([id, name, -1,
blob.type || "application/octet-stream"]);
for (i = 0, index = 0; i < blob_size; i += part_size, index += 1) {
query_list.push("INSERT INTO attachment(id, attachment, part, blob)" +
"VALUES(?, ?, ?, ?)");
argument_list.push([id, name, index]);
sendBlobPart(blob.slice(i, i + part_size), argument_list, index,
queue);
}
queue.push(function () {
return queueSql(db, query_list, argument_list);
});
return queue;
});
};
WebSQLStorage.prototype.getAttachment = function (id, name, options) {
var db = this._database,
that = this,
part_size = this._blob_length,
start,
end,
start_index,
end_index;
if (options === undefined) { options = {}; }
start = options.start || 0;
end = options.end || -1;
if (start < 0 || (options.end !== undefined && options.end < 0)) {
throw new jIO.util.jIOError("_start and _end must be positive",
400);
}
if (start > end && end !== -1) {
throw new jIO.util.jIOError("_start is greater than _end",
400);
}
start_index = Math.floor(start / part_size);
if (start === 0) { start_index -= 1; }
end_index = Math.floor(end / part_size);
if (end % part_size === 0) {
end_index -= 1;
}
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
var command = "SELECT part, blob FROM attachment WHERE id = ? AND " +
"attachment = ? AND part >= ?",
argument_list = [id, name, start_index];
if (end !== -1) {
command += " AND part <= ?";
argument_list.push(end_index);
}
return queueSql(db, [command], [argument_list]);
})
.push(function (response_list) {
var i,
response,
blob_array = [],
blob,
type;
response = response_list[0].rows;
if (response.length === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
for (i = 0; i < response.length; i += 1) {
if (response[i].part === -1) {
type = response[i].blob;
start_index += 1;
} else {
blob_array.push(jIO.util.dataURItoBlob(response[i].blob));
}
}
if ((start === 0) && (options.end === undefined)) {
return new Blob(blob_array, {type: type});
}
blob = new Blob(blob_array, {});
return blob.slice(start - (start_index * part_size),
end === -1 ? blob.size :
end - (start_index * part_size),
"application/octet-stream");
});
};
WebSQLStorage.prototype.removeAttachment = function (id, name) {
var db = this._database,
that = this;
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
return queueSql(db, ["DELETE FROM attachment WHERE " +
"id = ? AND attachment = ?"], [[id, name]]);
})
.push(function (result) {
if (result[0].rowsAffected === 0) {
throw new jIO.util.jIOError("Cannot find document", 404);
}
return name;
});
};
WebSQLStorage.prototype.hasCapacity = function (name) {
return (name === "list" || (name === "include"));
};
WebSQLStorage.prototype.buildQuery = function (options) {
var db = this._database,
that = this,
query = "SELECT id";
return new RSVP.Queue()
.push(function () {
return that._init_db_promise;
})
.push(function () {
if (options === undefined) { options = {}; }
if (options.include_docs === true) {
query += ", data AS doc";
}
query += " FROM document";
return queueSql(db, [query], [[]]);
})
.push(function (result) {
var array = [],
len = result[0].rows.length,
i;
for (i = 0; i < len; i += 1) {
array.push(result[0].rows[i]);
array[i].value = {};
if (array[i].doc !== undefined) {
array[i].doc = JSON.parse(array[i].doc);
}
}
return array;
});
};
jIO.addStorage('websql', WebSQLStorage);
}(jIO, RSVP, Blob, openDatabase));
/* /*
* Copyright 2017, Nexedi SA * Copyright 2017, Nexedi SA
* *
......
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