From 5c34f18a3ab45dc7f2684a8d75cb1b23e70b84a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20Cesar=20Laura=20Avenda=C3=B1o?= Date: Wed, 10 Jun 2020 23:00:46 +0000 Subject: [PATCH] PMCORE-1491 --- tests/Feature/DBQueryTest.php | 1 + workflow/engine/classes/DbConnections.php | 15 ++++++ workflow/engine/classes/class.pmFunctions.php | 49 ++++++++++++------- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/tests/Feature/DBQueryTest.php b/tests/Feature/DBQueryTest.php index a2ee1b029..00b15c367 100644 --- a/tests/Feature/DBQueryTest.php +++ b/tests/Feature/DBQueryTest.php @@ -23,6 +23,7 @@ class DBQueryTest extends TestCase /** * Verify the execution of a common SQL statement. + * Note, this test is now using Laravel DB backend work * @test */ public function testStandardExecuteQuery() diff --git a/workflow/engine/classes/DbConnections.php b/workflow/engine/classes/DbConnections.php index 784d97230..002b1deb2 100644 --- a/workflow/engine/classes/DbConnections.php +++ b/workflow/engine/classes/DbConnections.php @@ -206,6 +206,7 @@ class DbConnections }); foreach ($externalDbs as $externalDb) { $conf['datasources'][$externalDb->DBS_UID] = []; + $laravelConfig = []; $flagTns = ($externalDb->DBS_TYPE == "oracle" && $externalDb->DBS_CONNECTION_TYPE == "TNS")? 1 : 0; // Build the appropriate items to add to our Propel configuration // Let's grab the decrypted password @@ -235,12 +236,26 @@ class DbConnections . $externalDb->DBS_USERNAME . ':' . $passw . '@' . $externalDb->DBS_SERVER . $dbsPort . '/' . $externalDb->DBS_DATABASE_NAME . $encoding; } + $laravelConfig = [ + 'driver' => $externalDb->DBS_TYPE === 'mssql' ? 'sqlsrv' : $externalDb->DBS_TYPE, // MSSQL driver is not supported anymore, only SQLSRV + 'host' => $externalDb->DBS_SERVER, + 'port' => $externalDb->DBS_PORT == '' ? null : $externalDb->DBS_PORT, + 'database' => $externalDb->DBS_DATABASE_NAME, + 'username' => $externalDb->DBS_USERNAME, + 'password' => $passw, + 'charset' => trim($externalDb->DBS_ENCODE) == '' ? null : trim($externalDb->DBS_ENCODE), + 'options' => [PDO::ATTR_STRINGIFY_FETCHES => true] // For keep the old behaviour, all values are transformed to strings + ]; } else { // Is oracle and TNS, let's provide a TNS based DSN $conf["datasources"][$externalDb->DBS_UID]["connection"] = $externalDb->DBS_TYPE . "://" . $externalDb->DBS_USERNAME . ":" . $passw . "@" . $externalDb->DBS_TNS; } $conf['datasources'][$externalDb->DBS_UID]['adapter'] = $externalDb->DBS_TYPE; + // Load the config for the external database into laravel + config([ + 'database.connections.' . $externalDb->DBS_UID => $laravelConfig + ]); } Propel::initConfiguration($conf); $lastProcessId = $_SESSION['PROCESS']; diff --git a/workflow/engine/classes/class.pmFunctions.php b/workflow/engine/classes/class.pmFunctions.php index e99854804..d1a82733d 100644 --- a/workflow/engine/classes/class.pmFunctions.php +++ b/workflow/engine/classes/class.pmFunctions.php @@ -32,6 +32,7 @@ use ProcessMaker\BusinessModel\Cases as BusinessModelCases; use ProcessMaker\Core\System; use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Util\ElementTranslation; +use Illuminate\Support\Facades\DB; /** * ProcessMaker has made a number of its PHP functions available be used in triggers and conditions. @@ -243,8 +244,22 @@ function executeQuery ($SqlStatement, $DBConnectionUID = 'workflow', $aParameter { $sysSys = (!empty(config("system.workspace")))? config("system.workspace") : "Undefined"; $aContext = \Bootstrap::getDefaultContextLog(); - $con = Propel::getConnection( $DBConnectionUID ); - $con->begin(); + + // This means the DBConnectionUID is not loaded yet, so we'll force DbConnections::loadAdditionalConnections + if (is_null(config('database.connections.' . $DBConnectionUID . '.driver'))) { + // Force to load the external connections + DbConnections::loadAdditionalConnections(); + if (config('database.connections.' . $DBConnectionUID . '.driver') !== 'oracle') { + // If the connections drivers are "mysql", "pgsql" or "sqlsrv" we're using Laravel + $con = DB::connection($DBConnectionUID); + $con->beginTransaction(); + } else { + // If the connection driver is "oracle" we're using the native oci8 functions + $con = Propel::getConnection($DBConnectionUID); + $con->begin(); + } + } + $blackList = System::getQueryBlackList(); $listQueries = explode('|', isset($blackList['queries']) ? $blackList['queries'] : ''); $aListAllTables = explode( @@ -299,36 +314,34 @@ function executeQuery ($SqlStatement, $DBConnectionUID = 'workflow', $aParameter $statement = str_replace( '(', '', $statement ); $result = false; - if (getEngineDataBaseName( $con ) != 'oracle') { + + // Check to see if we're not running oracle, which is usually a safe default + if (config('database.connections.' . $DBConnectionUID . '.driver') != 'oracle') { switch (true) { case preg_match( "/^(SELECT|EXECUTE|EXEC|SHOW|DESCRIBE|EXPLAIN|BEGIN)\s/i", $statement ): - $rs = $con->executeQuery( $SqlStatement ); - $result = Array (); - $i = 1; - while ($rs->next()) { - $result[$i ++] = $rs->getRow(); - } - $rs->close(); + $result = $con->select( $SqlStatement ); + + // Convert to 1 index key array of array results + $result = collect($result)->map(function($x) { return (array)$x; })->toArray(); + array_unshift($result, []); + unset($result[0]); + $con->commit(); break; case preg_match( "/^INSERT\s/i", $statement ): - $rs = $con->executeUpdate( $SqlStatement ); - $result = $con->getUpdateCount(); + $result = $con->insert( $SqlStatement ); $con->commit(); break; case preg_match( "/^REPLACE\s/i", $statement ): - $rs = $con->executeUpdate( $SqlStatement ); - $result = $con->getUpdateCount(); + $result = $con->update( $SqlStatement ); $con->commit(); break; case preg_match( "/^UPDATE\s/i", $statement ): - $rs = $con->executeUpdate( $SqlStatement ); - $result = $con->getUpdateCount(); + $result = $con->update( $SqlStatement ); $con->commit(); break; case preg_match( "/^DELETE\s/i", $statement ): - $rs = $con->executeUpdate( $SqlStatement ); - $result = $con->getUpdateCount(); + $result = $con->delete( $SqlStatement ); $con->commit(); break; }