Second fix for returning with multiple entries in DB IO

- all data stored in array (size contrain needs to be checked)
- allows any returning data
- only named rows are returned (no numbers for column access)
- if multiple rows then insert_id is an array with the return data
- if single row the insert_id holds the PK, and insert_id_ext holds
extended data if exists
This commit is contained in:
Clemens Schwaighofer
2017-03-14 15:19:31 +09:00
parent 6810c030e8
commit d64e40ca2c
3 changed files with 56 additions and 17 deletions

View File

@@ -74,16 +74,16 @@
}
$status = $basic->db_exec("INSERT INTO foo (test) VALUES ('FOO TEST ".time()."') RETURNING test");
print "DIRECT INSERT STATUS: $status | PRIMARY KEY: ".$basic->insert_id."<br>";
print "DIRECT INSERT STATUS: $status | PRIMARY KEY: ".$basic->insert_id." | PRIMARY KEY EXT: ".print_r($basic->insert_id_ext, 1)."<br>";
print "DIRECT INSERT PREVIOUS INSERTED: ".print_r($basic->db_return_row("SELECT foo_id, test FROM foo WHERE foo_id = ".$basic->insert_id), 1)."<br>";
$basic->db_prepare("ins_foo", "INSERT INTO foo (test) VALUES ($1)");
$status = $basic->db_execute("ins_foo", array('BAR TEST '.time()));
print "PREPARE INSERT STATUS: $status | PRIMARY KEY: ".$basic->insert_id."<br>";
print "PREPARE INSERT STATUS: $status | PRIMARY KEY: ".$basic->insert_id." | PRIMARY KEY EXT: ".print_r($basic->insert_id_ext, 1)."<br>";
print "PREPARE INSERT PREVIOUS INSERTED: ".print_r($basic->db_return_row("SELECT foo_id, test FROM foo WHERE foo_id = ".$basic->insert_id), 1)."<br>";
// returning test with multiple entries
// $status = $basic->db_exec("INSERT INTO foo (test) values ('BAR 1 ".time()."'), ('BAR 2 ".time()."'), ('BAR 3 ".time()."') RETURNING foo_id");
$status = $basic->db_exec("INSERT INTO foo (test) values ('BAR 1 ".time()."'), ('BAR 2 ".time()."'), ('BAR 3 ".time()."')");
print "DIRECT MULTIPLE INSERT STATUS: $status | PRIMARY KEYS: ".print_r($basic->insert_id, 1)."<br>";
$status = $basic->db_exec("INSERT INTO foo (test) values ('BAR 1 ".time()."'), ('BAR 2 ".time()."'), ('BAR 3 ".time()."') RETURNING foo_id, test");
print "DIRECT MULTIPLE INSERT STATUS: $status | PRIMARY KEYS: ".print_r($basic->insert_id, 1)." | PRIMARY KEY EXT: ".print_r($basic->insert_id_ext, 1)."<br>";
# async test queries

View File

@@ -272,6 +272,7 @@
public $num_fields; // how many fields has the query
public $field_names; // array with the field names of the current query
public $insert_id; // last inserted ID
public $insert_id_ext; // extended insert ID (for data outside only primary key)
// other vars
private $nbsp = ''; // used by print_array recursion function
// error & warning id
@@ -668,11 +669,12 @@
}
elseif (preg_match("/ returning (.*)/i", $this->query, $matches) && $this->pk_name)
{
if (preg_match("/$this->pk_name/", $matches[1]))
// add the primary key if it is not in the returning set
if (!preg_match("/$this->pk_name/", $matches[1]))
{
$this->query .= " , ".$this->pk_name;
$this->returning_id = true;
}
$this->returning_id = true;
}
}
}
@@ -750,15 +752,33 @@
else
{
$this->insert_id = array ();
$this->insert_id_ext = array ();
// echo "** PREPARE RETURNING FOR CURSOR: ".$this->cursor."<br>";
// we have returning, now we need to check if we get one or many returned
// we'll need to loop this, if we have multiple insert_id returns
while ($_insert_id = $this->db_functions->_db_fetch_array($this->cursor))
while ($_insert_id = $this->db_functions->_db_fetch_array($this->cursor, PGSQL_ASSOC))
{
$this->insert_id[] = $_insert_id[$this->pk_name];
// echo "*** RETURNING: ".print_r($_insert_id, 1)."<br>";
$this->insert_id[] = $_insert_id;
}
// if we have only one, revert from arry to single
// if we have only one, revert from array to single
if (count($this->insert_id) == 1)
$this->insert_id = $this->insert_id[0];
{
// echo "* SINGLE DATA CONVERT: ".count($this->insert_id[0])." => ".array_key_exists($this->pk_name, $this->insert_id[0])."<br>";
// echo "* PK DIRECT: ".$this->insert_id[0][$this->pk_name]."<Br>";
// if this has only the pk_name, then only return this, else array of all data (but without the position)
// example if insert_id[0]['foo'] && insert_id[0]['bar'] it will become insert_id['foo'] & insert_id['bar']
// if only ['foo_id'] and it is the PK then the PK is directly written to the insert_id
if (count($this->insert_id[0]) > 1 || !array_key_exists($this->pk_name, $this->insert_id[0]))
{
$this->insert_id_ext = $this->insert_id[0];
$this->insert_id = $this->insert_id[0][$this->pk_name];
}
elseif ($this->insert_id[0][$this->pk_name])
{
$this->insert_id = $this->insert_id[0][$this->pk_name];
}
}
}
// this warning handling is only for pgsql
// we returned an array of PKs instread of a single one
@@ -1389,8 +1409,8 @@
if (!preg_match("/{$this->prepare_cursor[$stm_name]['pk_name']}/", $matches[1]))
{
$query .= " , ".$this->prepare_cursor[$stm_name]['pk_name'];
$this->prepare_cursor[$stm_name]['returning_id'] = true;
}
$this->prepare_cursor[$stm_name]['returning_id'] = true;
}
}
// search for $1, $2, in the query and push it into the control array
@@ -1467,13 +1487,28 @@ $this->debug('ExecuteData', 'ERROR in STM['.$stm_name.'|'.$this->prepare_cursor[
$this->insert_id = array ();
// we have returning, now we need to check if we get one or many returned
// we'll need to loop this, if we have multiple insert_id returns
while ($_insert_id = $this->db_functions->_db_fetch_array($this->cursor))
while ($_insert_id = $this->db_functions->_db_fetch_array($code, PGSQL_ASSOC))
{
$this->insert_id[] = $_insert_id[$this->prepare_cursor[$stm_name]['pk_name']];
$this->insert_id[] = $_insert_id;
}
// if we have only one, revert from arry to single
if (count($this->insert_id) == 1)
$this->insert_id = $this->insert_id[0];
{
// echo "+ SINGLE DATA CONVERT: ".count($this->insert_id[0])." => ".array_key_exists($this->prepare_cursor[$stm_name]['pk_name'], $this->insert_id[0])."<br>";
// echo "+ PK DIRECT: ".$this->insert_id[0][$this->prepare_cursor[$stm_name]['pk_name']]."<Br>";
// if this has only the pk_name, then only return this, else array of all data (but without the position)
// example if insert_id[0]['foo'] && insert_id[0]['bar'] it will become insert_id['foo'] & insert_id['bar']
// if only ['foo_id'] and it is the PK then the PK is directly written to the insert_id
if (count($this->insert_id[0]) > 1 || !array_key_exists($this->prepare_cursor[$stm_name]['pk_name'], $this->insert_id[0]))
{
$this->insert_id_ext = $this->insert_id[0];
$this->insert_id = $this->insert_id[0][$this->prepare_cursor[$stm_name]['pk_name']];
}
elseif ($this->insert_id[0][$this->pk_name])
{
$this->insert_id = $this->insert_id[0][$this->prepare_cursor[$stm_name]['pk_name']];
}
}
}
// this error handling is only for pgsql
if (is_array($this->insert_id))

View File

@@ -152,12 +152,16 @@
}
// METHOD: _db_fetch_array
// PARAMS: cursor
// PARAMS: cursor, opt result type
// RETURN: row
// DESC : wrapper for pg_fetch_array
public function _db_fetch_array($cursor)
public function _db_fetch_array($cursor, $result_type = '')
{
return pg_fetch_array($cursor);
// result type is passed on as is [should be checked]
if ($result_type)
return pg_fetch_array($cursor, NULL, $result_type);
else
return pg_fetch_array($cursor);
}
// METHOD: _db_fetch_all