diff --git a/4dev/tests/DB/CoreLibsDBIOTest.php b/4dev/tests/DB/CoreLibsDBIOTest.php index faadf6e1..14767292 100644 --- a/4dev/tests/DB/CoreLibsDBIOTest.php +++ b/4dev/tests/DB/CoreLibsDBIOTest.php @@ -5141,9 +5141,9 @@ final class CoreLibsDBIOTest extends TestCase INSERT INTO table_with_primary_key ( row_int, row_numeric, row_varchar, row_varchar_literal ) VALUES ( - -- comment 1 + -- comment 1 かな $1, $2, - -- comment 2 + -- comment 2 - $3 -- comment 3 , $4 @@ -5152,6 +5152,23 @@ final class CoreLibsDBIOTest extends TestCase 'count' => 4, 'convert' => false ], + 'comment in update' => [ + 'query' => << 4, + 'convert' => false, + ], // Note some are not set 'a complete set of possible' => [ 'query' => << 12, 'convert' => false, + ], + // all the same + 'all the same numbered' => [ + 'query' => << 1, + 'convert' => false, ] ]; } diff --git a/www/admin/class_test.db.convert-placeholder.php b/www/admin/class_test.db.convert-placeholder.php index 8cca56a9..e95586ad 100644 --- a/www/admin/class_test.db.convert-placeholder.php +++ b/www/admin/class_test.db.convert-placeholder.php @@ -28,7 +28,6 @@ $log = new CoreLibs\Logging\Logging([ 'log_per_date' => true, ]); - $PAGE_NAME = 'TEST CLASS: DB CONVERT PLACEHOLDER'; print ""; print "" . $PAGE_NAME . ""; diff --git a/www/admin/class_test.db.query-placeholder.php b/www/admin/class_test.db.query-placeholder.php index b2d729c4..c934962a 100644 --- a/www/admin/class_test.db.query-placeholder.php +++ b/www/admin/class_test.db.query-placeholder.php @@ -53,6 +53,9 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) { } else { print "NO DB HANDLER
"; } +// REGEX for placeholder count +print "Placeholder regex:
" . CoreLibs\DB\Support\ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS . "
"; + // turn on debug replace for placeholders $db->dbSetDebugReplacePlaceholder(true); @@ -62,53 +65,94 @@ $db->dbExec("TRUNCATE test_foo"); $uniqid = \CoreLibs\Create\Uids::uniqIdShort(); $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: ''); $query_params = [ - $uniqid, - true, - 'STRING A', - 2, - 2.5, - 1, - date('H:m:s'), - date('Y-m-d H:i:s'), - json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]), - null, - '{"a", "b"}', - '{1,2}', - '{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}', - '("Text", 4, 6.3)', - $binary_data + $uniqid, // test + true, // some_bool + 'STRING A', // string_a + 2, // number_a + 2.5, // numeric_a + 1, // smallint + date('H:m:s'), // some_internval + date('Y-m-d H:i:s'), // some_timestamp + json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]), // json_string + null, // null_var + '{"a", "b"}', // array_char_1 + '{1,2}', // array_int_1 + '{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}', // array_composite + '("Text", 4, 6.3)', // composite_item + $binary_data, // some_binary + date('Y-m-d'), // some_date + date('H:i:s'), // some_time + '{"c", "d", "e"}', // array_char_2 + '{3,4,5}', // array_int_2 + 12345667778818, // bigint + 1.56, // numbrer_real + 3.75, // number_double + 124.5, // numeric_3 + \CoreLibs\Create\Uids::uuidv4() // uuid_var ]; $query_insert = <<dbExecParams($query_insert, $query_params); echo "*
"; echo "INSERT ALL COLUMN TYPES: " . Support::printToString($query_params) . " |
" - . "QUERY: " . $db->dbGetQuery() . " |
" + . "QUERY:
" . $db->dbGetQuery() . "
|
" . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " |
" . "RETURNING EXT:
" . print_r($db->dbGetReturningExt(), true) . "
|
" . "RETURNING RETURN:
" . print_r($db->dbGetReturningArray(), true) . "
 |
" @@ -146,6 +190,16 @@ SQL, 'params' => [], 'direction' => 'pg', ], + 'numbers' => [ + 'query' => << [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234], + 'direction' => 'pdo', + ], 'a?' => [ 'query' => << 'pg', ], + 'select, compare $' => [ + 'query' => <<= $1 OR number_a <= $2 OR + number_a > $3 OR number_a < $4 + OR number_a = $5 OR number_a <> $6 + SQL, + 'params' => [1, 2, 3, 4, 5, 6], + 'direction' => 'pg' + ] ]; $db->dbSetConvertPlaceholder(true); @@ -184,11 +250,12 @@ foreach ($test_queries as $info => $data) { // . "
"; if ($db->dbCheckQueryForSelect($query)) { $row = $db->dbReturnRowParams($query, $params); - print "[$info] SELECT: " . Support::prAr($row) . "
"; + print "[$info] SELECT: " . Support::prAr($row) . "
"; } else { $db->dbExecParams($query, $params); } - print "[$info] " . Support::printAr($db->dbGetPlaceholderConverted()) . "
"; + print "ERROR: " . $db->dbGetLastError(true) . "
"; + print "[$info] " . Support::printAr($db->dbGetPlaceholderConverted()) . "
"; echo "
"; } @@ -203,22 +270,29 @@ SQL, ['string A-1'] )) ) { - print "RES: " . Support::prAr($res) . "
"; + print "RES: " . Support::prAr($res) . "
"; } +print "ERROR: " . $db->dbGetLastError(true) . "
"; +echo "
"; print "CursorExt: " . Support::prAr($db->dbGetCursorExt(<<"; +// ERROR BELOW: missing params $res = $db->dbReturnRowParams(<<dbGetPlaceholderConverted()) . "
"; +print "ERROR: " . $db->dbGetLastError(true) . "
"; +echo "
"; +// ERROR BELOW: LIKE cannot have placeholder echo "dbReturn read LIKE:
"; while ( is_array($res = $db->dbReturnParams( @@ -232,6 +306,7 @@ SQL, ) { print "RES: " . Support::prAr($res) . "
"; } +print "ERROR: " . $db->dbGetLastError(true) . "
"; print ""; $db->log->debug('DEBUGEND', '==================================== [END]'); diff --git a/www/admin/class_test.php b/www/admin/class_test.php index 616f684a..d8470134 100644 --- a/www/admin/class_test.php +++ b/www/admin/class_test.php @@ -91,7 +91,7 @@ HTML; $test_files = [ 'class_test.db.php' => 'Class Test: DB', 'class_test.db.types.php' => 'Class Test: DB column type convert', - 'class_test.db.query-placeholder.php' => 'Class Test: DB query placeholder convert', + 'class_test.db.query-placeholder.php' => 'Class Test: DB placeholder queries', 'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn', 'class_test.db.single.php' => 'Class Test: DB single query tests', 'class_test.db.convert-placeholder.php' => 'Class Test: DB convert placeholder', diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index d579fd16..7af3407f 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -1332,7 +1332,7 @@ class IO */ private function __dbCheckQueryParams(string $query, array $params): bool { - // $this->log->debug('DB QUERY PARAMS REGEX', ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS); + $this->log->debug('DB QUERY PARAMS REGEX', ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS); $placeholder_count = $this->__dbCountQueryParams($query); $params_count = count($params); if ($params_count != $placeholder_count) { diff --git a/www/lib/CoreLibs/DB/Support/ConvertPlaceholder.php b/www/lib/CoreLibs/DB/Support/ConvertPlaceholder.php index fd8eea60..dff03788 100644 --- a/www/lib/CoreLibs/DB/Support/ConvertPlaceholder.php +++ b/www/lib/CoreLibs/DB/Support/ConvertPlaceholder.php @@ -18,17 +18,20 @@ class ConvertPlaceholder // NOTE some combinations are allowed, but the query will fail before this /** @var string split regex, entries before $ group */ private const PATTERN_QUERY_SPLIT = - ',|' // for ',' mostly in INSERT - . '[(<>=]|' // general set for (, <, >, = in any query with any combination - . '(?:[\(,]\s*\-\-[\s\w]*)\r?\n|' // a comment that starts after a ( or , + '\?\?|' // UNKNOWN: double ??, is this to avoid something? + . '[\(,]|' // for ',' and '(' mostly in INSERT or ANY() + . '[<>=]|' // general set for <, >, = in any query with any combination . '\^@|' // text search for start from text with ^@ . '\|\||' // concats two elements . '&&|' // array overlap - . '\-\|\-|' // range overlap + . '\-\|\-|' // range overlap for array . '[^-]-{1}|' // single -, used in JSON too . '->|->>|#>|#>>|@>|<@|@@|@\?|\?{1}|\?\||\?&|#-'; //JSON searches, Array searchs, etc /** @var string the main regex including the pattern query split */ - private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:\?\?|' . self::PATTERN_QUERY_SPLIT . ')\s*'; + private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:' . self::PATTERN_QUERY_SPLIT . ')\s*'; + /** @var string comment regex + * anything that starts with -- and ends with a line break but any character that is not line break inbetween */ + private const PATTERN_COMMENT = '(?:\-\-[^\r\n]*?\r?\n)*\s*'; /** @var string parts to ignore in the SQL */ private const PATTERN_IGNORE = // digit -> ignore @@ -45,6 +48,7 @@ class ConvertPlaceholder /** @var string replace regex for named (:...) entries */ public const REGEX_REPLACE_NAMED = '/' . '(' . self::PATTERN_ELEMENT . ')' + . self::PATTERN_COMMENT . '(' . self::PATTERN_IGNORE . self::PATTERN_NAMED @@ -53,6 +57,7 @@ class ConvertPlaceholder /** @var string replace regex for question mark (?) entries */ public const REGEX_REPLACE_QUESTION_MARK = '/' . '(' . self::PATTERN_ELEMENT . ')' + . self::PATTERN_COMMENT . '(' . self::PATTERN_IGNORE . self::PATTERN_QUESTION_MARK @@ -61,6 +66,7 @@ class ConvertPlaceholder /** @var string replace regex for numbered ($n) entries */ public const REGEX_REPLACE_NUMBERED = '/' . '(' . self::PATTERN_ELEMENT . ')' + . self::PATTERN_COMMENT . '(' . self::PATTERN_IGNORE . self::PATTERN_NUMBERED @@ -71,6 +77,7 @@ class ConvertPlaceholder // prefix string part, must match towards // seperator for ( = , ? - [and json/jsonb in pg doc section 9.15] . self::PATTERN_ELEMENT + . self::PATTERN_COMMENT // match for replace part . '(?:' // ignore parts