1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik;
use Exception;
use Piwik\Db\AdapterInterface;
/**
* Used for generating auto increment ids.
*
* Example:
*
* $sequence = new Sequence('my_sequence_name');
* $id = $sequence->getNextId();
* $db->insert('anytable', array('id' => $id, '...' => '...'));
*/
class Sequence
{
public const TABLE_NAME = 'sequence';
/**
* @var string
*/
private $name;
/**
* @var AdapterInterface
*/
private $db;
/**
* @var string
*/
private $table;
/**
* The name of the table or sequence you want to get an id for.
*
* @param string $name eg 'archive_numeric_2014_11'
* @param AdapterInterface $db You can optionally pass a DB adapter to make it work against another database.
* @param string|null $tablePrefix
*/
public function __construct($name, $db = null, $tablePrefix = null)
{
$this->name = $name;
$this->db = $db ?: Db::get();
$this->table = $this->getTableName($tablePrefix);
}
/**
* Creates / initializes a new sequence.
*
* @param int $initialValue
* @return int The actually used value to initialize the table.
*
* @throws \Exception in case a sequence having this name already exists.
*/
public function create($initialValue = 0)
{
$initialValue = (int) $initialValue;
$this->db->insert($this->table, array('name' => $this->name, 'value' => $initialValue));
return $initialValue;
}
/**
* Returns true if the sequence exist.
*
* @return bool
*/
public function exists()
{
$query = $this->db->query('SELECT * FROM `' . $this->table . '` WHERE name = ?', $this->name);
return $query->rowCount() > 0;
}
/**
* Get / allocate / reserve a new id for the current sequence. Important: Getting the next id will fail in case
* no such sequence exists. Make sure to create one if needed, see {@link create()}.
*
* @return int
* @throws Exception
*/
public function getNextId()
{
$sql = 'UPDATE ' . $this->table . ' SET value = LAST_INSERT_ID(value + 1) WHERE name = ?';
$result = $this->db->query($sql, array($this->name));
$rowCount = $result->rowCount();
if (1 !== $rowCount) {
throw new Exception("Sequence '" . $this->name . "' not found.");
}
$createdId = $this->db->lastInsertId();
return (int) $createdId;
}
/**
* Returns the current max id.
* @return ?int
* @internal
*/
public function getCurrentId()
{
$sql = 'SELECT value FROM `' . $this->table . '` WHERE name = ?';
$id = $this->db->fetchOne($sql, array($this->name));
if (!empty($id) || '0' === $id || 0 === $id) {
return (int) $id;
}
return null;
}
private function getTableName($prefix)
{
return ($prefix !== null) ? $prefix . self::TABLE_NAME : Common::prefixTable(self::TABLE_NAME);
}
}
|