| Version | Date | Notes | By |
|---|---|---|---|
| 1.0 | 2023-06-20 | Initial release | ROB |
This system is used by several other systems to query for variable instances or create new instances of them. In order to query for the information, the system will request a query builder from the TokenProcess model, and then modify it by adding more where{...} queries until a first or get is called.
The model trait InstancesVariables exposes helper functions that allow for quick creation of new variable instance queriers and builders (more information bellow).
The model trait ExposesVariableInstances is applied to models that have variable definitions (as a reference to variable instances derived from that definition).
This system is quite complex so it will be explained in parts. The complexity is related to a few assumptions made during the initial design. For example, the instancing of a new variable instance can only be done if:
|--\ VariableInstances
|--\ QuerySubObjects
|--- BaseQueryPortion
|--- QueryPortionContainerPortion
|--- VariableDefinitionQueryPortion
|--- WhereChildOfVariableInstance
|--- WhereCreatedByCompletedTokenObject
|--- WhereIsRoot
|--- WhereVarTagReference
|--\ Traits
|--- HasVariableDefinitionQueryPortions
|--- VariableInstanceQuerier
|--- VariableInstancingBuilder
The model TokenProcess has a static function queryVariableInstanceQuerier that is used by the querier to generate the initial query builder.
The complete function definition is
public static function queryVariableInstanceQuerier(
array $limitingFactor,
bool $withSelects = true,
bool $withValuesModel = true,
string $returnType = VariableInstanceQuerier::RETURN_TYPE_VARIABLES
): EloquentBuilder|QueryBuilder
limitingFactor - Associative array that contains a type and value. This forms the first where, that will be used to get values by process holder or by case ids. This is used to retrieve all cases from a given process holder (process scope) or from an array of valid cases (case scope or process scope with limitation).
withSelects - Add standard select if true (this causes problems with aggreate functions)
withValuesModel - If true, the query becomes an eloquent builder that hidrates the results into a model (slower), else it becomes a query builder (faster but no model).
returnType - This both afects the query "source" and the model returned if withValuesModel is true. Acceptable values are RETURN_TYPE_VARIABLES (model returned is TokenProcessVariableDefinitionValues) and RETURN_TYPE_CASES (model returned is TokenProcess).
Internally the function will also make the joins necessary (with the 't20_valuestable ... ' tables that contain the actual attribute values for example) to ensure that filters (further wheres to be added later) work correctly.
Once the initial query builder (of either the simple or eloquent variant) is created, the variable instance querier class will impose further filtering on the query until just the values that matter remain.
The first series of query changes is set by the variable definition query portions section inside the getDirectQuery function. These are a series of classes defined inside the QuerySubObjects folder.
Each class receives a specific set of parameters and, when the querier requests it, makes a specific change to the query (usualy adding a where{...}).
Further details on the Query sub objects classes in a section bellow.
The next series of query changes is imposed by the VisualQuery™ frontend system, that allows the user to define query conditions. This appears in the backend as an associative array with the following structure.
{
"conditions":[ // You can have 0..n conditions
{
"query_assoc":"AND", // Can be AND or OR (applicable after the first condition. Default is AND)
"type":"intrinsics_variable_instance", // can be "intrinsics_variable_instance" OR "intrinsics_token_process" OR "root_variable_reference",
"definition_id":null, // if "type" == "root_variable_reference", this stores the variable definition id
"attribute_id":"created_at", // id of the attribute (db column)
"condition":">", // condition
"value_type":"direct", // type of value can be "direct" OR "input-variable"
"value":"2023-06-01 17:25", // The value to filter by
"end_value":null, // used in case the condition is 'between'
"tag_reference":"${INSTANCE.CREATED_AT}", // not being used at the moment but will be very relevant in the future, when all variable referencing becomes standardized
"order":0, // order of condition
// this following block is not important but it is automatically filled by the frontend component in order to ensure the condition is presentable in the frontend
"_queryAssocName":"E",
"_queryElementTypeName":"Informa\u00e7\u00e3o intrinseca \u00e1 inst\u00e2ncia da vari\u00e1vel",
"_variableDefinitionName":null,
"_attributeName":"Criado em",
"_conditionName":"Maior que",
"_valueName":"2023-06-01 17:25",
"_valueTypeName":"Directo"
}
],
"sortBy":{
"direction":null, // can be null, ASC or DESC
"type":null, // same as condition type above
"definition_id":null, // same as condition type above
"attribute_id":null // same as condition type above
}
}
The query will be directly modified acording to the definition above (conditions become wheres and the order by will be altered with the sortBy information if direction, type and attribute_id are not null)
Where are no subWheres in this system (grouping of wheres) and the "query_assoc" is applied with the previous condition, for example:
// where condition 0 AND (from condition 1) where condition 1
where(condition[0]) condition[1].query_assoc where(condition[1])
which means the very first query_assoc has no impact.
There is an area where all variable query portions are evaluated if the "createNew" is set to any value that would do so VARIABLE_INSTANCE_MODE_SINGLETON or VARIABLE_INSTANCE_MODE_APPEND
Essencially if create new HAS singleton AND variable definition is root or singularly related to parent definition AND no instance exists THEN it will create a new instance (which will be a part of the results returned by the query).
If create new HAS append AND variable definition has a relation of multiplicity multiple THEN it will create a new instance (which will be a part of the results returned by the query).
This is prety standard, used for paging for interface components that have paging.
These functions finalize the query by executing the corresponding first() and get() functions in the final query builder (returning the results).