Skip to content

Commit

Permalink
Add automatic generation of UUID primary keys.
Browse files Browse the repository at this point in the history
When saving new records we should have hooks to populate the primary
keys of entities in through the type system. This restores the auto-uuid
population, and allows user defined types to populate as well.

Add a new integration test to ensure saving/updating/deleting works as expected.
  • Loading branch information
markstory committed Nov 10, 2013
1 parent a6e39df commit 339ff2d
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 3 deletions.
22 changes: 19 additions & 3 deletions Cake/ORM/Table.php
Expand Up @@ -18,6 +18,7 @@


use Cake\Core\App; use Cake\Core\App;
use Cake\Database\Schema\Table as Schema; use Cake\Database\Schema\Table as Schema;
use Cake\Database\Type;
use Cake\Event\Event; use Cake\Event\Event;
use Cake\Event\EventManager; use Cake\Event\EventManager;
use Cake\ORM\Association\BelongsTo; use Cake\ORM\Association\BelongsTo;
Expand Down Expand Up @@ -865,15 +866,30 @@ protected function _processSave($entity, $options) {
*/ */
protected function _insert($entity, $data) { protected function _insert($entity, $data) {
$query = $this->_buildQuery(); $query = $this->_buildQuery();

$id = null;
$primary = $this->primaryKey();
if ($primary) {
$typeName = $this->schema()->columnType($primary);
$type = Type::build($typeName);
$id = $type->newId();
}
if ($id !== null) {
$data[$primary] = $id;
}

$statement = $query->insert($this->table(), array_keys($data)) $statement = $query->insert($this->table(), array_keys($data))
->values($data) ->values($data)
->executeStatement(); ->executeStatement();


$success = false; $success = false;
if ($statement->rowCount() > 0) { if ($statement->rowCount() > 0) {
$primary = $this->primaryKey(); if (!isset($data[$primary])) {
$id = $statement->lastInsertId($this->table(), $primary); $id = $statement->lastInsertId($this->table(), $primary);
$entity->set($primary, $id); }
if ($id !== null) {
$entity->set($primary, $id);
}
$entity->clean(); $entity->clean();
$success = $entity; $success = $entity;
} }
Expand Down
116 changes: 116 additions & 0 deletions Cake/Test/TestCase/ORM/TableUuidTest.php
@@ -0,0 +1,116 @@
<?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\ORM;

use Cake\Core\Configure;
use Cake\Database\ConnectionManager;
use Cake\Database\Expression\QueryExpression;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\Utility\String;

/**
* Integration tests for Table class with uuid primary keys.
*
*/
class UuidTableTest extends \Cake\TestSuite\TestCase {

/**
* Fixtures
*
* @var array
*/
public $fixtures = [
'core.uuiditem', 'core.uuidportfolio'
];

/**
* setup
*
* @return void
*/
public function setUp() {
parent::setUp();
$this->connection = ConnectionManager::get('test');
Configure::write('App.namespace', 'TestApp');
}

/**
* teardown
*
* @return void
*/
public function tearDown() {
parent::tearDown();
TableRegistry::clear();
}

/**
* Test saving new records sets uuids
*
* @return void
*/
public function testSaveNew() {
$entity = new \Cake\ORM\Entity([
'name' => 'shiny new',
'published' => true,
]);
$table = TableRegistry::get('uuiditems');
$this->assertSame($entity, $table->save($entity));
$this->assertRegExp('/^[a-f0-9-]{36}$/', $entity->id, 'Should be 36 characters');

$row = $table->find('all')->where(['id' => $entity->id])->first();
$this->assertEquals($entity->toArray(), $row->toArray());
}

/**
* Test saving existing records works
*
* @return void
*/
public function testSaveUpdate() {
$id = '481fc6d0-b920-43e0-a40d-6d1740cf8569';
$entity = new \Cake\ORM\Entity([
'id' => $id,
'name' => 'shiny update',
'published' => true,
]);

$table = TableRegistry::get('uuiditems');
$this->assertSame($entity, $table->save($entity));
$this->assertEquals($id, $entity->id, 'Should be 36 characters');

$row = $table->find('all')->where(['id' => $entity->id])->first();
$this->assertEquals($entity->toArray(), $row->toArray());
}

/**
* Test delete with string pk.
*
* @return void
*/
public function testDelete() {
$id = '481fc6d0-b920-43e0-a40d-6d1740cf8569';
$table = TableRegistry::get('uuiditems');
$entity = $table->find('all')->where(['id' => $id])->first();

$this->assertTrue($table->delete($entity));
$query = $table->find('all')->where(['id' => $id]);
$this->assertCount(0, $query->execute(), 'No rows left');
}

}

0 comments on commit 339ff2d

Please sign in to comment.