1<?php 2/* 3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 * 15 * This software consists of voluntary contributions made by many individuals 16 * and is licensed under the MIT license. For more information, see 17 * <http://www.doctrine-project.org>. 18 */ 19 20namespace Doctrine\ORM\Id; 21 22use Doctrine\ORM\EntityManager; 23use Serializable; 24 25/** 26 * Represents an ID generator that uses a database sequence. 27 * 28 * @since 2.0 29 * @author Roman Borschel <roman@code-factory.org> 30 */ 31class SequenceGenerator extends AbstractIdGenerator implements Serializable 32{ 33 /** 34 * The allocation size of the sequence. 35 * 36 * @var int 37 */ 38 private $_allocationSize; 39 40 /** 41 * The name of the sequence. 42 * 43 * @var string 44 */ 45 private $_sequenceName; 46 47 /** 48 * @var int 49 */ 50 private $_nextValue = 0; 51 52 /** 53 * @var int|null 54 */ 55 private $_maxValue = null; 56 57 /** 58 * Initializes a new sequence generator. 59 * 60 * @param string $sequenceName The name of the sequence. 61 * @param integer $allocationSize The allocation size of the sequence. 62 */ 63 public function __construct($sequenceName, $allocationSize) 64 { 65 $this->_sequenceName = $sequenceName; 66 $this->_allocationSize = $allocationSize; 67 } 68 69 /** 70 * {@inheritDoc} 71 */ 72 public function generate(EntityManager $em, $entity) 73 { 74 if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) { 75 // Allocate new values 76 $conn = $em->getConnection(); 77 $sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName); 78 79 // Using `query` to force usage of the master server in MasterSlaveConnection 80 $this->_nextValue = (int) $conn->query($sql)->fetchColumn(); 81 $this->_maxValue = $this->_nextValue + $this->_allocationSize; 82 } 83 84 return $this->_nextValue++; 85 } 86 87 /** 88 * Gets the maximum value of the currently allocated bag of values. 89 * 90 * @return integer|null 91 */ 92 public function getCurrentMaxValue() 93 { 94 return $this->_maxValue; 95 } 96 97 /** 98 * Gets the next value that will be returned by generate(). 99 * 100 * @return integer 101 */ 102 public function getNextValue() 103 { 104 return $this->_nextValue; 105 } 106 107 /** 108 * @return string 109 */ 110 public function serialize() 111 { 112 return serialize( 113 [ 114 'allocationSize' => $this->_allocationSize, 115 'sequenceName' => $this->_sequenceName 116 ] 117 ); 118 } 119 120 /** 121 * @param string $serialized 122 * 123 * @return void 124 */ 125 public function unserialize($serialized) 126 { 127 $array = unserialize($serialized); 128 129 $this->_sequenceName = $array['sequenceName']; 130 $this->_allocationSize = $array['allocationSize']; 131 } 132} 133