From 66b7e8146310ba71849dee8db3536cdb3a205095 Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Wed, 25 Jan 2023 16:47:31 +0900 Subject: [PATCH] Bug fix in DB\IO for EOM string build queries with returning on EOM string build queries it was not checked that RETURNING could have no space in front. Fixed and updated test calls --- 4dev/tests/CoreLibsDBIOTest.php | 136 +++++++++++++++++++++++++------- www/admin/class_test.db.php | 81 ++++++++++++++++++- www/lib/CoreLibs/DB/IO.php | 10 +-- 3 files changed, 194 insertions(+), 33 deletions(-) diff --git a/4dev/tests/CoreLibsDBIOTest.php b/4dev/tests/CoreLibsDBIOTest.php index 4f843e73..8b4ba092 100644 --- a/4dev/tests/CoreLibsDBIOTest.php +++ b/4dev/tests/CoreLibsDBIOTest.php @@ -155,37 +155,57 @@ final class CoreLibsDBIOTest extends TestCase $db->dbExec("DROP TABLE table_without_primary_key"); $db->dbExec("DROP TABLE test_meta"); } - $base_table = "uid VARCHAR, " // uid is for internal reference tests - . "row_int INT, " - . "row_numeric NUMERIC, " - . "row_varchar VARCHAR, " - . "row_varchar_literal VARCHAR, " - . "row_json JSON, " - . "row_jsonb JSONB, " - . "row_bytea BYTEA, " - . "row_timestamp TIMESTAMP WITHOUT TIME ZONE, " - . "row_date DATE, " - . "row_interval INTERVAL, " - . "row_array_int INT ARRAY, " - . "row_array_varchar VARCHAR ARRAY" - . ") WITHOUT OIDS"; + // uid is for internal reference tests + $base_table = <<dbExec( - "CREATE TABLE table_with_primary_key (" + // primary key name is table + '_id' + <<dbExec( - "CREATE TABLE table_without_primary_key (" - . $base_table + <<dbExec( - "CREATE TABLE test_meta (" + <<dbExec("CREATE SCHEMA IF NOT EXISTS testschema"); @@ -3893,6 +3913,38 @@ final class CoreLibsDBIOTest extends TestCase ] ] ], + // same but as EOM + 'single insert (PK), EOM string' => [ + << 'Text', + 'row_varchar_literal' => 'Other', + 'row_int' => 123, + 'row_date' => '2022-03-01', + // 'table_with_primary_key_id' => "/^\d+$/", + 'table_with_primary_key_id' => $table_with_primary_key_id + 2, + ], + [ + 0 => [ + 'row_varchar' => 'Text', + 'row_varchar_literal' => 'Other', + 'row_int' => 123, + 'row_date' => '2022-03-01', + // 'table_with_primary_key_id' => "/^\d+$/", + 'table_with_primary_key_id' => $table_with_primary_key_id + 2, + ] + ] + ], // double insert (PK) 'dobule insert (PK)' => [ "INSERT INTO table_with_primary_key " @@ -3910,14 +3962,14 @@ final class CoreLibsDBIOTest extends TestCase 'row_varchar_literal' => 'Other', 'row_int' => 123, 'row_date' => '2022-03-01', - 'table_with_primary_key_id' => $table_with_primary_key_id + 2, + 'table_with_primary_key_id' => $table_with_primary_key_id + 3, ], 1 => [ 'row_varchar' => 'Foxtrott', 'row_varchar_literal' => 'Tango', 'row_int' => 789, 'row_date' => '1982-10-15', - 'table_with_primary_key_id' => $table_with_primary_key_id + 3, + 'table_with_primary_key_id' => $table_with_primary_key_id + 4, ], ], [ @@ -3926,14 +3978,14 @@ final class CoreLibsDBIOTest extends TestCase 'row_varchar_literal' => 'Other', 'row_int' => 123, 'row_date' => '2022-03-01', - 'table_with_primary_key_id' => $table_with_primary_key_id + 2, + 'table_with_primary_key_id' => $table_with_primary_key_id + 3, ], 1 => [ 'row_varchar' => 'Foxtrott', 'row_varchar_literal' => 'Tango', 'row_int' => 789, 'row_date' => '1982-10-15', - 'table_with_primary_key_id' => $table_with_primary_key_id + 3, + 'table_with_primary_key_id' => $table_with_primary_key_id + 4, ], ] ], @@ -3961,7 +4013,35 @@ final class CoreLibsDBIOTest extends TestCase 'row_date' => '2022-03-01', ] ] - ] + ], + // same as above but as EOM string + 'single insert (No PK), EOM string' => [ + << 'Text', + 'row_varchar_literal' => 'Other', + 'row_int' => 123, + 'row_date' => '2022-03-01', + ], + [ + 0 => [ + 'row_varchar' => 'Text', + 'row_varchar_literal' => 'Other', + 'row_int' => 123, + 'row_date' => '2022-03-01', + ] + ] + ], ]; } @@ -4008,11 +4088,13 @@ final class CoreLibsDBIOTest extends TestCase $this->assertEquals( $expected_ret_ext, - $returning_ext + $returning_ext, + 'Returning extended failed' ); $this->assertEquals( $expected_ret_arr, - $returning_arr + $returning_arr, + 'Returning Array failed' ); // print "EXT: " . print_r($returning_ext, true) . "\n"; diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php index 1634f651..bb7a7452 100644 --- a/www/admin/class_test.db.php +++ b/www/admin/class_test.db.php @@ -118,7 +118,8 @@ print "TRUNCATE test_foobar
"; $query = "TRUNCATE test_foobar"; $db->dbExec($query); -$status = $db->dbExec("INSERT INTO test_foo (test) VALUES ('FOO TEST " . time() . "') RETURNING test"); +$status = $db->dbExec("INSERT INTO test_foo (test, number_a) VALUES " + . "('FOO TEST " . time() . "', 1) RETURNING test, number_a"); print "DIRECT INSERT STATUS: " . Support::printToString($status) . " |
" . "QUERY: " . $db->dbGetQuery() . " |
" . "DB OBJECT:
" . print_r($status, true) . "
| " @@ -127,6 +128,29 @@ print "DIRECT INSERT STATUS: " . Support::printToString($status) . " |
" . "RETURNING EXT[test]: " . print_r($db->dbGetReturningExt('test'), true) . " | " . "RETURNING ARRAY: " . print_r($db->dbGetReturningArray(), true) . "
"; +var_dump($db->dbGetReturningExt()); + +// same as above but use an EOM string +$some_time = time(); +$query = <<dbExec($query); +print "EOM STRING DIRECT INSERT STATUS: " . Support::printToString($status) . " |
" + . "QUERY: " . $db->dbGetQuery() . " |
" + . "DB OBJECT:
" . print_r($status, true) . "
| " + . "PRIMARY KEY: " . $db->dbGetInsertPK() . " | " + . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " + . "RETURNING EXT[test]: " . print_r($db->dbGetReturningExt('test'), true) . " | " + . "RETURNING ARRAY: " . print_r($db->dbGetReturningArray(), true) . "
"; + +var_dump($db->dbGetReturningExt()); + // should throw deprecated error // $db->getReturningExt(); print "DIRECT INSERT PREVIOUS INSERTED: " @@ -150,6 +174,23 @@ print "PREPARE CURSOR RETURN:
"; foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) { print "KEY: " . $key . ': ' . $db->dbGetPrepareCursorValue('ins_test_foo', $key) . "
"; } + +$query = <<dbPrepare("ins_test_foo_eom", $query); +$status = $db->dbExecute("ins_test_foo_eom", ['EOM BAR TEST ' . time()]); +print "EOM STRING PREPARE INSERT[ins_test_foo_eom] STATUS: " . Support::printToString($status) . " |
" + . "QUERY: " . $db->dbGetQuery() . " |
" + . "PRIMARY KEY: " . $db->dbGetInsertPK() . " | " + . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " + . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "
"; + // returning test with multiple entries // $status = $db->db_exec( // "INSERT INTO test_foo (test) VALUES " @@ -172,6 +213,26 @@ print "DIRECT MULTIPLE INSERT WITH RETURN STATUS: " . Support::printToString($st . "RETURNING EXT[test]: " . print_r($db->dbGetReturningExt('test'), true) . " | " . "RETURNING ARRAY: " . print_r($db->dbGetReturningArray(), true) . "
"; +$t_1 = time(); +$t_2 = time(); +$t_3 = time(); +$query = <<dbExec($query); +print "EOM STRING DIRECT MULTIPLE INSERT WITH RETURN STATUS: " . Support::printToString($status) . " |
" + . "QUERY: " . $db->dbGetQuery() . " |
" + . "PRIMARY KEYS: " . print_r($db->dbGetInsertPK(), true) . " | " + . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " + . "RETURNING EXT[test]: " . print_r($db->dbGetReturningExt('test'), true) . " | " + . "RETURNING ARRAY: " . print_r($db->dbGetReturningArray(), true) . "
"; + // no returning, but not needed ; $status = $db->dbExec("INSERT INTO test_foo (test) VALUES ('FOO; TEST " . time() . "')"); print "DIRECT INSERT NO RETURN STATUS: " . Support::printToString($status) . " |
" @@ -240,6 +301,24 @@ if ($db->dbPrepare('sel_test_foo', $q_prep) === false) { . $db->dbGetLastError() . "/" . $db->dbGetLastWarning() . "/" . "
" . print_r($db->dbGetCombinedErrorHistory(), true) . "

"; } + +echo "
"; +print "EOM STYLE STRINGS
"; +$test_bar = $db->dbEscapeLiteral('SOMETHING DIFFERENT'); +// Test EOM block +$q = <<dbReturn($q))) { + print "ROW:
" . print_r($res, true) . "

"; +} +echo "
"; + // NOTE: try to replacate connection still exists if script is run a second time // open pg bouncer connection $db_pgb = new CoreLibs\DB\IO($DB_CONFIG['test_pgbouncer'], $log); diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index b55b7259..16456572 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -1007,7 +1007,7 @@ class IO $this->pk_name_table[$table] : 'NULL'; } if ( - !preg_match("/ returning /i", $this->query) && + !preg_match("/\s?returning /i", $this->query) && $this->pk_name && $this->pk_name != 'NULL' ) { // check if this query has a ; at the end and remove it @@ -1016,7 +1016,7 @@ class IO $this->query = !is_string($__query) ? $this->query : $__query; $this->query .= " RETURNING " . $this->pk_name; $this->returning_id = true; - } elseif (preg_match("/ returning (.*)/i", $this->query, $matches)) { + } elseif (preg_match("/\s?returning (.*)/i", $this->query, $matches)) { if ($this->pk_name && $this->pk_name != 'NULL') { // add the primary key if it is not in the returning set if (!preg_match("/$this->pk_name/", $matches[1])) { @@ -1030,7 +1030,7 @@ class IO // if we have an UPDATE and RETURNING, flag for true, but do not add anything if ( $this->__checkQueryForUpdate($this->query) && - preg_match("/ returning (.*)/i", $this->query, $matches) + preg_match("/\s?returning (.*)/i", $this->query, $matches) ) { $this->returning_id = true; } @@ -2288,11 +2288,11 @@ class IO $this->prepare_cursor[$stm_name]['pk_name'] = $pk_name; } // if no returning, then add it - if (!preg_match("/ returning /i", $query) && $this->prepare_cursor[$stm_name]['pk_name']) { + if (!preg_match("/\s?returning /i", $query) && $this->prepare_cursor[$stm_name]['pk_name']) { $query .= " RETURNING " . $this->prepare_cursor[$stm_name]['pk_name']; $this->prepare_cursor[$stm_name]['returning_id'] = true; } elseif ( - preg_match("/ returning (.*)/i", $query, $matches) && + preg_match("/\s?returning (.*)/i", $query, $matches) && $this->prepare_cursor[$stm_name]['pk_name'] ) { // if returning exists but not pk_name, add it