DB\IO move db related queries to db functions and add interface class

A new interface class for DB\SQL\* functions

Also moved all PostgreSQL related SHOW/SET code to the DB\SQL\*
functions class.
This commit is contained in:
Clemens Schwaighofer
2022-03-07 13:35:54 +09:00
parent e3cf55efe5
commit cf49bf72fa
7 changed files with 1467 additions and 208 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -52,7 +52,8 @@ print "DBINFO: " . $db->dbInfo() . "<br>";
echo "DB_CONFIG_SET constant: <pre>" . print_r(DB_CONFIG, true) . "</pre><br>";
// DB client encoding
print "DB Client encoding: " . $db->dbGetEncoding() . "<br>";
print "DB client encoding: " . $db->dbGetEncoding() . "<br>";
print "DB search path: " . $db->dbGetSchema() . "<br>";
while (is_array($res = $db->dbReturn("SELECT * FROM max_test", DbIo::USE_CACHE, true))) {
print "UUD/TIME: " . $res['uid'] . "/" . $res['time'] . "<br>";
@@ -304,13 +305,14 @@ dbShowTableMetaData
# async test queries
/*
$db->dbExecAsync("SELECT test FROM test_foo, (SELECT pg_sleep(10)) as sub WHERE test_foo_id IN (27, 50, 67, 44, 10)");
$db->dbExecAsync(
"SELECT test FROM test_foo, (SELECT pg_sleep(10)) as sub "
. "WHERE test_foo_id IN (27, 50, 67, 44, 10)"
);
echo "WAITING FOR ASYNC: ";
$chars = ['|', '/', '-', '\\'];
while (($ret = $db->dbCheckAsync()) === true)
{
if ((list($_, $char) = each($chars)) === FALSE)
{
while (($ret = $db->dbCheckAsync()) === true) {
if ((list($_, $char) = each($chars)) === FALSE) {
reset($chars);
list($_, $char) = each($chars);
}
@@ -320,15 +322,13 @@ while (($ret = $db->dbCheckAsync()) === true)
}
print "<br>END STATUS: " . $ret . "<br>";
// while ($res = $db->dbFetchArray($ret))
while ($res = $db->dbFetchArray())
{
while ($res = $db->dbFetchArray()) {
echo "RES: " . $res['test'] . "<br>";
}
# test async insert
$db->dbExecAsync("INSERT INTO test_foo (Test) VALUES ('ASYNC TEST " . time() . "')");
echo "WAITING FOR ASYNC INSERT: ";
while (($ret = $db->dbCheckAsync()) === true)
{
while (($ret = $db->dbCheckAsync()) === true) {
print " . ";
sleep(1);
flush();

View File

@@ -828,7 +828,7 @@ class IO
// only do if array, else pass through row (can be false)
if (
!is_array($row) ||
empty($this->to_encoding) || empty($this->db_encoding)
empty($this->to_encoding)// || empty($this->db_encoding)
) {
return $row;
}
@@ -841,7 +841,11 @@ class IO
$from_encoding != $this->to_encoding &&
$from_encoding != 'ASCII'
) {
$row[$key] = mb_convert_encoding($value, $this->to_encoding, $from_encoding);
$row[$key] = mb_convert_encoding(
$value,
$this->to_encoding,
$from_encoding
);
}
}
return $row;
@@ -1216,6 +1220,9 @@ class IO
public function dbClose(): void
{
if ($this->dbh) {
// reset any client encodings set
$this->dbResetEncoding();
// calls db close
$this->db_functions->__dbClose();
$this->dbh = null;
$this->db_connection_closed = true;
@@ -2365,6 +2372,15 @@ class IO
}
}
/**
* Returns the current async running query hash
* @return string Current async running query hash
*/
public function dbGetAsyncRunning(): string
{
return $this->async_running;
}
// ***************************
// COMPLEX WRITE WITH CONFIG ARRAYS
// ***************************
@@ -2603,6 +2619,7 @@ class IO
*/
public function dbSetMaxQueryCall(?int $max_calls = null): bool
{
$this->__dbErrorReset();
// if null then reset to default
if ($max_calls === null) {
$max_calls = self::DEFAULT_MAX_QUERY_CALL;
@@ -2640,25 +2657,29 @@ class IO
*/
public function dbSetSchema(string $db_schema)
{
$this->__dbErrorReset();
if (empty($db_schema)) {
$this->__dbError(70);
return false;
}
// check if schema exists
$q = "SELECT EXISTS("
. "SELECT 1 FROM information_schema.schemata "
. "WHERE schema_name = " . $this->dbEscapeLiteral($db_schema)
. ")";
$row = $this->dbReturnRow($q);
if (!$this->dbBoolean($row['exists'])) {
$this->__dbError(71);
return false;
$status = false;
$set_value = $this->db_functions->__dbSetSchema($db_schema);
switch ($set_value) {
// no problem
case 0:
$this->db_schema = $db_schema;
$status = true;
break;
// cursor failed (1) or schema does not exists (2)
case 1:
case 2:
// setting schema failed (3)
case 3:
$this->__dbError(71);
$status = false;
break;
}
// set new schema
$q = "SET search_path TO '" . $this->dbEscapeString($db_schema) . "'";
$this->dbExec($q);
$this->db_schema = $db_schema;
return true;
return $status;
}
/**
@@ -2673,11 +2694,7 @@ class IO
if ($class_var === true) {
return $this->db_schema;
}
$search_path = $this->dbReturnRow('SHOW search_path');
if (!is_array($search_path)) {
return '';
}
return $search_path['search_path'] ?? '';
return $this->db_functions->__dbGetSchema();
}
/**
@@ -2688,32 +2705,31 @@ class IO
*/
public function dbSetEncoding(string $db_encoding): bool
{
$this->__dbErrorReset();
// no encding, abort
if (empty($db_encoding)) {
$this->__dbError(80);
return false;
}
// check if ecnoding is valid first
// does not take into account aliases
// TODO lookup with alisaes so eg ShiftJIS does not get a false
// $q = "SELECT EXISTS("
// . "SELECT pg_catalog.pg_encoding_to_char(conforencoding) "
// . "FROM pg_catalog.pg_conversion "
// . "WHERE pg_catalog.pg_encoding_to_char(conforencoding) = "
// . $this->dbEscapeLiteral($db_encoding)
// . ")";
// $row = $this->dbReturnRow($q);
// if (!$this->dbBoolean($row['exists'])) {
// $this->__dbError(81);
// return false;
// }
$q = "SET client_encoding TO '" . $this->dbEscapeString($db_encoding) . "'";
// abort on error
if ($this->dbExec($q) === false) {
$this->__dbError(81);
return false;
// set client encoding on database side
$status = false;
$set_value = $this->db_functions->__dbSetEncoding($db_encoding);
switch ($set_value) {
// no problem
case 0:
$this->db_encoding = $db_encoding;
$status = true;
break;
// 1 & 2 are for encoding not found
case 1:
case 2:
// 3 is set failed
case 3:
$this->__dbError(81);
$status = false;
break;
}
$this->db_encoding = $db_encoding;
return true;
return $status;
}
/**
@@ -2727,17 +2743,23 @@ class IO
if ($class_var === true) {
return $this->db_encoding;
}
$client_encoding = $this->dbReturnRow('SHOW client_encoding');
if (!is_array($client_encoding)) {
return '';
}
return $client_encoding['client_encoding'] ?? '';
return $this->db_functions->__dbGetEncoding();
}
/**
* Resets client encodig back to databse encoding
* @return void
*/
public function dbResetEncoding(): void
{
$this->dbExec('RESET client_encoding');
}
/**
* Set the to_encoding var that will trigger on return of selected data
* on the fly PHP encoding conversion
* Alternative use dbSetEcnoding to trigger encoding change on the DB side
* Set to empty string to turn off
* @param string $encoding PHP Valid encoding to set
* @return string Current set encoding
*/

View File

@@ -0,0 +1,297 @@
<?php
/**
* Intrface for all SQL\* functions
*/
declare(strict_types=1);
namespace CoreLibs\DB\SQL\Interface;
interface SqlFunctions
{
/**
* Undocumented function
*
* @return bool
*/
public function __dbLastErrorQuery(): bool;
/**
* Undocumented function
*
* @param string $query
* @return object|resource|bool
*/
public function __dbQuery(string $query);
/**
* Undocumented function
*
* @param string $query
* @param array<mixed> $params
* @return object|resource|bool
*/
public function __dbQueryParams(string $query, array $params);
/**
* Undocumented function
*
* @param string $query
* @return boolean
*/
public function __dbSendQuery(string $query): bool;
/**
* Undocumented function
*
* @return object|resource|bool
*/
public function __dbGetResult();
/**
* Undocumented function
*
* @return void
*/
public function __dbClose(): void;
/**
* Undocumented function
*
* @param string $name
* @param string $query
* @return object|resource|bool
*/
public function __dbPrepare(string $name, string $query);
/**
* Undocumented function
*
* @param string $name
* @param array<mixed> $data
* @return object|resource|bool
*/
public function __dbExecute(string $name, array $data);
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @return integer
*/
public function __dbNumRows($cursor): int;
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @return integer
*/
public function __dbNumFields($cursor): int;
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @param int $i
* @return string|bool
*/
public function __dbFieldName($cursor, int $i);
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @param int $result_type
* @return array<mixed>|bool
*/
public function __dbFetchArray($cursor, int $result_type = PGSQL_BOTH);
/**
* Undocumented function
*
* @param boolean $assoc_type
* @return integer
*/
public function __dbResultType(bool $assoc_type = true): int;
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @return array<mixed>|bool
*/
public function __dbFetchAll($cursor);
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @return integer
*/
public function __dbAffectedRows($cursor): int;
/**
* Undocumented function
*
* @param string $query
* @param string|null $pk_name
* @return string|integer|false
*/
public function __dbInsertId(string $query, ?string $pk_name);
/**
* Undocumented function
*
* @param string $table
* @param string $schema
* @return string|bool
*/
public function __dbPrimaryKey(string $table, string $schema = '');
/**
* Undocumented function
*
* @param string $db_host
* @param string $db_user
* @param string $db_pass
* @param string $db_name
* @param integer $db_port
* @param string $db_ssl
* @return object|resource|bool
*/
public function __dbConnect(
string $db_host,
string $db_user,
string $db_pass,
string $db_name,
int $db_port,
string $db_ssl = 'allow'
);
/**
* Undocumented function
*
* @param object|resource|bool $cursor
* @return string
*/
public function __dbPrintError($cursor = false): string;
/**
* Undocumented function
*
* @param string $table
* @param boolean $extended
* @return array<mixed>|bool
*/
public function __dbMetaData(string $table, $extended = true);
/**
* Undocumented function
*
* @param string|int|float|bool $string
* @return string
*/
public function __dbEscapeString($string): string;
/**
* Undocumented function
*
* @param string|int|float|bool $string
* @return string
*/
public function __dbEscapeLiteral($string): string;
/**
* Undocumented function
*
* @param string $string
* @return string
*/
public function __dbEscapeIdentifier(string $string): string;
/**
* Undocumented function
*
* @param string $bytea
* @return string
*/
public function __dbEscapeBytea(string $bytea): string;
/**
* Undocumented function
*
* @return boolean
*/
public function __dbConnectionBusy(): bool;
/**
* Undocumented function
*
* @param integer $timeout_seconds
* @return boolean
*/
public function __dbConnectionBusySocketWait(int $timeout_seconds = 3): bool;
/**
* Undocumented function
*
* @return string
*/
public function __dbVersion(): string;
/**
* Undocumented function
*
* @param string $array_text
* @param integer $start
* @param integer|null $end
* @return array<mixed>|null
*/
public function __dbArrayParse(
string $array_text,
int $start = 0,
?int &$end = null
): ?array;
/**
* Undocumented function
*
* @param string $show_string
* @return string
*/
public function __dbShow(string $show_string): string;
/**
* Undocumented function
*
* @param string $db_schema
* @return integer
*/
public function __dbSetSchema(string $db_schema): int;
/**
* Undocumented function
*
* @return string
*/
public function __dbGetSchema(): string;
/**
* Undocumented function
*
* @param string $db_encoding
* @return integer
*/
public function __dbSetEncoding(string $db_encoding): int;
/**
* Undocumented function
*
* @return string
*/
public function __dbGetEncoding(): string;
}
// __END__

View File

@@ -51,7 +51,7 @@ namespace CoreLibs\DB\SQL;
// as main system. Currently all @var sets are written as object
/** @#phan-file-suppress PhanUndeclaredTypeProperty,PhanUndeclaredTypeParameter,PhanUndeclaredTypeReturnType */
class PgSQL
class PgSQL implements Interface\SqlFunctions
{
/** @var string */
private $last_error_query;
@@ -62,15 +62,15 @@ class PgSQL
/**
* class constructor, empty does nothing
*/
public function __construct()
{
}
// public function __construct()
// {
// }
/**
* queries last error query and returns true or false if error was set
* @return bool true/false if last error is set
*/
public function __dbLastErrorQuery()
public function __dbLastErrorQuery(): bool
{
if ($this->last_error_query) {
return true;
@@ -210,7 +210,7 @@ class PgSQL
/**
* wrapper for pg_num_rows
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @return int number of rows, -1 on error
* @return int number of rows, -1 on error
*/
public function __dbNumRows($cursor): int
{
@@ -223,7 +223,7 @@ class PgSQL
/**
* wrapper for pg_num_fields
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @return int number for fields in result, -1 on error
* @return int number for fields in result, -1 on error
*/
public function __dbNumFields($cursor): int
{
@@ -235,11 +235,11 @@ class PgSQL
/**
* wrapper for pg_field_name
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @param int $i field position
* @return string|bool name or false on error
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @param int $i field position
* @return string|bool name or false on error
*/
public function __dbFieldName($cursor, $i)
public function __dbFieldName($cursor, int $i)
{
if ($cursor === false || is_bool($cursor)) {
return false;
@@ -251,8 +251,8 @@ class PgSQL
* wrapper for pg_fetch_array
* if through/true false, use __dbResultType(true)
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @param int $result_type result type as int number
* @return array<mixed>|bool array result data or false on end/error
* @param int $result_type result type as int number
* @return array<mixed>|bool array result data or false on end/error
*/
public function __dbFetchArray($cursor, int $result_type = PGSQL_BOTH)
{
@@ -279,8 +279,8 @@ class PgSQL
/**
* wrapper for pg_fetch_all
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @return array<mixed>|bool data array or false for end/error
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @return array<mixed>|bool data array or false for end/error
*/
public function __dbFetchAll($cursor)
{
@@ -293,7 +293,7 @@ class PgSQL
/**
* wrapper for pg_affected_rows
* @param object|resource|bool $cursor cursor PgSql\Result (former resource)
* @return int affected rows, 0 for none, -1 for error
* @return int affected rows, 0 for none, -1 for error
*/
public function __dbAffectedRows($cursor): int
{
@@ -362,19 +362,11 @@ class PgSQL
public function __dbPrimaryKey(string $table, string $schema = '')
{
if ($table) {
// check if schema set is different from schema given, only needed if schema is not empty
// check if schema set is different from schema given,
// only needed if schema is not empty
$table_prefix = '';
if ($schema) {
$q = "SHOW search_path";
$cursor = $this->__dbQuery($q);
if ($cursor === false) {
return false;
}
$__db_fetch_array = $this->__dbFetchArray($cursor);
if (!is_array($__db_fetch_array)) {
return false;
}
$search_path = $__db_fetch_array['search_path'] ?? '';
$search_path = $this->__dbGetSchema();
if ($search_path != $schema) {
$table_prefix = $schema . '.';
}
@@ -415,12 +407,12 @@ class PgSQL
/**
* wrapper for pg_connect, writes out failure to screen if error occurs (hidden var)
* @param string $db_host host name
* @param string $db_user user name
* @param string $db_pass password
* @param string $db_name databse name
* @param integer $db_port port (int, 5432 is default)
* @param string $db_ssl SSL (allow is default)
* @param string $db_host host name
* @param string $db_user user name
* @param string $db_pass password
* @param string $db_name databse name
* @param integer $db_port port (int, 5432 is default)
* @param string $db_ssl SSL (allow is default)
* @return object|resource|bool db handler PgSql\Connection or false on error
*/
public function __dbConnect(
@@ -458,9 +450,6 @@ class PgSQL
}
// connect
$this->dbh = pg_connect(join(' ', $connection_string));
// if (!$this->dbh) {
// die("<!-- Can't connect to database //-->");
// }
return $this->dbh;
}
@@ -469,7 +458,7 @@ class PgSQL
* html formatted string with error name
* @param bool|object|resource $cursor cursor PgSql\Result (former resource)
* or null
* @return string error string
* @return string error string
*/
public function __dbPrintError($cursor = false): string
{
@@ -508,7 +497,7 @@ class PgSQL
/**
* wrapper for pg_escape_string
* @param string|int|float|bool $string any string/int/float/bool
* @return string excaped string
* @return string excaped string
*/
public function __dbEscapeString($string): string
{
@@ -523,7 +512,7 @@ class PgSQL
* difference to escape string is that this one adds quotes ('') around
* the string too
* @param string|int|float|bool $string any string/int/float/bool
* @return string excaped string including quites
* @return string excaped string including quites
*/
public function __dbEscapeLiteral($string): string
{
@@ -554,7 +543,7 @@ class PgSQL
* @param string $bytea bytea data stream
* @return string escaped bytea string
*/
public function __dbEscapeBytea($bytea): string
public function __dbEscapeBytea(string $bytea): string
{
if ($this->dbh === false || is_bool($this->dbh)) {
return '';
@@ -564,7 +553,7 @@ class PgSQL
/**
* wrapper for pg_connection_busy
* @return bool true/false for busy connection
* @return bool True if connection is busy, False if not or no db connection at all
*/
public function __dbConnectionBusy(): bool
{
@@ -577,7 +566,8 @@ class PgSQL
/**
* Experimental wrapper with scoket timetout
* @param integer $timeout_seconds Wait how many seconds on timeout
* @return boolean
* @return boolean True if connection is busy, or false on
* not busy or no db connection at all
*/
public function __dbConnectionBusySocketWait(int $timeout_seconds = 3): bool
{
@@ -619,10 +609,10 @@ class PgSQL
* This is a fallback for old PostgreSQL versions
* postgresql array to php array
* https://stackoverflow.com/a/27964420
* @param string $array_text Array text from PostgreSQL
* @param int $start Start string position
* @param int|null $end End string position from recursive call
* @return null|array<mixed> PHP type array
* @param string $array_text Array text from PostgreSQL
* @param int $start Start string position
* @param int|null $end End string position from recursive call
* @return array<mixed>|null PHP type array
*/
public function __dbArrayParse(
string $array_text,
@@ -673,6 +663,110 @@ class PgSQL
return $return;
}
/**
* wrapper for any SHOW data blocks
* eg search_path or client_encoding
* @param string $show_string Part to show, if invalid will return empty string
* @return string Found part as is
*/
public function __dbShow(string $show_string): string
{
// get search path
$cursor = $this->__dbQuery("SHOW " . $this->__dbEscapeIdentifier($show_string));
// abort on failure and return empty
if ($cursor === false) {
return '';
}
// get result
$db_schema = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
/** @phpstan-ignore-next-line Cannot access offset string on array|bool */
return $db_schema[$show_string] ?? '';
}
/**
* Sets a new database schema/search_path
* Checks if schema exits and if not aborts with error code 2
* @param string $db_schema Schema to set
* @return int Returns 0 if no error
* 1 for check query failed
* 2 for schema not found in database
*/
public function __dbSetSchema(string $db_schema): int
{
// check if schema actually exists
$query = "SELECT EXISTS("
. "SELECT 1 FROM information_schema.schemata "
. "WHERE schema_name = " . $this->__dbEscapeLiteral($db_schema)
. ")";
$cursor = $this->__dbQuery($query);
// abort if execution fails
if ($cursor === false) {
return 1;
}
// check if schema does not exists
$row = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
/** @phpstan-ignore-next-line */
if (empty($row['exists']) || $row['exists'] == 'f') {
return 2;
}
$query = "SET search_path TO " . $this->__dbEscapeLiteral($db_schema);
$this->__dbQuery($query);
return 0;
}
/**
* Returns current set schema/search_path
* @return string Search Path as currently set in DB
*/
public function __dbGetSchema(): string
{
return $this->__dbShow('search_path');
}
/**
* set the client encoding
* Returns 0 on set ok, or 3 if the client encoding could not be set
* @param string $db_encoding
* @return int Returns 0 for no error
* [not used] 1 for check query failed
* [not used] 2 for invalid client encoding
* 3 client encoding could not be set
*/
public function __dbSetEncoding(string $db_encoding): int
{
// check if ecnoding is valid first
// does not take into account aliases
// TODO lookup with alisaes so eg ShiftJIS does not get a false
// $query = "SELECT EXISTS("
// . "SELECT pg_catalog.pg_encoding_to_char(conforencoding) "
// . "FROM pg_catalog.pg_conversion "
// . "WHERE pg_catalog.pg_encoding_to_char(conforencoding) = "
// . $this->dbEscapeLiteral($db_encoding)
// . ")";
// $cursor = $this->__dbQuery($query);
// if ($cursor === false) {
// return 1;
// }
// $row = $this->__dbFetchArray($cursor, PGSQL_ASSOC);
// if ($row['exists'] == 'f') {
// return 2;
// }
$query = "SET client_encoding TO " . $this->__dbEscapeLiteral($db_encoding);
if ($this->__dbQuery($query) === false) {
return 3;
}
return 0;
}
/**
* Returns current set client encoding
* @return string Client encoding string, empty if not set
*/
public function __dbGetEncoding(): string
{
return $this->__dbShow('client_encoding');
}
}
// __END__

View File

@@ -30,6 +30,7 @@ return array(
'CoreLibs\\Create\\Uids' => $baseDir . '/lib/CoreLibs/Create/Uids.php',
'CoreLibs\\DB\\Extended\\ArrayIO' => $baseDir . '/lib/CoreLibs/DB/Extended/ArrayIO.php',
'CoreLibs\\DB\\IO' => $baseDir . '/lib/CoreLibs/DB/IO.php',
'CoreLibs\\DB\\SQL\\Interface\\SqlFunctions' => $baseDir . '/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php',
'CoreLibs\\DB\\SQL\\PgSQL' => $baseDir . '/lib/CoreLibs/DB/SQL/PgSQL.php',
'CoreLibs\\Debug\\FileWriter' => $baseDir . '/lib/CoreLibs/Debug/FileWriter.php',
'CoreLibs\\Debug\\Logging' => $baseDir . '/lib/CoreLibs/Debug/Logging.php',

View File

@@ -95,6 +95,7 @@ class ComposerStaticInit10fe8fe2ec4017b8644d2b64bcf398b9
'CoreLibs\\Create\\Uids' => __DIR__ . '/../..' . '/lib/CoreLibs/Create/Uids.php',
'CoreLibs\\DB\\Extended\\ArrayIO' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/Extended/ArrayIO.php',
'CoreLibs\\DB\\IO' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/IO.php',
'CoreLibs\\DB\\SQL\\Interface\\SqlFunctions' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php',
'CoreLibs\\DB\\SQL\\PgSQL' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/SQL/PgSQL.php',
'CoreLibs\\Debug\\FileWriter' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/FileWriter.php',
'CoreLibs\\Debug\\Logging' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Logging.php',