diff --git a/4dev/tests/DB/CoreLibsDBIOTest.php b/4dev/tests/DB/CoreLibsDBIOTest.php index 0ee6e878..20e90fda 100644 --- a/4dev/tests/DB/CoreLibsDBIOTest.php +++ b/4dev/tests/DB/CoreLibsDBIOTest.php @@ -156,7 +156,7 @@ final class CoreLibsDBIOTest extends TestCase $db->dbExec("DROP TABLE test_meta"); } // uid is for internal reference tests - $base_table = <<dbExec( // primary key name is table + '_id' - <<dbExec( - <<dbExec( - << false, 'array dims' => 0, 'is enum' => false, - 'is base' => 1, + 'is base' => true, 'is composite' => false, - 'is pesudo' => false, 'description' => '', + 'is pseudo' => false ], 'row_2' => [ 'num' => 2, @@ -1355,10 +1355,10 @@ final class CoreLibsDBIOTest extends TestCase 'has default' => false, 'array dims' => 0, 'is enum' => false, - 'is base' => 1, + 'is base' => true, 'is composite' => false, - 'is pesudo' => false, 'description' => '', + 'is pseudo' => false ] ] ], @@ -1374,10 +1374,10 @@ final class CoreLibsDBIOTest extends TestCase 'has default' => false, 'array dims' => 0, 'is enum' => false, - 'is base' => 1, + 'is base' => true, 'is composite' => false, - 'is pesudo' => false, 'description' => '', + 'is pseudo' => false ], 'row_2' => [ 'num' => 2, @@ -1387,10 +1387,10 @@ final class CoreLibsDBIOTest extends TestCase 'has default' => false, 'array dims' => 0, 'is enum' => false, - 'is base' => 1, + 'is base' => true, 'is composite' => false, - 'is pesudo' => false, 'description' => '', + 'is pseudo' => false ] ] ], @@ -4425,16 +4425,16 @@ final class CoreLibsDBIOTest extends TestCase ] ] ], - // same but as EOM - 'single insert (PK), EOM string' => [ - << [ + << [ - << [ + <<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() . " |
" @@ -167,21 +167,21 @@ print "DIRECT INSERT PREVIOUS INSERTED: " . print_r($db->dbReturnRow("SELECT test_foo_id, test FROM test_foo " . "WHERE test_foo_id = " . (int)$last_insert_pk), true) . "
"; $__last_insert_pk = (int)$last_insert_pk; -$query = <<dbReturnRow($query), true) . "
"; print "LAST ERROR: " . $db->dbGetLastError() . "
"; print "
"; -$query = <<dbReturnRowParams( $query, @@ -208,7 +208,7 @@ 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) . " |
" @@ -235,7 +235,7 @@ print "EOM STRING EXEC PARAMS INSERT STATUS: " . Support::printToString($status) . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "
"; // I/S Query -$query_insert = <<dbExecParams( $query_insert, @@ -313,18 +313,51 @@ print "EOM STRING EXEC RETURN TEST: " . print_r( [$__last_insert_id] ) ) . "
"; +// params > 10 for debug +// error catcher +$query_insert = <<dbExecParams($query_insert, $query_params); +echo "*
"; +echo "EOM STRING WITH MORE THAN 10 PARAMETERS: " + . Support::printToString($query_params) . " |
" + . " |
" + . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " + . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " + . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) + . "ERROR: " . $db->dbGetLastError(true) . "
"; echo "
"; // binary insert tests $filename = $db->dbEscapeLiteral('class_test.db.php'); $rand_bin_uid = $db->dbEscapeLiteral(\CoreLibs\Create\Uids::uniqIdShort()); $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: ''); -$query = <<dbExec($query); $__last_insert_id = $db->dbGetInsertPK(); print "BINARY DATA INSERT: " @@ -336,13 +369,13 @@ print "BINARY DATA INSERT: " . "ERROR: " . $db->dbGetLastError(true) . "
"; echo "*
"; -$query = <<dbExecParams($query, [$filename, $rand_bin_uid, $binary_data]); $__last_insert_id = $db->dbGetInsertPK(); print "BINARY DATA INSERT PARAMS: " @@ -380,7 +413,7 @@ print "DIRECT MULTIPLE INSERT WITH RETURN STATUS: " . Support::printToString($st $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() . " |
" @@ -422,7 +455,7 @@ print "UPDATE WITH PK " . Support::printToString($last_insert_pk) . "RETURNING ARRAY: " . print_r($db->dbGetReturningArray(), true) . "
"; // UPDATE BUT EOM STYLE $status = $db->dbExecParams( - <<dbExecParams( tset_foo_id = ? RETURNING test_foo.test, string_a - EOM, + SQL, ['SOMETHING DIFFERENT EOM', (string)rand(1, 100)] ); print "UPDATE EOM WITH PK " . Support::printToString($last_insert_pk) @@ -524,27 +557,27 @@ echo "
"; print "EOM STYLE STRINGS
"; $test_bar = $db->dbEscapeLiteral('SOMETHING DIFFERENT'); // Test EOM block -$q = <<dbReturn($q))) { print "ROW:
" . print_r($res, true) . "

"; } echo "
"; print "DB RETURN PARAMS
"; -$q = <<dbReturnParams($q, ['SOMETHING DIFFERENT'])) ) { @@ -632,14 +665,14 @@ print "Wrote to DB tabel $table with data " . print_r($data, true) . " and got p $query = "SELECT type, sdate, integer FROM foobar"; $data = $db->dbReturnArray($query, true); print "RETURN ARRAY: " . $db->dbGetNumRows() . ", Full foobar list:
" . print_r($data, true) . "

"; -$query = <<dbReturnArrayParams($query, ['schmalz'], true); print "RETURN ARRAY PARAMS: " . $db->dbGetNumRows() . ", Full foobar list:
"
 	. print_r($data, true) . "

"; diff --git a/www/admin/class_test.db.single.php b/www/admin/class_test.db.single.php new file mode 100644 index 00000000..c70edb4c --- /dev/null +++ b/www/admin/class_test.db.single.php @@ -0,0 +1,105 @@ + BASE . LOG, + 'file_id' => $LOG_FILE_ID, + // add file date + 'print_file_date' => true, + // set debug and print flags + 'debug_all' => $DEBUG_ALL ?? true, + 'echo_all' => $ECHO_ALL, + 'print_all' => $PRINT_ALL ?? true, +]); +// db connection and attach logger +$db = new CoreLibs\DB\IO(DB_CONFIG, $log); +$db->log->debug('START', '=============================>'); + +$PAGE_NAME = 'TEST CLASS: DB SINGLE'; +print ""; +print "" . $PAGE_NAME . ""; +print ""; +print ''; +print ''; +print '

' . $PAGE_NAME . '

'; + +print "LOGFILE NAME: " . $db->log->getSetting('log_file_name') . "
"; +print "LOGFILE ID: " . $db->log->getSetting('log_file_id') . "
"; +print "DBINFO: " . $db->dbInfo() . "
"; +// DB client encoding +print "DB client encoding: " . $db->dbGetEncoding() . "
"; +print "DB search path: " . $db->dbGetSchema() . "
"; + +$to_db_version = '15.2'; +print "VERSION DB: " . $db->dbVersion() . "
"; +print "SERVER ENCODING: " . $db->dbVersionInfo('server_encoding') . "
"; +if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) { + print "ALL OUTPUT [TEST]:
" . print_r(pg_version($dbh), true) . "

"; +} else { + print "NO DB HANDLER
"; +} + +// params > 10 for debug +// error catcher +$query_insert = <<dbExecParams($query_insert, $query_params); +echo "*
"; +echo "EOM STRING WITH MORE THAN 10 PARAMETERS: " + . Support::printToString($query_params) . " |
" + . " |
" + . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " + // . "RETURNING EXT: " . Support::printToString($db->dbGetReturningExt()) . " | " + . "RETURNING RETURN: " . Support::printToString($db->dbGetReturningArray()) + . "ERROR: " . $db->dbGetLastError(true) . "
"; +echo "
"; + +// error message +print $log->printErrorMsg(); + +print ""; + +// __END__ diff --git a/www/admin/class_test.php b/www/admin/class_test.php index 5fd5ec47..9c2b453c 100644 --- a/www/admin/class_test.php +++ b/www/admin/class_test.php @@ -73,6 +73,7 @@ print "TEST CLASS"; print ""; print ''; +print ''; print ''; print ''; print ''; diff --git a/www/configs/config.master.php b/www/configs/config.master.php index 551dbb75..51ed8267 100644 --- a/www/configs/config.master.php +++ b/www/configs/config.master.php @@ -185,7 +185,7 @@ if (file_exists(BASE . CONFIGS . 'config.path.php')) { // live frontend pages // ** missing live domains ** // get the name without the port -list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null); +[$HOST_NAME] = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null); // set HOST name define('HOST_NAME', $HOST_NAME); // BAIL ON MISSING MASTER SITE CONFIG diff --git a/www/lib/CoreLibs/ACL/Login.php b/www/lib/CoreLibs/ACL/Login.php index c4126be7..92a87028 100644 --- a/www/lib/CoreLibs/ACL/Login.php +++ b/www/lib/CoreLibs/ACL/Login.php @@ -1608,7 +1608,7 @@ class Login // TODO: submit or JS to set target page as ajax call // NOTE: for the HTML block I ignore line lengths // phpcs:disable - $this->login_template['password_change'] = <<login_template['password_change'] = << @@ -1626,7 +1626,7 @@ class Login

{TITLE_PASSWORD_CHANGE}

{PASSWORD_CHANGE_SHOW} -EOM; +HTML; // phpcs:enable } if ($this->password_forgot) { @@ -1650,7 +1650,7 @@ EOM; // now check templates // TODO: submit or JS to set target page as ajax call if (!$this->login_template['template']) { - $this->login_template['template'] = <<login_template['template'] = << @@ -1712,7 +1712,7 @@ h3 { font-size: 18px; } -EOM; +HTML; } } diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index f637aa70..6d0f1e5c 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -735,7 +735,10 @@ class IO */ private function __dbErrorPreprocessor(\PgSql\Result|false $cursor = false): array { - $pg_error_string = ''; + $db_prefix = ''; + $db_error_string = ''; + $db_prefix_last = ''; + $db_error_string_last = ''; // 1 = self/__dbErrorPreprocessor, 2 = __dbError, __dbWarning, // 3+ == actual source // loop until we get a null, build where called chain @@ -749,16 +752,31 @@ class IO if ($where_called === null) { $where_called = '[Unknown Method]'; } + [$db_prefix_last, $db_error_string_last] = $this->db_functions->__dbPrintLastError(); if ($cursor !== false) { - $pg_error_string = $this->db_functions->__dbPrintError($cursor); + [$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError($cursor); } if ($cursor === false && method_exists($this->db_functions, '__dbPrintError')) { - $pg_error_string = $this->db_functions->__dbPrintError(); + [$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError(); } - if ($pg_error_string) { - $this->__dbDebug('db', $pg_error_string, 'DB_ERROR', $where_called); + // prefix the master if not the same + if ( + !empty($db_error_string_last) && + trim($db_error_string) != trim($db_error_string_last) + ) { + $db_error_string = + $db_prefix_last . ' ' . $db_error_string_last . ';' + . $db_prefix . ' ' . $db_error_string; + } elseif (!empty($db_error_string)) { + $db_error_string = $db_prefix . ' ' . $db_error_string; } - return [$where_called, $pg_error_string]; + if ($db_error_string) { + $this->__dbDebug('db', $db_error_string, 'DB_ERROR', $where_called); + } + return [ + $where_called, + $db_error_string + ]; } /** @@ -902,11 +920,14 @@ class IO // because the placeholders start with $ and at 1, // we need to increase each key and prefix it with a $ char for ($i = 0, $iMax = count($keys); $i < $iMax; $i++) { - $keys[$i] = '$' . ($keys[$i] + 1); + // note: if I use $ here, the str_replace will + // replace it again. eg $11 '$1'1would be replaced with $1 again // prefix data set with parameter pos - $data[$i] = $keys[$i] . ':' . ($data[$i] === null ? + $data[$i] = '#' . ($keys[$i] + 1) . ':' . ($data[$i] === null ? '"NULL"' : (string)$data[$i] ); + // search part + $keys[$i] = '$' . ($keys[$i] + 1); } // simply replace the $1, $2, ... with the actual data and return it return str_replace( diff --git a/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php b/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php index 5aa7fdb5..7e81a164 100644 --- a/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php +++ b/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php @@ -209,10 +209,17 @@ interface SqlFunctions /** * Undocumented function * - * @param \PgSql\Result|false $cursor - * @return string + * @return array{0:string,1:string} */ - public function __dbPrintError(\PgSql\Result|false $cursor = false): string; + public function __dbPrintLastError(): array; + + /** + * Undocumented function + * + * @param \PgSql\Result|false $cursor + * @return array{0:string,1:string} + */ + public function __dbPrintError(\PgSql\Result|false $cursor = false): array; /** * Undocumented function diff --git a/www/lib/CoreLibs/DB/SQL/PgSQL.php b/www/lib/CoreLibs/DB/SQL/PgSQL.php index 9f42f76a..2d9b34eb 100644 --- a/www/lib/CoreLibs/DB/SQL/PgSQL.php +++ b/www/lib/CoreLibs/DB/SQL/PgSQL.php @@ -61,7 +61,7 @@ class PgSQL implements Interface\SqlFunctions /** @var string */ private $last_error_query; /** @var \PgSql\Connection|false */ - private $dbh; + private $dbh = false; /** * queries last error query and returns true or false if error was set @@ -532,18 +532,37 @@ class PgSQL implements Interface\SqlFunctions return $this->dbh; } + /** + * Returns last error for active cursor + * + * @return array{0:string,1:string} prefix, error string + */ + public function __dbPrintLastError(): array + { + if (is_bool($this->dbh)) { + return ['', '']; + } + if (!empty($error_message = pg_last_error($this->dbh))) { + return [ + '-PostgreSQL-Error-Last-', + $error_message + ]; + } + return ['', '']; + } + /** * reads the last error for this cursor and returns * html formatted string with error name * * @param \PgSql\Result|false $cursor cursor - * or null - * @return string error string + * or null + * @return array{0:string,1:string} prefix, error string */ - public function __dbPrintError(\PgSql\Result|false $cursor = false): string + public function __dbPrintError(\PgSql\Result|false $cursor = false): array { if (is_bool($this->dbh)) { - return ''; + return ['', '']; } // run the query again for the error result here if ((is_bool($cursor)) && $this->last_error_query) { @@ -552,10 +571,12 @@ class PgSQL implements Interface\SqlFunctions $cursor = pg_get_result($this->dbh); } if ($cursor && $error_str = pg_result_error($cursor)) { - return '-PostgreSQL-Error- ' - . $error_str; + return [ + '-PostgreSQL-Error-', + $error_str + ]; } else { - return ''; + return ['', '']; } }