2008-08-31 22:27:16 +04:00
|
|
|
<?php
|
|
|
|
|
2009-01-22 22:38:10 +03:00
|
|
|
namespace Doctrine\ORM\Id;
|
|
|
|
|
2009-03-30 23:43:05 +04:00
|
|
|
use Doctrine\ORM\EntityManager;
|
|
|
|
|
2008-09-07 17:48:40 +04:00
|
|
|
/**
|
2010-03-05 19:35:00 +03:00
|
|
|
* Id generator that uses a single-row database table and a hi/lo algorithm.
|
2008-09-07 17:48:40 +04:00
|
|
|
*
|
|
|
|
* @since 2.0
|
2009-05-24 14:38:37 +04:00
|
|
|
* @todo Implementation
|
2008-09-07 17:48:40 +04:00
|
|
|
*/
|
2009-01-22 22:38:10 +03:00
|
|
|
class TableGenerator extends AbstractIdGenerator
|
2008-09-07 17:48:40 +04:00
|
|
|
{
|
2010-03-20 22:19:12 +03:00
|
|
|
private $_tableName;
|
|
|
|
private $_sequenceName;
|
|
|
|
private $_allocationSize;
|
|
|
|
private $_nextValue;
|
|
|
|
private $_maxValue;
|
|
|
|
|
|
|
|
public function __construct($tableName, $sequenceName = 'default', $allocationSize = 10)
|
|
|
|
{
|
|
|
|
$this->_tableName = $tableName;
|
|
|
|
$this->_sequenceName = $sequenceName;
|
|
|
|
$this->_allocationSize = $allocationSize;
|
|
|
|
}
|
|
|
|
|
2009-03-30 23:43:05 +04:00
|
|
|
public function generate(EntityManager $em, $entity)
|
2008-09-07 17:48:40 +04:00
|
|
|
{
|
2010-03-20 22:19:12 +03:00
|
|
|
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
|
|
|
|
// Allocate new values
|
|
|
|
$conn = $em->getConnection();
|
|
|
|
if ($conn->getTransactionNestingLevel() == 0) {
|
|
|
|
|
|
|
|
// use select for update
|
|
|
|
$sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
|
|
|
|
$currentLevel = $conn->fetchColumn($sql);
|
|
|
|
if ($currentLevel != null) {
|
|
|
|
$this->_nextValue = $currentLevel;
|
|
|
|
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
|
|
|
|
|
|
|
|
$updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql(
|
|
|
|
$this->_tableName, $this->_sequenceName, $this->_allocationSize
|
|
|
|
);
|
|
|
|
|
|
|
|
if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) {
|
|
|
|
// no affected rows, concurrency issue, throw exception
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// no current level returned, TableGenerator seems to be broken, throw exception
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// only table locks help here, implement this or throw exception?
|
|
|
|
// or do we want to work with table locks exclusively?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->_nextValue++;
|
2008-09-07 17:48:40 +04:00
|
|
|
}
|
2009-02-20 08:46:20 +03:00
|
|
|
}
|