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()
|
public static function spawn()
|
||||||
{
|
{
|
||||||
$entityClassName = static::getEntityClassName();
|
$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)
|
public static function remove($entities)
|
||||||
|
@ -40,7 +55,7 @@ abstract class AbstractCrudModel implements IModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? static::convertRow($row)
|
? static::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +68,7 @@ abstract class AbstractCrudModel implements IModel
|
||||||
|
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
if ($rows)
|
if ($rows)
|
||||||
return static::convertRows($rows);
|
return static::spawnFromDatabaseRows($rows);
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -76,55 +91,6 @@ abstract class AbstractCrudModel implements IModel
|
||||||
return $entityClassName;
|
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)
|
public static function forgeId($entity)
|
||||||
{
|
{
|
||||||
$table = static::getTableName();
|
$table = static::getTableName();
|
||||||
|
|
|
@ -9,16 +9,10 @@ final class CommentModel extends AbstractCrudModel
|
||||||
return 'comment';
|
return 'comment';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function spawn()
|
|
||||||
{
|
|
||||||
$comment = new CommentEntity;
|
|
||||||
$comment->setCreationTime(time());
|
|
||||||
return $comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function save($comment)
|
public static function save($comment)
|
||||||
{
|
{
|
||||||
$comment->validate();
|
$comment->validate();
|
||||||
|
$comment->getPost()->removeCache('comment_count');
|
||||||
|
|
||||||
Database::transaction(function() use ($comment)
|
Database::transaction(function() use ($comment)
|
||||||
{
|
{
|
||||||
|
@ -47,6 +41,7 @@ final class CommentModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($comment)
|
Database::transaction(function() use ($comment)
|
||||||
{
|
{
|
||||||
|
$comment->getPost()->removeCache('comment_count');
|
||||||
$stmt = new Sql\DeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($comment->getId())));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($comment->getId())));
|
||||||
|
@ -65,7 +60,7 @@ final class CommentModel extends AbstractCrudModel
|
||||||
|
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
if ($rows)
|
if ($rows)
|
||||||
return self::convertRows($rows);
|
return self::spawnFromDatabaseRows($rows);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
abstract class AbstractEntity implements IValidatable
|
abstract class AbstractEntity implements IValidatable
|
||||||
{
|
{
|
||||||
|
protected $model;
|
||||||
protected $id;
|
protected $id;
|
||||||
protected $__cache = [];
|
protected $__cache = [];
|
||||||
|
|
||||||
|
public abstract function fillNew();
|
||||||
|
public abstract function fillFromDatabase($row);
|
||||||
|
|
||||||
|
public function __construct($model)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
}
|
||||||
|
|
||||||
public function getId()
|
public function getId()
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
|
@ -14,16 +23,6 @@ abstract class AbstractEntity implements IValidatable
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resetCache()
|
|
||||||
{
|
|
||||||
$this->__cache = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCache($key, $value)
|
|
||||||
{
|
|
||||||
$this->__cache[$key] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCache($key)
|
public function getCache($key)
|
||||||
{
|
{
|
||||||
return isset($this->__cache[$key])
|
return isset($this->__cache[$key])
|
||||||
|
@ -31,8 +30,37 @@ abstract class AbstractEntity implements IValidatable
|
||||||
: null;
|
: 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)
|
public function hasCache($key)
|
||||||
{
|
{
|
||||||
return isset($this->__cache[$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
|
<?php
|
||||||
final class CommentEntity extends AbstractEntity implements IValidatable
|
final class CommentEntity extends AbstractEntity implements IValidatable
|
||||||
{
|
{
|
||||||
protected $text;
|
private $text;
|
||||||
protected $postId;
|
private $postId;
|
||||||
protected $commentDate;
|
private $commentDate;
|
||||||
protected $commenterId;
|
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()
|
public function validate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PostEntity extends AbstractEntity implements IValidatable
|
final class PostEntity extends AbstractEntity implements IValidatable
|
||||||
{
|
{
|
||||||
protected $type;
|
protected $type;
|
||||||
protected $name;
|
protected $name;
|
||||||
|
@ -18,9 +18,38 @@ class PostEntity extends AbstractEntity implements IValidatable
|
||||||
protected $uploaderId;
|
protected $uploaderId;
|
||||||
protected $source;
|
protected $source;
|
||||||
|
|
||||||
protected $commentCount = 0;
|
public function fillNew()
|
||||||
protected $favCount = 0;
|
{
|
||||||
protected $score = 0;
|
$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()
|
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->addInnerJoin('favoritee', new Sql\EqualsFunctor('favoritee.user_id', 'user.id'));
|
||||||
$stmt->setCriterion(new Sql\EqualsFunctor('favoritee.post_id', new Sql\Binding($this->getId())));
|
$stmt->setCriterion(new Sql\EqualsFunctor('favoritee.post_id', new Sql\Binding($this->getId())));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
$favorites = UserModel::convertRows($rows);
|
$favorites = UserModel::spawnFromDatabaseRows($rows);
|
||||||
$this->setCache('favoritee', $favorites);
|
$this->setCache('favoritee', $favorites);
|
||||||
return $favorites;
|
return $favorites;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getScore()
|
public function getScore()
|
||||||
{
|
{
|
||||||
return $this->score;
|
return (int) $this->getColumnWithCache('score');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCommentCount()
|
public function getCommentCount()
|
||||||
{
|
{
|
||||||
return $this->commentCount;
|
return (int) $this->getColumnWithCache('comment_count');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getFavoriteCount()
|
public function getFavoriteCount()
|
||||||
{
|
{
|
||||||
return $this->favCount;
|
return (int) $this->getColumnWithCache('fav_count');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRelations()
|
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('post.id', 'crossref.post_id'))
|
||||||
->add(new Sql\EqualsFunctor('crossref.post2_id', $binding))));
|
->add(new Sql\EqualsFunctor('crossref.post2_id', $binding))));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
$posts = PostModel::convertRows($rows);
|
$posts = PostModel::spawnFromDatabaseRows($rows);
|
||||||
$this->setCache('relations', $posts);
|
$this->setCache('relations', $posts);
|
||||||
return $posts;
|
return $posts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,22 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
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()
|
public function validate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
<?php
|
<?php
|
||||||
class TokenEntity extends AbstractEntity implements IValidatable
|
final class TokenEntity extends AbstractEntity implements IValidatable
|
||||||
{
|
{
|
||||||
protected $userId;
|
private $userId;
|
||||||
protected $token;
|
private $token;
|
||||||
protected $used;
|
private $used;
|
||||||
protected $expires;
|
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()
|
public function validate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class UserEntity extends AbstractEntity implements IValidatable
|
final class UserEntity extends AbstractEntity implements IValidatable
|
||||||
{
|
{
|
||||||
protected $name;
|
protected $name;
|
||||||
protected $passSalt;
|
protected $passSalt;
|
||||||
|
@ -19,6 +19,28 @@ class UserEntity extends AbstractEntity implements IValidatable
|
||||||
protected $__passwordChanged = false;
|
protected $__passwordChanged = false;
|
||||||
protected $__password;
|
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()
|
public function validate()
|
||||||
{
|
{
|
||||||
$this->validateUserName();
|
$this->validateUserName();
|
||||||
|
|
|
@ -2,40 +2,13 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PostModel extends AbstractCrudModel
|
final class PostModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
public static function getTableName()
|
public static function getTableName()
|
||||||
{
|
{
|
||||||
return 'post';
|
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)
|
public static function save($post)
|
||||||
{
|
{
|
||||||
$post->validate();
|
$post->validate();
|
||||||
|
@ -162,7 +135,7 @@ class PostModel extends AbstractCrudModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? self::convertRow($row)
|
? self::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +165,7 @@ class PostModel extends AbstractCrudModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? self::convertRow($row)
|
? self::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,8 +197,7 @@ class PostModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
if (isset($comments[$row['id']]))
|
if (isset($comments[$row['id']]))
|
||||||
continue;
|
continue;
|
||||||
unset($row['post_id']);
|
$comment = CommentModel::spawnFromDatabaseRow($row);
|
||||||
$comment = CommentModel::convertRow($row);
|
|
||||||
$comments[$row['id']] = $comment;
|
$comments[$row['id']] = $comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +239,7 @@ class PostModel extends AbstractCrudModel
|
||||||
if (isset($tags[$row['id']]))
|
if (isset($tags[$row['id']]))
|
||||||
continue;
|
continue;
|
||||||
unset($row['post_id']);
|
unset($row['post_id']);
|
||||||
$tag = TagModel::convertRow($row);
|
$tag = TagModel::spawnFromDatabaseRow($row);
|
||||||
$tags[$row['id']] = $tag;
|
$tags[$row['id']] = $tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PropertyModel implements IModel
|
final class PropertyModel implements IModel
|
||||||
{
|
{
|
||||||
const FeaturedPostId = 0;
|
const FeaturedPostId = 0;
|
||||||
const FeaturedPostUserName = 1;
|
const FeaturedPostUserName = 1;
|
||||||
|
|
|
@ -56,7 +56,7 @@ abstract class AbstractSearchService
|
||||||
{
|
{
|
||||||
$modelClassName = self::getModelClassName();
|
$modelClassName = self::getModelClassName();
|
||||||
$rows = static::getEntitiesRows($searchQuery, $perPage, $page);
|
$rows = static::getEntitiesRows($searchQuery, $perPage, $page);
|
||||||
return $modelClassName::convertRows($rows);
|
return $modelClassName::spawnFromDatabaseRows($rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getEntityCount($searchQuery)
|
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']); });
|
usort($rows, function($a, $b) { return intval($b['sort']) - intval($a['sort']); });
|
||||||
|
|
||||||
return TagModel::convertRows($rows);
|
return TagModel::spawnFromDatabaseRows($rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getMostUsedTag()
|
public static function getMostUsedTag()
|
||||||
|
@ -74,6 +74,6 @@ class TagSearchService extends AbstractSearchService
|
||||||
->setGroupBy('post_tag.tag_id')
|
->setGroupBy('post_tag.tag_id')
|
||||||
->setOrderBy('post_count', Sql\SelectStatement::ORDER_DESC)
|
->setOrderBy('post_count', Sql\SelectStatement::ORDER_DESC)
|
||||||
->setLimit(1, 0);
|
->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\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class TagModel extends AbstractCrudModel
|
final class TagModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
public static function getTableName()
|
public static function getTableName()
|
||||||
{
|
{
|
||||||
return 'tag';
|
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)
|
public static function save($tag)
|
||||||
{
|
{
|
||||||
$tag->validate();
|
$tag->validate();
|
||||||
|
@ -126,7 +118,7 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
if ($rows)
|
if ($rows)
|
||||||
return self::convertRows($rows);
|
return self::spawnFromDatabaseRows($rows);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +139,7 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? self::convertRow($row)
|
? self::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class TokenModel extends AbstractCrudModel
|
final class TokenModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
public static function getTableName()
|
public static function getTableName()
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ class TokenModel extends AbstractCrudModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? self::convertRow($row)
|
? self::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use \Chibi\Sql as Sql;
|
use \Chibi\Sql as Sql;
|
||||||
use \Chibi\Database as Database;
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class UserModel extends AbstractCrudModel
|
final class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
const SETTING_SAFETY = 1;
|
const SETTING_SAFETY = 1;
|
||||||
const SETTING_ENDLESS_SCROLLING = 2;
|
const SETTING_ENDLESS_SCROLLING = 2;
|
||||||
|
@ -14,24 +14,6 @@ class UserModel extends AbstractCrudModel
|
||||||
return 'user';
|
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)
|
public static function save($user)
|
||||||
{
|
{
|
||||||
$user->validate();
|
$user->validate();
|
||||||
|
@ -118,7 +100,7 @@ class UserModel extends AbstractCrudModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? self::convertRow($row)
|
? self::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +126,7 @@ class UserModel extends AbstractCrudModel
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
return $row
|
return $row
|
||||||
? self::convertRow($row)
|
? self::spawnFromDatabaseRow($row)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +136,7 @@ class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($user, $post, $score)
|
Database::transaction(function() use ($user, $post, $score)
|
||||||
{
|
{
|
||||||
|
$post->removeCache('score');
|
||||||
$stmt = new Sql\DeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_score');
|
$stmt->setTable('post_score');
|
||||||
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
|
@ -177,6 +160,7 @@ class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($user, $post)
|
Database::transaction(function() use ($user, $post)
|
||||||
{
|
{
|
||||||
|
$post->removeCache('fav_count');
|
||||||
self::removeFromUserFavorites($user, $post);
|
self::removeFromUserFavorites($user, $post);
|
||||||
$stmt = new Sql\InsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
|
@ -191,6 +175,7 @@ class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($user, $post)
|
Database::transaction(function() use ($user, $post)
|
||||||
{
|
{
|
||||||
|
$post->removeCache('fav_count');
|
||||||
$stmt = new Sql\DeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
|
|
|
@ -18,12 +18,16 @@ class ListCommentJobTest extends AbstractTest
|
||||||
|
|
||||||
$this->assert->areEqual(0, CommentModel::getCount());
|
$this->assert->areEqual(0, CommentModel::getCount());
|
||||||
|
|
||||||
$this->mockComment($this->mockUser());
|
$comment = $this->mockComment($this->mockUser());
|
||||||
|
|
||||||
$ret = $this->runApi(1);
|
$ret = $this->runApi(1);
|
||||||
$this->assert->areEqual(1, count($ret->entities));
|
$this->assert->areEqual(1, count($ret->entities));
|
||||||
|
|
||||||
$post = $ret->entities[0];
|
$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)
|
$samePost = $this->assert->doesNotThrow(function() use ($post)
|
||||||
{
|
{
|
||||||
return PostModel::getById($post->getId());
|
return PostModel::getById($post->getId());
|
||||||
|
|
Loading…
Reference in a new issue