Skip to content
Snippets Groups Projects
Commit 27df85f1 authored by S.Listl's avatar S.Listl
Browse files

SqlBuilder object

parent 39005163
No related branches found
No related tags found
No related merge requests found
......@@ -19,7 +19,7 @@ var showEmpty = vars.exists("$param.ShowEmpty_param") && vars.getString("$param.
var displaySimpleName = vars.exists("$param.DisplaySimpleName_param") && vars.get("$param.DisplaySimpleName_param");
var sqlCondition = new SqlCondition();
var subCondition = new SqlCondition();
var joinCondition = new SqlCondition();
if (vars.exists("$local.idvalues") && vars.get("$local.idvalues"))
{
......@@ -51,28 +51,29 @@ else if (showEmpty || rowId)
{
let filteredIds = JSON.parse(vars.getString("$param.FilteredAttributeIds_param"));
subCondition.clear();
joinCondition.clear();
let filteredIdChildren = AttributeUtil.getAllChildren(filteredIds);
subCondition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", filteredIdChildren);
subCondition.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?")
joinCondition.andIn("AB_ATTRIBUTE.AB_ATTRIBUTEID", filteredIdChildren);
joinCondition.andPrepare("AB_ATTRIBUTE.ATTRIBUTE_TYPE", $AttributeTypes.COMBOVALUE, "# != ?")
// return nothing if filteredAttributeIds is an empty array. (--> and 1=2)
sqlCondition.andSqlCondition(subCondition, "1=2");
sqlCondition.andSqlCondition(joinCondition, "1=2");
}
}
var joinCondition = "";
if (rowId)
{
subCondition.andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", rowId);
joinCondition.andPrepare("AB_ATTRIBUTERELATION.OBJECT_ROWID", rowId);
if (objectType != null)
subCondition.andPrepare("AB_ATTRIBUTERELATION.OBJECT_TYPE", objectType);
if (subCondition.isSet())
joinCondition = " and " + db.translateCondition(subCondition.build("1=1"));
joinCondition.andPrepare("AB_ATTRIBUTERELATION.OBJECT_TYPE", objectType);
// add condition to match all returned by joins (override default 1=2 of build)
sqlCondition.and("1=1");
}
joinCondition.and("AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID");
var defaultFields = [
"AB_ATTRIBUTERELATIONID",
"AB_ATTRIBUTE.AB_ATTRIBUTEID",
......@@ -84,14 +85,20 @@ var defaultFields = [
];
//these fields hold the attributeRelation value, depending on the attribute type
var valueFields = AttributeTypeUtil.getAllDatabaseFields();
var attributeSql = sqlCondition.buildSql("select " + defaultFields.join(", ") + ", " + valueFields.join(", ")
+ " from AB_ATTRIBUTE "
+ (showEmpty ? "left " : "") + "join AB_ATTRIBUTERELATION on AB_ATTRIBUTERELATION.AB_ATTRIBUTE_ID = AB_ATTRIBUTE.AB_ATTRIBUTEID " + joinCondition
+ " left join AB_ATTRIBUTE COMBOVAL on " + $AttributeTypes.COMBO.databaseField + " = COMBOVAL.AB_ATTRIBUTEID" //for the view value of combobox attributes
, "1=2"
);
var attributeValues = db.table(attributeSql).map(function (row)
var attributeSql = SqlBuilder.begin()
.select(defaultFields.concat(valueFields))
.from("AB_ATTRIBUTE");
if (showEmpty)
attributeSql.leftJoin("AB_ATTRIBUTERELATION", joinCondition.build("1=1"));
else
attributeSql.join("AB_ATTRIBUTERELATION", joinCondition.build("1=1"));
attributeSql.leftJoin("AB_ATTRIBUTE", SqlCondition.begin()
.andPrepare(["AB_ATTRIBUTE", "AB_ATTRIBUTEID", "COMBOVAL"], $AttributeTypes.COMBO.databaseField)
.build(), "COMBOVAL");
var attributeValues = db.table(attributeSql.build()).map(function (row)
{
var attributeId = row[1];
var attributeName = translate.text(row[4]);
......@@ -149,4 +156,4 @@ function _fetchAttributes (pAttributeIds)
if (nextIds.length)
_fetchAttributes(nextIds);
}
}
\ No newline at end of file
import("system.logging");
import("system.translate");
import("system.vars");
import("system.util");
......@@ -598,7 +599,17 @@ SqlCondition.equalsNot = function(pField, pValue, pAlternativeCond, pAlias) {
*/
function SqlBuilder ()
{
this._query = [];
if(!(this instanceof SqlBuilder))
throw new Error(translate.text("SqlBuilder must be instanciated with 'new'"));
this._sqlStr = "";
this._select = null;
this._from = null;
this._joins = [];
this._where = null;
this._groupBy = null;
this._having = null;
this._orderBy = null;
this._unions = [];
}
/**
......@@ -606,6 +617,20 @@ function SqlBuilder ()
* methods on it directly without having to put brackets around it
*
* @return {SqlBuilder} a new SqlBuilder object
*
* @example
* var query = SqlBuilder.begin()
* .select("ORGANISATION.NAME, FIRSTNAME, LASTNAME")
* .from("PERSON")
* .join("CONTACT", "CONTACT.PERSON_ID = PERSON.PERSONID")
* .leftJoin("ORGANISATION", SqlCondition.begin()
* .and("CONTACT.ORGANISATION_ID = ORGANISATION.ORGANISATIONID")
* .andPrepare("ORGANISATION.NAME", "S%", "# like ?"))
* .where(SqlCondition.begin()
* .andPrepare("CONTACT.STATUS", $KeywordRegistry.contactStatus$active()))
* .build();
*
* var data = db.table(query);
*/
SqlBuilder.begin = function ()
{
......@@ -628,7 +653,7 @@ SqlBuilder.prototype.toString = function ()
*/
SqlBuilder.prototype.select = function (pFields)
{
this._append(pFields, "select", true);
this._select = this._getClause(pFields, "select", true);
return this;
}
......@@ -639,7 +664,7 @@ SqlBuilder.prototype.select = function (pFields)
*/
SqlBuilder.prototype.selectDistinct = function (pFields)
{
this._append(pFields, "select distinct", true);
this._select = this._getClause(pFields, "select distinct", true);
return this;
}
......@@ -653,15 +678,15 @@ SqlBuilder.prototype.from = function (pTable, pAlias)
{
if (pAlias)
pTable += " " + pAlias;
this._append(pTable, "from");
this._from = this._getClause(pTable, "from");
return this;
}
/**
* Adds a join clause to the sql.
* @param {String} pTable
* @param {String|String[]} pCondition The where condition. This can be
* a string (without the where keyword) or an array (for prepared queries).
* @param {String|String[]|SqlCondition} pCondition The where condition. This can be
* a string (without the where keyword), a SqlCondition or an array (for prepared queries).
* @param {String} [pAlias] table alias
* @return {SqlBuilder} current SqlBuilder object
*/
......@@ -670,16 +695,15 @@ SqlBuilder.prototype.join = function (pTable, pCondition, pAlias)
var joinStr = "join " + pTable;
if (pAlias)
joinStr += " " + pAlias;
this._append(joinStr + " on");
this._append(pCondition);
this._joins.push(this._getClause(pCondition, joinStr + " on"));
return this;
}
/**
* Adds a left join clause to the sql.
* @param {String} pTable
* @param {String|String[]} pCondition The where condition. This can be
* a string (without the where keyword) or an array (for prepared queries).
* @param {String|String[]|SqlCondition} pCondition The where condition. This can be
* a string (without the where keyword), a SqlCondition or an array (for prepared queries).
* @param {String} [pAlias] table alias
* @return {SqlBuilder} current SqlBuilder object
*/
......@@ -688,23 +712,21 @@ SqlBuilder.prototype.leftJoin = function (pTable, pCondition, pAlias)
var joinStr = "left join " + pTable;
if (pAlias)
joinStr += " " + pAlias;
this._append(joinStr + " on");
this._append(pCondition);
this._joins.push(this._getClause(pCondition, joinStr + " on"));
return this;
}
/**
* Adds a where clause to the sql.
*
* @param {String|String[]} pCondition The where condition. This can be
* a string (without the where keyword) or an array (for prepared queries).
* @param {String|String[]|SqlCondition} pCondition The where condition. This can be
* a string (without the where keyword), a SqlCondition or an array (for prepared queries).
*
* @return {SqlBuilder} current SqlBuilder object
*/
SqlBuilder.prototype.where = function (pCondition)
{
this._append("where");
this._append(pCondition);
this._where = this._getClause(pCondition, "where");
return this;
}
......@@ -715,18 +737,7 @@ SqlBuilder.prototype.where = function (pCondition)
*/
SqlBuilder.prototype.orderBy = function (pOrderBy)
{
this._append(pOrderBy, "order by");
return this;
}
/**
* Adds another SqlBuilder object as a subquery.
* @param {SqlBuilder} pSubSelect
* @return {SqlBuilder} current SqlBuilder object
*/
SqlBuilder.prototype.subSelect = function (pSubSelect)
{
this._append(pSubSelect);
this.orderBy = this._getClause(pOrderBy, "order by");
return this;
}
......@@ -737,7 +748,7 @@ SqlBuilder.prototype.subSelect = function (pSubSelect)
*/
SqlBuilder.prototype.groupBy = function (pFields)
{
this._append(pFields, "group by", true);
this._groupBy = this._getClause(pFields, "group by", true);
return this;
}
......@@ -748,8 +759,7 @@ SqlBuilder.prototype.groupBy = function (pFields)
*/
SqlBuilder.prototype.union = function (pSelect)
{
this._append("union");
this._append(pSelect);
this._unions.push(this._getClause(pSelect, "union"));
return this;
}
......@@ -760,28 +770,26 @@ SqlBuilder.prototype.union = function (pSelect)
*/
SqlBuilder.prototype.unionAll = function (pSelect)
{
this._append("union all");
this._append(pSelect);
this._unions.push(this._getClause(pSelect, "union all"));
return this;
}
/**
* Adds a having clause to the sql.
*
* @param {String|String[]} pCondition The where condition. This can be
* a string (without the where keyword) or an array (for prepared queries).
* @param {String|String[]|SqlCondition} pCondition The where condition. This can be
* a string (without the where keyword), a SqlCondition or an array (for prepared queries).
*
* @return {SqlBuilder} current SqlBuilder object
*/
SqlBuilder.prototype.having = function (pCondition)
{
this._append("having");
this._append(pCondition);
this._having = this._getClause(pCondition, "having");
return this;
}
/**
* adds an element
* generates a part of the sql
*
* @param {String|String[]|SqlBuilder} pElement the element to append
* @param {String} [pPrefix] string to be added before pElement
......@@ -790,13 +798,44 @@ SqlBuilder.prototype.having = function (pCondition)
*
* @private
*/
SqlBuilder.prototype._append = function (pElement, pPrefix, pAutoJoin)
SqlBuilder.prototype._getClause = function (pElement, pPrefix, pAutoJoin)
{
if (pAutoJoin && pElement && typeof pElement !== "string" && pElement.length !== undefined)
pElement = pElement.join(", ");
var preparedValues = [];
if (pElement instanceof SqlBuilder || pElement instanceof SqlCondition)
{
pElement = _getElement(pElement);
}
else if (typeof pElement !== "string" && pElement.length !== undefined) //array
{
if (pAutoJoin)
{
for (let i = 0, l = pElement.length; i < l; i++)
{
if (pElement[i] instanceof SqlBuilder)
pElement[i] = _getElement(pElement);
}
pElement = pElement.join(", ");
}
else
{
preparedValues = preparedValues.concat(pElement[1]);
pElement = pElement[0];
}
}
if (pPrefix)
pElement = pPrefix + " " + pElement;
this._query.push(pPrefix + " " + pElement);
return [pElement.toString(), preparedValues];
function _getElement (element)
{
let condition = element.build();
preparedValues = preparedValues.concat(element[1]);
if (element instanceof SqlBuilder)
return "(" + element[0] + ")";
return element[0];
}
}
/**
......@@ -806,27 +845,36 @@ SqlBuilder.prototype._append = function (pElement, pPrefix, pAutoJoin)
*/
SqlBuilder.prototype.build = function ()
{
var sqlStr = "";
var preparedValues = [];
if (!this._select)
throw new Error(translate.text("SqlBuilder must contain a select clause!"));
if (!this._from)
throw new Error(translate.text("SqlBuilder must contain a from clause!"));
for (let i = 0, l = this._query.length; i < l; i++)
var sqlStr = "";
var preparedVals = [];
var allParts = [
this._select,
this._from
].concat(this._joins).concat([
this._where,
this._groupBy,
this._having,
this._orderBy,
this._unions
]).concat(this._unions);
for (let i = 0, l = allParts.length; i < l; i++)
{
let sqlPart = this._query[i];
if (sqlPart instanceof SqlBuilder)
{
let condition = sqlPart.build();
sqlPart = "(" + condition[0] + ")";
preparedValues = preparedValues.concat(condition[1]);
}
//array => prepared statement
else if (typeof pElement !== "string" && pElement.length === 2 && pElement[1].length !== undefined)
let part = allParts[i];
if (part && part.length)
{
preparedValues = preparedValues.concat(sqlPart[1]);
sqlPart = sqlPart[0];
if (sqlStr)
sqlStr += " ";
sqlStr += part[0];
preparedVals = preparedVals.concat(part[1]);
}
sqlStr += " " + sqlPart;
}
return [sqlStr.trim(), preparedValues];
return [sqlStr, preparedVals];
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment