diff --git a/src/Dao/AbstractDao.php b/src/Dao/AbstractDao.php index 5f3d2bcb..1dcd7523 100644 --- a/src/Dao/AbstractDao.php +++ b/src/Dao/AbstractDao.php @@ -131,9 +131,14 @@ abstract class AbstractDao implements ICrudDao, IBatchDao public function create(Entity $entity) { + $sequencerQuery = $this->pdo->from('sequencer')->where('tableName', $this->tableName); + $lastUsedId = intval(iterator_to_array($sequencerQuery)[0]['lastUsedId']); + $lastUsedId ++; + + $entity->setId($lastUsedId); $arrayEntity = $this->entityConverter->toArray($entity); $this->pdo->insertInto($this->tableName)->values($arrayEntity)->execute(); - $entity->setId(intval($this->pdo->lastInsertId())); + $this->pdo->update('sequencer')->set(['lastUsedId' => $lastUsedId])->where('tableName', $this->tableName)->execute(); return $entity; } diff --git a/src/Dao/EntityConverters/AbstractEntityConverter.php b/src/Dao/EntityConverters/AbstractEntityConverter.php index c3268109..b46b4340 100644 --- a/src/Dao/EntityConverters/AbstractEntityConverter.php +++ b/src/Dao/EntityConverters/AbstractEntityConverter.php @@ -1,6 +1,8 @@ toBasicArray($entity); + if ($entity->getId() !== null) + $array['id'] = $entity->getId(); + return $array; + } + protected abstract function toBasicEntity(array $array); + protected abstract function toBasicArray(Entity $entity); + protected function dbTimeToEntityTime($time) { if ($time === null) diff --git a/src/Dao/EntityConverters/CommentEntityConverter.php b/src/Dao/EntityConverters/CommentEntityConverter.php index b8855717..d841e424 100644 --- a/src/Dao/EntityConverters/CommentEntityConverter.php +++ b/src/Dao/EntityConverters/CommentEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Entity; class CommentEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'userId' => $entity->getUserId(), 'postId' => $entity->getPostId(), 'text' => $entity->getText(), diff --git a/src/Dao/EntityConverters/FavoriteEntityConverter.php b/src/Dao/EntityConverters/FavoriteEntityConverter.php index db50785a..73ddb72e 100644 --- a/src/Dao/EntityConverters/FavoriteEntityConverter.php +++ b/src/Dao/EntityConverters/FavoriteEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Favorite; class FavoriteEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'userId' => $entity->getUserId(), 'postId' => $entity->getPostId(), 'time' => $this->entityTimeToDbTime($entity->getTime()), diff --git a/src/Dao/EntityConverters/GlobalParamEntityConverter.php b/src/Dao/EntityConverters/GlobalParamEntityConverter.php index 56ea827d..0ad8f4bb 100644 --- a/src/Dao/EntityConverters/GlobalParamEntityConverter.php +++ b/src/Dao/EntityConverters/GlobalParamEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\GlobalParam; class GlobalParamEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'dataKey' => $entity->getKey(), 'dataValue' => $entity->getValue(), ]; diff --git a/src/Dao/EntityConverters/PostEntityConverter.php b/src/Dao/EntityConverters/PostEntityConverter.php index 897bdb45..df3b1901 100644 --- a/src/Dao/EntityConverters/PostEntityConverter.php +++ b/src/Dao/EntityConverters/PostEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Post; class PostEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'name' => $entity->getName(), 'userId' => $entity->getUserId(), 'uploadTime' => $this->entityTimeToDbTime($entity->getUploadTime()), diff --git a/src/Dao/EntityConverters/PostNoteEntityConverter.php b/src/Dao/EntityConverters/PostNoteEntityConverter.php index 0a8cfddd..627aba17 100644 --- a/src/Dao/EntityConverters/PostNoteEntityConverter.php +++ b/src/Dao/EntityConverters/PostNoteEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\PostNote; class PostNoteEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'postId' => $entity->getPostId(), 'x' => $entity->getLeft(), 'y' => $entity->getTop(), diff --git a/src/Dao/EntityConverters/ScoreEntityConverter.php b/src/Dao/EntityConverters/ScoreEntityConverter.php index 9b99f21d..6332fcda 100644 --- a/src/Dao/EntityConverters/ScoreEntityConverter.php +++ b/src/Dao/EntityConverters/ScoreEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Score; class ScoreEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'userId' => $entity->getUserId(), 'postId' => $entity->getPostId(), 'commentId' => $entity->getCommentId(), diff --git a/src/Dao/EntityConverters/SnapshotEntityConverter.php b/src/Dao/EntityConverters/SnapshotEntityConverter.php index 1b6f9794..970e86d7 100644 --- a/src/Dao/EntityConverters/SnapshotEntityConverter.php +++ b/src/Dao/EntityConverters/SnapshotEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Snapshot; class SnapshotEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'time' => $this->entityTimeToDbTime($entity->getTime()), 'type' => $entity->getType(), 'primaryKey' => $entity->getPrimaryKey(), diff --git a/src/Dao/EntityConverters/TagEntityConverter.php b/src/Dao/EntityConverters/TagEntityConverter.php index 28cabf85..1c6760b7 100644 --- a/src/Dao/EntityConverters/TagEntityConverter.php +++ b/src/Dao/EntityConverters/TagEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Tag; class TagEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'name' => $entity->getName(), 'creationTime' => $this->entityTimeToDbTime($entity->getCreationTime()), 'banned' => $entity->isBanned(), diff --git a/src/Dao/EntityConverters/TokenEntityConverter.php b/src/Dao/EntityConverters/TokenEntityConverter.php index 6d1105d3..5d80fcb6 100644 --- a/src/Dao/EntityConverters/TokenEntityConverter.php +++ b/src/Dao/EntityConverters/TokenEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\Token; class TokenEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'name' => $entity->getName(), 'purpose' => $entity->getPurpose(), 'additionalData' => $entity->getAdditionalData(), diff --git a/src/Dao/EntityConverters/UserEntityConverter.php b/src/Dao/EntityConverters/UserEntityConverter.php index b53ebb7d..4d502b26 100644 --- a/src/Dao/EntityConverters/UserEntityConverter.php +++ b/src/Dao/EntityConverters/UserEntityConverter.php @@ -5,11 +5,10 @@ use Szurubooru\Entities\User; class UserEntityConverter extends AbstractEntityConverter implements IEntityConverter { - public function toArray(Entity $entity) + public function toBasicArray(Entity $entity) { return [ - 'id' => $entity->getId(), 'name' => $entity->getName(), 'email' => $entity->getEmail(), 'emailUnconfirmed' => $entity->getEmailUnconfirmed(), diff --git a/src/DatabaseConnection.php b/src/DatabaseConnection.php index f6eb4952..2f84e57b 100644 --- a/src/DatabaseConnection.php +++ b/src/DatabaseConnection.php @@ -37,8 +37,12 @@ class DatabaseConnection $cwd = getcwd(); if ($this->config->getDataDirectory()) chdir($this->config->getDataDirectory()); - $this->pdo = new PDOEx($this->config->database->dsn, $this->config->database->user, - $this->config->database->password); + + $this->pdo = new PDOEx( + $this->config->database->dsn, + $this->config->database->user, + $this->config->database->password); + $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); chdir($cwd); } diff --git a/src/Upgrades/Upgrade30.php b/src/Upgrades/Upgrade30.php new file mode 100644 index 00000000..396302c2 --- /dev/null +++ b/src/Upgrades/Upgrade30.php @@ -0,0 +1,48 @@ +getPDO(); + + $pdo->exec(' + CREATE TABLE sequencer ( + tableName VARCHAR(32) NOT NULL, + lastUsedId INT(11) NOT NULL DEFAULT 0 + )'); + + $tables = [ + 'favorites', + 'tags', + 'comments', + 'globals', + 'postNotes', + 'posts', + 'scores', + 'snapshots', + 'tags', + 'tokens', + 'users']; + + foreach ($tables as $table) + { + $this->removeAutoIncrement($pdo, $table); + $this->createSequencer($pdo, $table); + } + } + + private function removeAutoIncrement($pdo, $table) + { + $pdo->exec('ALTER TABLE ' . $table . ' CHANGE id id INT(11) UNSIGNED NOT NULL'); + } + + private function createSequencer($pdo, $table) + { + $pdo->exec(sprintf(' + INSERT INTO sequencer (tableName, lastUsedId) + VALUES (\'%s\', IFNULL((SELECT MAX(id) FROM %s), 0))', $table, $table)); + } +} diff --git a/src/di.php b/src/di.php index 7e1fa66a..cff5a317 100644 --- a/src/di.php +++ b/src/di.php @@ -46,6 +46,7 @@ return [ $container->get(\Szurubooru\Upgrades\Upgrade27::class), $container->get(\Szurubooru\Upgrades\Upgrade28::class), $container->get(\Szurubooru\Upgrades\Upgrade29::class), + $container->get(\Szurubooru\Upgrades\Upgrade30::class), ]; }), diff --git a/tests/Dao/PostDaoTest.php b/tests/Dao/PostDaoTest.php index 51777f8c..3cc522b4 100644 --- a/tests/Dao/PostDaoTest.php +++ b/tests/Dao/PostDaoTest.php @@ -61,6 +61,9 @@ final class PostDaoTest extends AbstractDatabaseTestCase $post2 = self::getTestPost(); $postDao->save($post1); $postDao->save($post2); + $this->assertNotNull($post1->getId()); + $this->assertNotNull($post2->getId()); + $this->assertNotEquals($post1->getId(), $post2->getId()); $actual = $postDao->findAll(); diff --git a/tests/Services/TagServiceTest.php b/tests/Services/TagServiceTest.php index 32e6dff8..43b1c9c2 100644 --- a/tests/Services/TagServiceTest.php +++ b/tests/Services/TagServiceTest.php @@ -34,6 +34,7 @@ final class TagServiceTest extends AbstractDatabaseTestCase $pdo = $this->databaseConnection->getPDO(); $pdo->exec('INSERT INTO tags(id, name, creationTime) VALUES (1, \'test1\', \'2014-10-01 00:00:00\')'); $pdo->exec('INSERT INTO tags(id, name, creationTime) VALUES (2, \'test2\', \'2014-10-01 00:00:00\')'); + $pdo->exec('UPDATE sequencer SET lastUsedId = 2 WHERE tableName = \'tags\''); $tag1 = new Tag(); $tag1->setName('test1'); @@ -54,6 +55,7 @@ final class TagServiceTest extends AbstractDatabaseTestCase $pdo = $this->databaseConnection->getPDO(); $pdo->exec('INSERT INTO tags(id, name, creationTime) VALUES (1, \'test1\', \'2014-10-01 00:00:00\')'); $pdo->exec('INSERT INTO tags(id, name, creationTime) VALUES (2, \'test2\', \'2014-10-01 00:00:00\')'); + $pdo->exec('UPDATE sequencer SET lastUsedId = 2 WHERE tableName = \'tags\''); $tag1 = new Tag(); $tag1->setName('test1');