diff --git a/4dev/tests/CoreLibsDBIOTest.php b/4dev/tests/CoreLibsDBIOTest.php
index f75b6b0f..89d8cb8e 100644
--- a/4dev/tests/CoreLibsDBIOTest.php
+++ b/4dev/tests/CoreLibsDBIOTest.php
@@ -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
*
diff --git a/4dev/tests/log/.gitignore b/4dev/tests/log/.gitignore
new file mode 100644
index 00000000..2a50fc00
--- /dev/null
+++ b/4dev/tests/log/.gitignore
@@ -0,0 +1,3 @@
+*log
+*LOG
+!.gitignore
diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php
index 23341663..811d9b03 100644
--- a/www/admin/class_test.db.php
+++ b/www/admin/class_test.db.php
@@ -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:
" . print_r($data, true) . "
";
+// trigger a warning
+print "WARNING NEXT
";
+// trigger an error
+print "ERROR NEXT
";
+$query = "INSERT invalid FROM invalid";
+$data = $db->dbReturnArray($query);
+print "ERROR (INS ON dbExec): " . print_r($db->dbGetErrorHistory(true), true) . "
";
+$query = "SELECT invalid FROM invalid";
+$data = $db->dbReturnArray($query);
+print "ERROR (HARD ERROR): " . print_r($db->dbGetErrorHistory(true), true) . "
";
+
+// 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)
diff --git a/www/admin/class_test.php b/www/admin/class_test.php
index b0bf55d5..871c428f 100644
--- a/www/admin/class_test.php
+++ b/www/admin/class_test.php
@@ -67,6 +67,7 @@ print '';
print '';
print '';
print '';
+print '';
print '';
print '';
print '';
diff --git a/www/admin/class_test.readenvfile.php b/www/admin/class_test.readenvfile.php
new file mode 100644
index 00000000..1bd32f0f
--- /dev/null
+++ b/www/admin/class_test.readenvfile.php
@@ -0,0 +1,50 @@
+ 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 "TEST CLASS: READ ENV FILE";
+print "";
+print '';
+
+print "ALREADY from config.php: " . \CoreLibs\Debug\Support::printAr($_ENV) . "
";
+
+// test .env in local
+
+// error message
+print $log->printErrorMsg();
+
+print "";
+
+// __END__
diff --git a/www/configs/config.master.php b/www/configs/config.master.php
index ff3bab0d..b920c7f7 100644
--- a/www/configs/config.master.php
+++ b/www/configs/config.master.php
@@ -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__
diff --git a/www/configs/config.php b/www/configs/config.php
index def6a7a3..803b43e0 100755
--- a/www/configs/config.php
+++ b/www/configs/config.php
@@ -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;
}
diff --git a/www/configs/read_env_file.php b/www/configs/read_env_file.php
index 22f3e28c..c3c6006d 100644
--- a/www/configs/read_env_file.php
+++ b/www/configs/read_env_file.php
@@ -1,5 +1,10 @@
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) {
diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php
index ca0d8b12..4823efd2 100644
--- a/www/lib/CoreLibs/DB/IO.php
+++ b/www/lib/CoreLibs/DB/IO.php
@@ -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 */
+ private $error_history = [];
/** @var int */
private $warning_id;
/** @var int */
- private $had_warning;
+ // private $had_warning = 0;
+ /** @var array */
+ 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 .= '[' . $id . '] ';
@@ -625,7 +639,7 @@ class IO
}
switch ($id) {
case 'DB_ERROR':
- $prefix .= 'DB-Error:';
+ $prefix .= 'DB-Error:';
break;
case 'DB_WARNING':
$prefix .= 'DB-Warning:';
@@ -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',
'DB-Error ' . $stm_name
. ': Prepare field with: ' . $stm_name . ' | '
. $query . '',
'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',
- 'DB-Error ' . $stm_name
- . ': We do not have a prepared query entry for this statement name.',
- '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',
- 'DB-Error ' . $stm_name
- . ': Prepared query Data has to be given in array form.',
- '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',
- 'DB-Error ' . $stm_name
- . ': Array data count does not match prepared fields. Need: '
- . $this->prepare_cursor[$stm_name]['count'] . ', has: '
- . count($data) . '',
- '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',
- 'DB-Error ' . $stm_name
- . ': Execution failed',
- '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',
- 'DB-Error No async query '
- . 'has beedbFetchArrayn started yet.',
- '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
diff --git a/www/lib/CoreLibs/DB/SQL/PgSQL.php b/www/lib/CoreLibs/DB/SQL/PgSQL.php
index abd041a3..077d7124 100644
--- a/www/lib/CoreLibs/DB/SQL/PgSQL.php
+++ b/www/lib/CoreLibs/DB/SQL/PgSQL.php
@@ -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("");
// }
@@ -438,8 +483,8 @@ class PgSQL
$cursor = pg_get_result($this->dbh);
}
if ($cursor && !is_bool($cursor) && $error_str = pg_result_error($cursor)) {
- return "-PostgreSQL-Error-> "
- . $error_str . "
";
+ return '-PostgreSQL-Error- '
+ . $error_str;
} else {
return '';
}
diff --git a/www/lib/CoreLibs/Get/ReadEnvFile.php b/www/lib/CoreLibs/Get/ReadEnvFile.php
new file mode 100644
index 00000000..ae759eb7
--- /dev/null
+++ b/www/lib/CoreLibs/Get/ReadEnvFile.php
@@ -0,0 +1,94 @@
+ 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__
diff --git a/www/vendor/composer/autoload_classmap.php b/www/vendor/composer/autoload_classmap.php
index 31f9c715..a3b194cb 100644
--- a/www/vendor/composer/autoload_classmap.php
+++ b/www/vendor/composer/autoload_classmap.php
@@ -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',
diff --git a/www/vendor/composer/autoload_static.php b/www/vendor/composer/autoload_static.php
index 81db1480..8857d916 100644
--- a/www/vendor/composer/autoload_static.php
+++ b/www/vendor/composer/autoload_static.php
@@ -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',