Skip to content

Commit

Permalink
Refactoring lastInsertId. It never made sense to have the method in the
Browse files Browse the repository at this point in the history
connection object itself other than to mimic PDO.
This enables users to get the last insertion id directly from the insert
query statement, which is specially useful when using postgres as it will
return the full row inserted, thus avoiding any posibility for race
conditions and the hassle of having a map of sequences in the driver
itself
  • Loading branch information
lorenzo committed Oct 21, 2013
1 parent 74463fc commit 7937b34
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 14 deletions.
10 changes: 0 additions & 10 deletions Cake/Database/Connection.php
Expand Up @@ -470,16 +470,6 @@ public function quoteIdentifier($identifier) {
return $this->_driver->quoteIdentifier($identifier);
}

/**
* Returns last id generated for a table or sequence in database
*
* @param string $table table name or sequence to get last insert value from
* @return string|integer
*/
public function lastInsertId($table) {
return $this->_driver->lastInsertId($table);
}

/**
* Enables or disables query logging for this connection.
*
Expand Down
5 changes: 3 additions & 2 deletions Cake/Database/Driver.php
Expand Up @@ -164,10 +164,11 @@ public function schemaValue($value) {
* Returns last id generated for a table or sequence in database
*
* @param string $table table name or sequence to get last insert value from
* @param string column the name of the column representing the primary key
* @return string|integer
*/
public function lastInsertId($table = null) {
return $this->_connection->lastInsertId($table);
public function lastInsertId($table = null, $column = null) {
return $this->_connection->lastInsertId($table, $column);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions Cake/Database/Driver/PDODriverTrait.php
Expand Up @@ -126,9 +126,9 @@ public function quote($value, $type) {
* @param string $table table name or sequence to get last insert value from
* @return string|integer
*/
public function lastInsertId($table = null) {
public function lastInsertId($table = null, $column = null) {
$this->connect();
return $this->_connection->lastInsertId();
return $this->_connection->lastInsertId($table);
}

/**
Expand Down
14 changes: 14 additions & 0 deletions Cake/Database/Statement/StatementDecorator.php
Expand Up @@ -264,4 +264,18 @@ public function bind($params, $types) {
}
}

/**
* Returns the latest primary inserted using this statement
*
* @param string $table table name or sequence to get last insert value from
* @param string column the name of the column representing the primary key
* @return string
*/
public function lastInsertId($table = null, $column = null) {
if ($column && $row = $this->fetch('assoc')) {
return $row[$column];
}
return $this->_driver->lastInsertId($table, $column);
}

}
9 changes: 9 additions & 0 deletions Cake/Database/StatementInterface.php
Expand Up @@ -159,4 +159,13 @@ public function count();
*/
public function bind($params, $types);

/**
* Returns the latest primary inserted using this statement
*
* @param string $table table name or sequence to get last insert value from
* @param string column the name of the column representing the primary key
* @return string
*/
public function lastInsertId($table = null, $column = null);

}
63 changes: 63 additions & 0 deletions Cake/Test/TestCase/Database/Statement/StatementDecoratorTest.php
@@ -0,0 +1,63 @@
<?php
/**
* PHP Version 5.4
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\Database\Statement;

use Cake\Database\Statement\StatementDecorator;
use Cake\TestSuite\TestCase;
use \PDO;

/**
* Tests StatementDecorator class
*
*/
class StatemetDecoratorTest extends TestCase {

/**
* Tests that calling lastInsertId will proxy it to
* the driver's lastInsertId method
*
* @return void
*/
public function testLastInsertId() {
$statement = $this->getMock('\PDOStatement');
$driver = $this->getMock('\Cake\Database\Driver');
$statement = new StatementDecorator($statement, $driver);

$driver->expects($this->once())->method('lastInsertId')
->with('users')
->will($this->returnValue(2));
$this->assertEquals(2, $statement->lastInsertId('users'));
}

/**
* Tests that calling lastInsertId will get the
*
* @return void
*/
public function testLastInsertIdWithReturning() {
$internal = $this->getMock('\PDOStatement');
$driver = $this->getMock('\Cake\Database\Driver');
$statement = new StatementDecorator($internal, $driver);

$internal->expects($this->once())->method('fetch')
->with('assoc')
->will($this->returnValue(['id' => 2]));
$driver->expects($this->never())->method('lastInsertId');
$this->assertEquals(2, $statement->lastInsertId('users', 'id'));
}

}

0 comments on commit 7937b34

Please sign in to comment.