Autoloader updates, read env to class, DB IO update
Move autolaoder loading from config.master.php to config.php and before we read config.master.php The read env function has moved into a class and is launched after the auto loader has been loaded DB IO class update with better error reporting with last error set and error history of all errors in order. TODO: per query or per action error grouping
This commit is contained in:
@@ -15,8 +15,51 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
final class CoreLibsDBIOTest extends TestCase
|
||||
{
|
||||
private static $db_config = [];
|
||||
private static $log;
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
// define basic connection set valid and one invalid
|
||||
self::$db_config = [
|
||||
// self localhost/ip connection
|
||||
'valid' => [
|
||||
'db_name' => 'corelibs_db_io_test',
|
||||
'db_user' => 'corelibs_db_io_test',
|
||||
'db_pass' => 'corelibs_db_io_test',
|
||||
'db_host' => 'localhost',
|
||||
'db_port' => 5432,
|
||||
'db_schema' => 'public',
|
||||
'db_type' => 'pgsql',
|
||||
'db_encoding' => '',
|
||||
'db_ssl' => 'allow', // allow, disable, require, prefer
|
||||
'db_debug' => true,
|
||||
],
|
||||
'invalid' => [
|
||||
'db_name' => '',
|
||||
'db_user' => '',
|
||||
'db_pass' => '',
|
||||
'db_host' => '',
|
||||
'db_port' => 5432,
|
||||
'db_schema' => 'public',
|
||||
'db_type' => 'pgsql',
|
||||
'db_encoding' => '',
|
||||
'db_ssl' => 'allow', // allow, disable, require, prefer
|
||||
'db_debug' => true,
|
||||
],
|
||||
];
|
||||
self::$log = new \CoreLibs\Debug\Logging([
|
||||
// 'log_folder' => __DIR__ . DIRECTORY_SEPARATOR . 'log',
|
||||
'log_folder' => DIRECTORY_SEPARATOR . 'tmp',
|
||||
'file_id' => 'CoreLibs-DB-IO-Test',
|
||||
'debug_all' => false,
|
||||
'echo_all' => false,
|
||||
'print_all' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* Check that we can actually do these tests
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -27,10 +70,55 @@ final class CoreLibsDBIOTest extends TestCase
|
||||
'The PgSQL extension is not available.'
|
||||
);
|
||||
}
|
||||
// print_r(self::$db_config);
|
||||
}
|
||||
|
||||
// - connect to DB test (getConnectionStatus)
|
||||
// - connected get dbInfo data check (show true, false)
|
||||
// - disconnect: dbClose
|
||||
// - connected get all default settings via get
|
||||
// dbGetDebug, dbGetMaxQueryCall, dbGetSchema, dbGetEncoding,
|
||||
// dbVerions, dbCompareVersion
|
||||
// dbGetSetting (name, user, ecnoding, schema, host, port, ssl, debug, password)
|
||||
// - connected set
|
||||
// dbSetMaxQueryCall, dbSetDebug, dbToggleDebug, dbSetSchema, dbSetEncoding
|
||||
// - db execution tests
|
||||
// dbReturn, dbDumpData, dbCacheReset, dbExec, dbExecAsync, dbCheckAsync
|
||||
// dbFetchArray, dbReturnRow, dbReturnArray, dbCursorPos, dbCursorNumRows,
|
||||
// dbShowTableMetaData, dbPrepare, dbExecute
|
||||
// dbEscapeString, dbEscapeLiteral, dbEscapeBytea, dbSqlEscape, dbArrayParse
|
||||
// - complex write sets
|
||||
// dbWriteData, dbWriteDataExt
|
||||
// - non connection tests
|
||||
// dbBoolean, dbTimeFormat
|
||||
// - internal read data (post exec)
|
||||
// dbGetReturning, dbGetInsertPKName, dbGetInsertPK, dbGetReturningExt,
|
||||
// dbGetReturningArray, dbGetCursorExt, dbGetNumRows,
|
||||
// getHadError, getHadWarning,
|
||||
// dbResetQueryCalled, dbGetQueryCalled
|
||||
// - deprecated tests
|
||||
// getInsertReturn, getReturning, getInsertPK, getReturningExt,
|
||||
// getCursorExt, getNumRows
|
||||
|
||||
public function testConnection()
|
||||
{
|
||||
//
|
||||
$db = new \CoreLibs\DB\IO(
|
||||
self::$db_config['invalid'],
|
||||
self::$log
|
||||
);
|
||||
print "INIT ERROR INVALID: " . $db->getConnectionStatus() . "\n";
|
||||
print "LAST ERROR: " . $db->dbGetLastError(true) . "\n";
|
||||
print "ERRORS: " . print_r($db->dbGetErrorHistory(true), true) . "\n";
|
||||
$db = new \CoreLibs\DB\IO(
|
||||
self::$db_config['valid'],
|
||||
self::$log
|
||||
);
|
||||
print "INIT ERROR VALID: " . $db->getConnectionStatus() . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* grouped DB IO test
|
||||
*
|
||||
* @testdox DB\IO Class tests
|
||||
*
|
||||
|
||||
3
4dev/tests/log/.gitignore
vendored
Normal file
3
4dev/tests/log/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*log
|
||||
*LOG
|
||||
!.gitignore
|
||||
@@ -92,7 +92,7 @@ print "DIRECT INSERT PREVIOUS INSERTED: "
|
||||
|
||||
// PREPARED INSERT
|
||||
$db->dbPrepare("ins_test_foo", "INSERT INTO test_foo (test) VALUES ($1) RETURNING test");
|
||||
$status = $db->dbExecute("ins_test_foo", array('BAR TEST ' . time()));
|
||||
$status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]);
|
||||
print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status) . " | "
|
||||
. "PRIMARY KEY: " . $db->dbGetInsertPK() . " | "
|
||||
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
|
||||
@@ -245,11 +245,24 @@ $query = "SELECT type, sdate, integer FROM foobar";
|
||||
$data = $db->dbReturnArray($query, true);
|
||||
print "Full foobar list: <br><pre>" . print_r($data, true) . "</pre><br>";
|
||||
|
||||
// trigger a warning
|
||||
print "<b>WARNING NEXT</b><br>";
|
||||
// trigger an error
|
||||
print "<b>ERROR NEXT</b><br>";
|
||||
$query = "INSERT invalid FROM invalid";
|
||||
$data = $db->dbReturnArray($query);
|
||||
print "ERROR (INS ON dbExec): <pre>" . print_r($db->dbGetErrorHistory(true), true) . "</pre><br>";
|
||||
$query = "SELECT invalid FROM invalid";
|
||||
$data = $db->dbReturnArray($query);
|
||||
print "ERROR (HARD ERROR): <pre>" . print_r($db->dbGetErrorHistory(true), true) . "</pre><br>";
|
||||
|
||||
// how to handle HARD errors
|
||||
|
||||
# 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)");
|
||||
echo "WAITING FOR ASYNC: ";
|
||||
$chars = array('|', '/', '-', '\\');
|
||||
$chars = ['|', '/', '-', '\\'];
|
||||
while (($ret = $db->dbCheckAsync()) === true)
|
||||
{
|
||||
if ((list($_, $char) = each($chars)) === FALSE)
|
||||
|
||||
@@ -67,6 +67,7 @@ print '<div><a href="class_test.array.php">Class Test: ARRAY HANDLER</a></div>';
|
||||
print '<div><a href="class_test.file.php">Class Test: FILE</a></div>';
|
||||
print '<div><a href="class_test.randomkey.php">Class Test: RANDOM KEY</a></div>';
|
||||
print '<div><a href="class_test.system.php">Class Test: SYSTEM</a></div>';
|
||||
print '<div><a href="class_test.readenvfile.php">Class Test: READ ENV FILE</a></div>';
|
||||
print '<div><a href="class_test.runningtime.php">Class Test: RUNNING TIME</a></div>';
|
||||
print '<div><a href="class_test.debug.php">Class Test: DEBUG</a></div>';
|
||||
print '<div><a href="class_test.output.form.php">Class Test: OUTPUT FORM</a></div>';
|
||||
|
||||
50
www/admin/class_test.readenvfile.php
Normal file
50
www/admin/class_test.readenvfile.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php // phpcs:ignore warning
|
||||
|
||||
/**
|
||||
* @phan-file-suppress PhanTypeSuspiciousStringExpression
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
|
||||
|
||||
ob_start();
|
||||
|
||||
// basic class test file
|
||||
define('USE_DATABASE', false);
|
||||
// sample config
|
||||
require 'config.php';
|
||||
// set session name
|
||||
if (!defined('SET_SESSION_NAME')) {
|
||||
define('SET_SESSION_NAME', EDIT_SESSION_NAME);
|
||||
}
|
||||
// define log file id
|
||||
$LOG_FILE_ID = 'classTest-readEnvFile';
|
||||
ob_end_flush();
|
||||
|
||||
$log = new CoreLibs\Debug\Logging([
|
||||
'log_folder' => BASE . LOG,
|
||||
'file_id' => $LOG_FILE_ID,
|
||||
// add file date
|
||||
'print_file_date' => true,
|
||||
// set debug and print flags
|
||||
'debug_all' => $DEBUG_ALL ?? false,
|
||||
'echo_all' => $ECHO_ALL ?? false,
|
||||
'print_all' => $PRINT_ALL ?? false,
|
||||
]);
|
||||
$ref_class = 'CoreLibs\Get\ReadEnvFile';
|
||||
|
||||
print "<html><head><title>TEST CLASS: READ ENV FILE</title><head>";
|
||||
print "<body>";
|
||||
print '<div><a href="class_test.php">Class Test Master</a></div>';
|
||||
|
||||
print "ALREADY from config.php: " . \CoreLibs\Debug\Support::printAr($_ENV) . "<br>";
|
||||
|
||||
// test .env in local
|
||||
|
||||
// error message
|
||||
print $log->printErrorMsg();
|
||||
|
||||
print "</body></html>";
|
||||
|
||||
// __END__
|
||||
@@ -303,8 +303,11 @@ if (defined('DEBUG') && DEBUG == false) {
|
||||
}
|
||||
|
||||
/************* AUTO LOADER *******************/
|
||||
// **DEPRECATED** MOVED TO config.php
|
||||
// read auto loader for lib only
|
||||
// require BASE . LIB . 'autoloader.php';
|
||||
// if (is_file(BASE . LIB . 'autoloader.php')) {
|
||||
// require BASE . LIB . 'autoloader.php';
|
||||
// }
|
||||
// composer auto loader, IF composer.json file includes classmap for lib/:
|
||||
// "autoload": {
|
||||
// "classmap": [
|
||||
@@ -313,6 +316,8 @@ if (defined('DEBUG') && DEBUG == false) {
|
||||
// },
|
||||
// NOTE: MUST RUN composer dump-autoload if file/class names are changed or added
|
||||
// NOTE BASE: __DIR__ . DIRECTORY_SEPARATOR . '..' DIRECTORY_SEPARATOR;
|
||||
require BASE . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
// if (is_file(BASE . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) {
|
||||
// require BASE . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
// }
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -13,16 +13,36 @@ declare(strict_types=1);
|
||||
define('CONFIG_PATH', 'configs' . DIRECTORY_SEPARATOR);
|
||||
// config path prefix search, start with 0, got down each level __DIR__ has, if nothing found -> bail
|
||||
$CONFIG_PATH_PREFIX = '';
|
||||
$end_autoload = false;
|
||||
for ($dir_pos = 0, $dir_max = count(explode(DIRECTORY_SEPARATOR, __DIR__)); $dir_pos <= $dir_max; $dir_pos++) {
|
||||
$CONFIG_PATH_PREFIX .= '..' . DIRECTORY_SEPARATOR;
|
||||
if (file_exists($CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php')) {
|
||||
// check if there is an read env file, load it
|
||||
if (file_exists($CONFIG_PATH_PREFIX . CONFIG_PATH . 'read_env_file.php')) {
|
||||
require $CONFIG_PATH_PREFIX . CONFIG_PATH . 'read_env_file.php';
|
||||
// load env variables first
|
||||
readEnvFile($CONFIG_PATH_PREFIX . CONFIG_PATH);
|
||||
if ($end_autoload === false) {
|
||||
/************* AUTO LOADER *******************/
|
||||
// read auto loader for lib only
|
||||
// It is recommended to setup basic composer and use just one auto loader
|
||||
// if (is_file($CONFIG_PATH_PREFIX . 'lib' . DIRECTORY_SEPARATOR . 'autoloader.php')) {
|
||||
// require $CONFIG_PATH_PREFIX . 'lib' . DIRECTORY_SEPARATOR . 'autoloader.php';
|
||||
// $end_autoload = true;
|
||||
// }
|
||||
// composer auto loader, IF composer.json file includes classmap for lib/:
|
||||
// "autoload": {
|
||||
// "classmap": [
|
||||
// "lib/"
|
||||
// ]
|
||||
// },
|
||||
// NOTE: MUST RUN composer dump-autoload if file/class names are changed or added
|
||||
// NOTE BASE: __DIR__ . DIRECTORY_SEPARATOR . '..' DIRECTORY_SEPARATOR;
|
||||
// load auto loader
|
||||
if (is_file($CONFIG_PATH_PREFIX . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) {
|
||||
require $CONFIG_PATH_PREFIX . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
$end_autoload = true;
|
||||
}
|
||||
// then load master config file that loads all other config files
|
||||
// load enviorment file if it exists
|
||||
\CoreLibs\Get\ReadEnvFile::readEnvFile($CONFIG_PATH_PREFIX . CONFIG_PATH);
|
||||
}
|
||||
/************* MASTER CONFIG *******************/
|
||||
if (is_file($CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php')) {
|
||||
// load master config file that loads all other config files
|
||||
require $CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php';
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?php
|
||||
|
||||
// config.php reads auto loader and uses CoreLibs version of this
|
||||
// DEPRECATED for here
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* parses .env file
|
||||
*
|
||||
|
||||
@@ -156,8 +156,7 @@ class ArrayIO extends \CoreLibs\DB\IO
|
||||
// if not set ... produce error
|
||||
if (!$this->table_array[$this->pk_name]['value']) {
|
||||
// if no PK found, error ...
|
||||
$this->error_id = 91;
|
||||
$this->__dbError();
|
||||
$this->dbError(91);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -235,8 +234,7 @@ class ArrayIO extends \CoreLibs\DB\IO
|
||||
// if 0, error
|
||||
$this->pk_id = null;
|
||||
if (!$this->dbExec($q)) {
|
||||
$this->error_id = 92;
|
||||
$this->__dbError();
|
||||
$this->dbError(92);
|
||||
}
|
||||
return $this->table_array;
|
||||
}
|
||||
@@ -310,8 +308,7 @@ class ArrayIO extends \CoreLibs\DB\IO
|
||||
// possible dbFetchArray errors ...
|
||||
$this->pk_id = $this->table_array[$this->pk_name]['value'];
|
||||
} else {
|
||||
$this->error_id = 92;
|
||||
$this->__dbError();
|
||||
$this->dbError(92);
|
||||
}
|
||||
return $this->table_array;
|
||||
}
|
||||
@@ -535,8 +532,7 @@ class ArrayIO extends \CoreLibs\DB\IO
|
||||
}
|
||||
// return success or not
|
||||
if (!$this->dbExec($q)) {
|
||||
$this->error_id = 92;
|
||||
$this->__dbError();
|
||||
$this->dbError(92);
|
||||
}
|
||||
// set primary key
|
||||
if ($insert) {
|
||||
|
||||
@@ -324,13 +324,17 @@ class IO
|
||||
private $nbsp = ''; // used by print_array recursion function
|
||||
// error & warning id
|
||||
/** @var int */
|
||||
protected $error_id;
|
||||
private $error_id;
|
||||
/** @var int */
|
||||
private $had_error = 0;
|
||||
// private $had_error = 0;
|
||||
/** @var array<int> */
|
||||
private $error_history = [];
|
||||
/** @var int */
|
||||
private $warning_id;
|
||||
/** @var int */
|
||||
private $had_warning;
|
||||
// private $had_warning = 0;
|
||||
/** @var array<int> */
|
||||
private $warning_history = [];
|
||||
// error thrown on class init if we cannot connect to db
|
||||
/** @var bool */
|
||||
protected $db_init_error = false;
|
||||
@@ -411,35 +415,39 @@ class IO
|
||||
$this->MAX_QUERY_CALL = self::DEFAULT_MAX_QUERY_CALL;
|
||||
|
||||
// error & debug stuff, error & warning ids are the same, its just in which var they get written
|
||||
$this->error_string['10'] = 'Could not load DB interface functions';
|
||||
$this->error_string['11'] = 'No Querystring given';
|
||||
$this->error_string['12'] = 'No Cursor given, no correct query perhaps?';
|
||||
$this->error_string['13'] = 'Query could not be executed without errors';
|
||||
$this->error_string['14'] = 'Can\'t connect to DB server';
|
||||
$this->error_string['15'] = 'Can\'t select DB';
|
||||
$this->error_string['16'] = 'No DB Handler found / connect or reconnect failed';
|
||||
$this->error_string['17'] = 'All dbReturn* methods work only with SELECT statements, '
|
||||
. 'please use dbExec for everything else';
|
||||
$this->error_string['18'] = 'Query not found in cache. Nothing has been reset';
|
||||
$this->error_string['19'] = 'Wrong PK name given or no PK name given at all, can\'t get Insert ID';
|
||||
$this->error_string['20'] = 'Found given Prepare Statement Name in array, '
|
||||
. 'Query not prepared, will use existing one';
|
||||
$this->error_string['21'] = 'Query Prepare failed';
|
||||
$this->error_string['22'] = 'Query Execute failed';
|
||||
$this->error_string['23'] = 'Query Execute failed, data array does not match placeholders';
|
||||
$this->error_string['24'] = 'Missing prepared query entry for execute.';
|
||||
$this->error_string['25'] = 'Prepare query data is not in array format.';
|
||||
$this->error_string['30'] = 'Query call in a possible endless loop. '
|
||||
. 'Was called more than ' . $this->MAX_QUERY_CALL . ' times';
|
||||
$this->error_string['31'] = 'Could not fetch PK after query insert';
|
||||
$this->error_string['32'] = 'Multiple PK return as array';
|
||||
$this->error_string['33'] = 'Returning PK was not found';
|
||||
$this->error_string['34'] = 'Cursor invalid for fetch PK after query insert';
|
||||
$this->error_string['40'] = 'Query async call failed.';
|
||||
$this->error_string['41'] = 'Connection is busy with a different query. Cannot execute.';
|
||||
$this->error_string['42'] = 'Cannot check for async query, none has been started yet.';
|
||||
$this->error_string['50'] = 'Setting max query call to -1 will disable loop protection for all subsequent runs';
|
||||
$this->error_string['51'] = 'Max query call needs to be set to at least 1';
|
||||
$this->error_string = [
|
||||
'10' => 'Could not load DB interface functions',
|
||||
'11' => 'No Querystring given',
|
||||
'12' => 'No Cursor given, no correct query perhaps?',
|
||||
'13' => 'Query could not be executed without errors',
|
||||
'14' => 'Can\'t connect to DB server',
|
||||
'15' => 'Can\'t select DB or no db name given',
|
||||
'16' => 'No DB Handler found / connect or reconnect failed',
|
||||
'17' => 'All dbReturn* methods work only with SELECT statements, '
|
||||
. 'please use dbExec for everything else',
|
||||
'18' => 'Query not found in cache. Nothing has been reset',
|
||||
'19' => 'Wrong PK name given or no PK name given at all, can\'t '
|
||||
. 'get Insert ID',
|
||||
'20' => 'Found given Prepare Statement Name in array, '
|
||||
. 'Query not prepared, will use existing one',
|
||||
'21' => 'Query Prepare failed',
|
||||
'22' => 'Query Execute failed',
|
||||
'23' => 'Query Execute failed, data array does not match placeholders',
|
||||
'24' => 'Missing prepared query entry for execute.',
|
||||
'25' => 'Prepare query data is not in array format.',
|
||||
'30' => 'Query call in a possible endless loop. '
|
||||
. 'Was called more than ' . $this->MAX_QUERY_CALL . ' times',
|
||||
'31' => 'Could not fetch PK after query insert',
|
||||
'32' => 'Multiple PK return as array',
|
||||
'33' => 'Returning PK was not found',
|
||||
'34' => 'Cursor invalid for fetch PK after query insert',
|
||||
'40' => 'Query async call failed.',
|
||||
'41' => 'Connection is busy with a different query. Cannot execute.',
|
||||
'42' => 'Cannot check for async query, none has been started yet.',
|
||||
'50' => 'Setting max query call to -1 will disable loop protection '
|
||||
. 'for all subsequent runs',
|
||||
'51' => 'Max query call needs to be set to at least 1',
|
||||
];
|
||||
|
||||
// based on $this->db_type
|
||||
// here we need to load the db pgsql include one
|
||||
@@ -450,15 +458,13 @@ class IO
|
||||
$this->db_functions = new \CoreLibs\DB\SQL\PgSQL();
|
||||
} else {
|
||||
// abort error
|
||||
$this->error_id = 10;
|
||||
$this->__dbError();
|
||||
$this->dbError(10);
|
||||
$this->db_init_error = true;
|
||||
}
|
||||
|
||||
// connect to DB
|
||||
if (!$this->__connectToDB()) {
|
||||
$this->error_id = 16;
|
||||
$this->__dbError();
|
||||
$this->dbError(16);
|
||||
$this->db_init_error = true;
|
||||
}
|
||||
}
|
||||
@@ -482,6 +488,11 @@ class IO
|
||||
*/
|
||||
private function __connectToDB(): bool
|
||||
{
|
||||
// no DB name set, abort
|
||||
if (empty($this->db_name)) {
|
||||
$this->dbError(15);
|
||||
return false;
|
||||
}
|
||||
// generate connect string
|
||||
$this->dbh = $this->db_functions->__dbConnect(
|
||||
$this->db_host,
|
||||
@@ -493,17 +504,15 @@ class IO
|
||||
);
|
||||
// if no dbh here, we couldn't connect to the DB itself
|
||||
if (!$this->dbh) {
|
||||
$this->error_id = 14;
|
||||
$this->__dbError();
|
||||
$this->dbError(14);
|
||||
return false;
|
||||
}
|
||||
// 15 error (cant select to DB is not valid in postgres, as connect is different)
|
||||
// if returns 0 we couldn't select the DB
|
||||
if ($this->dbh == -1) {
|
||||
$this->error_id = 15;
|
||||
$this->__dbError();
|
||||
return false;
|
||||
}
|
||||
// if ($this->dbh == -1) {;
|
||||
// $this->dbError(15));
|
||||
// return false;
|
||||
// }
|
||||
// set search path if needed
|
||||
if ($this->db_schema) {
|
||||
$this->dbSetSchema();
|
||||
@@ -614,8 +623,13 @@ class IO
|
||||
* @param string $type query identifier (Q, I, etc)
|
||||
* @return void has no return
|
||||
*/
|
||||
protected function __dbDebug(string $debug_id, string $error_string, string $id = '', string $type = ''): void
|
||||
{
|
||||
protected function __dbDebug(
|
||||
string $debug_id,
|
||||
string $error_string,
|
||||
string $id = '',
|
||||
string $type = ''
|
||||
): void {
|
||||
// NOTE prefix allows html for echo output, will be stripped on file print
|
||||
$prefix = '';
|
||||
if ($id) {
|
||||
$prefix .= '[<span style="color: #920069;">' . $id . '</span>] ';
|
||||
@@ -625,7 +639,7 @@ class IO
|
||||
}
|
||||
switch ($id) {
|
||||
case 'DB_ERROR':
|
||||
$prefix .= '<span style="color: レd;"><b>DB-Error</b>:</span>';
|
||||
$prefix .= '<span style="color: red;"><b>DB-Error</b>:</span>';
|
||||
break;
|
||||
case 'DB_WARNING':
|
||||
$prefix .= '<span style="color: orange;"><b>DB-Warning</b>:</span>';
|
||||
@@ -638,16 +652,13 @@ class IO
|
||||
}
|
||||
|
||||
/**
|
||||
* if error_id set, writes long error string into error_msg
|
||||
* NOTE:
|
||||
* needed to make public so it can be called from DB.Array.IO too
|
||||
* @param object|resource|bool $cursor current cursor for pg_result_error,
|
||||
* pg_last_error too, but pg_result_error
|
||||
* is more accurate (PgSql\Result)
|
||||
* @param string $msg optional message
|
||||
* @return void has no return
|
||||
* Check if there is a cursor and write this cursors error info
|
||||
* @param object|resource|bool $cursor current cursor for pg_result_error,
|
||||
* pg_last_error too, but pg_result_error
|
||||
* is more accurate (PgSql\Result)
|
||||
* @return string|null If we could get the method where it was called
|
||||
*/
|
||||
public function __dbError($cursor = false, string $msg = ''): void
|
||||
private function __dbErrorPreprocessor($cursor = false): ?string
|
||||
{
|
||||
$pg_error_string = '';
|
||||
$where_called = (string)\CoreLibs\Debug\Support::getCallerMethod();
|
||||
@@ -660,32 +671,52 @@ class IO
|
||||
if ($pg_error_string) {
|
||||
$this->__dbDebug('db', $pg_error_string, 'DB_ERROR', $where_called);
|
||||
}
|
||||
// okay, an error occured
|
||||
if ($this->error_id) {
|
||||
// write error msg ...
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$this->error_id . ': ' . $this->error_string[$this->error_id]
|
||||
. ($msg ? ', ' . $msg : ''),
|
||||
'DB_ERROR',
|
||||
$where_called
|
||||
);
|
||||
$this->had_error = $this->error_id;
|
||||
// write detailed error log
|
||||
}
|
||||
if ($this->warning_id) {
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$this->warning_id . ': ' . $this->error_string[$this->warning_id]
|
||||
. ($msg ? ', ' . $msg : ''),
|
||||
'DB_WARNING',
|
||||
$where_called
|
||||
);
|
||||
$this->had_warning = $this->warning_id;
|
||||
}
|
||||
// unset the error/warning vars
|
||||
$this->error_id = 0;
|
||||
$this->warning_id = 0;
|
||||
return $where_called;
|
||||
}
|
||||
|
||||
/**
|
||||
* write an error
|
||||
* @param integer $error_id Any Error ID, used in debug message string
|
||||
* @param object|resource|bool $cursor Optional cursor, passed on to preprocessor
|
||||
* @param string $msg optional message added to debug
|
||||
* @return void
|
||||
*/
|
||||
protected function dbError(int $error_id, $cursor = false, string $msg = ''): void
|
||||
{
|
||||
$where_called = $this->__dbErrorPreprocessor($cursor);
|
||||
// write error msg ...
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$error_id . ': ' . $this->error_string[$error_id]
|
||||
. ($msg ? ', ' . $msg : ''),
|
||||
'DB_ERROR',
|
||||
$where_called
|
||||
);
|
||||
$this->error_id = $error_id;
|
||||
// keep warning history
|
||||
$this->error_history[] = $error_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* write a warning
|
||||
* @param integer $warning_id Integer warning id added to debug
|
||||
* @param object|resource|bool $cursor Optional cursor, passed on to preprocessor
|
||||
* @param string $msg optional message added to debug
|
||||
* @return void
|
||||
*/
|
||||
protected function dbWarning(int $warning_id, $cursor = false, string $msg = ''): void
|
||||
{
|
||||
$where_called = $this->__dbErrorPreprocessor($cursor);
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$warning_id . ': ' . $this->error_string[$warning_id]
|
||||
. ($msg ? ', ' . $msg : ''),
|
||||
'DB_WARNING',
|
||||
$where_called
|
||||
);
|
||||
$this->warning_id = $warning_id;
|
||||
// keep warning history
|
||||
$this->warning_history[] = $warning_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -775,23 +806,20 @@ class IO
|
||||
$this->query = $query;
|
||||
}
|
||||
if (!$this->query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
// if no DB Handler drop out
|
||||
if (!$this->dbh) {
|
||||
// if reconnect fails drop out
|
||||
if (!$this->__connectToDB()) {
|
||||
$this->error_id = 16;
|
||||
$this->__dbError();
|
||||
$this->dbError(16);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// check that no other query is running right now
|
||||
if ($this->db_functions->__dbConnectionBusy()) {
|
||||
$this->error_id = 41;
|
||||
$this->__dbError();
|
||||
$this->dbError(41);
|
||||
return false;
|
||||
}
|
||||
// if we do have an insert, check if there is no RETURNING pk_id,
|
||||
@@ -850,8 +878,7 @@ class IO
|
||||
$this->MAX_QUERY_CALL != -1 &&
|
||||
$this->query_called[$md5] > $this->MAX_QUERY_CALL
|
||||
) {
|
||||
$this->error_id = 30;
|
||||
$this->__dbError();
|
||||
$this->dbError(30);
|
||||
$this->__dbDebug('db', $this->query, 'dbExec', 'Q[nc]');
|
||||
return false;
|
||||
}
|
||||
@@ -874,8 +901,7 @@ class IO
|
||||
$this->__dbDebug('db', $this->query, 'dbExec', 'Q[nc]');
|
||||
}
|
||||
// internal error handling
|
||||
$this->error_id = 13;
|
||||
$this->__dbError($this->cursor);
|
||||
$this->dbError(13, $this->cursor);
|
||||
return false;
|
||||
} else {
|
||||
// if SELECT do here ...
|
||||
@@ -947,11 +973,10 @@ class IO
|
||||
// abort if cursor is empty
|
||||
if ($cursor === false) {
|
||||
// failed to get insert id
|
||||
$this->warning_id = 34;
|
||||
if ($stm_name === null) {
|
||||
$this->__dbError($cursor, '[dbExec]');
|
||||
$this->dbWarning(34, $cursor, '[dbExec]');
|
||||
} else {
|
||||
$this->__dbError();
|
||||
$this->dbWarning(34);
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$stm_name . ': CURSOR is null',
|
||||
@@ -968,8 +993,7 @@ class IO
|
||||
$this->insert_id_arr[] = $insert_id;
|
||||
// throw warning that no pk was found
|
||||
if ($insert_id === false) {
|
||||
$this->warning_id = 31;
|
||||
$this->__dbError($cursor, '[dbExec]');
|
||||
$this->dbWarning(31, $cursor, '[dbExec]');
|
||||
}
|
||||
} else { // was stm_name null or not null and cursor
|
||||
// we have returning, now we need to check if we get one or many returned
|
||||
@@ -985,11 +1009,10 @@ class IO
|
||||
// warning if we didn't get any returning data
|
||||
if (count($this->insert_id_arr) == 0) {
|
||||
// failed to get insert id
|
||||
$this->warning_id = 33;
|
||||
if ($stm_name === null) {
|
||||
$this->__dbError($cursor, '[dbExec]');
|
||||
$this->dbWarning(33, $cursor, '[dbExec]');
|
||||
} else {
|
||||
$this->__dbError();
|
||||
$this->dbWarning(33);
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$stm_name . ': RETURNING returned no data',
|
||||
@@ -1000,9 +1023,9 @@ class IO
|
||||
// this error handling is only for INSERT (), (), ... sets
|
||||
$this->warning_id = 32;
|
||||
if ($stm_name === null) {
|
||||
$this->__dbError($cursor, '[dbExec]');
|
||||
$this->dbWarning(32, $cursor, '[dbExec]');
|
||||
} else {
|
||||
$this->__dbError();
|
||||
$this->dbWarning(32);
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
$stm_name . ': RETURNING returned an array (possible multiple insert)',
|
||||
@@ -1393,8 +1416,7 @@ class IO
|
||||
public function dbReturn(string $query, int $reset = self::USE_CACHE, bool $assoc_only = false)
|
||||
{
|
||||
if (!$query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
// create MD5 from query ...
|
||||
@@ -1416,8 +1438,7 @@ class IO
|
||||
$this->cursor_ext[$md5]['query'] = $query;
|
||||
// before doing ANYTHING check if query is "SELECT ..." everything else does not work
|
||||
if (!$this->__checkQueryForSelect($this->cursor_ext[$md5]['query'])) {
|
||||
$this->error_id = 17;
|
||||
$this->__dbError(false, $this->cursor_ext[$md5]['query']);
|
||||
$this->dbError(17, false, $this->cursor_ext[$md5]['query']);
|
||||
return false;
|
||||
}
|
||||
// init return als false
|
||||
@@ -1441,15 +1462,13 @@ class IO
|
||||
if (!$this->dbh) {
|
||||
// if reconnect fails drop out
|
||||
if (!$this->__connectToDB()) {
|
||||
$this->error_id = 16;
|
||||
$this->__dbError();
|
||||
$this->dbError(16);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// check that no other query is running right now
|
||||
if ($this->db_functions->__dbConnectionBusy()) {
|
||||
$this->error_id = 41;
|
||||
$this->__dbError();
|
||||
$this->dbError(41);
|
||||
return false;
|
||||
}
|
||||
$this->cursor_ext[$md5]['cursor'] = $this->db_functions->__dbQuery($this->cursor_ext[$md5]['query']);
|
||||
@@ -1459,8 +1478,7 @@ class IO
|
||||
$this->__dbDebug('db', $this->cursor_ext[$md5]['query'], 'dbReturn', 'Q');
|
||||
}
|
||||
// internal error handling
|
||||
$this->error_id = 13;
|
||||
$this->__dbError($this->cursor_ext[$md5]['cursor']);
|
||||
$this->dbError(13, $this->cursor_ext[$md5]['cursor']);
|
||||
return false;
|
||||
} else {
|
||||
$this->cursor_ext[$md5]['firstcall'] = 1;
|
||||
@@ -1613,10 +1631,11 @@ class IO
|
||||
}
|
||||
// ** actual db exec call
|
||||
$cursor = $this->db_functions->__dbQuery($this->query);
|
||||
// if we faield, just set the master cursors to false too
|
||||
$this->cursor = $cursor;
|
||||
if ($cursor === false) {
|
||||
return false;
|
||||
}
|
||||
$this->cursor = $cursor;
|
||||
// if FALSE returned, set error stuff
|
||||
// run the post exec processing
|
||||
if (!$this->__dbPostExec()) {
|
||||
@@ -1645,8 +1664,7 @@ class IO
|
||||
$cursor = $this->cursor;
|
||||
}
|
||||
if ($cursor === false) {
|
||||
$this->error_id = 12;
|
||||
$this->__dbError();
|
||||
$this->dbError(12);
|
||||
return false;
|
||||
}
|
||||
return $this->__dbConvertEncoding(
|
||||
@@ -1666,17 +1684,18 @@ class IO
|
||||
public function dbReturnRow(string $query, bool $assoc_only = false)
|
||||
{
|
||||
if (!$query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
// before doing ANYTHING check if query is "SELECT ..." everything else does not work
|
||||
if (!$this->__checkQueryForSelect($query)) {
|
||||
$this->error_id = 17;
|
||||
$this->__dbError(false, $query);
|
||||
$this->dbError(17, false, $query);
|
||||
return false;
|
||||
}
|
||||
$cursor = $this->dbExec($query);
|
||||
if ($cursor === false) {
|
||||
$this->dbError(13);
|
||||
}
|
||||
$result = $this->dbFetchArray($cursor, $assoc_only);
|
||||
return $result;
|
||||
}
|
||||
@@ -1690,17 +1709,19 @@ class IO
|
||||
public function dbReturnArray(string $query, bool $assoc_only = false)
|
||||
{
|
||||
if (!$query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
// before doing ANYTHING check if query is "SELECT ..." everything else does not work
|
||||
if (!$this->__checkQueryForSelect($query)) {
|
||||
$this->error_id = 17;
|
||||
$this->__dbError(false, $query);
|
||||
$this->dbError(17, false, $query);
|
||||
return false;
|
||||
}
|
||||
$cursor = $this->dbExec($query);
|
||||
if ($cursor === false) {
|
||||
$this->dbError(13);
|
||||
return false;
|
||||
}
|
||||
$rows = [];
|
||||
while (is_array($res = $this->dbFetchArray($cursor, $assoc_only))) {
|
||||
$data = [];
|
||||
@@ -1726,8 +1747,7 @@ class IO
|
||||
$md5 = md5($query);
|
||||
// clears cache for this query
|
||||
if (!$this->cursor_ext[$md5]['query']) {
|
||||
$this->error_id = 18;
|
||||
$this->__dbError();
|
||||
$this->dbError(18);
|
||||
return false;
|
||||
}
|
||||
unset($this->cursor_ext[$md5]);
|
||||
@@ -1746,8 +1766,7 @@ class IO
|
||||
public function dbCursorPos(string $query)
|
||||
{
|
||||
if (!$query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
$md5 = md5($query);
|
||||
@@ -1762,8 +1781,7 @@ class IO
|
||||
public function dbCursorNumRows(string $query)
|
||||
{
|
||||
if (!$query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
$md5 = md5($query);
|
||||
@@ -1818,23 +1836,20 @@ class IO
|
||||
{
|
||||
$matches = [];
|
||||
if (!$query) {
|
||||
$this->error_id = 11;
|
||||
$this->__dbError();
|
||||
$this->dbError(11);
|
||||
return false;
|
||||
}
|
||||
// if no DB Handler drop out
|
||||
if (!$this->dbh) {
|
||||
// if reconnect fails drop out
|
||||
if (!$this->__connectToDB()) {
|
||||
$this->error_id = 16;
|
||||
$this->__dbError();
|
||||
$this->dbError(16);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// check that no other query is running right now
|
||||
if ($this->db_functions->__dbConnectionBusy()) {
|
||||
$this->error_id = 41;
|
||||
$this->__dbError();
|
||||
$this->dbError(41);
|
||||
return false;
|
||||
}
|
||||
// check if this was already prepared
|
||||
@@ -1884,15 +1899,18 @@ class IO
|
||||
$this->prepare_cursor[$stm_name]['result'] = $result;
|
||||
return $result;
|
||||
} else {
|
||||
$this->error_id = 21;
|
||||
$this->__dbError();
|
||||
$this->__dbDebug(
|
||||
$this->dbError(
|
||||
21,
|
||||
null,
|
||||
$stm_name . ': Prepare field with: ' . $stm_name . ' | ' . $query
|
||||
);
|
||||
/* $this->__dbDebug(
|
||||
'db',
|
||||
'<span style="color: red;"><b>DB-Error</b> ' . $stm_name
|
||||
. ': Prepare field with: ' . $stm_name . ' | '
|
||||
. $query . '</span>',
|
||||
'DB_ERROR'
|
||||
);
|
||||
); */
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
@@ -1912,34 +1930,29 @@ class IO
|
||||
{
|
||||
// if we do not have no prepare cursor array entry for this statement name, abort
|
||||
if (!is_array($this->prepare_cursor[$stm_name])) {
|
||||
$this->error_id = 24;
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
'<span style="color: red;"><b>DB-Error</b> ' . $stm_name
|
||||
. ': We do not have a prepared query entry for this statement name.</span>',
|
||||
'DB_ERROR'
|
||||
$this->dbError(
|
||||
24,
|
||||
false,
|
||||
$stm_name . ': We do not have a prepared query entry for this statement name.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (!is_array($data)) {
|
||||
$this->error_id = 25;
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
'<span style="color: red;"><b>DB-Error</b> ' . $stm_name
|
||||
. ': Prepared query Data has to be given in array form.</span>',
|
||||
'DB_ERROR'
|
||||
$this->dbError(
|
||||
25,
|
||||
false,
|
||||
$stm_name . ': Prepared query Data has to be given in array form.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($this->prepare_cursor[$stm_name]['count'] != count($data)) {
|
||||
$this->error_id = 23;
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
'<span style="color: red;"><b>DB-Error</b> ' . $stm_name
|
||||
. ': Array data count does not match prepared fields. Need: '
|
||||
. $this->prepare_cursor[$stm_name]['count'] . ', has: '
|
||||
. count($data) . '</span>',
|
||||
'DB_ERROR'
|
||||
$this->dbError(
|
||||
23,
|
||||
false,
|
||||
$stm_name
|
||||
. ': Array data count does not match prepared fields. Need: '
|
||||
. $this->prepare_cursor[$stm_name]['count'] . ', has: '
|
||||
. count($data)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -1951,13 +1964,10 @@ class IO
|
||||
$this->log->debug('ExecuteData', 'ERROR in STM[' . $stm_name . '|'
|
||||
. $this->prepare_cursor[$stm_name]['result'] . ']: '
|
||||
. $this->log->prAr($data));
|
||||
$this->error_id = 22;
|
||||
$this->__dbError($this->prepare_cursor[$stm_name]['result']);
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
'<span style="color: red;"><b>DB-Error</b> ' . $stm_name
|
||||
. ': Execution failed</span>',
|
||||
'DB_ERROR'
|
||||
$this->dbError(
|
||||
22,
|
||||
$this->prepare_cursor[$stm_name]['result'],
|
||||
$stm_name . ': Execution failed'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -2006,8 +2016,7 @@ class IO
|
||||
// run the async query
|
||||
if (!$this->db_functions->__dbSendQuery($this->query)) {
|
||||
// if failed, process here
|
||||
$this->error_id = 40;
|
||||
$this->__dbError();
|
||||
$this->dbError(40);
|
||||
return false;
|
||||
} else {
|
||||
$this->async_running = (string)$md5;
|
||||
@@ -2046,12 +2055,10 @@ class IO
|
||||
}
|
||||
} else {
|
||||
// if no async running print error
|
||||
$this->error_id = 42;
|
||||
$this->__dbDebug(
|
||||
'db',
|
||||
'<span style="color: red;"><b>DB-Error</b> No async query '
|
||||
. 'has beedbFetchArrayn started yet.</span>',
|
||||
'DB_ERROR'
|
||||
$this->dbError(
|
||||
42,
|
||||
false,
|
||||
'No async query has been started yet.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -2301,13 +2308,11 @@ class IO
|
||||
// if -1 then disable loop check
|
||||
// DANGEROUS, WARN USER
|
||||
if ($max_calls == -1) {
|
||||
$this->warning_id = 50;
|
||||
$this->__dbError();
|
||||
$this->dbWarning(50);
|
||||
}
|
||||
// negative or 0
|
||||
if ($max_calls < -1 || $max_calls == 0) {
|
||||
$this->error_id = 51;
|
||||
$this->__dbError();
|
||||
$this->dbError(51);
|
||||
// early abort
|
||||
return false;
|
||||
}
|
||||
@@ -2521,37 +2526,112 @@ class IO
|
||||
* null on empty
|
||||
* @return int|null Number of rows
|
||||
*/
|
||||
public function dbGetNumRows()
|
||||
public function dbGetNumRows(): ?int
|
||||
{
|
||||
return $this->num_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets error number that was last
|
||||
* So we always have the last error number stored even if a new one is created
|
||||
*
|
||||
* @return int last error number
|
||||
* So we always have the last error number stored even if a new
|
||||
* one is created
|
||||
* @param boolean $transform Set to true to transform into id + error message
|
||||
* @return string Last error number as string or error message
|
||||
*/
|
||||
public function getHadError()
|
||||
public function dbGetLastError(bool $transform = false): string
|
||||
{
|
||||
return $this->had_error;
|
||||
if (!$transform) {
|
||||
return (string)$this->error_id;
|
||||
} else {
|
||||
return $this->error_id . ': '
|
||||
. ($this->error_string[$this->error_id] ?? '[NO ERROR MESSAGE]');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the error history as is or map it to the error messages
|
||||
* @param boolean $transform Set to true to transform into id + error message
|
||||
* @return array Either as is, or id + error message array
|
||||
*/
|
||||
public function dbGetErrorHistory(bool $transform = false): array
|
||||
{
|
||||
if (!$transform) {
|
||||
return $this->error_history;
|
||||
} else {
|
||||
return array_map(
|
||||
function ($id) {
|
||||
return $id . ': '
|
||||
. ($this->error_string[$id] ?? '[NO ERROR MESSAGE]');
|
||||
},
|
||||
$this->error_history
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets warning number that was last
|
||||
* So we always have the last warning number stored even if a new one is created
|
||||
*
|
||||
* @return int last error number
|
||||
* @param boolean $transform Set to true to transform into id + warning message
|
||||
* @return string Last Warning number as string or warning message
|
||||
*/
|
||||
public function getHadWarning()
|
||||
public function dbGetLastWarning(bool $transform = false)
|
||||
{
|
||||
return $this->had_warning;
|
||||
if (!$transform) {
|
||||
return (string)$this->warning_id;
|
||||
} else {
|
||||
return $this->warning_id . ': '
|
||||
. ($this->error_string[$this->warning_id] ?? '[NO WARNING MESSAGE]');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the warning history as is or map it to the error messages
|
||||
* @param boolean $transform Set to true to transform into id + warning message
|
||||
* @return array Either as is, or id + warning message array
|
||||
*/
|
||||
public function dbGetWarningHistory(bool $transform = false): array
|
||||
{
|
||||
if (!$transform) {
|
||||
return $this->warning_history;
|
||||
} else {
|
||||
return array_map(
|
||||
function ($id) {
|
||||
return $id . ': '
|
||||
. ($this->error_string[$id] ?? '[NO WARNING MESSAGE]');
|
||||
},
|
||||
$this->warning_history
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************** */
|
||||
// DEPEREACTED CALLS
|
||||
/******************************** */
|
||||
|
||||
/**
|
||||
* Sets error number that was last
|
||||
* So we always have the last error number stored even if a new one is created
|
||||
* @return int last error number
|
||||
* @deprecated Use dbGetLastError()
|
||||
*/
|
||||
public function getHadError(): int
|
||||
{
|
||||
trigger_error('Method ' . __METHOD__ . ' is deprecated, use dbGetLastError()', E_USER_DEPRECATED);
|
||||
return (int)$this->dbGetLastError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets warning number that was last
|
||||
* So we always have the last warning number stored even if a new one is created
|
||||
* @return int last error number
|
||||
* @deprecated Use dbGetLastWarning()
|
||||
*/
|
||||
public function getHadWarning(): int
|
||||
{
|
||||
trigger_error('Method ' . __METHOD__ . ' is deprecated, use dbGetLastWarning()', E_USER_DEPRECATED);
|
||||
return (int)$this->dbGetLastWarning();
|
||||
}
|
||||
|
||||
/**
|
||||
* old call for getInserReturnExt
|
||||
* @param string|null $key See above
|
||||
|
||||
@@ -80,8 +80,8 @@ class PgSQL
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for gp_query, catches error and stores it in class var
|
||||
* @param string $query query string
|
||||
* wrapper for pg_query, catches error and stores it in class var
|
||||
* @param string $query Query string
|
||||
* @return object|resource|bool query result (PgSql\Result)
|
||||
*/
|
||||
public function __dbQuery(string $query)
|
||||
@@ -98,6 +98,30 @@ class PgSQL
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proposed
|
||||
* wrapperf or pg_query_params for queries in the style of
|
||||
* SELECT foo FROM bar WHERE foobar = $1
|
||||
* @param string $query Query string with placeholders $1, ..
|
||||
* @param array $params matching parameters for each placerhold
|
||||
* @return object|resource|bool query result (PgSql\Result)
|
||||
*/
|
||||
public function __dbQueryParams(string $query, array $params)
|
||||
{
|
||||
$this->last_error_query = '';
|
||||
if ($this->dbh === false || is_bool($this->dbh)) {
|
||||
return false;
|
||||
}
|
||||
// parse query and get all $n entries
|
||||
// TODO count of $n must match params
|
||||
// read out the query status and save the query if needed
|
||||
$result = pg_query_params($this->dbh, $query, $params);
|
||||
if ($result === false) {
|
||||
$this->last_error_query = $query;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* sends an async query to the server
|
||||
* @param string $query query string
|
||||
@@ -397,22 +421,43 @@ class PgSQL
|
||||
* @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
|
||||
* @return object|resource|bool db handler PgSql\Connection or false on error
|
||||
*/
|
||||
public function __dbConnect(
|
||||
string $db_host,
|
||||
string $db_user,
|
||||
string $db_pass,
|
||||
string $db_name,
|
||||
int $db_port = 5432,
|
||||
int $db_port,
|
||||
string $db_ssl = 'allow'
|
||||
) {
|
||||
// to avoid empty db_port
|
||||
if (!$db_port) {
|
||||
$db_port = 5432;
|
||||
if (empty($db_name)) {
|
||||
return false;
|
||||
}
|
||||
$this->dbh = pg_connect("host=" . $db_host . " port=" . $db_port . " user="
|
||||
. $db_user . " password=" . $db_pass . " dbname=" . $db_name . " sslmode=" . $db_ssl);
|
||||
// if there is no host, leave it empty, this will try default unix path
|
||||
// same for port (defaults to 5432 if not set)
|
||||
// must set is db name
|
||||
// if no user name, db name is used
|
||||
$connection_string = [];
|
||||
if (!empty($db_host)) {
|
||||
$connection_string[] = 'host=' . $db_host;
|
||||
}
|
||||
if (!empty($db_port)) {
|
||||
$connection_string[] = 'port=' . $db_port;
|
||||
}
|
||||
if (!empty($db_user)) {
|
||||
$connection_string[] = 'user=' . $db_user;
|
||||
}
|
||||
if (!empty($db_pass)) {
|
||||
$connection_string[] = 'password=' . $db_pass;
|
||||
}
|
||||
// we must have at least db name set
|
||||
$connection_string[] = 'dbname=' . $db_name;
|
||||
if (!empty($db_ssl)) {
|
||||
$connection_string[] = 'sslmode=' . $db_ssl;
|
||||
}
|
||||
// connect
|
||||
$this->dbh = pg_connect(join(' ', $connection_string));
|
||||
// if (!$this->dbh) {
|
||||
// die("<!-- Can't connect to database //-->");
|
||||
// }
|
||||
@@ -438,8 +483,8 @@ class PgSQL
|
||||
$cursor = pg_get_result($this->dbh);
|
||||
}
|
||||
if ($cursor && !is_bool($cursor) && $error_str = pg_result_error($cursor)) {
|
||||
return "<span style=\"color: red;\"><b>-PostgreSQL-Error-></b> "
|
||||
. $error_str . "</span><br>";
|
||||
return '-PostgreSQL-Error- '
|
||||
. $error_str;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
94
www/lib/CoreLibs/Get/ReadEnvFile.php
Normal file
94
www/lib/CoreLibs/Get/ReadEnvFile.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Get;
|
||||
|
||||
class ReadEnvFile
|
||||
{
|
||||
/**
|
||||
* parses .env file
|
||||
*
|
||||
* Rules for .env file
|
||||
* variable is any alphanumeric string followed by = on the same line
|
||||
* content starts with the first non space part
|
||||
* strings can be contained in "
|
||||
* strings MUST be contained in " if they are multiline
|
||||
* if string starts with " it will match until another " is found
|
||||
* anything AFTER " is ignored
|
||||
* if there are two variables with the same name only the first is used
|
||||
* variables are case sensitive
|
||||
*
|
||||
* @param string $path Folder to file, default is __DIR__
|
||||
* @param string $env_file What file to load, default is .env
|
||||
* @return int -1 other error
|
||||
* 0 for success full load
|
||||
* 1 for file loadable, but no data inside
|
||||
* 2 for file not readable
|
||||
* 3 for file not found
|
||||
*/
|
||||
public static function readEnvFile(
|
||||
string $path = __DIR__,
|
||||
string $env_file = '.env'
|
||||
): int {
|
||||
// default -1;
|
||||
$status = -1;
|
||||
$env_file_target = $path . DIRECTORY_SEPARATOR . $env_file;
|
||||
// this is not a file -> abort
|
||||
if (!is_file($env_file_target)) {
|
||||
$status = 3;
|
||||
return $status;
|
||||
}
|
||||
// cannot open file -> abort
|
||||
if (($fp = fopen($env_file_target, 'r')) === false) {
|
||||
$status = 2;
|
||||
return $status;
|
||||
}
|
||||
// set to readable but not yet any data loaded
|
||||
$status = 1;
|
||||
$block = false;
|
||||
$var = '';
|
||||
while ($line = fgets($fp)) {
|
||||
// main match for variable = value part
|
||||
if (preg_match("/^\s*([\w_.]+)\s*=\s*((\"?).*)/", $line, $matches)) {
|
||||
$var = $matches[1];
|
||||
$value = $matches[2];
|
||||
$quotes = $matches[3];
|
||||
// wirte only if env is not set yet, and write only the first time
|
||||
if (empty($_ENV[$var])) {
|
||||
if (!empty($quotes)) {
|
||||
// match greedy for first to last so we move any " if there are
|
||||
if (preg_match('/^"(.*[^\\\])"/U', $value, $matches)) {
|
||||
$value = $matches[1];
|
||||
} else {
|
||||
// this is a multi line
|
||||
$block = true;
|
||||
// first " in string remove
|
||||
// add removed new line back because this is a multi line
|
||||
$value = ltrim($value, '"') . PHP_EOL;
|
||||
}
|
||||
}
|
||||
// if block is set, we strip line of slashes
|
||||
$_ENV[$var] = $block === true ? stripslashes($value) : $value;
|
||||
// set successful load
|
||||
$status = 0;
|
||||
}
|
||||
} elseif ($block === true) {
|
||||
// read line until there is a unescaped "
|
||||
// this also strips everything after the last "
|
||||
if (preg_match("/(.*[^\\\])\"/", $line, $matches)) {
|
||||
$block = false;
|
||||
// strip ending " and EVERYTHING that follows after that
|
||||
$line = $matches[1];
|
||||
}
|
||||
// strip line of slashes
|
||||
$_ENV[$var] .= stripslashes($line);
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// __END__
|
||||
1
www/vendor/composer/autoload_classmap.php
vendored
1
www/vendor/composer/autoload_classmap.php
vendored
@@ -35,6 +35,7 @@ return array(
|
||||
'CoreLibs\\Debug\\Logging' => $baseDir . '/lib/CoreLibs/Debug/Logging.php',
|
||||
'CoreLibs\\Debug\\RunningTime' => $baseDir . '/lib/CoreLibs/Debug/RunningTime.php',
|
||||
'CoreLibs\\Debug\\Support' => $baseDir . '/lib/CoreLibs/Debug/Support.php',
|
||||
'CoreLibs\\Get\\ReadEnvFile' => $baseDir . '/lib/CoreLibs/Get/ReadEnvFile.php',
|
||||
'CoreLibs\\Get\\System' => $baseDir . '/lib/CoreLibs/Get/System.php',
|
||||
'CoreLibs\\Language\\Core\\CachedFileReader' => $baseDir . '/lib/CoreLibs/Language/Core/CachedFileReader.php',
|
||||
'CoreLibs\\Language\\Core\\FileReader' => $baseDir . '/lib/CoreLibs/Language/Core/FileReader.php',
|
||||
|
||||
1
www/vendor/composer/autoload_static.php
vendored
1
www/vendor/composer/autoload_static.php
vendored
@@ -100,6 +100,7 @@ class ComposerStaticInit10fe8fe2ec4017b8644d2b64bcf398b9
|
||||
'CoreLibs\\Debug\\Logging' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Logging.php',
|
||||
'CoreLibs\\Debug\\RunningTime' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/RunningTime.php',
|
||||
'CoreLibs\\Debug\\Support' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Support.php',
|
||||
'CoreLibs\\Get\\ReadEnvFile' => __DIR__ . '/../..' . '/lib/CoreLibs/Get/ReadEnvFile.php',
|
||||
'CoreLibs\\Get\\System' => __DIR__ . '/../..' . '/lib/CoreLibs/Get/System.php',
|
||||
'CoreLibs\\Language\\Core\\CachedFileReader' => __DIR__ . '/../..' . '/lib/CoreLibs/Language/Core/CachedFileReader.php',
|
||||
'CoreLibs\\Language\\Core\\FileReader' => __DIR__ . '/../..' . '/lib/CoreLibs/Language/Core/FileReader.php',
|
||||
|
||||
Reference in New Issue
Block a user