Added "created" snapshot operation

This commit is contained in:
Marcin Kurczewski 2014-11-09 17:04:04 +01:00
parent 9130b162b7
commit 6679afbb6b
13 changed files with 134 additions and 62 deletions

View file

@ -48,10 +48,14 @@ var reprValue = function(value) {
</td> </td>
<td class="difference"> <td class="difference">
<% if (historyEntry.operation == 1) { %> <% if (historyEntry.operation == 2) { %>
deleted deleted
<% } else { %>
<% if (historyEntry.operation == 0) { %>
added
<% } else { %> <% } else { %>
changed changed
<% } %>
<% if (historyEntry.dataDifference) { %> <% if (historyEntry.dataDifference) { %>
<ul><!-- <ul><!--

View file

@ -7,8 +7,9 @@ final class Snapshot extends Entity
const TYPE_POST = 0; const TYPE_POST = 0;
const TYPE_TAG = 1; const TYPE_TAG = 1;
const OPERATION_CHANGE = 0; const OPERATION_CREATION = 0;
const OPERATION_DELETE = 1; const OPERATION_CHANGE = 1;
const OPERATION_DELETE = 2;
const LAZY_LOADER_USER = 'user'; const LAZY_LOADER_USER = 'user';

View file

@ -0,0 +1,10 @@
<?php
namespace Szurubooru\Services;
use Szurubooru\Entities\Entity;
interface ISnapshotProvider
{
public function getCreationSnapshot(Entity $entity);
public function getChangeSnapshot(Entity $entity);
public function getDeleteSnapshot(Entity $entity);
}

View file

@ -46,13 +46,18 @@ class PostHistoryService
return $this->transactionManager->rollback($transactionFunc); return $this->transactionManager->rollback($transactionFunc);
} }
public function savePostCreation(Post $post)
{
$this->historyService->saveSnapshot($this->postSnapshotProvider->getCreationSnapshot($post));
}
public function savePostChange(Post $post) public function savePostChange(Post $post)
{ {
$this->historyService->saveSnapshot($this->postSnapshotProvider->getPostChangeSnapshot($post)); $this->historyService->saveSnapshot($this->postSnapshotProvider->getChangeSnapshot($post));
} }
public function savePostDeletion(Post $post) public function savePostDeletion(Post $post)
{ {
$this->historyService->saveSnapshot($this->postSnapshotProvider->getPostDeleteSnapshot($post)); $this->historyService->saveSnapshot($this->postSnapshotProvider->getDeleteSnapshot($post));
} }
} }

View file

@ -123,7 +123,7 @@ class PostService
$savedPost = $this->postDao->save($post); $savedPost = $this->postDao->save($post);
$this->postHistoryService->savePostChange($savedPost); $this->postHistoryService->savePostCreation($savedPost);
return $savedPost; return $savedPost;
}; };
$ret = $this->transactionManager->commit($transactionFunc); $ret = $this->transactionManager->commit($transactionFunc);

View file

@ -2,6 +2,7 @@
namespace Szurubooru\Services; namespace Szurubooru\Services;
use Szurubooru\Dao\GlobalParamDao; use Szurubooru\Dao\GlobalParamDao;
use Szurubooru\Dao\PostNoteDao; use Szurubooru\Dao\PostNoteDao;
use Szurubooru\Entities\Entity;
use Szurubooru\Entities\GlobalParam; use Szurubooru\Entities\GlobalParam;
use Szurubooru\Entities\Post; use Szurubooru\Entities\Post;
use Szurubooru\Entities\PostNote; use Szurubooru\Entities\PostNote;
@ -9,7 +10,7 @@ use Szurubooru\Entities\Snapshot;
use Szurubooru\Entities\Tag; use Szurubooru\Entities\Tag;
use Szurubooru\Helpers\EnumHelper; use Szurubooru\Helpers\EnumHelper;
class PostSnapshotProvider class PostSnapshotProvider implements ISnapshotProvider
{ {
private $globalParamDao; private $globalParamDao;
private $postNoteDao; private $postNoteDao;
@ -22,7 +23,39 @@ class PostSnapshotProvider
$this->postNoteDao = $postNoteDao; $this->postNoteDao = $postNoteDao;
} }
public function getPostChangeSnapshot(Post $post) public function getCreationSnapshot(Entity $post)
{
$snapshot = $this->getPostSnapshot($post);
$snapshot->setOperation(Snapshot::OPERATION_CREATION);
$snapshot->setData($this->getFullData($post));
return $snapshot;
}
public function getChangeSnapshot(Entity $post)
{
$snapshot = $this->getPostSnapshot($post);
$snapshot->setOperation(Snapshot::OPERATION_CHANGE);
$snapshot->setData($this->getFullData($post));
return $snapshot;
}
public function getDeleteSnapshot(Entity $post)
{
$snapshot = $this->getPostSnapshot($post);
$snapshot->setData([]);
$snapshot->setOperation(Snapshot::OPERATION_DELETE);
return $snapshot;
}
private function getPostSnapshot(Post $post)
{
$snapshot = new Snapshot();
$snapshot->setType(Snapshot::TYPE_POST);
$snapshot->setPrimaryKey($post->getId());
return $snapshot;
}
private function getFullData(Post $post)
{ {
static $featuredPostParam = null; static $featuredPostParam = null;
if ($featuredPostParam === null) if ($featuredPostParam === null)
@ -75,25 +108,6 @@ class PostSnapshotProvider
sort($data['relations']); sort($data['relations']);
usort($data['notes'], function ($note1, $note2) { return $note1['x'] - $note2['x']; }); usort($data['notes'], function ($note1, $note2) { return $note1['x'] - $note2['x']; });
$snapshot = $this->getPostSnapshot($post); return $data;
$snapshot->setOperation(Snapshot::OPERATION_CHANGE);
$snapshot->setData($data);
return $snapshot;
}
public function getPostDeleteSnapshot(Post $post)
{
$snapshot = $this->getPostSnapshot($post);
$snapshot->setData([]);
$snapshot->setOperation(Snapshot::OPERATION_DELETE);
return $snapshot;
}
private function getPostSnapshot(Post $post)
{
$snapshot = new Snapshot();
$snapshot->setType(Snapshot::TYPE_POST);
$snapshot->setPrimaryKey($post->getId());
return $snapshot;
} }
} }

View file

@ -46,14 +46,19 @@ class TagHistoryService
return $this->transactionManager->rollback($transactionFunc); return $this->transactionManager->rollback($transactionFunc);
} }
public function saveTagCreation(Tag $tag)
{
$this->historyService->saveSnapshot($this->tagSnapshotProvider->getCreationSnapshot($tag));
}
public function saveTagChange(Tag $tag) public function saveTagChange(Tag $tag)
{ {
$this->historyService->saveSnapshot($this->tagSnapshotProvider->getTagChangeSnapshot($tag)); $this->historyService->saveSnapshot($this->tagSnapshotProvider->getChangeSnapshot($tag));
} }
public function saveTagDeletion(Tag $tag) public function saveTagDeletion(Tag $tag)
{ {
$this->historyService->saveSnapshot($this->tagSnapshotProvider->getTagDeleteSnapshot($tag)); $this->historyService->saveSnapshot($this->tagSnapshotProvider->getDeleteSnapshot($tag));
} }
} }

View file

@ -113,7 +113,7 @@ class TagService
foreach ($this->tagDao->batchSave($tagsToCreate) as $tag) foreach ($this->tagDao->batchSave($tagsToCreate) as $tag)
{ {
$createdTags[$tagNameGetter($tag)] = $tag; $createdTags[$tagNameGetter($tag)] = $tag;
$this->tagHistoryService->saveTagChange($tag); $this->tagHistoryService->saveTagCreation($tag);
} }
$result = []; $result = [];

View file

@ -1,11 +1,44 @@
<?php <?php
namespace Szurubooru\Services; namespace Szurubooru\Services;
use Szurubooru\Entities\Entity;
use Szurubooru\Entities\Snapshot; use Szurubooru\Entities\Snapshot;
use Szurubooru\Entities\Tag; use Szurubooru\Entities\Tag;
class TagSnapshotProvider class TagSnapshotProvider implements ISnapshotProvider
{ {
public function getTagChangeSnapshot(Tag $tag) public function getCreationSnapshot(Entity $tag)
{
$snapshot = $this->getTagSnapshot($tag);
$snapshot->setOperation(Snapshot::OPERATION_CREATION);
$snapshot->setData($this->getFullData($tag));
return $snapshot;
}
public function getChangeSnapshot(Entity $tag)
{
$snapshot = $this->getTagSnapshot($tag);
$snapshot->setOperation(Snapshot::OPERATION_CHANGE);
$snapshot->setData($this->getFullData($tag));
return $snapshot;
}
public function getDeleteSnapshot(Entity $tag)
{
$snapshot = $this->getTagSnapshot($tag);
$snapshot->setData(['name' => $tag->getName()]);
$snapshot->setOperation(Snapshot::OPERATION_DELETE);
return $snapshot;
}
private function getTagSnapshot(Tag $tag)
{
$snapshot = new Snapshot();
$snapshot->setType(Snapshot::TYPE_TAG);
$snapshot->setPrimaryKey($tag->getId());
return $snapshot;
}
private function getFullData(Tag $tag)
{ {
$data = $data =
[ [
@ -26,26 +59,6 @@ class TagSnapshotProvider
sort($data['implications']); sort($data['implications']);
sort($data['suggestions']); sort($data['suggestions']);
return $data;
$snapshot = $this->getTagSnapshot($tag);
$snapshot->setOperation(Snapshot::OPERATION_CHANGE);
$snapshot->setData($data);
return $snapshot;
}
public function getTagDeleteSnapshot(Tag $tag)
{
$snapshot = $this->getTagSnapshot($tag);
$snapshot->setData(['name' => $tag->getName()]);
$snapshot->setOperation(Snapshot::OPERATION_DELETE);
return $snapshot;
}
private function getTagSnapshot(Tag $tag)
{
$snapshot = new Snapshot();
$snapshot->setType(Snapshot::TYPE_TAG);
$snapshot->setPrimaryKey($tag->getId());
return $snapshot;
} }
} }

View file

@ -0,0 +1,19 @@
<?php
namespace Szurubooru\Upgrades;
use Szurubooru\DatabaseConnection;
class Upgrade33 implements IUpgrade
{
public function run(DatabaseConnection $databaseConnection)
{
$pdo = $databaseConnection->getPDO();
$pdo->exec('UPDATE snapshots SET operation = 2 WHERE operation = 1');
$pdo->exec('UPDATE snapshots SET operation = 1 WHERE operation = 0');
$pdo->exec('CREATE INDEX tempIndex ON snapshots(primaryKey)');
$pdo->exec('CREATE TABLE tempTable AS SELECT MIN(id) AS id FROM snapshots GROUP BY type, primaryKey');
$pdo->exec('DROP INDEX tempIndex ON snapshots');
$pdo->exec('UPDATE snapshots SET operation = 0 WHERE id IN (SELECT id FROM tempTable)');
$pdo->exec('DROP TABLE tempTable');
}
}

View file

@ -49,6 +49,7 @@ return [
$container->get(\Szurubooru\Upgrades\Upgrade30::class), $container->get(\Szurubooru\Upgrades\Upgrade30::class),
$container->get(\Szurubooru\Upgrades\Upgrade31::class), $container->get(\Szurubooru\Upgrades\Upgrade31::class),
$container->get(\Szurubooru\Upgrades\Upgrade32::class), $container->get(\Szurubooru\Upgrades\Upgrade32::class),
$container->get(\Szurubooru\Upgrades\Upgrade33::class),
]; ];
}), }),

View file

@ -61,7 +61,7 @@ final class PostServiceTest extends AbstractDatabaseTestCase
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0)); $this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->authServiceMock->expects($this->once())->method('getLoggedInUser')->willReturn(new User(5)); $this->authServiceMock->expects($this->once())->method('getLoggedInUser')->willReturn(new User(5));
$this->postHistoryServiceMock->expects($this->once())->method('savePostChange')->willReturn(new Snapshot()); $this->postHistoryServiceMock->expects($this->once())->method('savePostCreation')->willReturn(new Snapshot());
$this->imageConverterMock->expects($this->never())->method('createImageFromBuffer'); $this->imageConverterMock->expects($this->never())->method('createImageFromBuffer');
$this->postService = $this->getPostService(); $this->postService = $this->getPostService();
@ -91,7 +91,7 @@ final class PostServiceTest extends AbstractDatabaseTestCase
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0)); $this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->imageManipulatorMock->expects($this->once())->method('getImageWidth')->willReturn(640); $this->imageManipulatorMock->expects($this->once())->method('getImageWidth')->willReturn(640);
$this->imageManipulatorMock->expects($this->once())->method('getImageHeight')->willReturn(480); $this->imageManipulatorMock->expects($this->once())->method('getImageHeight')->willReturn(480);
$this->postHistoryServiceMock->expects($this->once())->method('savePostChange')->willReturn(new Snapshot()); $this->postHistoryServiceMock->expects($this->once())->method('savePostCreation')->willReturn(new Snapshot());
$this->postService = $this->getPostService(); $this->postService = $this->getPostService();
$savedPost = $this->postService->createPost($formData); $savedPost = $this->postService->createPost($formData);
@ -112,7 +112,7 @@ final class PostServiceTest extends AbstractDatabaseTestCase
$formData->contentFileName = 'blah'; $formData->contentFileName = 'blah';
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0)); $this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->postHistoryServiceMock->expects($this->once())->method('savePostChange')->willReturn(new Snapshot()); $this->postHistoryServiceMock->expects($this->once())->method('savePostCreation')->willReturn(new Snapshot());
$this->imageConverterMock->expects($this->once())->method('createImageFromBuffer'); $this->imageConverterMock->expects($this->once())->method('createImageFromBuffer');
$this->postService = $this->getPostService(); $this->postService = $this->getPostService();
@ -132,7 +132,7 @@ final class PostServiceTest extends AbstractDatabaseTestCase
$formData->contentFileName = 'blah'; $formData->contentFileName = 'blah';
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0)); $this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->postHistoryServiceMock->expects($this->once())->method('savePostChange')->willReturn(new Snapshot()); $this->postHistoryServiceMock->expects($this->once())->method('savePostCreation')->willReturn(new Snapshot());
$this->imageConverterMock->expects($this->once())->method('createImageFromBuffer'); $this->imageConverterMock->expects($this->once())->method('createImageFromBuffer');
$this->postService = $this->getPostService(); $this->postService = $this->getPostService();
@ -196,7 +196,7 @@ final class PostServiceTest extends AbstractDatabaseTestCase
$this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0)); $this->postDaoMock->expects($this->once())->method('save')->will($this->returnArgument(0));
$this->authServiceMock->expects($this->never())->method('getLoggedInUser'); $this->authServiceMock->expects($this->never())->method('getLoggedInUser');
$this->postHistoryServiceMock->expects($this->once())->method('savePostChange')->willReturn(new Snapshot()); $this->postHistoryServiceMock->expects($this->once())->method('savePostCreation')->willReturn(new Snapshot());
$this->postService = $this->getPostService(); $this->postService = $this->getPostService();
$savedPost = $this->postService->createPost($formData); $savedPost = $this->postService->createPost($formData);

View file

@ -44,7 +44,7 @@ class PostSnapshotProviderTest extends AbstractTestCase
->willReturn([$this->getTestPostNote()]); ->willReturn([$this->getTestPostNote()]);
$postSnapshotProvider = $this->getPostSnapshotProvider(); $postSnapshotProvider = $this->getPostSnapshotProvider();
$snapshot = $postSnapshotProvider->getPostChangeSnapshot($post); $snapshot = $postSnapshotProvider->getChangeSnapshot($post);
$this->assertEquals([ $this->assertEquals([
'source' => 'amazing source', 'source' => 'amazing source',
@ -82,7 +82,7 @@ class PostSnapshotProviderTest extends AbstractTestCase
->willReturn([]); ->willReturn([]);
$postSnapshotProvider = $this->getPostSnapshotProvider(); $postSnapshotProvider = $this->getPostSnapshotProvider();
$snapshot = $postSnapshotProvider->getPostChangeSnapshot($post); $snapshot = $postSnapshotProvider->getChangeSnapshot($post);
$this->assertTrue($snapshot->getData()['featured']); $this->assertTrue($snapshot->getData()['featured']);
} }