diff --git a/src/DB/IO.php b/src/DB/IO.php index 4daad5b..d579fd1 100644 --- a/src/DB/IO.php +++ b/src/DB/IO.php @@ -1332,6 +1332,7 @@ class IO */ private function __dbCheckQueryParams(string $query, array $params): bool { + // $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/src/DB/Support/ConvertPlaceholder.php b/src/DB/Support/ConvertPlaceholder.php index 0b9542b..fd8eea6 100644 --- a/src/DB/Support/ConvertPlaceholder.php +++ b/src/DB/Support/ConvertPlaceholder.php @@ -14,8 +14,19 @@ namespace CoreLibs\DB\Support; class ConvertPlaceholder { - /** @var string split regex */ - private const PATTERN_QUERY_SPLIT = '[(<>=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-'; + // NOTE for missing: range */+ are not iplemented in the regex below, but - is for now + // 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 , + . '\^@|' // text search for start from text with ^@ + . '\|\||' // concats two elements + . '&&|' // array overlap + . '\-\|\-|' // range overlap + . '[^-]-{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*'; /** @var string parts to ignore in the SQL */ diff --git a/test/phpunit/ACL/database/CoreLibsACLLogin_database_create_data.sql b/test/phpunit/ACL/database/CoreLibsACLLogin_database_create_data.sql index d3a8d0e..3d4a54b 100644 --- a/test/phpunit/ACL/database/CoreLibsACLLogin_database_create_data.sql +++ b/test/phpunit/ACL/database/CoreLibsACLLogin_database_create_data.sql @@ -321,7 +321,7 @@ CREATE TABLE edit_generic ( -- DROP TABLE edit_visible_group; CREATE TABLE edit_visible_group ( - edit_visible_group_id SERIAL PRIMARY KEY, + edit_visible_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name VARCHAR, flag VARCHAR ) INHERITS (edit_generic) WITHOUT OIDS; @@ -336,7 +336,7 @@ CREATE TABLE edit_visible_group ( -- DROP TABLE edit_menu_group; CREATE TABLE edit_menu_group ( - edit_menu_group_id SERIAL PRIMARY KEY, + edit_menu_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name VARCHAR, flag VARCHAR, order_number INT NOT NULL @@ -354,7 +354,7 @@ CREATE TABLE edit_menu_group ( -- DROP TABLE edit_page; CREATE TABLE edit_page ( - edit_page_id SERIAL PRIMARY KEY, + edit_page_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE, filename VARCHAR, @@ -378,7 +378,7 @@ CREATE TABLE edit_page ( -- DROP TABLE edit_query_string; CREATE TABLE edit_query_string ( - edit_query_string_id SERIAL PRIMARY KEY, + edit_query_string_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_page_id INT NOT NULL, FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, enabled SMALLINT NOT NULL DEFAULT 0, @@ -430,7 +430,7 @@ CREATE TABLE edit_page_menu_group ( -- DROP TABLE edit_access_right; CREATE TABLE edit_access_right ( - edit_access_right_id SERIAL PRIMARY KEY, + edit_access_right_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name VARCHAR, level SMALLINT, type VARCHAR, @@ -447,7 +447,7 @@ CREATE TABLE edit_access_right ( -- DROP TABLE edit_scheme; CREATE TABLE edit_scheme ( - edit_scheme_id SERIAL PRIMARY KEY, + edit_scheme_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, enabled SMALLINT NOT NULL DEFAULT 0, name VARCHAR, header_color VARCHAR, @@ -466,7 +466,7 @@ CREATE TABLE edit_scheme ( -- DROP TABLE edit_language; CREATE TABLE edit_language ( - edit_language_id SERIAL PRIMARY KEY, + edit_language_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, enabled SMALLINT NOT NULL DEFAULT 0, lang_default SMALLINT NOT NULL DEFAULT 0, long_name VARCHAR, @@ -485,7 +485,7 @@ CREATE TABLE edit_language ( -- DROP TABLE edit_group; CREATE TABLE edit_group ( - edit_group_id SERIAL PRIMARY KEY, + edit_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_scheme_id INT, FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, edit_access_right_id INT NOT NULL, @@ -507,7 +507,7 @@ CREATE TABLE edit_group ( -- DROP TABLE edit_page_access; CREATE TABLE edit_page_access ( - edit_page_access_id SERIAL PRIMARY KEY, + edit_page_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_group_id INT NOT NULL, FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, edit_page_id INT NOT NULL, @@ -530,7 +530,7 @@ CREATE TABLE edit_page_access ( -- DROP TABLE edit_page_content; CREATE TABLE edit_page_content ( - edit_page_content_id SERIAL PRIMARY KEY, + edit_page_content_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_page_id INT NOT NULL, FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, edit_access_right_id INT NOT NULL, @@ -551,7 +551,7 @@ CREATE TABLE edit_page_content ( -- DROP TABLE edit_user; CREATE TABLE edit_user ( - edit_user_id SERIAL PRIMARY KEY, + edit_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, connect_edit_user_id INT, -- possible reference to other user FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, edit_language_id INT NOT NULL, @@ -652,11 +652,11 @@ COMMENT ON COLUMN edit_user.additional_acl IS 'Additional Access Control List st -- DROP TABLE edit_log; CREATE TABLE edit_log ( - edit_log_id SERIAL PRIMARY KEY, + edit_log_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, euid INT, -- this is a foreign key, but I don't nedd to reference to it + FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL, ecuid VARCHAR, ecuuid UUID, - FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL, username VARCHAR, password VARCHAR, event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP, @@ -712,7 +712,7 @@ ALTER TABLE edit_log_overflow ADD CONSTRAINT edit_log_overflow_euid_fkey FOREIGN -- DROP TABLE edit_access; CREATE TABLE edit_access ( - edit_access_id SERIAL PRIMARY KEY, + edit_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, enabled SMALLINT NOT NULL DEFAULT 0, protected SMALLINT DEFAULT 0, deleted SMALLINT DEFAULT 0, @@ -733,7 +733,7 @@ CREATE TABLE edit_access ( -- DROP TABLE edit_access_user; CREATE TABLE edit_access_user ( - edit_access_user_id SERIAL PRIMARY KEY, + edit_access_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_access_id INT NOT NULL, FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, edit_user_id INT NOT NULL, @@ -754,7 +754,7 @@ CREATE TABLE edit_access_user ( -- DROP TABLE edit_access_data; CREATE TABLE edit_access_data ( - edit_access_data_id SERIAL PRIMARY KEY, + edit_access_data_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_access_id INT NOT NULL, FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, enabled SMALLINT NOT NULL DEFAULT 0, diff --git a/test/phpunit/DB/CoreLibsDBIOTest.php b/test/phpunit/DB/CoreLibsDBIOTest.php index ec8a28e..faadf6e 100644 --- a/test/phpunit/DB/CoreLibsDBIOTest.php +++ b/test/phpunit/DB/CoreLibsDBIOTest.php @@ -17,7 +17,7 @@ Table with Primary Key: table_with_primary_key Table without Primary Key: table_without_primary_key Table with primary key has additional row: -row_primary_key SERIAL PRIMARY KEY, +row_primary_key INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, Each table has the following rows row_int INT, row_numeric NUMERIC, @@ -160,7 +160,6 @@ final class CoreLibsDBIOTest extends TestCase // create the tables $db->dbExec( // primary key name is table + '_id' - // table_with_primary_key_id SERIAL PRIMARY KEY, << 6, 'convert' => false, + ], + 'comments in insert' => [ + 'query' => << 4, + 'convert' => false + ], + // Note some are not set + 'a complete set of possible' => [ + 'query' => << $3 + AND row_varchar > $4 AND row_varchar < $5 + AND row_varchar >= $6 AND row_varchar <=$7 + AND row_jsonb->'a' = $8 AND row_jsonb->>$9 = 'a' + AND row_jsonb<@$10 AND row_jsonb@>$11 + AND row_varchar ^@ $12 + SQL, + 'count' => 12, + 'convert' => false, ] ]; }