diff --git a/workflow/engine/bin/tasks/cliWorkspaces.php b/workflow/engine/bin/tasks/cliWorkspaces.php index 7455ee574..13df97e38 100644 --- a/workflow/engine/bin/tasks/cliWorkspaces.php +++ b/workflow/engine/bin/tasks/cliWorkspaces.php @@ -1,5 +1,8 @@ removeDeprecatedFiles(); CLI::logging("<*> The deprecated files has been removed. \n"); } + +/** + * This function review the queries for each workspace or for an specific workspace + * + * @param array $args + * + * @return void + */ +function run_check_queries_incompatibilities($args) +{ + try { + $workspaces = get_workspaces_from_args($args); + if (count($args) === 1) { + CLI::logging("> Workspace: " . $workspaces[0]->name . PHP_EOL); + check_queries_incompatibilities($workspaces[0]->name); + } else { + foreach ($workspaces as $workspace) { + passthru(PHP_BINARY . " processmaker check-queries-incompatibilities " . $workspace->name); + } + } + echo "Done!\n\n"; + } catch (Exception $e) { + G::outRes(CLI::error($e->getMessage()) . "\n"); + } +} + +/** + * Check for the incompatibilities in the queries for the specific workspace + * + * @param string $wsName + */ +function check_queries_incompatibilities($wsName) +{ + Bootstrap::setConstantsRelatedWs($wsName); + require_once(PATH_DB . $wsName . '/db.php'); + System::initLaravel(); + + $query = Process::query()->select('PRO_UID', 'PRO_TITLE'); + $processesToCheck = $query->get()->values()->toArray(); + + $obj = new MySQL57(); + $resTriggers = $obj->checkIncompatibilityTriggers($processesToCheck); + + if (!empty($resTriggers)) { + foreach ($resTriggers as $trigger) { + echo ">> The \"" . $trigger['PRO_TITLE'] . "\" process has a trigger called: \"" . $trigger['TRI_TITLE'] . "\" that contains UNION queries. Review the code to discard incompatibilities with MySQL5.7." . PHP_EOL; + } + } else { + echo ">> No MySQL 5.7 incompatibilities in triggers found for this workspace." . PHP_EOL; + } + + $resDynaforms = $obj->checkIncompatibilityDynaforms($processesToCheck); + + if (!empty($resDynaforms)) { + foreach ($resDynaforms as $dynaform) { + echo ">> The \"" . $dynaform['PRO_TITLE'] . "\" process has a dynaform called: \"" . $dynaform['DYN_TITLE'] . "\" that contains UNION queries. Review the code to discard incompatibilities with MySQL5.7." . PHP_EOL; + } + } else { + echo ">> No MySQL 5.7 incompatibilities in dynaforms found for this workspace." . PHP_EOL; + } + + $resVariables = $obj->checkIncompatibilityVariables($processesToCheck); + + if (!empty($resVariables)) { + foreach ($resVariables as $variable) { + echo ">> The \"" . $variable['PRO_TITLE'] . "\" process has a variable called: \"" . $variable['VAR_NAME'] . "\" that contains UNION queries. Review the code to discard incompatibilities with MySQL5.7." . PHP_EOL; + } + } else { + echo ">> No MySQL 5.7 incompatibilities in variables found for this workspace." . PHP_EOL; + } +} \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Core/System.php b/workflow/engine/src/ProcessMaker/Core/System.php index e0e469a32..36e3061ed 100644 --- a/workflow/engine/src/ProcessMaker/Core/System.php +++ b/workflow/engine/src/ProcessMaker/Core/System.php @@ -9,6 +9,7 @@ use Faker; use G; use GzipFile; use Illuminate\Database\QueryException; +use Illuminate\Foundation\Http\Kernel; use Illuminate\Support\Facades\DB; use InputFilter; use InstallerModule; @@ -1629,5 +1630,21 @@ class System { return !empty(self::getServerHostname()) ? self::getServerHostname() : 'processmaker.com'; } + + /** + * Initialize laravel database configuration + * @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities() + */ + public static function initLaravel() + { + config(['database.connections.workflow.host' => DB_HOST]); + config(['database.connections.workflow.database' => DB_NAME]); + config(['database.connections.workflow.username' => DB_USER]); + config(['database.connections.workflow.password' => DB_PASS]); + + app()->useStoragePath(realpath(PATH_DATA)); + app()->make(Kernel::class)->bootstrap(); + restore_error_handler(); + } } // end System class diff --git a/workflow/engine/src/ProcessMaker/Model/Dynaform.php b/workflow/engine/src/ProcessMaker/Model/Dynaform.php index 4d270b2dc..1147c6e5d 100644 --- a/workflow/engine/src/ProcessMaker/Model/Dynaform.php +++ b/workflow/engine/src/ProcessMaker/Model/Dynaform.php @@ -61,4 +61,16 @@ class Dynaform extends Model ->where('DYNAFORM.DYN_UID', '!=', $dynUid) ->get(); } + + /** + * Scope a query to filter an specific process + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $columns + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeProcess($query, string $proUID) + { + return $query->where('PRO_UID', $proUID); + } } diff --git a/workflow/engine/src/ProcessMaker/Model/ProcessVariables.php b/workflow/engine/src/ProcessMaker/Model/ProcessVariables.php new file mode 100644 index 000000000..9170390a7 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Model/ProcessVariables.php @@ -0,0 +1,27 @@ +where('PRJ_UID', $proUID); + } +} \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Model/Triggers.php b/workflow/engine/src/ProcessMaker/Model/Triggers.php new file mode 100644 index 000000000..88947dee8 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Model/Triggers.php @@ -0,0 +1,27 @@ +where('PRO_UID', $proUID); + } +} \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Validation/MySQL57.php b/workflow/engine/src/ProcessMaker/Validation/MySQL57.php new file mode 100644 index 000000000..a6a2f3be0 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Validation/MySQL57.php @@ -0,0 +1,110 @@ +check_queries_incompatibilities() + * @param array $processes + * @return array + */ + public function checkIncompatibilityTriggers($processes) + { + $result = []; + + foreach ($processes as $process) { + $triggerQuery = Triggers::query()->select(); + //Call the scope method to filter by process + $triggerQuery->process($process['PRO_UID']); + $triggers = $triggerQuery->get()->values()->toArray(); + foreach ($triggers as $trigger) { + $resultIncompatibility = $this->analyzeQuery($trigger['TRI_WEBBOT']); + if ($resultIncompatibility) { + $aux = array_merge($process, $trigger); + array_push($result, $aux); + } + } + } + + return $result; + } + + /** + * Checks the queries inside dynaforms that could have possible incompatibilities with MySQL 5.7 + * + * @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities() + * @param array $processes + * @return array + */ + public function checkIncompatibilityDynaforms($processes) + { + $result = []; + + foreach ($processes as $process) { + $dynaformQuery = Dynaform::query()->select(); + //Call the scope method to filter by process + $dynaformQuery->process($process['PRO_UID']); + $dynaforms = $dynaformQuery->get()->values()->toArray(); + foreach ($dynaforms as $dynaform) { + $resultIncompatibility = $this->analyzeQuery($dynaform['DYN_CONTENT']); + if ($resultIncompatibility) { + $aux = array_merge($process, $dynaform); + array_push($result, $aux); + } + } + } + + return $result; + } + + /** + * Checks the queries inside variables that could have possible incompatibilities with MySQL 5.7 + * + * @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities() + * @param array $processes + * @return array + */ + public function checkIncompatibilityVariables($processes) + { + $result = []; + + foreach ($processes as $process) { + $variablesQuery = ProcessVariables::query()->select(); + //Call the scope method to filter by process + $variablesQuery->process($process['PRO_UID']); + $variables = $variablesQuery->get()->values()->toArray(); + foreach ($variables as $variable) { + $resultIncompatibility = $this->analyzeQuery($variable['VAR_SQL']); + if ($resultIncompatibility) { + $aux = array_merge($process, $variable); + array_push($result, $aux); + } + } + } + + return $result; + } + + /** + * Analyze the query using the regular expression + * + * @param string $query + * @return bool + */ + public function analyzeQuery($query) + { + preg_match_all($this::REGEX, $query, $matches, PREG_SET_ORDER, 0); + + return !empty($matches); + } +} \ No newline at end of file