diff --git a/4dev/tests/DB/CoreLibsDBIOTest.php b/4dev/tests/DB/CoreLibsDBIOTest.php index ac6314d6..d85de03f 100644 --- a/4dev/tests/DB/CoreLibsDBIOTest.php +++ b/4dev/tests/DB/CoreLibsDBIOTest.php @@ -3692,7 +3692,7 @@ final class CoreLibsDBIOTest extends TestCase * * @return array */ - public function preparedProviderValue(): array + public function providerDbGetPrepareCursorValue(): array { // 1: query (can be empty for do not set) // 2: stm name @@ -3736,7 +3736,7 @@ final class CoreLibsDBIOTest extends TestCase * test return prepare cursor errors * * @covers ::dbGetPrepareCursorValue - * @dataProvider preparedProviderValue + * @dataProvider providerDbGetPrepareCursorValue * @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName] * * @param string $query @@ -3769,6 +3769,94 @@ final class CoreLibsDBIOTest extends TestCase ); } + /** + * Undocumented function + * + * @return array + */ + public function providerDbPreparedCursorStatus(): array + { + return [ + 'empty statement pararm' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_a', + 'check_stm_name' => '', + 'check_query' => '', + 'expected' => false + ], + 'different stm_name' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_b', + 'check_stm_name' => 'other_name', + 'check_query' => '', + 'expected' => 0 + ], + 'same stm_name' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_c', + 'check_stm_name' => 'test_stm_c', + 'check_query' => '', + 'expected' => 1 + ], + 'same stm_name and query' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_d', + 'check_stm_name' => 'test_stm_d', + 'check_query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'expected' => 2 + ], + 'same stm_name and different query' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_e', + 'check_stm_name' => 'test_stm_e', + 'check_query' => 'SELECT row_int, uid, row_int FROM table_with_primary_key', + 'expected' => 1 + ], + 'insert query test' => [ + 'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)', + 'stm_name' => 'test_stm_f', + 'check_stm_name' => 'test_stm_f', + 'check_query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)', + 'expected' => 2 + ] + ]; + } + + /** + * test cursor status for prepared statement + * + * @covers ::dbPreparedCursorStatus + * @dataProvider providerDbPreparedCursorStatus + * @testdox Check prepared $stm_name ($check_stm_name) status is $expected [$_dataName] + * + * @param string $query + * @param string $stm_name + * @param string $check_stm_name + * @param string $check_query + * @param bool|int $expected + * @return void + */ + public function testDbPreparedCursorStatus( + string $query, + string $stm_name, + string $check_stm_name, + string $check_query, + bool|int $expected + ): void { + $db = new \CoreLibs\DB\IO( + self::$db_config['valid'], + self::$log + ); + $db->dbPrepare($stm_name, $query); + // $db->dbExecute($stm_name); + $this->assertEquals( + $expected, + $db->dbPreparedCursorStatus($check_stm_name, $check_query), + 'check prepared stement cursor status' + ); + unset($db); + } + // - schema set/get tests // dbGetSchema, dbSetSchema diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php index eb9ba2e6..a5537600 100644 --- a/www/admin/class_test.db.php +++ b/www/admin/class_test.db.php @@ -707,6 +707,17 @@ if ( } else { print "[PGB] [3] pgb_sel_test_foo prepare OK
"; } +$stm_status = $db->dbPreparedCursorStatus(''); +print "[PGB] Empty statement name: " . $log->prAr($stm_status) . "
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foobar'); +print "[PGB] Prepared name not match status: $stm_status
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo'); +print "[PGB] Prepared name match status: $stm_status
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', $q_prep); +print "[PGB] prepared exists and query match status: $stm_status
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', "SELECT * FROM test_foo"); +print "[PGB] prepared exists and query not match status: $stm_status
"; + $db_pgb->dbClose(); # db write class test diff --git a/www/admin/class_test.deprecated.helper.php b/www/admin/class_test.deprecated.helper.php index 2c858be9..b629ff05 100644 --- a/www/admin/class_test.deprecated.helper.php +++ b/www/admin/class_test.deprecated.helper.php @@ -57,6 +57,51 @@ fclose($fp); $out = \CoreLibs\DeprecatedHelper\Deprecated84::str_getcsv("A,B,C"); print "str_getcsv:
" . print_r($out, true) . "
"; +/** + * temporary different CSV function, because fgetcsv seems to be broken on some systems + * (does not read out japanese text) + * + * @param string $string full line for csv split + * @param string $encoding optional, if given, converts string to the internal encoding + * before we do anything + * @param string $delimiter sepperate character, default ',' + * @param string $enclosure string line marker, default '"' + * @param string $flag INTERN | EXTERN. if INTERN uses the PHP function, else uses explode + * @return array array with split data from input line + */ +function mtParseCSV( + string $string, + string $encoding = '', + string $delimiter = ',', + string $enclosure = '"', + string $flag = 'INTERN' +): array { + $lines = []; + if ($encoding) { + $string = \CoreLibs\Convert\Encoding::convertEncoding( + $string, + 'UTF-8', + $encoding + ); + } + if ($flag == 'INTERN') { + // split with PHP function + $lines = str_getcsv($string, $delimiter, $enclosure); + } else { + // split up with delimiter + $lines = explode(',', $string) ?: []; + } + // strip " from beginning and end of line + for ($i = 0; $i < count($lines); $i++) { + // remove line breaks + $lines[$i] = preg_replace("/\r\n?/", '', (string)$lines[$i]) ?? ''; + // lingering " at the beginning and end of the line + $lines[$i] = preg_replace("/^\"/", '', (string)$lines[$i]) ?? ''; + $lines[$i] = preg_replace("/\"$/", '', (string)$lines[$i]) ?? ''; + } + return $lines; +} + print ""; // __END__ diff --git a/www/admin/class_test.login.php b/www/admin/class_test.login.php index 31a7bfea..5b717b0b 100644 --- a/www/admin/class_test.login.php +++ b/www/admin/class_test.login.php @@ -145,9 +145,12 @@ print "

Legacy Lookups

"; $edit_access_id = 1; $edit_access_cuid = $login->loginGetEditAccessCuidFromId($edit_access_id); -$edit_access_id_rev = $login->loginGetEditAccessIdFromCuid($edit_access_cuid); +$edit_access_id_rev = null; +if (is_string($edit_access_cuid)) { + $edit_access_id_rev = $login->loginGetEditAccessIdFromCuid($edit_access_cuid); +} print "EA ID: " . $edit_access_id . "
"; -print "EA CUID: " . $edit_access_cuid . "
"; -print "REV EA CUID: " . $edit_access_id_rev . "
"; +print "EA CUID: " . $log->prAr($edit_access_cuid) . "
"; +print "REV EA CUID: " . $log->prAr($edit_access_id_rev) . "
"; print ""; diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index 4daad5b8..a0ae64de 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -3141,6 +3141,7 @@ class IO 'pk_name' => '', 'count' => 0, 'query' => '', + 'query_raw' => $query, 'result' => null, 'returning_id' => false, 'placeholder_converted' => [], @@ -3237,11 +3238,12 @@ class IO } } else { // if we try to use the same statement name for a differnt query, error abort - if ($this->prepare_cursor[$stm_name]['query'] != $query) { + if ($this->prepare_cursor[$stm_name]['query_raw'] != $query) { // thrown error $this->__dbError(26, false, context: [ 'statement_name' => $stm_name, 'prepared_query' => $this->prepare_cursor[$stm_name]['query'], + 'prepared_query_raw' => $this->prepare_cursor[$stm_name]['query_raw'], 'query' => $query, 'pk_name' => $pk_name, ]); @@ -4364,6 +4366,37 @@ class IO return $this->prepare_cursor[$stm_name][$key]; } + /** + * Checks if a prepared query eixsts + * + * @param string $stm_name Statement to check + * @param string $query [default=''] If set then query must also match + * @return false|int<0,2> False on missing stm_name + * 0: ok, 1: stm_name matchin, 2: stm_name and query matching + */ + public function dbPreparedCursorStatus(string $stm_name, string $query = ''): false|int + { + if (empty($stm_name)) { + $this->__dbError( + 101, + false, + 'No statement name given' + ); + return false; + } + // does not exist + $return_value = 0; + if (!empty($this->prepare_cursor[$stm_name]['query_raw'])) { + // statement name eixts + $return_value = 1; + if ($this->prepare_cursor[$stm_name]['query_raw'] == $query) { + // query also matches + $return_value = 2; + } + } + return $return_value; + } + // *************************** // ERROR AND WARNING DATA // ***************************