diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php
index 7d2bb913..23341663 100644
--- a/www/admin/class_test.db.php
+++ b/www/admin/class_test.db.php
@@ -6,14 +6,8 @@
declare(strict_types=1);
-$DEBUG_ALL_OVERRIDE = false; // set to 1 to debug on live/remote server locations
-$DEBUG_ALL = true;
-$PRINT_ALL = true;
-$DB_DEBUG = true;
-
-if ($DEBUG_ALL) {
- error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
-}
+// turn on all error reporting
+error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
@@ -23,10 +17,6 @@ define('USE_DATABASE', true);
require 'config.php';
// override ECHO ALL FALSE
$ECHO_ALL = true;
-// set session name
-if (!defined('SET_SESSION_NAME')) {
- define('SET_SESSION_NAME', EDIT_SESSION_NAME);
-}
// define log file id
$LOG_FILE_ID = 'classTest-db';
ob_end_flush();
@@ -45,17 +35,13 @@ $log = new CoreLibs\Debug\Logging([
'echo_all' => $ECHO_ALL ?? false,
'print_all' => $PRINT_ALL ?? false,
]);
-$basic = new CoreLibs\Basic($log);
+// $basic = new CoreLibs\Basic($log, EDIT_SESSION_NAME);
+//start session
+\CoreLibs\Create\Session::startSession(EDIT_SESSION_NAME);
+// db connection and attach logger
$db = new CoreLibs\Admin\Backend(DB_CONFIG, $log);
$db->log->debug('START', '=============================>');
-// NEXT STEP
-// $basic = new CoreLibs\Basic();
-// change __construct
-// add object $logger
-// add $this->log = $logger;
-// $db = new CoreLibs\DB\IO(DB_CONFIG, $basic->log);
-
print "
TEST CLASS: DB";
print "";
print '';
diff --git a/www/configs/config.master.php b/www/configs/config.master.php
index c8efc3ee..ff3bab0d 100644
--- a/www/configs/config.master.php
+++ b/www/configs/config.master.php
@@ -246,6 +246,8 @@ if (
// define the db config set name, the db config and the db schema
define('DB_CONFIG_NAME', $SITE_CONFIG[HOST_NAME]['db_host']);
define('DB_CONFIG', isset($DB_CONFIG[DB_CONFIG_NAME]) ? $DB_CONFIG[DB_CONFIG_NAME] : []);
+// because we can't change constant, but we want to for db debug flag
+$GLOBALS['DB_CONIFG'] = DB_CONFIG;
// define('DB_CONFIG_TARGET', SITE_CONFIG[$HOST_NAME]['db_host_target']);
// define('DB_CONFIG_OTHER', SITE_CONFIG[$HOST_NAME]['db_host_other']);
// override for login and global schemas
diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php
index a88dcb10..ca0d8b12 100644
--- a/www/lib/CoreLibs/DB/IO.php
+++ b/www/lib/CoreLibs/DB/IO.php
@@ -283,7 +283,7 @@ class IO
/** @var object|resource|bool|int|null */ // replace object with PgSql\Connection|
private $dbh; // the dbh handler, if disconnected by command is null, bool:false/int:-1 on error,
/** @var bool */
- public $db_debug = false; // DB_DEBUG ... (if set prints out debug msgs)
+ private $db_debug = false; // DB_DEBUG ... (if set prints out debug msgs)
/** @var string */
private $db_name; // the DB connected to
/** @var string */
@@ -371,10 +371,12 @@ class IO
* main DB concstructor with auto connection to DB and failure set on failed connection
* @param array $db_config DB configuration array
* @param \CoreLibs\Debug\Logging|null $log Logging class
+ * @param bool|null $db_debug_override Overrides debug settings in db_config
*/
public function __construct(
array $db_config,
- ?\CoreLibs\Debug\Logging $log = null
+ ?\CoreLibs\Debug\Logging $log = null,
+ ?bool $db_debug_override = null,
) {
// attach logger
$this->log = $log ?? new \CoreLibs\Debug\Logging();
@@ -391,6 +393,9 @@ class IO
$this->db_ssl = !empty($db_config['db_ssl']) ? $db_config['db_ssl'] : 'allow';
// set debug, either via global var, or from config, else set to false
$this->dbSetDebug(
+ // override
+ $db_debug_override ??
+ // from db config setting
$db_config['db_debug'] ??
// should be handled from outside
$_SESSION['DB_DEBUG'] ??
@@ -1012,113 +1017,14 @@ class IO
// PUBLIC METHODS
// *************************************************************
- /**
- * switches the debug flag on or off
- * if none given, then the debug flag auto switches from
- * the previous setting to either then on or off
- * else override with boolean true/false
- * @param bool|null $debug true/false or null for no set
- * @return bool debug flag in int
- */
- public function dbSetDebug($debug = null): bool
- {
- if ($debug === true) {
- $this->db_debug = true;
- } elseif ($debug === false) {
- $this->db_debug = false;
- } elseif ($this->db_debug === null) {
- $this->db_debug = false;
- }
- return $this->db_debug;
- }
-
- /**
- * Switches db debug flag on or off
- * OR
- * with the optional parameter fix sets debug
- * returns current set stats
- * @param bool|null $debug Flag to turn debug on off
- * @return bool True for debug is on, False for off
- */
- public function dbToggleDebug(?bool $debug = null): bool
- {
- if ($debug !== null) {
- $this->db_debug = $debug;
- } else {
- $this->db_debug = $this->db_debug ? false : true;
- }
- return $this->db_debug;
- }
-
- /**
- * set max query calls, set to -1 to disable loop
- * protection. this will generate a warning
- * empty call (null) will reset to default
- * @param int|null $max_calls Set the max loops allowed
- * @return bool True for succesfull set
- */
- public function dbSetMaxQueryCall(?int $max_calls = null): bool
- {
- // if null then reset to default
- if ($max_calls === null) {
- $max_calls = self::DEFAULT_MAX_QUERY_CALL;
- }
- // if -1 then disable loop check
- // DANGEROUS, WARN USER
- if ($max_calls == -1) {
- $this->warning_id = 50;
- $this->__dbError();
- }
- // negative or 0
- if ($max_calls < -1 || $max_calls == 0) {
- $this->error_id = 51;
- $this->__dbError();
- // early abort
- return false;
- }
- // ok entry, set
- $this->MAX_QUERY_CALL = $max_calls;
- return true;
- }
-
- /**
- * returns current set max query calls for loop avoidance
- * @return int Integer number, if -1 the loop check is disabled
- */
- public function dbGetMaxQueryCall(): int
- {
- return $this->MAX_QUERY_CALL;
- }
-
- /**
- * resets the call times for the max query called to 0
- * USE CAREFULLY: rather make the query prepare -> execute
- * @param string $query query string
- * @return void has no return
- */
- public function dbResetQueryCalled(string $query): void
- {
- $this->query_called[md5($query)] = 0;
- }
-
- /**
- * gets how often a query was called already
- * @param string $query query string
- * @return int count of times the query was executed
- */
- public function dbGetQueryCalled(string $query): int
- {
- $md5 = md5($query);
- if ($this->query_called[$md5]) {
- return $this->query_called[$md5];
- } else {
- return 0;
- }
- }
+ // ***************************
+ // CLOSE, STATUS, SETTINGS VARIABLE READ
+ // ***************************
/**
* closes the db_connection
- * normally this is not used, as the class deconstructor closes the connection down
+ * normally this is not used, as the class deconstructor closes
+ * the connection down
* @return void has no return
*/
public function dbClose(): void
@@ -1140,63 +1046,6 @@ class IO
return $this->db_init_error;
}
- /**
- * sets new db schema
- * @param string $db_schema schema name, if not given tries internal default db schema
- * @return bool false on failure to find schema values, true of db exec schema set
- */
- public function dbSetSchema(string $db_schema = '')
- {
- if (!$db_schema && $this->db_schema) {
- $db_schema = $this->db_schema;
- }
- if (!$db_schema) {
- return false;
- }
- $q = "SET search_path TO '" . $this->dbEscapeString($db_schema) . "'";
- return $this->dbExec($q) ? true : false;
- }
-
- /**
- * returns the current set db schema
- * @return string db schema name
- */
- public function dbGetSchema(): string
- {
- return $this->db_schema;
- }
-
- /**
- * sets the client encoding in the postgres database
- * @param string $db_encoding valid encoding name,
- * so the the data gets converted to this encoding
- * @return bool false, or true of db exec encoding set
- */
- public function dbSetEncoding(string $db_encoding = ''): bool
- {
- if (!$db_encoding && $this->db_encoding) {
- $db_encoding = $this->db_encoding;
- }
- if (!$db_encoding) {
- return false;
- }
- $q = "SET client_encoding TO '" . $this->dbEscapeString($db_encoding) . "'";
- return $this->dbExec($q) ? true : false;
- }
-
- /**
- * returns the current set client encoding from the connected DB
- * @return string current client encoding
- */
- public function dbGetEncoding(): string
- {
- $client_encoding = $this->dbReturnRow('SHOW client_encoding');
- if (!is_array($client_encoding)) {
- return '';
- }
- return $client_encoding['client_encoding'] ?? '';
- }
-
/**
* get certain settings like username, db name
* @param string $name what setting to query
@@ -1227,6 +1076,9 @@ class IO
case 'ssl':
$setting = $this->db_ssl;
break;
+ case 'debug':
+ $setting = $this->db_debug;
+ break;
// we return *** and never the actual password
case 'password':
$setting = '***';
@@ -1264,10 +1116,238 @@ class IO
return str_replace(['{b}', '{/b}', '{br}'], ['', '', '
'], $string);
}
+/**
+ * return current database version
+ * @return string database version as string
+ */
+ public function dbVersion(): string
+ {
+ return $this->db_functions->__dbVersion();
+ }
+
+ /**
+ * returns boolean true or false if the string matches the database version
+ * @param string $compare string to match in type =X.Y, >X.Y, =X.Y
+ * @return bool true for ok, false on not ok
+ */
+ public function dbCompareVersion(string $compare): bool
+ {
+ $matches = [];
+ // compare has =, >, < prefix, and gets stripped, if the rest is not X.Y format then error
+ preg_match("/^([<>=]{1,})(\d{1,})\.(\d{1,})/", $compare, $matches);
+ $compare = $matches[1];
+ $to_master = $matches[2];
+ $to_minor = $matches[3];
+ if (!$compare || !$to_master || !$to_minor) {
+ return false;
+ } else {
+ $to_version = $to_master . ($to_minor < 10 ? '0' : '') . $to_minor;
+ }
+ // db_version can return X.Y.Z
+ // we only compare the first two
+ preg_match("/^(\d{1,})\.(\d{1,})\.?(\d{1,})?/", $this->dbVersion(), $matches);
+ $master = $matches[1];
+ $minor = $matches[2];
+ $version = $master . ($minor < 10 ? '0' : '') . $minor;
+ $return = false;
+ // compare
+ switch ($compare) {
+ case '=':
+ if ($to_version == $version) {
+ $return = true;
+ }
+ break;
+ case '<':
+ if ($version < $to_version) {
+ $return = true;
+ }
+ break;
+ case '<=':
+ if ($version <= $to_version) {
+ $return = true;
+ }
+ break;
+ case '>':
+ if ($version > $to_version) {
+ $return = true;
+ }
+ break;
+ case '>=':
+ if ($version >= $to_version) {
+ $return = true;
+ }
+ break;
+ default:
+ $return = false;
+ }
+ return $return;
+ }
+
+ /**
+ * only for postgres. pretty formats an age or datetime difference string
+ * @param string $age age or datetime difference
+ * @param bool $show_micro micro on off (default false)
+ * @return string Y/M/D/h/m/s formatted string (like TimeStringFormat)
+ */
+ public function dbTimeFormat(string $age, bool $show_micro = false): string
+ {
+ $matches = [];
+ // in string (datetime diff): 1786 days 22:11:52.87418
+ // or (age): 4 years 10 mons 21 days 12:31:11.87418
+ // also -09:43:54.781021 or without - prefix
+ preg_match("/(.*)?(\d{2}):(\d{2}):(\d{2})(\.(\d+))/", $age, $matches);
+
+ $prefix = $matches[1] != '-' ? $matches[1] : '';
+ $hour = $matches[2] != '00' ? preg_replace('/^0/', '', $matches[2]) : '';
+ $minutes = $matches[3] != '00' ? preg_replace('/^0/', '', $matches[3]) : '';
+ $seconds = $matches[4] != '00' ? preg_replace('/^0/', '', $matches[4]) : '';
+ $milliseconds = $matches[6];
+
+ return $prefix
+ . (!empty($hour) && is_string($hour) ? $hour . 'h ' : '')
+ . (!empty($minutes) && is_string($minutes) ? $minutes . 'm ' : '')
+ . (!empty($seconds) && is_string($seconds) ? $seconds . 's' : '')
+ . ($show_micro && !empty($milliseconds) ? ' ' . $milliseconds . 'ms' : '');
+ }
+
+ /**
+ * clear up any data for valid DB insert
+ * @param int|float|string $value to escape data
+ * @param string $kbn escape trigger type
+ * @return string escaped value
+ */
+ public function dbSqlEscape($value, string $kbn = '')
+ {
+ switch ($kbn) {
+ case 'i':
+ $value = $value === '' ? "NULL" : intval($value);
+ break;
+ case 'f':
+ $value = $value === '' ? "NULL" : floatval($value);
+ break;
+ case 't':
+ $value = $value === '' ? "NULL" : "'" . $this->dbEscapeString($value) . "'";
+ break;
+ case 'd':
+ $value = $value === '' ? "NULL" : "'" . $this->dbEscapeString($value) . "'";
+ break;
+ case 'i2':
+ $value = $value === '' ? 0 : intval($value);
+ break;
+ }
+ return (string)$value;
+ }
+
+ /**
+ * this is only needed for Postgresql. Converts postgresql arrays to PHP
+ * @param string $text input text to parse to an array
+ * @return array PHP array of the parsed data
+ */
+ public function dbArrayParse(string $text): array
+ {
+ $output = [];
+ $__db_array_parse = $this->db_functions->__dbArrayParse($text, $output);
+ return is_array($__db_array_parse) ? $__db_array_parse : [];
+ }
+
+ // ***************************
+ // DATA WRITE CONVERSION
+ // ***************************
+
+ /**
+ * neutral function to escape a string for DB writing
+ * @param string|int|float|bool $string string to escape
+ * @return string escaped string
+ */
+ public function dbEscapeString($string): string
+ {
+ return $this->db_functions->__dbEscapeString($string);
+ }
+
+ /**
+ * neutral function to escape a string for DB writing
+ * this one adds '' quotes around the string
+ * @param string|int|float|bool $string string to escape
+ * @return string escaped string
+ */
+ public function dbEscapeLiteral($string): string
+ {
+ return $this->db_functions->__dbEscapeLiteral($string);
+ }
+
+ /**
+ * neutral function to escape a bytea for DB writing
+ * @param string $bytea bytea to escape
+ * @return string escaped bytea
+ */
+ public function dbEscapeBytea($bytea)
+ {
+ return $this->db_functions->__dbEscapeBytea($bytea);
+ }
+
+ /**
+ * if the input is a single char 't' or 'f
+ * it will return the boolean value instead
+ * also converts smallint 1/0 to true false
+ * @param string|bool|int $string 't' / 'f' or any string, or bool true/false
+ * @param boolean $rev do reverse (bool to string)
+ * @return bool|string correct php boolean true/false
+ * or postgresql 't'/'f'
+ */
+ public function dbBoolean($string, $rev = false)
+ {
+ if (!$rev) {
+ if ($string == 't' || $string == 'true') {
+ return true;
+ }
+ if ($string == 'f' || $string == 'false') {
+ return false;
+ }
+ // fallback in case top is not t/f, default on set unset
+ if ($string) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ($string) {
+ return 't';
+ } else {
+ return 'f';
+ }
+ }
+ }
+
+ // ***************************
+ // TABLE META DATA READ
+ // ***************************
+
+ /**
+ * returns an array of the table with columns and values. FALSE on no table found
+ * @param string $table table name
+ * @param string $schema optional schema name
+ * @return array|bool array of table data, false on error (table not found)
+ */
+ public function dbShowTableMetaData(string $table, string $schema = '')
+ {
+ $table = ($schema ? $schema . '.' : '') . $table;
+
+ $array = $this->db_functions->__dbMetaData($table);
+ if (!is_array($array)) {
+ $array = false;
+ }
+ return $array;
+ }
+
+ // ***************************
+ // QUERY EXECUSION AND DATA READ
+ // ***************************
+
/**
* dumps ALL data for this query, OR if no query given all in cursor_ext array
- * @param string $query query, if given, only from this quey (if found), else current cursor
- * @return string formated string with all the data in the array
+ * @param string $query Query, if given, only from this quey (if found)
+ * else current cursor
+ * @return string Formated string with all the data in the array
*/
public function dbDumpData($query = ''): string
{
@@ -1509,24 +1589,6 @@ class IO
return $return;
}
- /**
- * resets all data stored to this query
- * @param string $query The Query whose cache should be cleaned
- * @return bool false if query not found, true if success
- */
- public function dbCacheReset(string $query): bool
- {
- $md5 = md5($query);
- // clears cache for this query
- if (!$this->cursor_ext[$md5]['query']) {
- $this->error_id = 18;
- $this->__dbError();
- return false;
- }
- unset($this->cursor_ext[$md5]);
- return true;
- }
-
/**
* executes the query and returns & sets the internal cursor
* furthermore this functions also sets varios other vars
@@ -1540,7 +1602,7 @@ class IO
* if pk name is table name and _id, pk_name
* is not needed to be set
* if NULL is given here, no RETURNING will be auto added
- * @return object|resource|bool cursor for this query or false on error (PgSql\Result)
+ * @return object|resource|bool cursor for this query or false on error (PgSql\Result)
*/
public function dbExec(string $query = '', string $pk_name = '')
{
@@ -1564,78 +1626,6 @@ class IO
}
}
- /**
- * executres the query async so other methods can be run during this
- * for INSERT INTO queries it is highly recommended to set the pk_name
- * to avoid an additional
- * read from the database for the PK NAME
- * NEEDS : dbCheckAsync
- * @param string $query query to run
- * @param string $pk_name optional primary key name, only used with
- * insert for returning call
- * @return bool true if async query was sent ok, false if error happened
- */
- public function dbExecAsync(string $query, string $pk_name = ''): bool
- {
- // prepare and check if we can actually run the query
- if (($md5 = $this->__dbPrepareExec($query, $pk_name)) === false) {
- // bail if no md5 set
- return false;
- }
- // run the async query
- if (!$this->db_functions->__dbSendQuery($this->query)) {
- // if failed, process here
- $this->error_id = 40;
- $this->__dbError();
- return false;
- } else {
- $this->async_running = (string)$md5;
- // all ok, we return true (as would be from the original send query function)
- return true;
- }
- }
-
- /**
- * checks a previous async query and returns data if finished
- * NEEDS : dbExecAsync
- * @return bool|object|resource cursor resource if the query is still running,
- * false if an error occured or cursor of that query
- * (PgSql\Result)
- */
- public function dbCheckAsync()
- {
- // if there is actually a async query there
- if ($this->async_running) {
- if ($this->db_functions->__dbConnectionBusy()) {
- return true;
- } else {
- $cursor = $this->db_functions->__dbGetResult();
- if ($cursor === false) {
- return false;
- }
- // get the result/or error
- $this->cursor = $cursor;
- $this->async_running = '';
- // run the post exec processing
- if (!$this->__dbPostExec()) {
- return false;
- } else {
- return $this->cursor;
- }
- }
- } 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'
- );
- return false;
- }
- }
-
/**
* executes a cursor and returns the data, if no more data 0 will be returned
* @param object|resource|bool $cursor the cursor from db_exec or
@@ -1722,6 +1712,32 @@ class IO
return $rows;
}
+ // ***************************
+ // CURSOR CACHE RESET
+ // ***************************
+
+ /**
+ * resets all data stored to this query
+ * @param string $query The Query whose cache should be cleaned
+ * @return bool false if query not found, true if success
+ */
+ public function dbCacheReset(string $query): bool
+ {
+ $md5 = md5($query);
+ // clears cache for this query
+ if (!$this->cursor_ext[$md5]['query']) {
+ $this->error_id = 18;
+ $this->__dbError();
+ return false;
+ }
+ unset($this->cursor_ext[$md5]);
+ return true;
+ }
+
+ // ***************************
+ // CURSOR POSITON CHECK
+ // ***************************
+
/**
* returns the current position the read out
* @param string $query query to find in cursor_ext
@@ -1754,23 +1770,40 @@ class IO
return (int)$this->cursor_ext[$md5]['num_rows'];
}
- /**
- * returns an array of the table with columns and values. FALSE on no table found
- * @param string $table table name
- * @param string $schema optional schema name
- * @return array|bool array of table data, false on error (table not found)
- */
- public function dbShowTableMetaData(string $table, string $schema = '')
- {
- $table = ($schema ? $schema . '.' : '') . $table;
+ // ***************************
+ // MAXIMUM QUERY EXECUTION CHECK HELPERS
+ // ***************************
- $array = $this->db_functions->__dbMetaData($table);
- if (!is_array($array)) {
- $array = false;
- }
- return $array;
+ /**
+ * resets the call times for the max query called to 0
+ * USE CAREFULLY: rather make the query prepare -> execute
+ * @param string $query query string
+ * @return void has no return
+ */
+ public function dbResetQueryCalled(string $query): void
+ {
+ $this->query_called[md5($query)] = 0;
}
+ /**
+ * gets how often a query was called already
+ * @param string $query query string
+ * @return int count of times the query was executed
+ */
+ public function dbGetQueryCalled(string $query): int
+ {
+ $md5 = md5($query);
+ if ($this->query_called[$md5]) {
+ return $this->query_called[$md5];
+ } else {
+ return 0;
+ }
+ }
+
+ // ***************************
+ // PREPARED QUERY WORK
+ // ***************************
+
/**
* prepares a query
* for INSERT INTO queries it is highly recommended to set the pk_name to avoid an additional
@@ -1948,137 +1981,86 @@ class IO
return $result;
}
- /**
- * neutral function to escape a string for DB writing
- * @param string|int|float|bool $string string to escape
- * @return string escaped string
- */
- public function dbEscapeString($string): string
- {
- return $this->db_functions->__dbEscapeString($string);
- }
+ // ***************************
+ // ASYNCHRONUS EXECUTION/CHECK
+ // ***************************
/**
- * neutral function to escape a string for DB writing
- * this one adds '' quotes around the string
- * @param string|int|float|bool $string string to escape
- * @return string escaped string
+ * executres the query async so other methods can be run during this
+ * for INSERT INTO queries it is highly recommended to set the pk_name
+ * to avoid an additional
+ * read from the database for the PK NAME
+ * NEEDS : dbCheckAsync
+ * @param string $query query to run
+ * @param string $pk_name optional primary key name, only used with
+ * insert for returning call
+ * @return bool true if async query was sent ok, false if error happened
*/
- public function dbEscapeLiteral($string): string
+ public function dbExecAsync(string $query, string $pk_name = ''): bool
{
- return $this->db_functions->__dbEscapeLiteral($string);
- }
-
- /**
- * neutral function to escape a bytea for DB writing
- * @param string $bytea bytea to escape
- * @return string escaped bytea
- */
- public function dbEscapeBytea($bytea)
- {
- return $this->db_functions->__dbEscapeBytea($bytea);
- }
-
- /**
- * return current database version
- * @return string database version as string
- */
- public function dbVersion(): string
- {
- return $this->db_functions->__dbVersion();
- }
-
- /**
- * returns boolean true or false if the string matches the database version
- * @param string $compare string to match in type =X.Y, >X.Y, =X.Y
- * @return bool true for ok, false on not ok
- */
- public function dbCompareVersion(string $compare): bool
- {
- $matches = [];
- // compare has =, >, < prefix, and gets stripped, if the rest is not X.Y format then error
- preg_match("/^([<>=]{1,})(\d{1,})\.(\d{1,})/", $compare, $matches);
- $compare = $matches[1];
- $to_master = $matches[2];
- $to_minor = $matches[3];
- if (!$compare || !$to_master || !$to_minor) {
+ // prepare and check if we can actually run the query
+ if (($md5 = $this->__dbPrepareExec($query, $pk_name)) === false) {
+ // bail if no md5 set
+ return false;
+ }
+ // run the async query
+ if (!$this->db_functions->__dbSendQuery($this->query)) {
+ // if failed, process here
+ $this->error_id = 40;
+ $this->__dbError();
return false;
} else {
- $to_version = $to_master . ($to_minor < 10 ? '0' : '') . $to_minor;
+ $this->async_running = (string)$md5;
+ // all ok, we return true (as would be from the original send query function)
+ return true;
}
- // db_version can return X.Y.Z
- // we only compare the first two
- preg_match("/^(\d{1,})\.(\d{1,})\.?(\d{1,})?/", $this->dbVersion(), $matches);
- $master = $matches[1];
- $minor = $matches[2];
- $version = $master . ($minor < 10 ? '0' : '') . $minor;
- $return = false;
- // compare
- switch ($compare) {
- case '=':
- if ($to_version == $version) {
- $return = true;
- }
- break;
- case '<':
- if ($version < $to_version) {
- $return = true;
- }
- break;
- case '<=':
- if ($version <= $to_version) {
- $return = true;
- }
- break;
- case '>':
- if ($version > $to_version) {
- $return = true;
- }
- break;
- case '>=':
- if ($version >= $to_version) {
- $return = true;
- }
- break;
- default:
- $return = false;
- }
- return $return;
}
/**
- * if the input is a single char 't' or 'f
- * it will return the boolean value instead
- * also converts smallint 1/0 to true false
- * @param string|bool|int $string 't' / 'f' or any string, or bool true/false
- * @param boolean $rev do reverse (bool to string)
- * @return bool|string correct php boolean true/false
- * or postgresql 't'/'f'
+ * checks a previous async query and returns data if finished
+ * NEEDS : dbExecAsync
+ * @return bool|object|resource cursor resource if the query is still running,
+ * false if an error occured or cursor of that query
+ * (PgSql\Result)
*/
- public function dbBoolean($string, $rev = false)
+ public function dbCheckAsync()
{
- if (!$rev) {
- if ($string == 't' || $string == 'true') {
- return true;
- }
- if ($string == 'f' || $string == 'false') {
- return false;
- }
- // fallback in case top is not t/f, default on set unset
- if ($string) {
+ // if there is actually a async query there
+ if ($this->async_running) {
+ if ($this->db_functions->__dbConnectionBusy()) {
return true;
} else {
- return false;
+ $cursor = $this->db_functions->__dbGetResult();
+ if ($cursor === false) {
+ return false;
+ }
+ // get the result/or error
+ $this->cursor = $cursor;
+ $this->async_running = '';
+ // run the post exec processing
+ if (!$this->__dbPostExec()) {
+ return false;
+ } else {
+ return $this->cursor;
+ }
}
} else {
- if ($string) {
- return 't';
- } else {
- return 'f';
- }
+ // if no async running print error
+ $this->error_id = 42;
+ $this->__dbDebug(
+ 'db',
+ 'DB-Error No async query '
+ . 'has beedbFetchArrayn started yet.',
+ 'DB_ERROR'
+ );
+ return false;
}
}
+ // ***************************
+ // COMPLEX WRITE WITH CONFIG ARRAYS
+ // ***************************
+
// ** REMARK **
// db_write_data is the old without separate update no write list
// db_write_data_ext is the extended with additional array for no write list for update
@@ -2257,75 +2239,151 @@ class IO
return $primary_key['value'] ?? false;
}
- /**
- * only for postgres. pretty formats an age or datetime difference string
- * @param string $age age or datetime difference
- * @param bool $show_micro micro on off (default false)
- * @return string Y/M/D/h/m/s formatted string (like TimeStringFormat)
- */
- public function dbTimeFormat(string $age, bool $show_micro = false): string
- {
- $matches = [];
- // in string (datetime diff): 1786 days 22:11:52.87418
- // or (age): 4 years 10 mons 21 days 12:31:11.87418
- // also -09:43:54.781021 or without - prefix
- preg_match("/(.*)?(\d{2}):(\d{2}):(\d{2})(\.(\d+))/", $age, $matches);
-
- $prefix = $matches[1] != '-' ? $matches[1] : '';
- $hour = $matches[2] != '00' ? preg_replace('/^0/', '', $matches[2]) : '';
- $minutes = $matches[3] != '00' ? preg_replace('/^0/', '', $matches[3]) : '';
- $seconds = $matches[4] != '00' ? preg_replace('/^0/', '', $matches[4]) : '';
- $milliseconds = $matches[6];
-
- return $prefix
- . (!empty($hour) && is_string($hour) ? $hour . 'h ' : '')
- . (!empty($minutes) && is_string($minutes) ? $minutes . 'm ' : '')
- . (!empty($seconds) && is_string($seconds) ? $seconds . 's' : '')
- . ($show_micro && !empty($milliseconds) ? ' ' . $milliseconds . 'ms' : '');
- }
+ // ***************************
+ // INTERNAL SETTINGS READ/CHANGE
+ // ***************************
/**
- * this is only needed for Postgresql. Converts postgresql arrays to PHP
- * @param string $text input text to parse to an array
- * @return array PHP array of the parsed data
+ * switches the debug flag on or off
+ * if none given, then return current set only
+ * @param bool|null $debug true/false or null for just getting current set
+ * @return bool Current debug flag as set
*/
- public function dbArrayParse(string $text): array
+ public function dbSetDebug($debug = null): bool
{
- $output = [];
- $__db_array_parse = $this->db_functions->__dbArrayParse($text, $output);
- return is_array($__db_array_parse) ? $__db_array_parse : [];
- }
-
- /**
- * clear up any data for valid DB insert
- * @param int|float|string $value to escape data
- * @param string $kbn escape trigger type
- * @return string escaped value
- */
- public function dbSqlEscape($value, string $kbn = '')
- {
- switch ($kbn) {
- case 'i':
- $value = $value === '' ? "NULL" : intval($value);
- break;
- case 'f':
- $value = $value === '' ? "NULL" : floatval($value);
- break;
- case 't':
- $value = $value === '' ? "NULL" : "'" . $this->dbEscapeString($value) . "'";
- break;
- case 'd':
- $value = $value === '' ? "NULL" : "'" . $this->dbEscapeString($value) . "'";
- break;
- case 'i2':
- $value = $value === '' ? 0 : intval($value);
- break;
+ if ($debug !== null) {
+ $this->db_debug = $debug;
}
- return (string)$value;
+ return $this->db_debug;
+ }
+
+ /**
+ * Switches db debug flag on or off
+ * OR
+ * with the optional parameter fix sets debug
+ * returns current set stats
+ * @param bool|null $debug Flag to turn debug on off or null for toggle
+ * @return bool Current debug status
+ * True for debug is on, False for off
+ */
+ public function dbToggleDebug(?bool $debug = null): bool
+ {
+ if ($debug !== null) {
+ $this->db_debug = $debug;
+ } else {
+ $this->db_debug = $this->db_debug ? false : true;
+ }
+ return $this->db_debug;
+ }
+
+ /**
+ * Return current set db debug flag status
+ * @return bool Current debug status
+ */
+ public function dbGetDebug(): bool
+ {
+ return $this->db_debug;
+ }
+
+ /**
+ * set max query calls, set to -1 to disable loop
+ * protection. this will generate a warning
+ * empty call (null) will reset to default
+ * @param int|null $max_calls Set the max loops allowed
+ * @return bool True for succesfull set
+ */
+ public function dbSetMaxQueryCall(?int $max_calls = null): bool
+ {
+ // if null then reset to default
+ if ($max_calls === null) {
+ $max_calls = self::DEFAULT_MAX_QUERY_CALL;
+ }
+ // if -1 then disable loop check
+ // DANGEROUS, WARN USER
+ if ($max_calls == -1) {
+ $this->warning_id = 50;
+ $this->__dbError();
+ }
+ // negative or 0
+ if ($max_calls < -1 || $max_calls == 0) {
+ $this->error_id = 51;
+ $this->__dbError();
+ // early abort
+ return false;
+ }
+ // ok entry, set
+ $this->MAX_QUERY_CALL = $max_calls;
+ return true;
+ }
+
+ /**
+ * returns current set max query calls for loop avoidance
+ * @return int Integer number, if -1 the loop check is disabled
+ */
+ public function dbGetMaxQueryCall(): int
+ {
+ return $this->MAX_QUERY_CALL;
+ }
+
+ /**
+ * sets new db schema
+ * @param string $db_schema schema name, if not given tries internal default db schema
+ * @return bool false on failure to find schema values, true of db exec schema set
+ */
+ public function dbSetSchema(string $db_schema = '')
+ {
+ if (!$db_schema && $this->db_schema) {
+ $db_schema = $this->db_schema;
+ }
+ if (!$db_schema) {
+ return false;
+ }
+ $q = "SET search_path TO '" . $this->dbEscapeString($db_schema) . "'";
+ return $this->dbExec($q) ? true : false;
+ }
+
+ /**
+ * returns the current set db schema
+ * @return string db schema name
+ */
+ public function dbGetSchema(): string
+ {
+ return $this->db_schema;
+ }
+
+ /**
+ * sets the client encoding in the postgres database
+ * @param string $db_encoding valid encoding name,
+ * so the the data gets converted to this encoding
+ * @return bool false, or true of db exec encoding set
+ */
+ public function dbSetEncoding(string $db_encoding = ''): bool
+ {
+ if (!$db_encoding && $this->db_encoding) {
+ $db_encoding = $this->db_encoding;
+ }
+ if (!$db_encoding) {
+ return false;
+ }
+ $q = "SET client_encoding TO '" . $this->dbEscapeString($db_encoding) . "'";
+ return $this->dbExec($q) ? true : false;
+ }
+
+ /**
+ * returns the current set client encoding from the connected DB
+ * @return string current client encoding
+ */
+ public function dbGetEncoding(): string
+ {
+ $client_encoding = $this->dbReturnRow('SHOW client_encoding');
+ if (!is_array($client_encoding)) {
+ return '';
+ }
+ return $client_encoding['client_encoding'] ?? '';
}
// ***************************
- // INTERNAL VARIABLES READ
+ // INTERNAL VARIABLES READ POST QUERY RUN
// ***************************
/**
@@ -2490,7 +2548,9 @@ class IO
return $this->had_warning;
}
+ /******************************** */
// DEPEREACTED CALLS
+ /******************************** */
/**
* old call for getInserReturnExt