diff --git a/4dev/tests/CoreLibsDBIOTest.php b/4dev/tests/CoreLibsDBIOTest.php
index 1f74c0f6..4f843e73 100644
--- a/4dev/tests/CoreLibsDBIOTest.php
+++ b/4dev/tests/CoreLibsDBIOTest.php
@@ -2770,7 +2770,7 @@ final class CoreLibsDBIOTest extends TestCase
}
// - prepared query execute
- // dbPrepare, dbExecute, dbFetchArray
+ // dbPrepare, dbExecute, dbFetchArray, dbGetPrepareCursorValue
/**
* Undocumented function
@@ -2795,6 +2795,7 @@ final class CoreLibsDBIOTest extends TestCase
// 11: read query (if insert/update)
// 11: execute data to check (array)
// 12: insert data
+ // 13: prepated cursor array data match values
return [
// insert
'prepare query insert' => [
@@ -2818,6 +2819,14 @@ final class CoreLibsDBIOTest extends TestCase
],
// insert data (for select)
'',
+ // get prepared data
+ [
+ 'pk_name' => 'table_with_primary_key_id',
+ 'count' => 2,
+ 'query' => 'INSERT INTO table_with_primary_key (row_int, uid) '
+ . 'VALUES ($1, $2) RETURNING table_with_primary_key_id',
+ 'returning_id' => true,
+ ],
],
// update
'prepare query update' => [
@@ -2844,6 +2853,14 @@ final class CoreLibsDBIOTest extends TestCase
//
"INSERT INTO table_with_primary_key (row_int, uid) VALUES "
. "(111, 'TEST A')",
+ //
+ [
+ 'pk_name' => '',
+ 'count' => 3,
+ 'query' => 'UPDATE table_with_primary_key SET row_int = $1, '
+ . 'row_varchar = $2 WHERE uid = $3',
+ 'returning_id' => false,
+ ],
],
// select
'prepare select query' => [
@@ -2865,7 +2882,14 @@ final class CoreLibsDBIOTest extends TestCase
],
],
//
- $insert_query
+ $insert_query,
+ //
+ [
+ 'pk_name' => '',
+ 'count' => 1,
+ 'query' => 'SELECT row_int, uid FROM table_with_primary_key WHERE uid = $1',
+ 'returning_id' => false,
+ ],
],
// any query but with no parameters
'prepare select query no parameter' => [
@@ -2890,7 +2914,14 @@ final class CoreLibsDBIOTest extends TestCase
],
],
//
- $insert_query
+ $insert_query,
+ //
+ [
+ 'pk_name' => '',
+ 'count' => 0,
+ 'query' => 'SELECT row_int, uid FROM table_with_primary_key',
+ 'returning_id' => false,
+ ],
],
// no statement name (25)
'empty statement' => [
@@ -2907,6 +2938,13 @@ final class CoreLibsDBIOTest extends TestCase
[],
//
'',
+ //
+ [
+ 'pk_name' => '',
+ 'count' => 0,
+ 'query' => '',
+ 'returning_id' => false,
+ ],
],
// no query (prepare 11)
// no prepared cursor found with statement name (execute 24)
@@ -2924,6 +2962,13 @@ final class CoreLibsDBIOTest extends TestCase
[],
//
'',
+ //
+ [
+ 'pk_name' => '',
+ 'count' => 0,
+ 'query' => '',
+ 'returning_id' => false,
+ ],
],
// no db connection (prepare/execute 16)
// TODO no db connection test
@@ -2944,8 +2989,15 @@ final class CoreLibsDBIOTest extends TestCase
// no query but data for data only compare
'',
[],
- //,
- $insert_query
+ //
+ $insert_query,
+ //
+ [
+ 'pk_name' => '',
+ 'count' => 0,
+ 'query' => 'SELECT row_int, uid FROM table_with_primary_key',
+ 'returning_id' => false,
+ ],
],
// insert wrong data count compared to needed (execute 23)
'wrong parmeter count' => [
@@ -2962,7 +3014,15 @@ final class CoreLibsDBIOTest extends TestCase
'',
[],
//
- ''
+ '',
+ //
+ [
+ 'pk_name' => 'table_with_primary_key_id',
+ 'count' => 2,
+ 'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES '
+ . '($1, $2) RETURNING table_with_primary_key_id',
+ 'returning_id' => true,
+ ],
],
// execute does not return a result (22)
// TODO execute does not return a result
@@ -2975,6 +3035,7 @@ final class CoreLibsDBIOTest extends TestCase
* @covers ::dbPrepare
* @covers ::dbExecute
* @covers ::dbFetchArray
+ * @covers ::dbGetPrepareCursorValue
* @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]
*
@@ -2991,6 +3052,7 @@ final class CoreLibsDBIOTest extends TestCase
* @param string $expected_data_query
* @param array $expected_data
* @param string $insert_data
+ * @param array $prepare_cursor
* @return void
*/
public function testDbPrepared(
@@ -3006,7 +3068,8 @@ final class CoreLibsDBIOTest extends TestCase
string $error_execute,
string $expected_data_query,
array $expected_data,
- string $insert_data
+ string $insert_data,
+ array $prepare_cursor,
): void {
// self::$log->setLogLevelAll('debug', true);
// self::$log->setLogLevelAll('print', true);
@@ -3116,6 +3179,15 @@ final class CoreLibsDBIOTest extends TestCase
);
}
+ // check dbGetPrepareCursorValue
+ foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
+ $this->assertEquals(
+ $prepare_cursor[$key],
+ $db->dbGetPrepareCursorValue($stm_name, $key),
+ 'Prepared cursor: ' . $key . ': failed assertion'
+ );
+ }
+
// reset all data
$db->dbExec("TRUNCATE table_with_primary_key");
$db->dbExec("TRUNCATE table_without_primary_key");
@@ -3123,6 +3195,90 @@ final class CoreLibsDBIOTest extends TestCase
$db->dbClose();
}
+ // dedicated error checks for prepare cursor return
+
+ /**
+ * Undocumented function
+ *
+ * @return array
+ */
+ public function preparedProviderValue(): array
+ {
+ // 1: query (can be empty for do not set)
+ // 2: stm name
+ // 3: key
+ // 4: expected error return
+ return [
+ 'no error' => [
+ "SELECT row_int, uid FROM table_with_primary_key",
+ 'read',
+ 'pk_name',
+ ''
+ ],
+ 'statement name empty' => [
+ '',
+ '',
+ '',
+ '101',
+ ],
+ 'key empty' => [
+ '',
+ 'read',
+ '',
+ '102',
+ ],
+ 'key invalid' => [
+ '',
+ 'read',
+ 'invalid',
+ '102',
+ ],
+ 'statement name not found' => [
+ '',
+ 'invalid',
+ 'pk_name',
+ '103',
+ ],
+ ];
+ }
+
+ /**
+ * test return prepare cursor errors
+ *
+ * @covers ::dbGetPrepareCursorValue
+ * @dataProvider preparedProviderValue
+ * @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName]
+ *
+ * @param string $query
+ * @param string $stm_name
+ * @param string $key
+ * @param string $error_id
+ * @return void
+ */
+ public function testDbGetPrepareCursorValue(
+ string $query,
+ string $stm_name,
+ string $key,
+ $error_id
+ ): void {
+ $db = new \CoreLibs\DB\IO(
+ self::$db_config['valid'],
+ self::$log
+ );
+ if (!empty($query)) {
+ $db->dbPrepare($stm_name, $query);
+ $db->dbExecute($stm_name);
+ }
+ $db->dbGetPrepareCursorValue($stm_name, $key);
+ // match check error
+ $last_error = $db->dbGetLastError();
+ $this->assertEquals(
+ $error_id,
+ $last_error,
+ 'get prepare cursor value error check'
+ );
+ }
+
// - schema set/get tests
// dbGetSchema, dbSetSchema
diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php
index ee19d98a..1634f651 100644
--- a/www/admin/class_test.db.php
+++ b/www/admin/class_test.db.php
@@ -145,6 +145,11 @@ print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status)
print "PREPARE INSERT PREVIOUS INSERTED: "
. print_r($db->dbReturnRow("SELECT test_foo_id, test FROM test_foo "
. "WHERE test_foo_id = " . $db->dbGetInsertPK()), true) . "
";
+
+print "PREPARE CURSOR RETURN:
";
+foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
+ print "KEY: " . $key . ': ' . $db->dbGetPrepareCursorValue('ins_test_foo', $key) . "
";
+}
// returning test with multiple entries
// $status = $db->db_exec(
// "INSERT INTO test_foo (test) VALUES "
diff --git a/www/lib/CoreLibs/DB/IO.php b/www/lib/CoreLibs/DB/IO.php
index 540e4a92..b55b7259 100644
--- a/www/lib/CoreLibs/DB/IO.php
+++ b/www/lib/CoreLibs/DB/IO.php
@@ -452,6 +452,11 @@ class IO
'71' => 'Failed to set search path/schema',
'80' => 'Trying to set an empty encoding',
'81' => 'Failed to set client encoding',
+ // for prepared cursor return
+ '101' => 'Statement name empty for get prepare cursor',
+ '102' => 'Key empty for get prepare cursir',
+ '103' => 'No prepared cursor with this name',
+ '104' => 'No Key with this name in the prepared cursor array'
];
// load the core DB functions wrapper class
@@ -3066,6 +3071,60 @@ class IO
return $this->field_names;
}
+ /**
+ * Returns the value for given key in statement
+ * Will write error if statemen id does not exist
+ * or key is invalid
+ *
+ * @param string $stm_name The name of the stored statement
+ * @param string $key Key field name in prepared cursor array
+ * Allowed are: pk_name, count, query, returning_id
+ * @return null|string|int|bool Entry from each of the valid keys
+ * Will return false on error
+ * Not ethat returnin_id also can return false
+ * but will not set an error entry
+ */
+ public function dbGetPrepareCursorValue(string $stm_name, string $key)
+ {
+ // if no statement name
+ if (empty($stm_name)) {
+ $this->__dbError(
+ 101,
+ false,
+ 'No statement name given'
+ );
+ return false;
+ }
+ // if not a valid key
+ if (!in_array($key, ['pk_name', 'count', 'query', 'returning_id'])) {
+ $this->__dbError(
+ 102,
+ false,
+ 'Invalid key name'
+ );
+ return false;
+ }
+ // statement name not in prepared list
+ if (empty($this->prepare_cursor[$stm_name])) {
+ $this->__dbError(
+ 103,
+ false,
+ 'Statement name does not exist in prepare cursor array'
+ );
+ return false;
+ }
+ // key doest not exists, this will never hit as we filter out invalid ones
+ if (!isset($this->prepare_cursor[$stm_name][$key])) {
+ $this->__dbError(
+ 104,
+ false,
+ 'Key does not exist in prepare cursor array'
+ );
+ return false;
+ }
+ return $this->prepare_cursor[$stm_name][$key];
+ }
+
// ***************************
// ERROR AND WARNING DATA
// ***************************