| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
  [2006-07-26 10:13 UTC] mim at serverconnect dot org
 Description:
------------
Using SDO 1.0.2
If I create a situation where I load some data from a Relational DB and the DB data gets changed outside of SDO in the meantime, I'd expect an attempt to write my modifications on that data to cause an SDO_DAS_Relational_Exception, but it doesn't. So I'm left thinking my data got written when it didn't.
Reproduce code:
---------------
/*
MySql statements:
CREATE DATABASE sdo_user;
USE sdo_user;
CREATE TABLE `Mbr` (
    `id` INTEGER auto_increment,
    `name` VARCHAR( 40 ) NULL,
    PRIMARY KEY ( `id` )
    ) COMMENT = 'Members';
CREATE TABLE `Profile` (
    `id` INTEGER auto_increment,
    `parent` VARCHAR( 40 ) NOT NULL,
    `address` VARCHAR( 100 ) NULL,
    PRIMARY KEY ( `id` )
    ) COMMENT = 'Contact address details';
INSERT INTO Mbr VALUES(NULL, "Jimmy");
*/
// Member table structure
$mbr = array(
    'name' => 'Mbr',
    'columns' => array('id', 'name'),
    'PK' => 'id'
    );
// Profile table structure
$profile = array (
    'name' => 'Profile',
    'columns' => array('id', 'parent', 'address'),
    'PK' => 'id',
    'FK' => array ('from' => 'parent', 'to' => 'Mbr')
    );
$table_lib = array($mbr, $profile);
// Table containment structure
$table_tree = array('parent' => 'Mbr', 'child' => 'Profile');
// Constants
define('PDO_DSN', 'mysql:host=localhost;dbname=sdo_user');
define('DATABASE_USER', 'mim');
define('DATABASE_PASSWORD', '????????');
// Get SDO/DAS
require 'SDO/DAS/Relational.php';
$dbh = new PDO(PDO_DSN, DATABASE_USER, DATABASE_PASSWORD);
$das = new SDO_DAS_Relational($table_lib, 'Mbr', array($table_tree));
$pdo_stmt = $dbh->prepare('select id, name from Mbr where id=?');
//ob_start(); // :BUG: dirty fix prevents two spaces appearing
$root = $das->executePreparedQuery($dbh, $pdo_stmt, array(2), array('Mbr.id', 'Mbr.name'));
//ob_end_clean();
$mbr = $root['Mbr'][0];
$mbr->name = 'Norbett';
// Now let's change the DB behind SDO's back
$result = $dbh->query('update Mbr set name="Silly Name" where id="2"');
echo "BugStart=#8280: Undefined variable: settings_as_array, The second argument should be either an array or an object\n";
$das->applyChanges($dbh, $root);
echo "BugEnd\n";
echo "Done\n";
Expected result:
----------------
An SDO_DAS_Relational_Exception thrown
Actual result:
--------------
(With DEBUG_BUILD_PLAN=true in Relational.php)
  BugStart=#8280: Undefined variable: settings_as_array, The second argument should be either an array or an object
===============================
Executing plan as follows:
executing the following SQL statement:
UPDATE Mbr SET name = ? WHERE id = ? AND name = ?;
using the following list of values:
   string(7) "Norbett"
   string(1) "2"
   string(5) "Jimmy"
BugEnd
Done
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             
             | 
    |||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 12:00:01 2025 UTC | 
I got some more time to look at this, and have come up with a bugfix suggestion that hopefully covers all the fault scenarios: DatabaseHelper.php: <?php public static function executeStatement($dbh,$stmt,$value_list) { if (SDO_DAS_Relational::DEBUG_EXECUTE_PLAN) { echo "executing the following SQL statement:\n" . $stmt . "\n"; echo "using the following list of values:\n"; foreach ($value_list as $value) { ob_start(); var_dump($value); $content = ob_get_contents(); ob_end_clean(); echo " $content"; } } // Detect all possible error scenarios whilst attempting the update (see PDO return values for details) $pdo_stmt = $dbh->prepare($stmt); $is_pdo_success = $pdo_stmt === false ? false : $pdo_stmt->execute($value_list); $rows_affected = $is_pdo_success === true ? $pdo_stmt->rowCount() : 0; $is_sdo_success = ($is_pdo_success === true and $rows_affected) > 0 ? true : false; if ($is_sdo_success === false) { $msg = "\nSDO/DAS/Relational.php::applyChanges encountered an error when attempting to execute $stmt"; if ($is_pdo_success === false) { // SQL statement encountered and SQL error $pdo_error_info = $dbh->errorInfo(); $msg .= "\nThe error information returned from PDO::errorInfo() was:"; $msg .= "\n SQLSTATE: " . $pdo_error_info[0]; $msg .= "\n Driver-specific error code: " . $pdo_error_info[1]; $msg .= "\n Driver-specific error message: " . $pdo_error_info[2]; } else { // SQL completed but affected 0 rows, and with no SQL error, under SDO, this becomes a concurrency fault $msg .= "\nPDO reported no rows affected by the SQL statement."; $msg .= "\nThis occurs when data retrieved and updated has been changed by another "; $msg .= "processs in the database in the meantime. An optimistic conurrency failure."; } $dbh->rollback(); $msg .= "\nAll changes have been rolled back."; throw new SDO_DAS_Relational_Exception($msg); } } ?>