[eluser]Black Buddha[/eluser]
Documenting this in the hopes it saves some other poor soul 3 hours of their life. Porting a MySQL-based application to Postgres, and in between figuring out how to do UUID and DATE_SUB in Postgres and replacing all NOW() calls with CURRENT_TIMESTAMP I ran into significant problems creating relationships between new objects. Turns out that the CI postgres driver is broken (in 1.7.1).
When an INSERT, UPDATE or DELETE occurs the driver saves the statement resource. In the postgres driver this is used by
affected_rows() to determine how many rows were affected. However, under certain circumstances the
insert_id() function executes a SQL statement. Unfortunately, IgnitedRecord calls
insert_id before
affected_rows(), changing the statement resource: this causes
affected_rows() to return 0 (because the SQL statement executed by
insert_id does not affect any rows). When this returns 0 the IgnitedRecord
save() function returns false, and All Sorts Of Bad Things Happen preventing constraints from being satisfied.
The answer turned out (after 3 hours of scuffling with
print_r() and
echo()) to be: save the result_id at the beginning of
insert_id() and restore it at the end if it changes. Replace the
insert_id() function in the
Quote:database/drivers/postgre/postgre_driver.php
file, and you should be golden.
Code:
function insert_id()
{
$old_result_id = $this->result_id;
$v = $this->_version();
$v = $v['server'];
$table = func_num_args() > 0 ? func_get_arg(0) : null;
$column = func_num_args() > 1 ? func_get_arg(1) : null;
if ($table == null && $v >= '8.1')
{
$sql='SELECT LASTVAL() as ins_id';
}
elseif ($table != null && $column != null && $v >= '8.0')
{
$sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
$query = $this->query($sql);
$row = $query->row();
$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
}
elseif ($table != null)
{
// seq_name passed in table parameter
$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
}
else
{
return pg_last_oid($this->result_id);
}
$query = $this->query($sql);
$row = $query->row();
$this->result_id = $old_result_id;
return $row->ins_id;
}