Improved model performance a little bit
This commit is contained in:
parent
8ee80ea170
commit
343268d029
16 changed files with 196 additions and 163 deletions
|
@ -9,7 +9,22 @@ abstract class AbstractCrudModel implements IModel
|
|||
public static function spawn()
|
||||
{
|
||||
$entityClassName = static::getEntityClassName();
|
||||
return new $entityClassName();
|
||||
$entity = new $entityClassName(new static);
|
||||
$entity->fillNew();
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public static function spawnFromDatabaseRows($input)
|
||||
{
|
||||
return array_map([get_called_class(), 'spawnFromDatabaseRow'], $input);
|
||||
}
|
||||
|
||||
public static function spawnFromDatabaseRow($row)
|
||||
{
|
||||
$entityClassName = static::getEntityClassName();
|
||||
$entity = new $entityClassName(new static);
|
||||
$entity->fillFromDatabase($row);
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public static function remove($entities)
|
||||
|
@ -40,7 +55,7 @@ abstract class AbstractCrudModel implements IModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? static::convertRow($row)
|
||||
? static::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -53,7 +68,7 @@ abstract class AbstractCrudModel implements IModel
|
|||
|
||||
$rows = Database::fetchAll($stmt);
|
||||
if ($rows)
|
||||
return static::convertRows($rows);
|
||||
return static::spawnFromDatabaseRows($rows);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -76,55 +91,6 @@ abstract class AbstractCrudModel implements IModel
|
|||
return $entityClassName;
|
||||
}
|
||||
|
||||
public static function convertRow($row)
|
||||
{
|
||||
$entity = static::spawn();
|
||||
|
||||
//todo: force this to be implemented by children
|
||||
//instead of providing clumsy generic solution
|
||||
|
||||
if (isset($row['id']))
|
||||
$row['id'] = (int) $row['id'];
|
||||
|
||||
foreach ($row as $key => $val)
|
||||
{
|
||||
if (isset(self::$keyCache[$key]))
|
||||
{
|
||||
$key = self::$keyCache[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = self::$keyCache[$key] = TextCaseConverter::convert($key,
|
||||
TextCaseConverter::SNAKE_CASE,
|
||||
TextCaseConverter::LOWER_CAMEL_CASE);
|
||||
}
|
||||
|
||||
if (property_exists($entity, $key))
|
||||
{
|
||||
$reflectionProperty = new ReflectionProperty(get_class($entity), $key);
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue($entity, $val);
|
||||
}
|
||||
else
|
||||
{
|
||||
$entity->$key = $val;
|
||||
}
|
||||
}
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public static function convertRows(array $rows)
|
||||
{
|
||||
$entities = [];
|
||||
foreach ($rows as $i => $row)
|
||||
{
|
||||
$entities[$i] = static::convertRow($row);
|
||||
}
|
||||
return $entities;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function forgeId($entity)
|
||||
{
|
||||
$table = static::getTableName();
|
||||
|
|
|
@ -9,16 +9,10 @@ final class CommentModel extends AbstractCrudModel
|
|||
return 'comment';
|
||||
}
|
||||
|
||||
public static function spawn()
|
||||
{
|
||||
$comment = new CommentEntity;
|
||||
$comment->setCreationTime(time());
|
||||
return $comment;
|
||||
}
|
||||
|
||||
public static function save($comment)
|
||||
{
|
||||
$comment->validate();
|
||||
$comment->getPost()->removeCache('comment_count');
|
||||
|
||||
Database::transaction(function() use ($comment)
|
||||
{
|
||||
|
@ -47,6 +41,7 @@ final class CommentModel extends AbstractCrudModel
|
|||
{
|
||||
Database::transaction(function() use ($comment)
|
||||
{
|
||||
$comment->getPost()->removeCache('comment_count');
|
||||
$stmt = new Sql\DeleteStatement();
|
||||
$stmt->setTable('comment');
|
||||
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($comment->getId())));
|
||||
|
@ -65,7 +60,7 @@ final class CommentModel extends AbstractCrudModel
|
|||
|
||||
$rows = Database::fetchAll($stmt);
|
||||
if ($rows)
|
||||
return self::convertRows($rows);
|
||||
return self::spawnFromDatabaseRows($rows);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
<?php
|
||||
abstract class AbstractEntity implements IValidatable
|
||||
{
|
||||
protected $model;
|
||||
protected $id;
|
||||
protected $__cache = [];
|
||||
|
||||
public abstract function fillNew();
|
||||
public abstract function fillFromDatabase($row);
|
||||
|
||||
public function __construct($model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
|
@ -14,16 +23,6 @@ abstract class AbstractEntity implements IValidatable
|
|||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function resetCache()
|
||||
{
|
||||
$this->__cache = [];
|
||||
}
|
||||
|
||||
public function setCache($key, $value)
|
||||
{
|
||||
$this->__cache[$key] = $value;
|
||||
}
|
||||
|
||||
public function getCache($key)
|
||||
{
|
||||
return isset($this->__cache[$key])
|
||||
|
@ -31,8 +30,37 @@ abstract class AbstractEntity implements IValidatable
|
|||
: null;
|
||||
}
|
||||
|
||||
public function setCache($key, $value)
|
||||
{
|
||||
$this->__cache[$key] = $value;
|
||||
}
|
||||
|
||||
public function removeCache($key)
|
||||
{
|
||||
unset($this->__cache[$key]);
|
||||
}
|
||||
|
||||
public function resetCache()
|
||||
{
|
||||
$this->__cache = [];
|
||||
}
|
||||
|
||||
public function hasCache($key)
|
||||
{
|
||||
return isset($this->__cache[$key]);
|
||||
}
|
||||
|
||||
protected function getColumnWithCache($columnName)
|
||||
{
|
||||
if ($this->hasCache($columnName))
|
||||
return $this->getCache($columnName);
|
||||
|
||||
$stmt = new \Chibi\Sql\SelectStatement();
|
||||
$stmt->setTable($this->model->getTableName());
|
||||
$stmt->setColumn($columnName);
|
||||
$stmt->setCriterion(new \Chibi\Sql\EqualsFunctor('id', new \Chibi\Sql\Binding($this->getId())));
|
||||
$value = \Chibi\Database::fetchOne($stmt)[$columnName];
|
||||
$this->setCache($columnName, $value);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
<?php
|
||||
final class CommentEntity extends AbstractEntity implements IValidatable
|
||||
{
|
||||
protected $text;
|
||||
protected $postId;
|
||||
protected $commentDate;
|
||||
protected $commenterId;
|
||||
private $text;
|
||||
private $postId;
|
||||
private $commentDate;
|
||||
private $commenterId;
|
||||
|
||||
public function fillNew()
|
||||
{
|
||||
$this->commentDate = time();
|
||||
}
|
||||
|
||||
public function fillFromDatabase($row)
|
||||
{
|
||||
$this->id = (int) $row['id'];
|
||||
$this->text = $row['text'];
|
||||
$this->postId = (int) $row['post_id'];
|
||||
$this->commentDate = $row['comment_date'];
|
||||
$this->commenterId = (int) $row['commenter_id'];
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class PostEntity extends AbstractEntity implements IValidatable
|
||||
final class PostEntity extends AbstractEntity implements IValidatable
|
||||
{
|
||||
protected $type;
|
||||
protected $name;
|
||||
|
@ -18,9 +18,38 @@ class PostEntity extends AbstractEntity implements IValidatable
|
|||
protected $uploaderId;
|
||||
protected $source;
|
||||
|
||||
protected $commentCount = 0;
|
||||
protected $favCount = 0;
|
||||
protected $score = 0;
|
||||
public function fillNew()
|
||||
{
|
||||
$this->setSafety(new PostSafety(PostSafety::Safe));
|
||||
$this->setHidden(false);
|
||||
$this->setCreationTime(time());
|
||||
do
|
||||
{
|
||||
$this->setName(md5(mt_rand() . uniqid()));
|
||||
}
|
||||
while (file_exists($this->getFullPath()));
|
||||
}
|
||||
|
||||
public function fillFromDatabase($row)
|
||||
{
|
||||
$this->id = (int) $row['id'];
|
||||
$this->name = $row['name'];
|
||||
$this->origName = $row['orig_name'];
|
||||
$this->fileHash = $row['file_hash'];
|
||||
$this->fileSize = (int) $row['file_size'];
|
||||
$this->mimeType = $row['mime_type'];
|
||||
$this->hidden = (bool) $row['hidden'];
|
||||
$this->uploadDate = $row['upload_date'];
|
||||
$this->imageWidth = (int) $row['image_width'];
|
||||
$this->imageHeight = (int) $row['image_height'];
|
||||
$this->uploaderId = (int) $row['uploader_id'];
|
||||
$this->source = $row['source'];
|
||||
$this->setCache('comment_count', $row['comment_count']);
|
||||
$this->setCache('fav_count', $row['fav_count']);
|
||||
$this->setCache('score', $row['score']);
|
||||
$this->setType(new PostType($row['type']));
|
||||
$this->setSafety(new PostSafety($row['safety']));
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
|
@ -80,24 +109,24 @@ class PostEntity extends AbstractEntity implements IValidatable
|
|||
$stmt->addInnerJoin('favoritee', new Sql\EqualsFunctor('favoritee.user_id', 'user.id'));
|
||||
$stmt->setCriterion(new Sql\EqualsFunctor('favoritee.post_id', new Sql\Binding($this->getId())));
|
||||
$rows = Database::fetchAll($stmt);
|
||||
$favorites = UserModel::convertRows($rows);
|
||||
$favorites = UserModel::spawnFromDatabaseRows($rows);
|
||||
$this->setCache('favoritee', $favorites);
|
||||
return $favorites;
|
||||
}
|
||||
|
||||
public function getScore()
|
||||
{
|
||||
return $this->score;
|
||||
return (int) $this->getColumnWithCache('score');
|
||||
}
|
||||
|
||||
public function getCommentCount()
|
||||
{
|
||||
return $this->commentCount;
|
||||
return (int) $this->getColumnWithCache('comment_count');
|
||||
}
|
||||
|
||||
public function getFavoriteCount()
|
||||
{
|
||||
return $this->favCount;
|
||||
return (int) $this->getColumnWithCache('fav_count');
|
||||
}
|
||||
|
||||
public function getRelations()
|
||||
|
@ -119,7 +148,7 @@ class PostEntity extends AbstractEntity implements IValidatable
|
|||
->add(new Sql\EqualsFunctor('post.id', 'crossref.post_id'))
|
||||
->add(new Sql\EqualsFunctor('crossref.post2_id', $binding))));
|
||||
$rows = Database::fetchAll($stmt);
|
||||
$posts = PostModel::convertRows($rows);
|
||||
$posts = PostModel::spawnFromDatabaseRows($rows);
|
||||
$this->setCache('relations', $posts);
|
||||
return $posts;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,22 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class TagEntity extends AbstractEntity implements IValidatable
|
||||
final class TagEntity extends AbstractEntity implements IValidatable
|
||||
{
|
||||
protected $name;
|
||||
private $name;
|
||||
|
||||
public function fillNew()
|
||||
{
|
||||
}
|
||||
|
||||
public function fillFromDatabase($row)
|
||||
{
|
||||
$this->id = (int) $row['id'];
|
||||
$this->name = $row['name'];
|
||||
|
||||
if (isset($row['post_count']))
|
||||
$this->setCache('post_count', (int) $row['post_count']);
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
<?php
|
||||
class TokenEntity extends AbstractEntity implements IValidatable
|
||||
final class TokenEntity extends AbstractEntity implements IValidatable
|
||||
{
|
||||
protected $userId;
|
||||
protected $token;
|
||||
protected $used;
|
||||
protected $expires;
|
||||
private $userId;
|
||||
private $token;
|
||||
private $used;
|
||||
private $expires;
|
||||
|
||||
public function fillNew()
|
||||
{
|
||||
}
|
||||
|
||||
public function fillFromDatabase($row)
|
||||
{
|
||||
$this->id = (int) $row['id'];
|
||||
$this->userId = (int) $row['user_id'];
|
||||
$this->token = $row['token'];
|
||||
$this->used = (bool) $row['used'];
|
||||
$this->expires = $row['expires'];
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class UserEntity extends AbstractEntity implements IValidatable
|
||||
final class UserEntity extends AbstractEntity implements IValidatable
|
||||
{
|
||||
protected $name;
|
||||
protected $passSalt;
|
||||
|
@ -19,6 +19,28 @@ class UserEntity extends AbstractEntity implements IValidatable
|
|||
protected $__passwordChanged = false;
|
||||
protected $__password;
|
||||
|
||||
public function fillNew()
|
||||
{
|
||||
$this->setAccessRank(new AccessRank(AccessRank::Anonymous));
|
||||
$this->setPasswordSalt(md5(mt_rand() . uniqid()));
|
||||
}
|
||||
|
||||
public function fillFromDatabase($row)
|
||||
{
|
||||
$this->id = (int) $row['id'];
|
||||
$this->name = $row['name'];
|
||||
$this->passSalt = $row['pass_salt'];
|
||||
$this->passHash = $row['pass_hash'];
|
||||
$this->staffConfirmed = $row['staff_confirmed'];
|
||||
$this->emailUnconfirmed = $row['email_unconfirmed'];
|
||||
$this->emailConfirmed = $row['email_confirmed'];
|
||||
$this->joinDate = $row['join_date'];
|
||||
$this->lastLoginDate = $row['last_login_date'];
|
||||
$this->settings = $row['settings'];
|
||||
$this->banned = $row['banned'];
|
||||
$this->setAccessRank(new AccessRank($row['access_rank']));
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
$this->validateUserName();
|
||||
|
|
|
@ -2,40 +2,13 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class PostModel extends AbstractCrudModel
|
||||
final class PostModel extends AbstractCrudModel
|
||||
{
|
||||
public static function getTableName()
|
||||
{
|
||||
return 'post';
|
||||
}
|
||||
|
||||
public static function convertRow($row)
|
||||
{
|
||||
$entity = parent::convertRow($row);
|
||||
|
||||
if (isset($row['type']))
|
||||
$entity->setType(new PostType($row['type']));
|
||||
|
||||
if (isset($row['safety']))
|
||||
$entity->setSafety(new PostSafety($row['safety']));
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public static function spawn()
|
||||
{
|
||||
$post = new PostEntity;
|
||||
$post->setSafety(new PostSafety(PostSafety::Safe));
|
||||
$post->setHidden(false);
|
||||
$post->setCreationTime(time());
|
||||
do
|
||||
{
|
||||
$post->setName(md5(mt_rand() . uniqid()));
|
||||
}
|
||||
while (file_exists($post->getFullPath()));
|
||||
return $post;
|
||||
}
|
||||
|
||||
public static function save($post)
|
||||
{
|
||||
$post->validate();
|
||||
|
@ -162,7 +135,7 @@ class PostModel extends AbstractCrudModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? self::convertRow($row)
|
||||
? self::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -192,7 +165,7 @@ class PostModel extends AbstractCrudModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? self::convertRow($row)
|
||||
? self::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -224,8 +197,7 @@ class PostModel extends AbstractCrudModel
|
|||
{
|
||||
if (isset($comments[$row['id']]))
|
||||
continue;
|
||||
unset($row['post_id']);
|
||||
$comment = CommentModel::convertRow($row);
|
||||
$comment = CommentModel::spawnFromDatabaseRow($row);
|
||||
$comments[$row['id']] = $comment;
|
||||
}
|
||||
|
||||
|
@ -267,7 +239,7 @@ class PostModel extends AbstractCrudModel
|
|||
if (isset($tags[$row['id']]))
|
||||
continue;
|
||||
unset($row['post_id']);
|
||||
$tag = TagModel::convertRow($row);
|
||||
$tag = TagModel::spawnFromDatabaseRow($row);
|
||||
$tags[$row['id']] = $tag;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class PropertyModel implements IModel
|
||||
final class PropertyModel implements IModel
|
||||
{
|
||||
const FeaturedPostId = 0;
|
||||
const FeaturedPostUserName = 1;
|
||||
|
|
|
@ -56,7 +56,7 @@ abstract class AbstractSearchService
|
|||
{
|
||||
$modelClassName = self::getModelClassName();
|
||||
$rows = static::getEntitiesRows($searchQuery, $perPage, $page);
|
||||
return $modelClassName::convertRows($rows);
|
||||
return $modelClassName::spawnFromDatabaseRows($rows);
|
||||
}
|
||||
|
||||
public static function getEntityCount($searchQuery)
|
||||
|
|
|
@ -62,7 +62,7 @@ class TagSearchService extends AbstractSearchService
|
|||
|
||||
usort($rows, function($a, $b) { return intval($b['sort']) - intval($a['sort']); });
|
||||
|
||||
return TagModel::convertRows($rows);
|
||||
return TagModel::spawnFromDatabaseRows($rows);
|
||||
}
|
||||
|
||||
public static function getMostUsedTag()
|
||||
|
@ -74,6 +74,6 @@ class TagSearchService extends AbstractSearchService
|
|||
->setGroupBy('post_tag.tag_id')
|
||||
->setOrderBy('post_count', Sql\SelectStatement::ORDER_DESC)
|
||||
->setLimit(1, 0);
|
||||
return TagModel::convertRow(Database::fetchOne($stmt));
|
||||
return TagModel::spawnFromDatabaseRow(Database::fetchOne($stmt));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,21 +2,13 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class TagModel extends AbstractCrudModel
|
||||
final class TagModel extends AbstractCrudModel
|
||||
{
|
||||
public static function getTableName()
|
||||
{
|
||||
return 'tag';
|
||||
}
|
||||
|
||||
public static function convertRow($row)
|
||||
{
|
||||
$entity = parent::convertRow($row);
|
||||
if (isset($row['post_count']))
|
||||
$entity->setCache('post_count', $row['post_count']);
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public static function save($tag)
|
||||
{
|
||||
$tag->validate();
|
||||
|
@ -126,7 +118,7 @@ class TagModel extends AbstractCrudModel
|
|||
|
||||
$rows = Database::fetchAll($stmt);
|
||||
if ($rows)
|
||||
return self::convertRows($rows);
|
||||
return self::spawnFromDatabaseRows($rows);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -147,7 +139,7 @@ class TagModel extends AbstractCrudModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? self::convertRow($row)
|
||||
? self::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class TokenModel extends AbstractCrudModel
|
||||
final class TokenModel extends AbstractCrudModel
|
||||
{
|
||||
public static function getTableName()
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ class TokenModel extends AbstractCrudModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? self::convertRow($row)
|
||||
? self::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use \Chibi\Sql as Sql;
|
||||
use \Chibi\Database as Database;
|
||||
|
||||
class UserModel extends AbstractCrudModel
|
||||
final class UserModel extends AbstractCrudModel
|
||||
{
|
||||
const SETTING_SAFETY = 1;
|
||||
const SETTING_ENDLESS_SCROLLING = 2;
|
||||
|
@ -14,24 +14,6 @@ class UserModel extends AbstractCrudModel
|
|||
return 'user';
|
||||
}
|
||||
|
||||
public static function convertRow($row)
|
||||
{
|
||||
$entity = parent::convertRow($row);
|
||||
|
||||
if (isset($row['access_rank']))
|
||||
$entity->setAccessRank(new AccessRank($row['access_rank']));
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
public static function spawn()
|
||||
{
|
||||
$user = new UserEntity();
|
||||
$user->setAccessRank(new AccessRank(AccessRank::Anonymous));
|
||||
$user->setPasswordSalt(md5(mt_rand() . uniqid()));
|
||||
return $user;
|
||||
}
|
||||
|
||||
public static function save($user)
|
||||
{
|
||||
$user->validate();
|
||||
|
@ -118,7 +100,7 @@ class UserModel extends AbstractCrudModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? self::convertRow($row)
|
||||
? self::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -144,7 +126,7 @@ class UserModel extends AbstractCrudModel
|
|||
|
||||
$row = Database::fetchOne($stmt);
|
||||
return $row
|
||||
? self::convertRow($row)
|
||||
? self::spawnFromDatabaseRow($row)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -154,6 +136,7 @@ class UserModel extends AbstractCrudModel
|
|||
{
|
||||
Database::transaction(function() use ($user, $post, $score)
|
||||
{
|
||||
$post->removeCache('score');
|
||||
$stmt = new Sql\DeleteStatement();
|
||||
$stmt->setTable('post_score');
|
||||
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||
|
@ -177,6 +160,7 @@ class UserModel extends AbstractCrudModel
|
|||
{
|
||||
Database::transaction(function() use ($user, $post)
|
||||
{
|
||||
$post->removeCache('fav_count');
|
||||
self::removeFromUserFavorites($user, $post);
|
||||
$stmt = new Sql\InsertStatement();
|
||||
$stmt->setTable('favoritee');
|
||||
|
@ -191,6 +175,7 @@ class UserModel extends AbstractCrudModel
|
|||
{
|
||||
Database::transaction(function() use ($user, $post)
|
||||
{
|
||||
$post->removeCache('fav_count');
|
||||
$stmt = new Sql\DeleteStatement();
|
||||
$stmt->setTable('favoritee');
|
||||
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||
|
|
|
@ -18,12 +18,16 @@ class ListCommentJobTest extends AbstractTest
|
|||
|
||||
$this->assert->areEqual(0, CommentModel::getCount());
|
||||
|
||||
$this->mockComment($this->mockUser());
|
||||
$comment = $this->mockComment($this->mockUser());
|
||||
|
||||
$ret = $this->runApi(1);
|
||||
$this->assert->areEqual(1, count($ret->entities));
|
||||
|
||||
$post = $ret->entities[0];
|
||||
$newComment = $post->getComments()[0];
|
||||
$this->assert->areEqual($comment->getPostId(), $newComment->getPostId());
|
||||
$this->assert->areEqual($comment->getPost()->getId(), $newComment->getPost()->getId());
|
||||
|
||||
$samePost = $this->assert->doesNotThrow(function() use ($post)
|
||||
{
|
||||
return PostModel::getById($post->getId());
|
||||
|
|
Loading…
Reference in a new issue