From 6cdae12720d6f1c39610839b0382fb85a4937e87 Mon Sep 17 00:00:00 2001 From: doctrine Date: Wed, 10 May 2006 18:51:11 +0000 Subject: [PATCH] Transactional SELECT MAX(id) bug fixed --- classes/Session.class.php | 30 +++++++++++------------- classes/Session/Mysql.class.php | 41 ++++++++++++++++----------------- classes/Table.class.php | 11 +++++++++ tests/SessionTestCase.class.php | 16 +++++++++---- tests/run.php | 8 +++---- 5 files changed, 59 insertions(+), 47 deletions(-) diff --git a/classes/Session.class.php b/classes/Session.class.php index 321bbaab1..37e23e14c 100644 --- a/classes/Session.class.php +++ b/classes/Session.class.php @@ -428,8 +428,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab public function bulkInsert() { if(empty($this->insert)) return false; - - foreach($this->insert as $name => $inserts) { if( ! isset($inserts[0])) @@ -438,18 +436,12 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab $record = $inserts[0]; $table = $record->getTable(); $seq = $table->getSequenceName(); + $increment = false; - $id = null; $keys = $table->getPrimaryKeys(); + $id = null; + if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) { - - // record uses auto_increment column - - $sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName(); - $stmt = $this->dbh->query($sql); - $data = $stmt->fetch(PDO::FETCH_NUM); - $id = $data[0]; - $stmt->closeCursor(); $increment = true; } @@ -459,13 +451,18 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab // listen the onPreInsert event $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreInsert($record); - if($increment) { + + $this->insert($record); + + if($increment && $k == 0) { // record uses auto_increment column - $id++; + + $id = $table->getMaxIdentifier(); } + + $record->setID($id); + $id++; - - $this->insert($record,$id); // listen the onInsert event $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record); @@ -682,7 +679,7 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab * @param Doctrine_Record $record * @return boolean */ - private function insert(Doctrine_Record $record,$id = null) { + private function insert(Doctrine_Record $record) { $array = $record->getPrepared(); if(empty($array)) @@ -710,7 +707,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab $stmt->execute(array_values($array)); - $record->setID($id); return true; } /** diff --git a/classes/Session/Mysql.class.php b/classes/Session/Mysql.class.php index a6cb44ef9..e320ccd1c 100644 --- a/classes/Session/Mysql.class.php +++ b/classes/Session/Mysql.class.php @@ -68,9 +68,12 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common { /** * bulkInsert * inserts all the objects in the pending insert list into database + * TODO: THIS IS NOT WORKING YET AS THERE ARE BUGS IN COMPONENTS USING SELF-REFERENCENCING * * @return boolean */ + + /** public function bulkInsert() { if(empty($this->insert)) return false; @@ -82,21 +85,7 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common { $record = $inserts[0]; $table = $record->getTable(); $seq = $table->getSequenceName(); - $increment = false; - $id = null; $keys = $table->getPrimaryKeys(); - if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) { - - // record uses auto_increment column - - $sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName(); - $stmt = $this->getDBH()->query($sql); - $data = $stmt->fetch(PDO::FETCH_NUM); - $id = $data[0]; - $stmt->closeCursor(); - $increment = true; - } - $marks = array(); $params = array(); @@ -105,12 +94,6 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common { // listen the onPreInsert event $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreInsert($record); - - if($increment) { - // record uses auto_increment column - $id++; - } - $array = $record->getPrepared(); if(isset($this->validator)) { @@ -126,7 +109,6 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common { $marks[$key][] = "(".substr(str_repeat("?, ",count($array)),0,-2).")"; $params[$key] = array_merge($params[$key], array_values($array)); - $record->setID($id); // listen the onInsert event $record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record); @@ -141,11 +123,28 @@ class Doctrine_Session_Mysql extends Doctrine_Session_Common { $stmt->execute($params[$key]); } } + if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) { + + // record uses auto_increment column + + $sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$record->getTable()->getTableName(); + $stmt = $this->getDBH()->query($sql); + $data = $stmt->fetch(PDO::FETCH_NUM); + $id = $data[0]; + $stmt->closeCursor(); + + foreach(array_reverse($inserts) as $record) { + + $record->setID((int) $id); + $id--; + } + } } $this->insert = array(); return true; } + */ } ?> diff --git a/classes/Table.class.php b/classes/Table.class.php index 6d62324ac..0376fe914 100644 --- a/classes/Table.class.php +++ b/classes/Table.class.php @@ -638,6 +638,17 @@ class Doctrine_Table extends Doctrine_Configurable { public function setData(array $data) { $this->data = $data; } + /** + * returns the maximum primary key value + * + * @return integer + */ + final public function getMaxIdentifier() { + $sql = "SELECT MAX(".$this->getIdentifier().") FROM ".$this->getTableName(); + $stmt = $this->session->getDBH()->query($sql); + $data = $stmt->fetch(PDO::FETCH_NUM); + return isset($data[0])?$data[0]:1; + } /** * @return boolean whether or not a newly created object is new or not */ diff --git a/tests/SessionTestCase.class.php b/tests/SessionTestCase.class.php index ea8ca9fa7..c409f3da5 100644 --- a/tests/SessionTestCase.class.php +++ b/tests/SessionTestCase.class.php @@ -6,6 +6,15 @@ class Doctrine_SessionTestCase extends Doctrine_UnitTestCase { //print_r($tree); } + public function testBulkInsert() { + $u1 = new User(); + $u1->name = "Jean Reno"; + $u1->save(); + + $id = $u1->getID(); + $u1->delete(); + + } public function testFlush() { @@ -35,16 +44,13 @@ class Doctrine_SessionTestCase extends Doctrine_UnitTestCase { $this->session->flush(); - $this->assertTrue(gettype($user->getID()) == "integer"); - - $this->assertTrue(gettype($user->email_id) == "integer"); $this->assertTrue(is_numeric($user->Phonenumber[0]->entity_id)); $this->assertEqual(count($user->Group), 2); - $user = $this->objTable->find(12); + $user = $this->objTable->find($user->getID()); - $this->assertEqual($user->getID(), 12); + $this->assertEqual($user->getID(), $user->getID()); $this->assertTrue(is_numeric($user->getID())); $this->assertTrue(is_numeric($user->email_id)); diff --git a/tests/run.php b/tests/run.php index 3a46cf591..bb5791817 100644 --- a/tests/run.php +++ b/tests/run.php @@ -8,7 +8,6 @@ require_once("EventListenerTestCase.class.php"); require_once("BatchIteratorTestCase.class.php"); require_once("CacheFileTestCase.class.php"); require_once("RecordTestCase.class.php"); -require_once("DQLParserTestCase.class.php"); require_once("AccessTestCase.class.php"); require_once("ValidatorTestCase.class.php"); require_once("CollectionTestCase.class.php"); @@ -28,13 +27,13 @@ $test = new GroupTest("Doctrine Framework Unit Tests"); -$test->addTestCase(new Doctrine_RecordTestCase()); -$test->addTestCase(new Doctrine_TableTestCase()); $test->addTestCase(new Doctrine_SessionTestCase()); -//$test->addTestCase(new Doctrine_DQL_ParserTestCase()); +$test->addTestCase(new Doctrine_RecordTestCase()); + +$test->addTestCase(new Doctrine_TableTestCase()); $test->addTestCase(new Doctrine_ValidatorTestCase()); @@ -55,6 +54,7 @@ $test->addTestCase(new Doctrine_Collection_OffsetTestCase()); $test->addTestCase(new Sensei_UnitTestCase()); $test->addTestCase(new Doctrine_QueryTestCase()); + //$test->addTestCase(new Doctrine_Cache_FileTestCase()); //$test->addTestCase(new Doctrine_Cache_SqliteTestCase());