Commit 20f2d3e9 authored by Romain Courteaud's avatar Romain Courteaud

Release 3.37.0

Deprecate websql.

Add group_by parameter to allDocs.

Queries: Fix some parsing/serialization issues
parent 83d022d4
...@@ -26,7 +26,7 @@ TESTDIR = test ...@@ -26,7 +26,7 @@ TESTDIR = test
EXAMPLEDIR = examples EXAMPLEDIR = examples
EXTERNALDIR = external EXTERNALDIR = external
VERSION = 3.36.1 VERSION = 3.37.0
JIOVERSION = ${DISTDIR}/jio-v${VERSION}.js JIOVERSION = ${DISTDIR}/jio-v${VERSION}.js
JIOLATEST = ${DISTDIR}/jio-latest.js JIOLATEST = ${DISTDIR}/jio-latest.js
JIONODEVERSION = ${DISTDIR}/jio-v${VERSION}-node.js JIONODEVERSION = ${DISTDIR}/jio-v${VERSION}-node.js
......
...@@ -7870,11 +7870,11 @@ var arrayExtend = function () { ...@@ -7870,11 +7870,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;
} }
...@@ -7995,7 +7995,7 @@ case 12: ...@@ -7995,7 +7995,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];
...@@ -9124,21 +9124,8 @@ return new Parser; ...@@ -9124,21 +9124,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(" ");
}; };
/** /**
...@@ -9237,21 +9224,60 @@ return new Parser; ...@@ -9237,21 +9224,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");
} }
...@@ -9419,8 +9445,7 @@ return new Parser; ...@@ -9419,8 +9445,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 + '"';
}; };
/** /**
...@@ -10090,17 +10115,11 @@ var XMLHttpRequest = global.XMLHttpRequest || module.exports, ...@@ -10090,17 +10115,11 @@ var XMLHttpRequest = global.XMLHttpRequest || module.exports,
* 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 = {};
...@@ -10546,6 +10565,7 @@ var XMLHttpRequest = global.XMLHttpRequest || module.exports, ...@@ -10546,6 +10565,7 @@ var XMLHttpRequest = global.XMLHttpRequest || module.exports,
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) ||
...@@ -10632,7 +10652,7 @@ var XMLHttpRequest = global.XMLHttpRequest || module.exports, ...@@ -10632,7 +10652,7 @@ var XMLHttpRequest = global.XMLHttpRequest || module.exports,
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));
/* /*
* Copyright 2018, Nexedi SA * Copyright 2018, Nexedi SA
* *
...@@ -14178,7 +14198,7 @@ var jIO = window.jIO, ...@@ -14178,7 +14198,7 @@ var jIO = window.jIO,
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) {
...@@ -14246,7 +14266,8 @@ var jIO = window.jIO, ...@@ -14246,7 +14266,8 @@ var jIO = window.jIO,
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);
...@@ -14318,6 +14339,10 @@ var jIO = window.jIO, ...@@ -14318,6 +14339,10 @@ var jIO = window.jIO,
} }
} }
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);
} }
...@@ -14331,6 +14356,7 @@ var jIO = window.jIO, ...@@ -14331,6 +14356,7 @@ var jIO = window.jIO,
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
}) })
......
...@@ -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
* *
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"name": "jio", "name": "jio",
"version": "v3.36.0", "version": "v3.37.0",
"license": "GPLv3+", "license": "GPLv3+",
"author": "Nexedi SA", "author": "Nexedi SA",
"contributors": [ "contributors": [
......
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