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

merged origin/2020.2 into 2020.2.1

parents 98a71ca5 a88ceaa0
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
......
......@@ -38,23 +38,23 @@ WorkflowUtils.getPossibleWorkflowDefinitions = function (pContext)
* opens the WorkflowInstance context in new-mode
*
* @param {Object} [pVariables] variables for the process instance
* @param {String} [pTargetId=$sys.uid] uid of the target object
* @param {String} [pTargetIds=$sys.uid] uid of the target object
* @param {String} [pTargetContext=current context] target context
* @param {String} [pSelectionFilter] filter
*/
WorkflowUtils.openNewInstance = function (pVariables, pTargetId, pTargetContext, pSelectionFilter)
WorkflowUtils.openNewInstance = function (pVariables, pTargetIds, pTargetContext, pSelectionFilter)
{
if ((!pTargetId || pTargetId.length === 0) && pSelectionFilter)
pTargetId = [];
if ((!pTargetIds || pTargetIds.length === 0) && pSelectionFilter)
pTargetIds = [];
if (!pVariables)
pVariables = {};
Object.assign(pVariables, WorkflowVariables.getTargetVariables(pTargetId, pTargetContext));
Object.assign(pVariables, WorkflowVariables.getTargetVariables(pTargetIds, pTargetContext));
neon.openContext("WorkflowInstance", null, null, neon.OPERATINGSTATE_NEW, {
neon.openContext("WorkflowLauncher", "WorkflowLauncherEdit_view", null, neon.OPERATINGSTATE_VIEW, {
"ProcessVariables_param" : JSON.stringify(pVariables),
"TargetContext_param" : pVariables[WorkflowVariables.TARGET_CONTEXT()],
"TargetIdFilter_param" : pSelectionFilter ? JSON.stringify(pSelectionFilter) : ""
"TargetFilter_param" : pSelectionFilter ? JSON.stringify(pSelectionFilter) : ""
});
}
......@@ -67,7 +67,8 @@ WorkflowUtils.getPossibleTargetContexts = function ()
"Organisation",
"Person",
"Offer",
"Salesproject"
"Salesproject",
"MarketingWorkflowLauncher"
];
}
......@@ -76,7 +77,7 @@ WorkflowUtils.getPossibleTargetContexts = function ()
*/
WorkflowUtils.engineIsEnabled = function ()
{
return String(project.getInstanceConfigValue("workflowEngineEnabled", "false")) == "true";
return Utils.toBoolean(project.getInstanceConfigValue("workflowEngineEnabled", "false"));
}
/**
......@@ -602,9 +603,16 @@ WorkflowModelerApiCall.prototype.importModel = function ()
return WorkflowModel.fromObject(JSON.parse(modelJson));
}
/**
* Provides functionality to work with urls that trigger certain workflow actions
*/
function WorkflowLinkActions () {}
/**
* Contains the different types of workflow actions that can be performed
*
* @enum
*/
WorkflowLinkActions.types = {
RECEIVE_TASK: function () {return "rec";},
SIGNAL: function () {return "sig";},
......@@ -612,29 +620,48 @@ WorkflowLinkActions.types = {
};
WorkflowLinkActions.types.RECEIVE_TASK.title = "Receive Task";
WorkflowLinkActions.types.SIGNAL.title = "Signal";
WorkflowLinkActions.types.MESSAGE.title = "Message";
/**
* Callback-function that performs the action for the type RECEIVE_TASK.
*/
WorkflowLinkActions.types.RECEIVE_TASK.execute = function (pParameters)
{
if (!pParameters.processInstanceId)
return;
workflow.triggerReceiveTask(pParameters.processInstanceId, pParameters.receiveTask || null);
}
WorkflowLinkActions.types.SIGNAL.title = "Signal";
/**
* Callback-function that performs the action for the type SIGNAL.
*/
WorkflowLinkActions.types.SIGNAL.execute = function (pParameters)
{
if (!pParameters.processInstanceId)
if (!pParameters.signal)
return;
workflow.signalEventReceived(pParameters.signal);
}
WorkflowLinkActions.types.MESSAGE.title = "Message";
/**
* Callback-function that performs the action for the type MESSAGE.
*/
WorkflowLinkActions.types.MESSAGE.execute = function (pParameters)
{
if (!pParameters.processInstanceId || !pParameters.message)
return;
workflow.messageEventReceived(pParameters.message, pParameters.processInstanceId);
}
/**
* Encodes an action into a special string containing the data required to execute the action.
* This string can be decoded with WorkflowLinkActions.parseAction.
*
* @param {String} pType the action type, see WorkflowLinkActions.types
* @param {String} pLink the url to redirect to after the action has been executed
* @param {Object} pParams extra parameters required for the action
* @return {String} the encoded action-string
*/
WorkflowLinkActions.encodeAction = function (pType, pLink, pParams)
{
if (!pParams)
......@@ -656,6 +683,7 @@ WorkflowLinkActions.encodeAction = function (pType, pLink, pParams)
return encodeURIComponent(util.encodeBase64String(actionString));
}
WorkflowLinkActions.getActionLink = function (pBaseUrl, pType, pLink, pParams)
{
if (!pBaseUrl.endsWith("/"))
......@@ -663,6 +691,12 @@ WorkflowLinkActions.getActionLink = function (pBaseUrl, pType, pLink, pParams)
return pBaseUrl + "services/rest/redirect_rest?act=" + WorkflowLinkActions.encodeAction(pType, pLink, pParams);
}
/**
* Decodes the given action-string and gives back an object that can run the action.
*
* @param {String} pEncodedAction the encoded action-string, see WorkflowLinkActions.encodeAction
* @return {Object} an object that contains the properties of the action and the function 'run' that can be called to execute the action
*/
WorkflowLinkActions.parseAction = function (pEncodedAction)
{
try
......
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