From 5c003588fa0bd5215156914f1bf145e246f3d82e Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sun, 4 May 2014 09:41:50 +0200 Subject: [PATCH] Made tag retrieval use entity conversion again Previously engine used raw database rows for performance boost. The benefits were negligibly small, therefore it was changed so that it returns full entities again. That way serializing job return values for HTTP API should be easier in the future. --- src/Api/Jobs/ListRelatedTagsJob.php | 4 +- src/Api/Jobs/ListTagsJob.php | 2 +- src/Controllers/TagController.php | 10 ++--- src/Models/AbstractCrudModel.php | 38 ++++++++----------- src/Models/Entities/TagEntity.php | 3 ++ .../SearchServices/TagSearchService.php | 6 +-- src/Models/TagModel.php | 8 ++++ src/Views/tag-list.phtml | 4 +- 8 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/Api/Jobs/ListRelatedTagsJob.php b/src/Api/Jobs/ListRelatedTagsJob.php index 20555809..66f77ba2 100644 --- a/src/Api/Jobs/ListRelatedTagsJob.php +++ b/src/Api/Jobs/ListRelatedTagsJob.php @@ -8,9 +8,9 @@ class ListRelatedTagsJob extends ListTagsJob $tag = $this->getArgument(self::TAG_NAME); $otherTags = $this->hasArgument(self::TAG_NAMES) ? $this->getArgument(self::TAG_NAMES) : []; - $tags = TagSearchService::getRelatedTagRows($tag); + $tags = TagSearchService::getRelatedTags($tag); $tagCount = count($tags); - $tags = array_filter($tags, function($tag) use ($otherTags) { return !in_array($tag['name'], $otherTags); }); + $tags = array_filter($tags, function($tag) use ($otherTags) { return !in_array($tag->name, $otherTags); }); $tags = array_slice($tags, 0, $pageSize); return $this->getPager($tags, $tagCount, $page, $pageSize); diff --git a/src/Api/Jobs/ListTagsJob.php b/src/Api/Jobs/ListTagsJob.php index 288668d1..58af22d8 100644 --- a/src/Api/Jobs/ListTagsJob.php +++ b/src/Api/Jobs/ListTagsJob.php @@ -7,7 +7,7 @@ class ListTagsJob extends AbstractPageJob $page = $this->getArgument(self::PAGE_NUMBER); $query = $this->getArgument(self::QUERY); - $tags = TagSearchService::getEntitiesRows($query, $pageSize, $page); + $tags = TagSearchService::getEntities($query, $pageSize, $page); $tagCount = TagSearchService::getEntityCount($query); return $this->getPager($tags, $tagCount, $page, $pageSize); diff --git a/src/Controllers/TagController.php b/src/Controllers/TagController.php index 36e40a0d..b79d777f 100644 --- a/src/Controllers/TagController.php +++ b/src/Controllers/TagController.php @@ -12,7 +12,7 @@ class TagController $context = getContext(); $context->viewName = 'tag-list-wrapper'; - $context->highestUsage = TagSearchService::getMostUsedTag()['post_count']; + $context->highestUsage = TagSearchService::getMostUsedTag()->getPostCount(); $context->filter = $filter; $context->transport->tags = $ret->entities; $context->transport->paginator = $ret; @@ -36,8 +36,8 @@ class TagController function($tag) { return [ - 'name' => $tag['name'], - 'count' => $tag['post_count'] + 'name' => $tag->name, + 'count' => $tag->getPostCount(), ]; }, $ret->entities)); } @@ -61,8 +61,8 @@ class TagController function($tag) { return [ - 'name' => $tag['name'], - 'count' => $tag['post_count'] + 'name' => $tag->name, + 'count' => $tag->getPostCount(), ]; }, $ret->entities)); } diff --git a/src/Models/AbstractCrudModel.php b/src/Models/AbstractCrudModel.php index 434fdf32..bc52f67c 100644 --- a/src/Models/AbstractCrudModel.php +++ b/src/Models/AbstractCrudModel.php @@ -4,6 +4,8 @@ use \Chibi\Database as Database; abstract class AbstractCrudModel implements IModel { + private static $keyCache = []; + public static function spawn() { $entityClassName = static::getEntityClassName(); @@ -31,7 +33,7 @@ abstract class AbstractCrudModel implements IModel $row = Database::fetchOne($stmt); if ($row) - return self::convertRow($row); + return static::convertRow($row); if ($throw) throw new SimpleNotFoundException('Invalid %s ID "%s"', static::getTableName(), $key); @@ -47,7 +49,7 @@ abstract class AbstractCrudModel implements IModel $rows = Database::fetchAll($stmt); if ($rows) - return self::convertRows($rows); + return static::convertRows($rows); return []; } @@ -72,12 +74,19 @@ abstract class AbstractCrudModel implements IModel public static function convertRow($row) { - $entity = self::spawn(); + $entity = static::spawn(); foreach ($row as $key => $val) { - $key = TextCaseConverter::convert($key, - TextCaseConverter::SNAKE_CASE, - TextCaseConverter::LOWER_CAMEL_CASE); + if (isset(self::$keyCache[$key])) + { + $key = self::$keyCache[$key]; + } + else + { + $key = self::$keyCache[$key] = TextCaseConverter::convert($key, + TextCaseConverter::SNAKE_CASE, + TextCaseConverter::LOWER_CAMEL_CASE); + } $entity->$key = $val; } @@ -86,25 +95,10 @@ abstract class AbstractCrudModel implements IModel public static function convertRows(array $rows) { - $keyCache = []; $entities = []; foreach ($rows as $i => $row) { - $entity = self::spawn(); - foreach ($row as $key => $val) - { - if (isset($keyCache[$key])) - $key = $keyCache[$key]; - else - { - $key = $keyCache[$key] = TextCaseConverter::convert($key, - TextCaseConverter::SNAKE_CASE, - TextCaseConverter::LOWER_CAMEL_CASE); - } - - $entity->$key = $val; - } - $entities[$i] = $entity; + $entities[$i] = static::convertRow($row); } return $entities; } diff --git a/src/Models/Entities/TagEntity.php b/src/Models/Entities/TagEntity.php index 6274c81e..6cdd72c5 100644 --- a/src/Models/Entities/TagEntity.php +++ b/src/Models/Entities/TagEntity.php @@ -8,6 +8,9 @@ class TagEntity extends AbstractEntity public function getPostCount() { + if ($this->hasCache('post_count')) + return $this->getCache('post_count'); + $stmt = new Sql\SelectStatement(); $stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count')); $stmt->setTable('post_tag'); diff --git a/src/Models/SearchServices/TagSearchService.php b/src/Models/SearchServices/TagSearchService.php index 593c592b..28052847 100644 --- a/src/Models/SearchServices/TagSearchService.php +++ b/src/Models/SearchServices/TagSearchService.php @@ -9,7 +9,7 @@ class TagSearchService extends AbstractSearchService $stmt->addColumn(new Sql\AliasFunctor(new Sql\CountFunctor('post_tag.post_id'), 'post_count')); } - public static function getRelatedTagRows($parentTagName) + public static function getRelatedTags($parentTagName) { $parentTagEntity = TagModel::findByName($parentTagName, false); if (empty($parentTagEntity)) @@ -62,7 +62,7 @@ class TagSearchService extends AbstractSearchService usort($rows, function($a, $b) { return intval($b['sort']) - intval($a['sort']); }); - return $rows; + return TagModel::convertRows($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 Database::fetchOne($stmt); + return TagModel::convertRow(Database::fetchOne($stmt)); } } diff --git a/src/Models/TagModel.php b/src/Models/TagModel.php index 1fa3f66b..0c3aaa54 100644 --- a/src/Models/TagModel.php +++ b/src/Models/TagModel.php @@ -9,6 +9,14 @@ class TagModel extends AbstractCrudModel 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) { Database::transaction(function() use ($tag) diff --git a/src/Views/tag-list.phtml b/src/Views/tag-list.phtml index 7c3c1b29..dd794237 100644 --- a/src/Views/tag-list.phtml +++ b/src/Views/tag-list.phtml @@ -32,8 +32,8 @@