Skip to content

Commit

Permalink
zendframework#186 Generate sequence name for names up to 63 chars.
Browse files Browse the repository at this point in the history
  • Loading branch information
alextech committed Dec 20, 2016
1 parent 07b5e38 commit 98ede10
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 14 deletions.
4 changes: 1 addition & 3 deletions src/TableGateway/AbstractTableGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
*
* @property AdapterInterface $adapter
* @property int $lastInsertValue
* @property string $table
*/
abstract class AbstractTableGateway implements TableGatewayInterface
{
Expand Down Expand Up @@ -83,7 +82,6 @@ public function isInitialized()
* Initialize
*
* @throws Exception\RuntimeException
* @return null
*/
public function initialize()
{
Expand Down Expand Up @@ -122,7 +120,7 @@ public function initialize()
/**
* Get table name
*
* @return string
* @return string|array|TableIdentifier
*/
public function getTable()
{
Expand Down
33 changes: 31 additions & 2 deletions src/TableGateway/Feature/SequenceFeature.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Zend\Db\Sql\Insert;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\Adapter\Driver\StatementInterface;
use Zend\Db\Sql\TableIdentifier;

class SequenceFeature extends AbstractFeature
{
Expand All @@ -33,14 +34,42 @@ class SequenceFeature extends AbstractFeature

/**
* @param string $primaryKeyField
* @param string $sequenceName
* @param string|array|null $sequenceName
*/
public function __construct($primaryKeyField, $sequenceName)
public function __construct($primaryKeyField, $sequenceName = null)
{
$this->primaryKeyField = $primaryKeyField;
$this->sequenceName = $sequenceName;
}

/**
* @return string
*/
public function getSequenceName() {
if ($this->sequenceName !== null) {
return $this->sequenceName;
}

$platform = $this->tableGateway->getAdapter()->getPlatform();
$table = $this->tableGateway->getTable();

$sequenceSuffix = '_' . $this->primaryKeyField . '_seq';

if(is_string($table)) {
$this->sequenceName = $table . $sequenceSuffix;
} elseif(is_array($table)) {
// assuming key 0 is schema name
$table[1] .= $sequenceSuffix;
$this->sequenceName = $table;
} elseif($table instanceof TableIdentifier) {
$this->sequenceName = $table->hasSchema() ? [$table->getSchema(), $table->getTable().$sequenceSuffix] : $table->getTable().$sequenceSuffix;
}

$this->sequenceName = $platform->quoteIdentifierChain($this->sequenceName);

return $this->sequenceName;
}

/**
* @param Insert $insert
* @return Insert
Expand Down
65 changes: 56 additions & 9 deletions test/TableGateway/Feature/SequenceFeatureTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
namespace ZendTest\Db\TableGateway\Feature;

use PHPUnit_Framework_TestCase;
use Zend\Db\Adapter\Platform\Postgresql;
use Zend\Db\Sql\TableIdentifier;
use Zend\Db\TableGateway\Feature\SequenceFeature;
use ZendTest\Db\TestAsset\TrustingPostgresqlPlatform;

class SequenceFeatureTest extends PHPUnit_Framework_TestCase
{
/** @var SequenceFeature */
protected $feature = null;

/** @var \Zend\Db\TableGateway\TableGateway */
protected $tableGateway = null;

Expand All @@ -26,15 +26,51 @@ class SequenceFeatureTest extends PHPUnit_Framework_TestCase
/** @var string sequence name */
protected $sequenceName = 'table_sequence';

public function setup()
/**
* @dataProvider nextSequenceIdProvider
*/
public function testNextSequenceIdForNamedSequence($platformName, $statementSql)
{
$this->feature = new SequenceFeature($this->primaryKeyField, $this->sequenceName);
$feature = new SequenceFeature($this->primaryKeyField, $this->sequenceName);
$feature->setTableGateway($this->tableGateway);
$feature->nextSequenceId();
}

/**
* @dataProvider nextSequenceIdProvider
* @dataProvider tableIdentifierProvider
*/
public function testNextSequenceId($platformName, $statementSql)
public function testSequenceNameGenerated($tableIdentifier, $sequenceName)
{
$adapter = $this->getMock('Zend\Db\Adapter\Adapter', ['getPlatform', 'createStatement'], [], '', false);
$adapter->expects($this->any())
->method('getPlatform')
->will($this->returnValue(new TrustingPostgresqlPlatform()));

$this->tableGateway = $this->getMockForAbstractClass('Zend\Db\TableGateway\TableGateway', [$tableIdentifier, $adapter], '', true);

$sequence = new SequenceFeature('serial_column');
$sequence->setTableGateway($this->tableGateway);
$sequence->getSequenceName();
}

public function testSequenceNameQueriedWhenTooLong()
{

}

/**
* Sequences for SERIAL columns start with no name which eventually gets filled.
* Ensure null value is replaced with actual on first call
* so that repeated calls to getSequenceName() do not make extra database calls (for long name case)
*
* Also test do not try to generate when name is manually supplied in constructor.
*/
public function testCacheSequenceName()
{

}

public function testNextSequenceIdForSerialColumn($platformName, $statementSql)
{
$platform = $this->getMockForAbstractClass('Zend\Db\Adapter\Platform\PlatformInterface', ['getName']);
$platform->expects($this->any())
Expand Down Expand Up @@ -62,13 +98,24 @@ public function testNextSequenceId($platformName, $statementSql)
->method('createStatement')
->will($this->returnValue($statement));
$this->tableGateway = $this->getMockForAbstractClass('Zend\Db\TableGateway\TableGateway', ['table', $adapter], '', true);
$this->feature->setTableGateway($this->tableGateway);
$this->feature->nextSequenceId();

$feature = new SequenceFeature($this->primaryKeyField);
$feature->setTableGateway($this->tableGateway);
$feature->nextSequenceId();
}

public function nextSequenceIdProvider()
{
return [['PostgreSQL', 'SELECT NEXTVAL(\'"' . $this->sequenceName . '"\')'],
['Oracle', 'SELECT ' . $this->sequenceName . '.NEXTVAL as "nextval" FROM dual']];
}

public function tableIdentifierProvider()
{
return [
['table', 'table_serial_column_seq'],
[['schema', 'table'], '"schema"."table_serial_column_seq"'],
[new TableIdentifier('table', 'schema'), '"schema"."table_serial_column_seq"']
];
}
}
20 changes: 20 additions & 0 deletions test/TestAsset/TrustingPostgresqlPlatform.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Db\TestAsset;

use Zend\Db\Adapter\Platform\Postgresql;

class TrustingPostgresqlPlatform extends Postgresql
{
public function quoteValue($value) {
return $this->quoteTrustedValue($value);
}
}

0 comments on commit 98ede10

Please sign in to comment.