Skip to content
Snippets Groups Projects
Commit 60f50fdb authored by Sebastian Listl's avatar Sebastian Listl :speech_balloon:
Browse files

Sql_lib case when

parent 2292266a
No related branches found
No related tags found
No related merge requests found
......@@ -801,6 +801,26 @@ function SqlBuilder (pAlias)
this._where = {};
this._initWhere();
SqlBuilder.defineCanBuildSql(this);
}
/**
* @return {Symbol}
*/
SqlBuilder.getCanBuildSqlSymbol = function ()
{
return Symbol["for"]("canBuildSql");
}
SqlBuilder.defineCanBuildSql = function (pObject)
{
pObject[SqlBuilder.getCanBuildSqlSymbol()] = true;
}
SqlBuilder.checkCanBuildSql = function (pObject)
{
return pObject[SqlBuilder.getCanBuildSqlSymbol()];
}
/**
......@@ -1097,11 +1117,11 @@ SqlBuilder.prototype.join = function(pTable, pCondition, pTableAlias, pPrefix, p
if (pCondition)
{
if (pCondition instanceof SqlBuilder)
pCondition = [pCondition._where._sqlStorage, pCondition._where.preparedValues]
pCondition = [pCondition._where.sqlStorage, pCondition._where.preparedValues]
var conditionPart = SqlBuilder._getStatement(pCondition);
joinPart._sqlStorage += " " + conditionPart._sqlStorage;
joinPart.sqlStorage += " " + conditionPart.sqlStorage;
joinPart.preparedValues = joinPart.preparedValues.concat(conditionPart.preparedValues);
}
......@@ -1200,7 +1220,7 @@ SqlBuilder.prototype.where = function(pFieldOrCond, pValue, pCondition, pFieldTy
copiedCondition._where.preparedValues = pFieldOrCond.preparedValues;
copiedCondition._where._lastWasOr = pFieldOrCond._lastWasOr;
copiedCondition._where._sqlStorage = pFieldOrCond._sqlStorage;
copiedCondition._where.sqlStorage = pFieldOrCond.sqlStorage;
pFieldOrCond = copiedCondition;
......@@ -1351,7 +1371,7 @@ SqlBuilder.prototype._whereCondition = function(pCondition, pMandatory, pAddPrep
if (sql instanceof SqlBuilder)
{
// add only brackets if needed
var sqlString = sql._where._sqlStorage;
var sqlString = sql._where.sqlStorage;
var condString = sqlString;
......@@ -1509,7 +1529,7 @@ SqlBuilder.prototype._addWhere = function(pFieldOrCond, pValue, pMandatory, pCon
var subSqlPrepared = pFieldOrCond.build();
tmpCond._where._sqlStorage = SqlUtils.replaceConditionTemplate(tmpCond._where._sqlStorage, 'SQL_LIB_DUMMY_TABLE.SQL_LIB_DUMMY_COLUMN', "( " + subSqlPrepared[0] + " )");
tmpCond._where.sqlStorage = SqlUtils.replaceConditionTemplate(tmpCond._where.sqlStorage, 'SQL_LIB_DUMMY_TABLE.SQL_LIB_DUMMY_COLUMN', "( " + subSqlPrepared[0] + " )");
tmpCond._where.preparedValues = subSqlPrepared[1].concat(tmpCond._where.preparedValues)
this._whereCondition(tmpCond, pMandatory, pAddPreparedConditionCallback, true)
......@@ -1629,9 +1649,9 @@ SqlBuilder.prototype._and = function(pFieldOrCond, pValue, pMandatory, pConditio
if (pPreparedCondition.length == 2 && typeof pPreparedCondition[0] == "string" && pPreparedCondition[0] != "" && Array.isArray(pPreparedCondition[1]))
{
if (that.hasCondition())
that._where._sqlStorage += " and ";
that._where.sqlStorage += " and ";
that._where._sqlStorage += pPreparedCondition[0];
that._where.sqlStorage += pPreparedCondition[0];
that._where.preparedValues = that._where.preparedValues.concat(pPreparedCondition[1]);
}
});
......@@ -1657,7 +1677,7 @@ SqlBuilder.prototype._or = function(pFieldOrCond, pValue, pMandatory, pCondition
{
if (that._where._previouslyOnlyOr)
{
that._where._sqlStorage = that._where._sqlStorage + " or " + pPreparedCondition[0];
that._where.sqlStorage = that._where.sqlStorage + " or " + pPreparedCondition[0];
that._where._lastWasOr = true;
}
else if (that.hasCondition())
......@@ -1668,9 +1688,9 @@ SqlBuilder.prototype._or = function(pFieldOrCond, pValue, pMandatory, pCondition
cond = "(" + cond + ")";
if (that._where._lastWasOr)
that._where._sqlStorage = that._where._sqlStorage + " or " + cond;
that._where.sqlStorage = that._where.sqlStorage + " or " + cond;
else
that._where._sqlStorage = "(" + that._where._sqlStorage + ") or " + cond;
that._where.sqlStorage = "(" + that._where.sqlStorage + ") or " + cond;
that._where._lastWasOr = true;
}
......@@ -1679,7 +1699,7 @@ SqlBuilder.prototype._or = function(pFieldOrCond, pValue, pMandatory, pCondition
if (!that.hasCondition())
that._where._previouslyOnlyOr = true;
that._where._sqlStorage = pPreparedCondition[0];
that._where.sqlStorage = pPreparedCondition[0];
}
that._where.preparedValues = that._where.preparedValues.concat(pPreparedCondition[1]);
}
......@@ -2170,7 +2190,7 @@ SqlBuilder.prototype.having = function(pCondition)
* @return {Boolean} true if conditions have been added, false when not
*/
SqlBuilder.prototype.hasCondition = function() {
if (this._where._sqlStorage)
if (this._where.sqlStorage)
return true;
return false;
}
......@@ -2217,7 +2237,7 @@ SqlBuilder.prototype.clearWhere = function()
SqlBuilder.prototype._initWhere = function ()
{
//TODO: maybe put conditions in an object/array for better internal object structure
this._where._sqlStorage = "";
this._where.sqlStorage = "";
this._where.preparedValues = [];
this._where._lastWasOr = false; // save, if the last condition was an OR. For better bracket-placement
this._where._previouslyOnlyOr = false; // also for better bracket-placement
......@@ -2329,24 +2349,22 @@ SqlBuilder._getStatement = function (pElement, pPrefix, pPostfix, pAutoJoin, pUs
return {
preparedValues: preparedValues,
_sqlStorage: pElement.toString()
sqlStorage: pElement.toString()
};
function _getElement (element)
{
var isSubQuery = false;
var subselectAlias = "";
if (element instanceof SqlBuilder)
if (SqlBuilder.checkCanBuildSql(element))
{
if (element.isFullSelect())
if (element instanceof SqlBuilder && element.isFullSelect())
{
isSubQuery = true;
if (pUseSubselectAlias && element._subselectAlias)
subselectAlias = " " + element._subselectAlias;
}
element = element.build();
}
preparedValues = preparedValues.concat(element[1]);
......@@ -2363,7 +2381,7 @@ SqlBuilder._getStatement = function (pElement, pPrefix, pPostfix, pAutoJoin, pUs
*/
SqlBuilder.prototype.buildCondition = function()
{
return [this._where._sqlStorage, this._where.preparedValues];
return [this._where.sqlStorage, this._where.preparedValues];
}
/**
......@@ -2378,17 +2396,17 @@ SqlBuilder.prototype.build = function(pDefaultConditionIfNone)
if (this.isFullSelect())
{
if (this._where._sqlStorage)
if (this._where.sqlStorage)
wherePrefix = "where ";
}
var whereSql = this._where._sqlStorage;
var whereSql = this._where.sqlStorage;
if (!this.hasCondition() && pDefaultConditionIfNone)
whereSql = wherePrefix + pDefaultConditionIfNone;
var whereObj = {
_sqlStorage : wherePrefix + whereSql,
sqlStorage : wherePrefix + whereSql,
preparedValues : this._where.preparedValues
}
......@@ -2409,9 +2427,9 @@ SqlBuilder.prototype.build = function(pDefaultConditionIfNone)
let part = allParts[i];
if (part)
{
if (sqlStr && part._sqlStorage)
if (sqlStr && part.sqlStorage)
sqlStr += " ";
sqlStr += part._sqlStorage;
sqlStr += part.sqlStorage;
if (part.preparedValues.length)
preparedVals = preparedVals.concat(part.preparedValues);
}
......@@ -3057,6 +3075,157 @@ SqlBuilder.prototype.translate = function(pAlias)
return SqlUtils.translateStatementWithQuotes(this.build(), pAlias);
}
/**
* Creates an object for building a case-when statement.
*
* @param {String|String[]|SqlBuilder|PreparedSqlArray} [pFieldOrCond] If this is the only parameter, it is used as Subselect <br/>
* else it is used as Field. <br/>
* Please see .where() for more information and examples.
* @param {String|SqlBuilder|PreparedSqlArray|Array|OtherTypes} [pValue] This is the value whitch is used for the condition.<br/>
* Basically it can be nearly everything you need.<br/>
* Please see .where() for more information and examples.
* @param {String} [pCondition="# = ?"] This is the condition which should be used.<br/>
* # will be replaced by the field (pFieldOrCond) If pFieldOrCond is null, you can ommit #<br/>
* ? will be replaced by pValue<br/>
* <strong>IMPORTANT: the # has to be before the ?</strong><br/>
* Please see .where() for more information and examples.
* @param {SQLTYPES|Numeric} [pFieldType=AutomaticallyLoadedType] You can specify which datatype should be used for the prepared statement<br/>
* In most cases you don't need this.<br/>
* Please see .where() for more information and examples.
*
* @return {SqlBuilder._CaseWhen}
*/
SqlBuilder.caseWhen = function (pFieldOrCond, pValue, pCondition, pFieldType)
{
return new SqlBuilder._CaseStatement().when(pFieldOrCond, pValue, pCondition, pFieldType);
}
/**
* Represents a case-when statement
*/
SqlBuilder._CaseStatement = function ()
{
this._whenCondition = null;
this._whenThens = [];
this._elseValue = null;
this._afterWhenMask = new SqlBuilder._CaseWhen(this);
SqlBuilder.defineCanBuildSql(this);
}
/**
* @param {String|String[]|SqlBuilder|PreparedSqlArray} [pFieldOrCond] If this is the only parameter, it is used as Subselect <br/>
* else it is used as Field. <br/>
* Please see .where() for more information and examples.
* @param {String|SqlBuilder|PreparedSqlArray|Array|OtherTypes} [pValue] This is the value whitch is used for the condition.<br/>
* Basically it can be nearly everything you need.<br/>
* Please see .where() for more information and examples.
* @param {String} [pCondition="# = ?"] This is the condition which should be used.<br/>
* # will be replaced by the field (pFieldOrCond) If pFieldOrCond is null, you can ommit #<br/>
* ? will be replaced by pValue<br/>
* <strong>IMPORTANT: the # has to be before the ?</strong><br/>
* Please see .where() for more information and examples.
* @param {SQLTYPES|Numeric} [pFieldType=AutomaticallyLoadedType] You can specify which datatype should be used for the prepared statement<br/>
* In most cases you don't need this.<br/>
* Please see .where() for more information and examples.
*
* @return {SqlBuilder._CaseWhen}
*/
SqlBuilder._CaseStatement.prototype.when = function (pFieldOrCond, pValue, pCondition, pFieldType)
{
this._whenCondition = newWhere(pFieldOrCond, pValue, pCondition, pFieldType);
return this._afterWhenMask;
}
/**
* Sets the expression used for the else-part
*
* @param {String|SqlBuilder} pValue else-value
* @return {SqlBuilder._CaseStatement}
*/
SqlBuilder._CaseStatement.prototype.elseValue = function (pValue)
{
this._elseValue = pValue;
return this;
}
/**
* Sets the value used for the else-part, but wraps the value in ''
*
* @param {String} pValue else-value
* @return {SqlBuilder._CaseStatement}
*/
SqlBuilder._CaseStatement.prototype.elseString = function (pValue)
{
return this.elseValue("'" + pValue + "'");
}
/**
* @return {String} the case-when expression
*/
SqlBuilder._CaseStatement.prototype.toString = function (pAlias)
{
return db.translateStatement(this.build(), pAlias || db.getCurrentAlias());
}
SqlBuilder._CaseStatement.prototype.build = function ()
{
var caseStatement = ["case"];
var preparedValues = [];
this._whenThens.forEach(function (whenThen)
{
var when = SqlBuilder._getStatement(whenThen.condition, "when");
var then = SqlBuilder._getStatement(whenThen.thenValue, "then");
caseStatement.push(when.sqlStorage);
caseStatement.push(then.sqlStorage);
preparedValues = preparedValues.concat(when.preparedValues, then.preparedValues);
});
if (this._elseValue)
{
let elseStatement = SqlBuilder._getStatement(this._elseValue, "else");
caseStatement.push(elseStatement.sqlStorage);
preparedValues = preparedValues.concat(elseStatement.preparedValues);
}
caseStatement.push("end");
return [
caseStatement.join(" "),
preparedValues
];
}
/**
* Object providing the then-methods for the case-when expression. It can be only be accessed after calling .when to ensure a 'then'
* can only be added after a 'when'.
*/
SqlBuilder._CaseWhen = function (pCaseStatement)
{
this._caseStatement = pCaseStatement;
}
/**
* Sets the expression for the then
*
* @param {String|SqlBuilder} pValue then-value
* @return {SqlBuilder._CaseStatement}
*/
SqlBuilder._CaseWhen.prototype.then = function (pValue)
{
var condition = this._caseStatement._whenCondition;
this._caseStatement._whenCondition = null;
this._caseStatement._whenThens.push({condition: condition, thenValue: pValue});
return this._caseStatement;
}
/**
* Sets the value for the then, but wraps the value in ''
*
* @param {String} pValue then-value
* @return {SqlBuilder._CaseStatement}
*/
SqlBuilder._CaseWhen.prototype.thenString = function (pValue)
{
return this.then("'" + pValue + "'");
}
/**
*provides functions for masking sql functions
......
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