diff --git a/4dev/tests/CoreLibsDBIOTest.php b/4dev/tests/CoreLibsDBIOTest.php index e5f3505d..bd784bbb 100644 --- a/4dev/tests/CoreLibsDBIOTest.php +++ b/4dev/tests/CoreLibsDBIOTest.php @@ -86,6 +86,19 @@ final class CoreLibsDBIOTest extends TestCase 'db_ssl' => 'allow', // allow, disable, require, prefer 'db_debug' => true, ], + // valid with no schema set + 'valid_no_schema' => [ + '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' => '', + 'db_type' => 'pgsql', + 'db_encoding' => '', + 'db_ssl' => 'allow', // allow, disable, require, prefer + 'db_debug' => true, + ], // invalid (missing db name) 'invalid' => [ 'db_name' => '', @@ -567,86 +580,6 @@ final class CoreLibsDBIOTest extends TestCase $db->dbClose(); } - // - set and get schema - // dbGetSchema, dbSetSchema, - - // TODO: schema set/get test - - // - encoding settings (exclude encoding test, just set) - // dbGetEncoding, dbSetEncoding - - /** - * test encoding change list for dbSetEncoding - * - * @return array - */ - public function encodingProvider(): array - { - // 0: connection - // 1: set encoding - // 2: expected return from set - // 2: expected to get - return [ - 'default set no encoding' => [ - 'valid', - '', - false, - // I expect that the default DB is set to UTF8 - 'UTF8' - ], - 'set to Shift JIS' => [ - 'valid', - 'ShiftJIS', - true, - 'SJIS' - ], - // 'set to Invalid' => [ - // 'valid', - // 'Invalid', - // false, - // 'UTF8' - // ], - // other tests includ perhaps mocking for error? - // TODO actual data check - ]; - } - - /** - * change DB encoding, only function set test, not test of encoding change - * TODO: add encoding changed test with DB insert - * - * @covers ::dbSetEncoding - * @covers ::dbGetEncoding - * @dataProvider encodingProvider - * @testdox Set encoding on $connection to $set_encoding expect $expected_set_flag and $expected_get_encoding [$_dataName] - * - * @param string $connection - * @param string $set_encoding - * @param boolean $expected_set_flag - * @param string $expected_get_encoding - * @return void - */ - public function testEncoding( - string $connection, - string $set_encoding, - bool $expected_set_flag, - string $expected_get_encoding - ): void { - $db = new \CoreLibs\DB\IO( - self::$db_config[$connection], - self::$log - ); - $this->assertEquals( - $expected_set_flag, - $db->dbSetEncoding($set_encoding) - ); - $this->assertEquals( - $expected_get_encoding, - $db->dbGetEncoding() - ); - $db->dbClose(); - } - // - all general data from connection array // dbGetSetting (name, user, ecnoding, schema, host, port, ssl, debug, password) @@ -1403,7 +1336,9 @@ final class CoreLibsDBIOTest extends TestCase '11', ], // no db connection setable (16) [needs Mocking] + // TODO failed db connection // connection busy [async] (41) + // TODO connection busy // same query run too many times (30) 'same query run too many times' => [ 'SELECT row_date FROM table_with_primary_key', @@ -1427,7 +1362,7 @@ final class CoreLibsDBIOTest extends TestCase // NOTE: After an error was encountered, queries after this // will return a true connection busy although it was error // https://bugs.php.net/bug.php?id=36469 - // TODO: fix wron error 42 after error insert + // FIX with socket check type 'invalid returning' => [ 'INSERT INTO table_with_primary_key (row_date) VALUES (NOW()) RETURNING invalid', '', @@ -1490,13 +1425,13 @@ final class CoreLibsDBIOTest extends TestCase $last_warning = $db->dbGetLastWarning(); $last_error = $db->dbGetLastError(); } else { + $result = $pk_name === null ? + $db->dbExec($query) : + $db->dbExec($query, $pk_name); + $last_warning = $db->dbGetLastWarning(); + $last_error = $db->dbGetLastError(); // if PHP or newer, must be Object PgSql\Result if (\CoreLibs\Check\PhpVersion::checkPHPVersion('8.1')) { - $result = $pk_name === null ? - $db->dbExec($query) : - $db->dbExec($query, $pk_name); - $last_warning = $db->dbGetLastWarning(); - $last_error = $db->dbGetLastError(); $this->assertIsObject( $result ); @@ -1507,12 +1442,8 @@ final class CoreLibsDBIOTest extends TestCase ); } else { $this->assertIsResource( - $pk_name === null ? - $db->dbExec($query) : - $db->dbExec($query, $pk_name) + $result ); - $last_warning = $db->dbGetLastWarning(); - $last_error = $db->dbGetLastError(); } } // if we have more than one run time @@ -2046,39 +1977,240 @@ final class CoreLibsDBIOTest extends TestCase // - prepared query execute // dbPrepare, dbExecute, dbFetchArray + /** + * Undocumented function + * + * @return array + */ public function preparedProvider(): array { + $insert_query = "INSERT INTO table_with_primary_key (row_int, uid) VALUES " + . "(1, 'A'), (2, 'B')"; + $read_query = "SELECT row_int, uid FROM table_with_primary_key"; // 0: statement name // 1: query to prepare // 2: primary key name: null for default run - // 3: arguments for query (double array 0: for select, 0..n for insert/update) + // 3: arguments for query (single array for all) // 4: expected prepare return // 5: prepare warning // 6: prepare error // 7: expected execute return // 8: execute warning // 9: execute error - // 10: execute data to check (array) - // 11: insert data + // 11: read query (if insert/update) + // 11: execute data to check (array) + // 12: insert data return [ - + // insert + 'prepare query insert' => [ + // base statements 0-3 + 'insert', + "INSERT INTO table_with_primary_key (row_int, uid) VALUES " + . "($1, $2)", + null, + [990, 'TEST A'], + // prepare (4-6) + 'result', '', '', + // execute + 'result', '', '', + // check query and compare data (for insert/update) + $read_query, + [ + [ + 'row_int' => 990, + 'uid' => 'TEST A', + ], + ], + // insert data (for select) + '', + ], + // update + 'prepare query update' => [ + 'update', + "UPDATE table_with_primary_key SET " + . "row_int = $1, " + . "row_varchar = $2 " + . "WHERE uid = $3", + null, + [550, 'I AM NEW TEXT', 'TEST A'], + // + 'result', '', '', + // + 'result', '', '', + // + "SELECT row_int, row_varchar FROM table_with_primary_key " + . "WHERE uid = 'TEST A'", + [ + [ + 'row_int' => 550, + 'row_varchar' => 'I AM NEW TEXT', + ], + ], + // + "INSERT INTO table_with_primary_key (row_int, uid) VALUES " + . "(111, 'TEST A')", + ], + // select + 'prepare select query' => [ + 'select', + $read_query + . " WHERE uid = $1", + null, + ['A'], + // + 'result', '', '', + // execute here needs to read too + 'result', '', '', + // + '', + [ + [ + 'row_int' => 1, + 'uid' => 'A', + ], + ], + // + $insert_query + ], + // any query but with no parameters + 'prepare select query no parameter' => [ + 'select_noparam', + $read_query, + null, + null, + // + 'result', '', '', + // execute here needs to read too + 'result', '', '', + // + '', + [ + [ + 'row_int' => 1, + 'uid' => 'A', + ], + [ + 'row_int' => 2, + 'uid' => 'B', + ], + ], + // + $insert_query + ], + // no statement name (25) + 'empty statement' => [ + '', + 'SELECT', + null, + [], + // + false, '', '25', + // + false, '', '25', + // + '', + [], + // + '', + ], + // no query (prepare 11) + // no prepared cursor found with statement name (execute 24) + 'empty query' => [ + 'Empty Query', + '', + null, + [], + // + false, '', '11', + // + false, '', '24', + // + '', + [], + // + '', + ], + // no db connection (prepare/execute 16) + // TODO no db connection test + // connection busy (prepare/execute 41) + // TODO connection busy test + // query could not be prepare (prepare 21) + // TODO query could not be prepared test + // some query with same statement name exists (prepare W20) + 'prepare query with same statement name' => [ + 'double', + $read_query, + null, + null, + // + true, '20', '', + // + 'result', '', '', + // no query but data for data only compare + '', + [], + //, + $insert_query + ], + // insert wrong data count compared to needed (execute 23) + 'wrong parmeter count' => [ + 'wrong_param_count', + "INSERT INTO table_with_primary_key (row_int, uid) VALUES " + . "($1, $2)", + null, + [], + // + 'result', '', '', + // + false, '', '23', + // + '', + [], + // + '' + ], + // execute does not return a result (22) + // TODO execute does not return a result ]; } - // bool|object|resource - + /** + * Undocumented function + * + * @covers ::dbPrepare + * @covers ::dbExecute + * @covers ::dbFetchArray + * @dataProvider preparedProvider + * @testdox prepared query $stm_name with $expected_prepare (warning $warning_prepare/error $error_prepare) and $expected_execute (warning $warning_execute/error $error_execute) [$_dataName] + * + * @param string $stm_name + * @param string $query + * @param string|null $pk_name + * @param array|null $query_data + * @param bool|string $expected_prepare + * @param string $warning_prepare + * @param string $error_prepare + * @param bool|string $expected_execute + * @param string $warning_execute + * @param string $error_execute + * @param string $expected_data_query + * @param array $expected_data + * @param string $insert_data + * @return void + */ public function testDbPrepared( string $stm_name, string $query, ?string $pk_name, - array $query_data, + ?array $query_data, $expected_prepare, string $warning_prepare, string $error_prepare, $expected_execute, string $warning_execute, string $error_execute, - array $excute_data, + string $expected_data_query, + array $expected_data, string $insert_data, ): void { // self::$log->setLogLevelAll('debug', true); @@ -2088,7 +2220,124 @@ final class CoreLibsDBIOTest extends TestCase self::$log ); // insert data before we can test, from expected array - $db->dbExec($insert_data); + if (!empty($insert_data)) { + $db->dbExec($insert_data); + } + + // test prepare + $prepare_result = $pk_name === null ? + $db->dbPrepare($stm_name, $query) : + $db->dbPrepare($stm_name, $query, $pk_name); + // if warning is 20, call prepare again + if ($warning_prepare == '20') { + $prepare_result = $pk_name === null ? + $db->dbPrepare($stm_name, $query) : + $db->dbPrepare($stm_name, $query, $pk_name); + } + $last_warning = $db->dbGetLastWarning(); + $last_error = $db->dbGetLastError(); + // if result type, or if forced bool + if (is_string($expected_prepare) && $expected_prepare == 'result') { + // if PHP or newer, must be Object PgSql\Result + if (\CoreLibs\Check\PhpVersion::checkPHPVersion('8.1')) { + $this->assertIsObject( + $prepare_result + ); + // also check that this is correct instance type + $this->assertInstanceOf( + 'PgSql\Result', + $prepare_result + ); + } else { + $this->assertIsResource( + $prepare_result + ); + } + } else { + $this->assertEquals( + $expected_prepare, + $prepare_result + ); + } + // error/warning check + $this->assertEquals( + $warning_prepare, + $last_warning, + ); + $this->assertEquals( + $error_prepare, + $last_error, + ); + + // for non fail prepare test exec + // check test result + $execute_result = $query_data === null ? + $db->dbExecute($stm_name) : + $db->dbExecute($stm_name, $query_data); + $last_warning = $db->dbGetLastWarning(); + $last_error = $db->dbGetLastError(); + if ($expected_execute == 'result') { + // if PHP or newer, must be Object PgSql\Result + if (\CoreLibs\Check\PhpVersion::checkPHPVersion('8.1')) { + $this->assertIsObject( + $execute_result + ); + // also check that this is correct instance type + $this->assertInstanceOf( + 'PgSql\Result', + $execute_result + ); + // if this is an select use dbFetchArray to get data and test + } else { + $this->assertIsResource( + $execute_result + ); + } + } else { + $this->assertEquals( + $expected_execute, + $execute_result + ); + } + // error/warning check + $this->assertEquals( + $warning_execute, + $last_warning, + ); + $this->assertEquals( + $error_execute, + $last_error, + ); + // now check test result if expected return is result + if ( + $expected_execute == 'result' && + !empty($expected_data_query) + ) { + // $expected_data_query + // $expected_data + $rows = $db->dbReturnArray($expected_data_query); + $this->assertEquals( + $expected_data, + $rows + ); + } + if ( + $expected_execute == 'result' && + $execute_result !== false && + empty($expected_data_query) && + count($expected_data) + ) { + // compare previously read data to compare data + $compare_data = []; + // read in the query data + while (is_array($row = $db->dbFetchArray($execute_result, true))) { + $compare_data[] = $row; + } + $this->assertEquals( + $expected_data, + $compare_data + ); + } // reset all data $db->dbExec("TRUNCATE table_with_primary_key"); @@ -2097,10 +2346,441 @@ final class CoreLibsDBIOTest extends TestCase $db->dbClose(); } - // - db execution tests - // dbExecAsync, dbCheckAsync - // - encoding conversion on read + // - schema set/get tests + // dbGetSchema, dbSetSchema + + /** + * Undocumented function + * + * @return array + */ + public function schemaProvider(): array + { + // 0: db connection + // 1: schema to set + // 2: set result + // 3: set error + // 4: get result flagged + // 5: get result DB + return [ + 'schema get check only' => [ + 'valid', + null, + true, + '', + 'public', + 'public', + ], + 'new schema set' => [ + 'valid', + 'public', + true, + '', + 'public', + 'public', + ], + 'no schema set, set new schema' => [ + 'valid_no_schema', + 'public', + true, + '', + 'public', + 'public', + ], + 'try to set empty schema' => [ + 'valid', + '', + false, + '70', + 'public', + 'public' + ], + // invalid schema (does not throw error) + 'try to set empty schema' => [ + 'valid', + 'invalid', + false, + '71', + 'public', + 'public' + ], + ]; + } + + /** + * Undocumented function + * + * @covers ::dbSetSchema + * @covers ::dbGetSchema + * @dataProvider schemaProvider + * @testdox set schema $schema on $connection with $expected_set (error $error_set) and get $expected_get_var/$expected_get_db [$_dataName] + * + * @param string $connection + * @param string|null $schema + * @param boolean $expected_set + * @param string $error_set + * @param string $expected_get_var + * @param string $expected_get_db + * @return void + */ + public function testDbSchema( + string $connection, + ?string $schema, + bool $expected_set, + string $error_set, + string $expected_get_var, + string $expected_get_db + ): void { + // self::$log->setLogLevelAll('debug', true); + // self::$log->setLogLevelAll('print', true); + $db = new \CoreLibs\DB\IO( + self::$db_config[$connection], + self::$log + ); + + // schema is not null, we do set testing + if ($schema !== null) { + $result_set = $db->dbSetSchema($schema); + $last_error = $db->dbGetLastError(); + $this->assertEquals( + $expected_set, + $result_set + ); + // error/warning check + $this->assertEquals( + $error_set, + $last_error, + ); + } + + // get current set from db + $result_get_var = $db->dbGetSchema(true); + $this->assertEquals( + $expected_get_var, + $result_get_var + ); + $result_get_db = $db->dbGetSchema(); + $this->assertEquals( + $expected_get_db, + $result_get_db + ); + + // close connection + $db->dbClose(); + } + + // - check error and warning handling + // dbGetCombinedErrorHistory, dbGetLastError, dbGetLastWarning + + /** + * Undocumented function + * + * @return array + */ + public function errorHandlingProvider(): array + { + // 0: some error call + // 1: type (error/warning) + // 2: error/warning code + // 3: return array matcher (excluding time) + return [ + 'trigger error' => [ + 0, + 'error', + '51', + [ + 'timestamp' => "/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{1,}/", + 'level' => 'error', + 'id' => '51', + 'error' => 'Max query call needs to be set to at least 1', + 'source' => 'main::run::run::run::run::run::run::runBare::runTest::testDbErrorHandling::dbSetMaxQueryCall', + 'pg_error' => '', + 'msg' => '', + ] + ], + 'trigger warning' => [ + -1, + 'warning', + '50', + [] + ], + ]; + } + + /** + * Undocumented function + * + * @covers ::dbGetLastError + * @covers ::dbGetLastWarning + * @covers ::dbGetCombinedErrorHistory + * @dataProvider errorHandlingProvider + * @testdox error $call_value for type $type with $error_id [$_dataName] + * + * @param integer $call_value + * @param string $type + * @param string $error_id + * @param array $error_history + * @return void + */ + public function testDbErrorHandling( + int $call_value, + string $type, + string $error_id, + array $expected_history + ): void { + // self::$log->setLogLevelAll('debug', true); + // self::$log->setLogLevelAll('print', true); + $db = new \CoreLibs\DB\IO( + self::$db_config['valid'], + self::$log + ); + + // trigger the error call + $db->dbSetMaxQueryCall($call_value); + if ($type == 'error') { + $last_error = $db->dbGetLastError(); + } else { + $last_error = $db->dbGetLastWarning(); + } + $this->assertEquals( + $error_id, + $last_error + ); + + $error_history = $db->dbGetCombinedErrorHistory(); + // pop first error off + $first_error_element = array_shift($error_history); + // get first row element + // comarep all, except timestamp that is a regex + foreach ($expected_history as $key => $value) { + // check if starts with / because this is regex (timestamp) + if (strpos($value, "/") === 0) { + // this is regex + $this->assertMatchesRegularExpression( + $value, + $first_error_element[0][$key] + ); + } else { + // assert equal + $this->assertEquals( + $value, + $first_error_element[0][$key], + ); + } + } + + // close connection + $db->dbClose(); + } + + // - encoding settings (exclude encoding test, just set) + // dbGetEncoding, dbSetEncoding + + /** + * test encoding change list for dbSetEncoding + * + * @return array + */ + public function encodingProvider(): array + { + // 0: connection + // 1: set encoding + // 2: expected return from set + // 2: expected to get + // 3: error id + return [ + 'default set no encoding' => [ + 'valid', + '', + false, + // I expect that the default DB is set to UTF8 + 'UTF8', + '', + ], + 'set to Shift JIS' => [ + 'valid', + 'ShiftJIS', + true, + 'SJIS', + '', + ], + 'set to Invalid' => [ + 'valid', + 'Invalid', + false, + 'UTF8', + '81', + ], + 'set to empty' => [ + 'valid', + '', + false, + 'UTF8', + '80', + ] + ]; + } + + /** + * change DB encoding, only function set test, not test of encoding change + * TODO: add encoding changed test with DB insert + * + * @covers ::dbSetEncoding + * @covers ::dbGetEncoding + * @dataProvider encodingProvider + * @testdox Set encoding on $connection to $set_encoding expect $expected_set_flag and $expected_get_encoding [$_dataName] + * + * @param string $connection + * @param string $set_encoding + * @param boolean $expected_set_flag + * @param string $expected_get_encoding + * @return void + */ + public function testEncoding( + string $connection, + string $set_encoding, + bool $expected_set_flag, + string $expected_get_encoding + ): void { + // self::$log->setLogLevelAll('debug', true); + // self::$log->setLogLevelAll('print', true); + $db = new \CoreLibs\DB\IO( + self::$db_config[$connection], + self::$log + ); + $this->assertEquals( + $expected_set_flag, + // avoid bubbling up error + @$db->dbSetEncoding($set_encoding) + ); + $this->assertEquals( + $expected_get_encoding, + $db->dbGetEncoding() + ); + $db->dbClose(); + } + + // - encoding conversion on read and test encoding conversion on db connection // dbSetToEncoding, dbGetToEncoding + // [and test encoding transfer with both types] + // dbSetEncoding, dbGetEncoding + + /** + * Undocumented function + * + * @return array + */ + public function encodingConversionProvider(): array + { + // 0: connection + // 1: target encoding (or alias) + // 2: optional name for php for proper alias matching + // 3: text to check + return [ + 'convert from UTF8 to SJIS' => [ + 'valid', + 'SJIS', + null, + '日本語カタカナひらがな' + ], + // SHIFT_JIS_2004/SJIS-win + // EUC_JP/EUC-JP + // + ]; + } + + /** + * tests actually text conversion and not only just setting + * NOTE: database is always stored as UTF8 in our case so all + * tests check conversion FROM utf8 to a target. + * Also because only SJIS is of interest, only this one is tested + * https://www.postgresql.org/docs/current/multibyte.html#MULTIBYTE-CHARSET-SUPPORTED + * SHIFT_JIS_2004 + * SJIS (Mskanji, ShiftJIS, WIN932, Windows932) + * EUC_JP + * EUC_JIS_2004 + * + * @covers ::dbSetToEncoding + * @covers ::dbGetToEncoding + * @covers ::dbSetEncoding + * @covers ::dbGetEncoding + * @dataProvider encodingConversionProvider + * @testdox Check encoding on $connection with $encoding [$_dataName] + * + * @param string $connection + * @param string $encoding + * @param string|null $encoding_php + * @param string $text + * @return void + */ + public function testEncodingConversion( + string $connection, + string $encoding, + ?string $encoding_php, + string $text + ): void { + // self::$log->setLogLevelAll('debug', true); + // self::$log->setLogLevelAll('print', true); + $db = new \CoreLibs\DB\IO( + self::$db_config[$connection], + self::$log + ); + + // convert in php unless encoding is the smae + if (strtolower($encoding) != 'utf8') { + $encoded = mb_convert_encoding($text, $encoding_php ?? $encoding, 'UTF-8'); + } else { + $encoded = $text; + } + + // insert data + $insert_query = "INSERT INTO table_with_primary_key (row_varchar, uid) VALUES " + . "(" . $db->dbEscapeLiteral($text) . ", 'A')"; + $db->dbExec($insert_query); + // for check read + $read_query = "SELECT row_varchar, uid FROM table_with_primary_key WHERE uid = 'A'"; + + // TEST 1 in class + // test to encoding (conversion with mb_convert_encoding) + $db->dbSetToEncoding($encoding); + $this->assertEquals( + $encoding, + $db->dbGetToEncoding() + ); + // read query, check that row_varchar matches + $row = $db->dbReturnRow($read_query, true); + $this->assertEquals( + $encoded, + $row['row_varchar'] + ); + // reset to encoding to empty + $db->dbSetToEncoding(''); + // and check + $this->assertEquals( + '', + $db->dbGetToEncoding() + ); + + // TEST 2 DB side + // same test with setting database encoding + // if connection encoding differts + if (strtolower($db->dbGetSetting('encoding')) != strtolower($encoding)) { + $db->dbSetEncoding($encoding); + } + // read from DB and check encoding + $row = $db->dbReturnRow($read_query, true); + $this->assertEquals( + $encoded, + $row['row_varchar'] + ); + + // reset all data + $db->dbExec("TRUNCATE table_with_primary_key"); + $db->dbExec("TRUNCATE table_without_primary_key"); + // close connection + $db->dbClose(); + } + // - data debug // dbDumpData // - internal read data (post exec) @@ -2112,8 +2792,172 @@ final class CoreLibsDBIOTest extends TestCase // - deprecated tests [no need to test perhaps] // getInsertReturn, getReturning, getInsertPK, getReturningExt, // getCursorExt, getNumRows - // - error handling - // dbGetCombinedErrorHistory, dbGetLastError, dbGetLastWarning + + // ASYNC at the end because it has 3s timeout + // - asynchronous executions + // dbExecAsync, dbCheckAsync + + /** + * Undocumented function + * + * @return array + */ + public function asyncProvider(): array + { + // 0: query + // 1: primary key + // 2: exepected exec return + // 3: warning + // 4: error + // 5: exepcted check return 1st + // 6: final result + // 7: warning + // 8: error + return [ + 'run simple async query' => [ + "SELECT pg_sleep(1)", + null, + // exec result + true, + '', + '', + // check first + true, + // check final + 'result', + '', + '' + ], + // send query failed (E40) + // result failed (E43) + // no query running (E42) + 'no async query running' => [ + '', + null, + // + false, + '', + '11', + // + false, + // + false, + '', + '42' + ] + ]; + } + + /** + * Undocumented function + * + * @covers ::dbExecAsync + * @covers ::dbCheckAsync + * @dataProvider asyncProvider + * @testdox async query $query with $expected_exec (warning $warning_exec/error $error_exec) and $expected_check/$expected_final (warning $warning_final/error $error_final) [$_dataName] + * + * @param string $query + * @param string|null $pk_name + * @param boolean $expected_exec + * @param string $warning_exec + * @param string $error_exec + * @param bool $expected_check + * @param bool|object|resource $expected_final + * @param string $warning_final + * @param string $error_final + * @return void + */ + public function testDbExecAsync( + string $query, + ?string $pk_name, + bool $expected_exec, + string $warning_exec, + string $error_exec, + bool $expected_check, + $expected_final, + string $warning_final, + string $error_final + ): void { + // self::$log->setLogLevelAll('debug', true); + // self::$log->setLogLevelAll('print', true); + $db = new \CoreLibs\DB\IO( + self::$db_config['valid'], + self::$log + ); + + // exec the query + $result_exec = $pk_name === null ? + $db->dbExecAsync($query) : + $db->dbExecAsync($query, $pk_name); + $last_warning = $db->dbGetLastWarning(); + $last_error = $db->dbGetLastError(); + $this->assertEquals( + $expected_exec, + $result_exec + ); + // error/warning check + $this->assertEquals( + $warning_exec, + $last_warning, + ); + $this->assertEquals( + $error_exec, + $last_error, + ); + + $run = 1; + // first loop check + while (($result_check = $db->dbCheckAsync()) === true) { + if ($run == 1) { + $this->assertEquals( + $expected_check, + $result_check + ); + } + $run++; + } + $last_warning = $db->dbGetLastWarning(); + $last_error = $db->dbGetLastError(); + // check after final + if ($expected_final == 'result') { + // post end check + if (\CoreLibs\Check\PhpVersion::checkPHPVersion('8.1')) { + $this->assertIsObject( + $result_check + ); + // also check that this is correct instance type + $this->assertInstanceOf( + 'PgSql\Result', + $result_check + ); + } else { + $this->assertIsResource( + $result_check + ); + } + } else { + // else compar check + $this->assertEquals( + $expected_final, + $result_check + ); + } + // error/warning check + $this->assertEquals( + $warning_final, + $last_warning, + ); + $this->assertEquals( + $error_final, + $last_error, + ); + + // reset all data + $db->dbExec("TRUNCATE table_with_primary_key"); + $db->dbExec("TRUNCATE table_without_primary_key"); + // close connection + $db->dbClose(); + } } // __END__ diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php index 895f0901..370c702c 100644 --- a/www/admin/class_test.db.php +++ b/www/admin/class_test.db.php @@ -52,7 +52,8 @@ print "DBINFO: " . $db->dbInfo() . "
"; echo "DB_CONFIG_SET constant:
" . print_r(DB_CONFIG, true) . "

"; // DB client encoding -print "DB Client encoding: " . $db->dbGetEncoding() . "
"; +print "DB client encoding: " . $db->dbGetEncoding() . "
"; +print "DB search path: " . $db->dbGetSchema() . "
"; while (is_array($res = $db->dbReturn("SELECT * FROM max_test", DbIo::USE_CACHE, true))) { print "UUD/TIME: " . $res['uid'] . "/" . $res['time'] . "
"; @@ -304,13 +305,14 @@ dbShowTableMetaData # async test queries /* -$db->dbExecAsync("SELECT test FROM test_foo, (SELECT pg_sleep(10)) as sub WHERE test_foo_id IN (27, 50, 67, 44, 10)"); +$db->dbExecAsync( + "SELECT test FROM test_foo, (SELECT pg_sleep(10)) as sub " + . "WHERE test_foo_id IN (27, 50, 67, 44, 10)" +); echo "WAITING FOR ASYNC: "; $chars = ['|', '/', '-', '\\']; -while (($ret = $db->dbCheckAsync()) === true) -{ - if ((list($_, $char) = each($chars)) === FALSE) - { +while (($ret = $db->dbCheckAsync()) === true) { + if ((list($_, $char) = each($chars)) === FALSE) { reset($chars); list($_, $char) = each($chars); } @@ -320,15 +322,13 @@ while (($ret = $db->dbCheckAsync()) === true) } print "
END STATUS: " . $ret . "
"; // while ($res = $db->dbFetchArray($ret)) -while ($res = $db->dbFetchArray()) -{ +while ($res = $db->dbFetchArray()) { echo "RES: " . $res['test'] . "
"; } # test async insert $db->dbExecAsync("INSERT INTO test_foo (Test) VALUES ('ASYNC TEST " . time() . "')"); echo "WAITING FOR ASYNC INSERT: "; -while (($ret = $db->dbCheckAsync()) === true) -{ +while (($ret = $db->dbCheckAsync()) === true) { print " . "; sleep(1); flush(); diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php index 910176d4..91151bd8 100644 --- a/www/lib/CoreLibs/DB/IO.php +++ b/www/lib/CoreLibs/DB/IO.php @@ -828,7 +828,7 @@ class IO // only do if array, else pass through row (can be false) if ( !is_array($row) || - empty($this->to_encoding) || empty($this->db_encoding) + empty($this->to_encoding)// || empty($this->db_encoding) ) { return $row; } @@ -841,7 +841,11 @@ class IO $from_encoding != $this->to_encoding && $from_encoding != 'ASCII' ) { - $row[$key] = mb_convert_encoding($value, $this->to_encoding, $from_encoding); + $row[$key] = mb_convert_encoding( + $value, + $this->to_encoding, + $from_encoding + ); } } return $row; @@ -1216,6 +1220,9 @@ class IO public function dbClose(): void { if ($this->dbh) { + // reset any client encodings set + $this->dbResetEncoding(); + // calls db close $this->db_functions->__dbClose(); $this->dbh = null; $this->db_connection_closed = true; @@ -2365,6 +2372,15 @@ class IO } } + /** + * Returns the current async running query hash + * @return string Current async running query hash + */ + public function dbGetAsyncRunning(): string + { + return $this->async_running; + } + // *************************** // COMPLEX WRITE WITH CONFIG ARRAYS // *************************** @@ -2603,6 +2619,7 @@ class IO */ public function dbSetMaxQueryCall(?int $max_calls = null): bool { + $this->__dbErrorReset(); // if null then reset to default if ($max_calls === null) { $max_calls = self::DEFAULT_MAX_QUERY_CALL; @@ -2640,25 +2657,29 @@ class IO */ public function dbSetSchema(string $db_schema) { + $this->__dbErrorReset(); if (empty($db_schema)) { $this->__dbError(70); return false; } - // check if schema exists - $q = "SELECT EXISTS(" - . "SELECT 1 FROM information_schema.schemata " - . "WHERE schema_name = " . $this->dbEscapeLiteral($db_schema) - . ")"; - $row = $this->dbReturnRow($q); - if (!$this->dbBoolean($row['exists'])) { - $this->__dbError(71); - return false; + $status = false; + $set_value = $this->db_functions->__dbSetSchema($db_schema); + switch ($set_value) { + // no problem + case 0: + $this->db_schema = $db_schema; + $status = true; + break; + // cursor failed (1) or schema does not exists (2) + case 1: + case 2: + // setting schema failed (3) + case 3: + $this->__dbError(71); + $status = false; + break; } - // set new schema - $q = "SET search_path TO '" . $this->dbEscapeString($db_schema) . "'"; - $this->dbExec($q); - $this->db_schema = $db_schema; - return true; + return $status; } /** @@ -2673,11 +2694,7 @@ class IO if ($class_var === true) { return $this->db_schema; } - $search_path = $this->dbReturnRow('SHOW search_path'); - if (!is_array($search_path)) { - return ''; - } - return $search_path['search_path'] ?? ''; + return $this->db_functions->__dbGetSchema(); } /** @@ -2688,32 +2705,31 @@ class IO */ public function dbSetEncoding(string $db_encoding): bool { + $this->__dbErrorReset(); + // no encding, abort if (empty($db_encoding)) { $this->__dbError(80); return false; } - // check if ecnoding is valid first - // does not take into account aliases - // TODO lookup with alisaes so eg ShiftJIS does not get a false - // $q = "SELECT EXISTS(" - // . "SELECT pg_catalog.pg_encoding_to_char(conforencoding) " - // . "FROM pg_catalog.pg_conversion " - // . "WHERE pg_catalog.pg_encoding_to_char(conforencoding) = " - // . $this->dbEscapeLiteral($db_encoding) - // . ")"; - // $row = $this->dbReturnRow($q); - // if (!$this->dbBoolean($row['exists'])) { - // $this->__dbError(81); - // return false; - // } - $q = "SET client_encoding TO '" . $this->dbEscapeString($db_encoding) . "'"; - // abort on error - if ($this->dbExec($q) === false) { - $this->__dbError(81); - return false; + // set client encoding on database side + $status = false; + $set_value = $this->db_functions->__dbSetEncoding($db_encoding); + switch ($set_value) { + // no problem + case 0: + $this->db_encoding = $db_encoding; + $status = true; + break; + // 1 & 2 are for encoding not found + case 1: + case 2: + // 3 is set failed + case 3: + $this->__dbError(81); + $status = false; + break; } - $this->db_encoding = $db_encoding; - return true; + return $status; } /** @@ -2727,17 +2743,23 @@ class IO if ($class_var === true) { return $this->db_encoding; } - $client_encoding = $this->dbReturnRow('SHOW client_encoding'); - if (!is_array($client_encoding)) { - return ''; - } - return $client_encoding['client_encoding'] ?? ''; + return $this->db_functions->__dbGetEncoding(); + } + + /** + * Resets client encodig back to databse encoding + * @return void + */ + public function dbResetEncoding(): void + { + $this->dbExec('RESET client_encoding'); } /** * Set the to_encoding var that will trigger on return of selected data * on the fly PHP encoding conversion * Alternative use dbSetEcnoding to trigger encoding change on the DB side + * Set to empty string to turn off * @param string $encoding PHP Valid encoding to set * @return string Current set encoding */ diff --git a/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php b/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php new file mode 100644 index 00000000..d4fdb7bf --- /dev/null +++ b/www/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php @@ -0,0 +1,297 @@ + $params + * @return object|resource|bool + */ + public function __dbQueryParams(string $query, array $params); + + /** + * Undocumented function + * + * @param string $query + * @return boolean + */ + public function __dbSendQuery(string $query): bool; + + /** + * Undocumented function + * + * @return object|resource|bool + */ + public function __dbGetResult(); + + /** + * Undocumented function + * + * @return void + */ + public function __dbClose(): void; + + /** + * Undocumented function + * + * @param string $name + * @param string $query + * @return object|resource|bool + */ + public function __dbPrepare(string $name, string $query); + + /** + * Undocumented function + * + * @param string $name + * @param array $data + * @return object|resource|bool + */ + public function __dbExecute(string $name, array $data); + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @return integer + */ + public function __dbNumRows($cursor): int; + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @return integer + */ + public function __dbNumFields($cursor): int; + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @param int $i + * @return string|bool + */ + public function __dbFieldName($cursor, int $i); + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @param int $result_type + * @return array|bool + */ + public function __dbFetchArray($cursor, int $result_type = PGSQL_BOTH); + + /** + * Undocumented function + * + * @param boolean $assoc_type + * @return integer + */ + public function __dbResultType(bool $assoc_type = true): int; + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @return array|bool + */ + public function __dbFetchAll($cursor); + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @return integer + */ + public function __dbAffectedRows($cursor): int; + + /** + * Undocumented function + * + * @param string $query + * @param string|null $pk_name + * @return string|integer|false + */ + public function __dbInsertId(string $query, ?string $pk_name); + + /** + * Undocumented function + * + * @param string $table + * @param string $schema + * @return string|bool + */ + public function __dbPrimaryKey(string $table, string $schema = ''); + + /** + * Undocumented function + * + * @param string $db_host + * @param string $db_user + * @param string $db_pass + * @param string $db_name + * @param integer $db_port + * @param string $db_ssl + * @return object|resource|bool + */ + public function __dbConnect( + string $db_host, + string $db_user, + string $db_pass, + string $db_name, + int $db_port, + string $db_ssl = 'allow' + ); + + /** + * Undocumented function + * + * @param object|resource|bool $cursor + * @return string + */ + public function __dbPrintError($cursor = false): string; + + /** + * Undocumented function + * + * @param string $table + * @param boolean $extended + * @return array|bool + */ + public function __dbMetaData(string $table, $extended = true); + + /** + * Undocumented function + * + * @param string|int|float|bool $string + * @return string + */ + public function __dbEscapeString($string): string; + + /** + * Undocumented function + * + * @param string|int|float|bool $string + * @return string + */ + public function __dbEscapeLiteral($string): string; + + /** + * Undocumented function + * + * @param string $string + * @return string + */ + public function __dbEscapeIdentifier(string $string): string; + + /** + * Undocumented function + * + * @param string $bytea + * @return string + */ + public function __dbEscapeBytea(string $bytea): string; + + /** + * Undocumented function + * + * @return boolean + */ + public function __dbConnectionBusy(): bool; + + /** + * Undocumented function + * + * @param integer $timeout_seconds + * @return boolean + */ + public function __dbConnectionBusySocketWait(int $timeout_seconds = 3): bool; + + /** + * Undocumented function + * + * @return string + */ + public function __dbVersion(): string; + + /** + * Undocumented function + * + * @param string $array_text + * @param integer $start + * @param integer|null $end + * @return array|null + */ + public function __dbArrayParse( + string $array_text, + int $start = 0, + ?int &$end = null + ): ?array; + + /** + * Undocumented function + * + * @param string $show_string + * @return string + */ + public function __dbShow(string $show_string): string; + + /** + * Undocumented function + * + * @param string $db_schema + * @return integer + */ + public function __dbSetSchema(string $db_schema): int; + + /** + * Undocumented function + * + * @return string + */ + public function __dbGetSchema(): string; + + /** + * Undocumented function + * + * @param string $db_encoding + * @return integer + */ + public function __dbSetEncoding(string $db_encoding): int; + + /** + * Undocumented function + * + * @return string + */ + public function __dbGetEncoding(): string; +} + +// __END__ diff --git a/www/lib/CoreLibs/DB/SQL/PgSQL.php b/www/lib/CoreLibs/DB/SQL/PgSQL.php index aa0db2b1..0d411827 100644 --- a/www/lib/CoreLibs/DB/SQL/PgSQL.php +++ b/www/lib/CoreLibs/DB/SQL/PgSQL.php @@ -51,7 +51,7 @@ namespace CoreLibs\DB\SQL; // as main system. Currently all @var sets are written as object /** @#phan-file-suppress PhanUndeclaredTypeProperty,PhanUndeclaredTypeParameter,PhanUndeclaredTypeReturnType */ -class PgSQL +class PgSQL implements Interface\SqlFunctions { /** @var string */ private $last_error_query; @@ -62,15 +62,15 @@ class PgSQL /** * class constructor, empty does nothing */ - public function __construct() - { - } + // public function __construct() + // { + // } /** * queries last error query and returns true or false if error was set * @return bool true/false if last error is set */ - public function __dbLastErrorQuery() + public function __dbLastErrorQuery(): bool { if ($this->last_error_query) { return true; @@ -210,7 +210,7 @@ class PgSQL /** * wrapper for pg_num_rows * @param object|resource|bool $cursor cursor PgSql\Result (former resource) - * @return int number of rows, -1 on error + * @return int number of rows, -1 on error */ public function __dbNumRows($cursor): int { @@ -223,7 +223,7 @@ class PgSQL /** * wrapper for pg_num_fields * @param object|resource|bool $cursor cursor PgSql\Result (former resource) - * @return int number for fields in result, -1 on error + * @return int number for fields in result, -1 on error */ public function __dbNumFields($cursor): int { @@ -235,11 +235,11 @@ class PgSQL /** * wrapper for pg_field_name - * @param object|resource|bool $cursor cursor PgSql\Result (former resource) - * @param int $i field position - * @return string|bool name or false on error + * @param object|resource|bool $cursor cursor PgSql\Result (former resource) + * @param int $i field position + * @return string|bool name or false on error */ - public function __dbFieldName($cursor, $i) + public function __dbFieldName($cursor, int $i) { if ($cursor === false || is_bool($cursor)) { return false; @@ -251,8 +251,8 @@ class PgSQL * wrapper for pg_fetch_array * if through/true false, use __dbResultType(true) * @param object|resource|bool $cursor cursor PgSql\Result (former resource) - * @param int $result_type result type as int number - * @return array|bool array result data or false on end/error + * @param int $result_type result type as int number + * @return array|bool array result data or false on end/error */ public function __dbFetchArray($cursor, int $result_type = PGSQL_BOTH) { @@ -279,8 +279,8 @@ class PgSQL /** * wrapper for pg_fetch_all - * @param object|resource|bool $cursor cursor PgSql\Result (former resource) - * @return array|bool data array or false for end/error + * @param object|resource|bool $cursor cursor PgSql\Result (former resource) + * @return array|bool data array or false for end/error */ public function __dbFetchAll($cursor) { @@ -293,7 +293,7 @@ class PgSQL /** * wrapper for pg_affected_rows * @param object|resource|bool $cursor cursor PgSql\Result (former resource) - * @return int affected rows, 0 for none, -1 for error + * @return int affected rows, 0 for none, -1 for error */ public function __dbAffectedRows($cursor): int { @@ -362,19 +362,11 @@ class PgSQL public function __dbPrimaryKey(string $table, string $schema = '') { if ($table) { - // check if schema set is different from schema given, only needed if schema is not empty + // check if schema set is different from schema given, + // only needed if schema is not empty $table_prefix = ''; if ($schema) { - $q = "SHOW search_path"; - $cursor = $this->__dbQuery($q); - if ($cursor === false) { - return false; - } - $__db_fetch_array = $this->__dbFetchArray($cursor); - if (!is_array($__db_fetch_array)) { - return false; - } - $search_path = $__db_fetch_array['search_path'] ?? ''; + $search_path = $this->__dbGetSchema(); if ($search_path != $schema) { $table_prefix = $schema . '.'; } @@ -415,12 +407,12 @@ class PgSQL /** * wrapper for pg_connect, writes out failure to screen if error occurs (hidden var) - * @param string $db_host host name - * @param string $db_user user name - * @param string $db_pass password - * @param string $db_name databse name - * @param integer $db_port port (int, 5432 is default) - * @param string $db_ssl SSL (allow is default) + * @param string $db_host host name + * @param string $db_user user name + * @param string $db_pass password + * @param string $db_name databse name + * @param integer $db_port port (int, 5432 is default) + * @param string $db_ssl SSL (allow is default) * @return object|resource|bool db handler PgSql\Connection or false on error */ public function __dbConnect( @@ -458,9 +450,6 @@ class PgSQL } // connect $this->dbh = pg_connect(join(' ', $connection_string)); - // if (!$this->dbh) { - // die(""); - // } return $this->dbh; } @@ -469,7 +458,7 @@ class PgSQL * html formatted string with error name * @param bool|object|resource $cursor cursor PgSql\Result (former resource) * or null - * @return string error string + * @return string error string */ public function __dbPrintError($cursor = false): string { @@ -508,7 +497,7 @@ class PgSQL /** * wrapper for pg_escape_string * @param string|int|float|bool $string any string/int/float/bool - * @return string excaped string + * @return string excaped string */ public function __dbEscapeString($string): string { @@ -523,7 +512,7 @@ class PgSQL * difference to escape string is that this one adds quotes ('') around * the string too * @param string|int|float|bool $string any string/int/float/bool - * @return string excaped string including quites + * @return string excaped string including quites */ public function __dbEscapeLiteral($string): string { @@ -554,7 +543,7 @@ class PgSQL * @param string $bytea bytea data stream * @return string escaped bytea string */ - public function __dbEscapeBytea($bytea): string + public function __dbEscapeBytea(string $bytea): string { if ($this->dbh === false || is_bool($this->dbh)) { return ''; @@ -564,7 +553,7 @@ class PgSQL /** * wrapper for pg_connection_busy - * @return bool true/false for busy connection + * @return bool True if connection is busy, False if not or no db connection at all */ public function __dbConnectionBusy(): bool { @@ -577,7 +566,8 @@ class PgSQL /** * Experimental wrapper with scoket timetout * @param integer $timeout_seconds Wait how many seconds on timeout - * @return boolean + * @return boolean True if connection is busy, or false on + * not busy or no db connection at all */ public function __dbConnectionBusySocketWait(int $timeout_seconds = 3): bool { @@ -619,10 +609,10 @@ class PgSQL * This is a fallback for old PostgreSQL versions * postgresql array to php array * https://stackoverflow.com/a/27964420 - * @param string $array_text Array text from PostgreSQL - * @param int $start Start string position - * @param int|null $end End string position from recursive call - * @return null|array PHP type array + * @param string $array_text Array text from PostgreSQL + * @param int $start Start string position + * @param int|null $end End string position from recursive call + * @return array|null PHP type array */ public function __dbArrayParse( string $array_text, @@ -673,6 +663,110 @@ class PgSQL return $return; } + + /** + * wrapper for any SHOW data blocks + * eg search_path or client_encoding + * @param string $show_string Part to show, if invalid will return empty string + * @return string Found part as is + */ + public function __dbShow(string $show_string): string + { + // get search path + $cursor = $this->__dbQuery("SHOW " . $this->__dbEscapeIdentifier($show_string)); + // abort on failure and return empty + if ($cursor === false) { + return ''; + } + // get result + $db_schema = $this->__dbFetchArray($cursor, PGSQL_ASSOC); + /** @phpstan-ignore-next-line Cannot access offset string on array|bool */ + return $db_schema[$show_string] ?? ''; + } + + /** + * Sets a new database schema/search_path + * Checks if schema exits and if not aborts with error code 2 + * @param string $db_schema Schema to set + * @return int Returns 0 if no error + * 1 for check query failed + * 2 for schema not found in database + */ + public function __dbSetSchema(string $db_schema): int + { + // check if schema actually exists + $query = "SELECT EXISTS(" + . "SELECT 1 FROM information_schema.schemata " + . "WHERE schema_name = " . $this->__dbEscapeLiteral($db_schema) + . ")"; + $cursor = $this->__dbQuery($query); + // abort if execution fails + if ($cursor === false) { + return 1; + } + // check if schema does not exists + $row = $this->__dbFetchArray($cursor, PGSQL_ASSOC); + /** @phpstan-ignore-next-line */ + if (empty($row['exists']) || $row['exists'] == 'f') { + return 2; + } + $query = "SET search_path TO " . $this->__dbEscapeLiteral($db_schema); + $this->__dbQuery($query); + return 0; + } + + /** + * Returns current set schema/search_path + * @return string Search Path as currently set in DB + */ + public function __dbGetSchema(): string + { + return $this->__dbShow('search_path'); + } + + /** + * set the client encoding + * Returns 0 on set ok, or 3 if the client encoding could not be set + * @param string $db_encoding + * @return int Returns 0 for no error + * [not used] 1 for check query failed + * [not used] 2 for invalid client encoding + * 3 client encoding could not be set + */ + public function __dbSetEncoding(string $db_encoding): int + { + // check if ecnoding is valid first + // does not take into account aliases + // TODO lookup with alisaes so eg ShiftJIS does not get a false + // $query = "SELECT EXISTS(" + // . "SELECT pg_catalog.pg_encoding_to_char(conforencoding) " + // . "FROM pg_catalog.pg_conversion " + // . "WHERE pg_catalog.pg_encoding_to_char(conforencoding) = " + // . $this->dbEscapeLiteral($db_encoding) + // . ")"; + // $cursor = $this->__dbQuery($query); + // if ($cursor === false) { + // return 1; + // } + // $row = $this->__dbFetchArray($cursor, PGSQL_ASSOC); + // if ($row['exists'] == 'f') { + // return 2; + // } + $query = "SET client_encoding TO " . $this->__dbEscapeLiteral($db_encoding); + if ($this->__dbQuery($query) === false) { + return 3; + } + return 0; + } + + /** + * Returns current set client encoding + * @return string Client encoding string, empty if not set + */ + public function __dbGetEncoding(): string + { + return $this->__dbShow('client_encoding'); + } } // __END__ diff --git a/www/vendor/composer/autoload_classmap.php b/www/vendor/composer/autoload_classmap.php index a3b194cb..639b2a49 100644 --- a/www/vendor/composer/autoload_classmap.php +++ b/www/vendor/composer/autoload_classmap.php @@ -30,6 +30,7 @@ return array( 'CoreLibs\\Create\\Uids' => $baseDir . '/lib/CoreLibs/Create/Uids.php', 'CoreLibs\\DB\\Extended\\ArrayIO' => $baseDir . '/lib/CoreLibs/DB/Extended/ArrayIO.php', 'CoreLibs\\DB\\IO' => $baseDir . '/lib/CoreLibs/DB/IO.php', + 'CoreLibs\\DB\\SQL\\Interface\\SqlFunctions' => $baseDir . '/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php', 'CoreLibs\\DB\\SQL\\PgSQL' => $baseDir . '/lib/CoreLibs/DB/SQL/PgSQL.php', 'CoreLibs\\Debug\\FileWriter' => $baseDir . '/lib/CoreLibs/Debug/FileWriter.php', 'CoreLibs\\Debug\\Logging' => $baseDir . '/lib/CoreLibs/Debug/Logging.php', diff --git a/www/vendor/composer/autoload_static.php b/www/vendor/composer/autoload_static.php index 8857d916..eea27b16 100644 --- a/www/vendor/composer/autoload_static.php +++ b/www/vendor/composer/autoload_static.php @@ -95,6 +95,7 @@ class ComposerStaticInit10fe8fe2ec4017b8644d2b64bcf398b9 'CoreLibs\\Create\\Uids' => __DIR__ . '/../..' . '/lib/CoreLibs/Create/Uids.php', 'CoreLibs\\DB\\Extended\\ArrayIO' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/Extended/ArrayIO.php', 'CoreLibs\\DB\\IO' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/IO.php', + 'CoreLibs\\DB\\SQL\\Interface\\SqlFunctions' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/SQL/Interface/SqlFunctions.php', 'CoreLibs\\DB\\SQL\\PgSQL' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/SQL/PgSQL.php', 'CoreLibs\\Debug\\FileWriter' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/FileWriter.php', 'CoreLibs\\Debug\\Logging' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Logging.php',