PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Database » DB_DataObject » Bug #57

Auto Sequence problems with PostgreSql

Details

Submitted2003-10-02 19:30 UTC
Fromedvan at interativainternet dot com dot br
Assignedalan_k
StatusClosed
PackageDB_DataObject
PHP Version4.3.2
OSLinux Slackware 9.0
Roadmaps(Not assigned)

Comments

[2003-10-02 19:30 UTC] edvan at interativainternet dot com dot br

Description:
------------
The function insert() on DataObject.php arquive erroneous check for ignore_sequence_keys.

Reproduce code:
---------------
// big check for using sequences
if ( ($key = @$keys[0]) &&
($dbtype != 'mysql') &&
(@$options['ignore_sequence_keys'] != 'ALL') &&
(!is_array(@$options['ignore_sequence_keys']) ||
@!in_array($this->__table,$options['ignore_sequence_keys']))
)

Expected result:
----------------
This code checks whether to use the sequence when inserting data on a table. This check looks for table names inserted on ignore_sequence_keys label at the .ini file that configures the aplication. The expected result is that, it does not use Pear created sequence keys when exists a node whith the referred table name on the $options[ignore_sequencee_keys] array. But it does not work.

Actual result:
--------------
Even if I insert a table_name on the ignore_sequence_keys label on .ini arquive, the insert() function uses a sequence on this table. I seggest that this code be changed to the code above or something like that:
if ( ($key = @$keys[0]) &&
($dbtype != 'mysql') &&
(@$options['ignore_sequence_keys'] != 'ALL') &&
(is_array(@$options['ignore_sequence_keys']) &&
@in_array($this->__table,$options['ignore_sequence_keys']))
)

[2003-10-06 16:22 UTC] rodrigo dot rezende at magnetimarelli dot com dot br

function insert()
{
global $_DB_DATAOBJECT;
// connect will load the config!
$this->_connect();

$__DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$items = $this->table();
if (!$items) {
DB_DataObject::raiseError("insert:No table definition for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$options= &$_DB_DATAOBJECT['CONFIG'];

// turn the sequence keys into an array
if ((@$options['ignore_sequence_keys']) &&
(@$options['ignore_sequence_keys'] != 'ALL') &&
(!is_array($options['ignore_sequence_keys']))) {
$options['ignore_sequence_keys'] = explode(',', $options['ignore_sequence_keys']);
}

$datasaved = 1;
$leftq = '';
$rightq = '';
$key = false;
$keys = $this->keys();
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["phptype"];


if ( ($key = @$keys[0]) &&
($dbtype == 'pgsql') &&
(@$options['ignore_sequence_keys'] != 'ALL') &&
(!is_array(@$options['ignore_sequence_keys']) ||
@!in_array($this->__table,$options['ignore_sequence_keys'])) )
{
if (!($seq = @$options['sequence_'. $this->__table])) {

$dummy = explode('.',$this->__table);
$schema_name = $dummy[0];
$table_name = $dummy[1];

$sql_seq = "
SELECT
a.attname as attname, adef.adsrc as sequence
FROM
pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef adef
ON a.attrelid=adef.adrelid
AND a.attnum=adef.adnum
WHERE
a.atthasdef = 't' AND
a.attname = '$key' AND
a.attrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname='$table_name'
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE
nspname = '$schema_name'))
AND a.attnum > 0 AND NOT a.attisdropped
;
";
$r = $__DB->getRow($sql_seq,DB_FETCHMODE_ASSOC);
$attrname_seq = $r['attname'];
$sequence_name = explode('\'',$r['sequence']);
$sequence_name = (isset($sequence_name[1]))?$sequence_name[1]:'';
$seq = $sequence_name;
}
$this->$key = $__DB->nextId($seq);
}

foreach($items as $k => $v) {
if (!isset($this->$k) || $this->$k == '' || $this->$k === 'null') {
continue;
}

if ($leftq) {
$leftq .= ', ';
$rightq .= ', ';
}
$leftq .= "$k ";

if (strtolower($this->$k) === 'null') {
$rightq .= " NULL ";
continue;
}
if ($v & DB_DATAOBJECT_STR) {
$rightq .= $__DB->quote($this->$k) . " ";
continue;
}

if (is_numeric($this->$k)) {
$rightq .=" {$this->$k} ";
continue;
}
// at present we only cast to integers
// - V2 may store additional data about float/int
$rightq .= ' ' . intval($this->$k) . ' ';

}
if ($leftq) {
$r = $this->_query("INSERT INTO {$this->__table} ($leftq) VALUES ($rightq) ");
if (PEAR::isError($r)) {
DB_DataObject::raiseError($r);
return false;
}
if ($r < 1) {
DB_DataObject::raiseError('No Data Affected By insert',DB_DATAOBJECT_ERROR_NOAFFECTEDROWS);
return false;
}

if ($key &&
($items[$key] & DB_DATAOBJECT_INT) &&
($dbtype == 'mysql') &&
(@$options['ignore_sequence_keys'] != 'ALL') &&
(
!@$options['ignore_sequence_keys'] ||
(is_array(@$options['ignore_sequence_keys']) &&
in_array($this->__table,@$options['ignore_sequence_keys']))
)
)
{
$this->$key = mysql_insert_id($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->connection);
}

$this->_clear_cache();
if ($key) {
return $this->$key;
}
return true;
}
DB_DataObject::raiseError("insert: No Data specifed for query", DB_DATAOBJECT_ERROR_NODATA);
return false;
}

[2003-10-06 17:05 UTC] edvan at interativainternet dot com dot br

Ok folks! I have downloaded the newer version of DataObjects.php and it seems work fine. Thanks.