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.
This commit is contained in:
Marcin Kurczewski 2014-05-04 09:41:50 +02:00
parent 70f187c431
commit 5c003588fa
8 changed files with 40 additions and 35 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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');

View file

@ -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));
}
}

View file

@ -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)

View file

@ -32,8 +32,8 @@
<div class="tags paginator-content">
<ul>
<?php foreach ($this->context->transport->tags as $tag): ?>
<?php $name = $tag['name'] ?>
<?php $count = $tag['post_count'] ?>
<?php $name = $tag->name ?>
<?php $count = $tag->getPostCount() ?>
<li class="tag" title="<?= $name ?> (<?= $count ?>)">
<a href="<?= str_replace('_query_', $name, $url) ?>"
class="frequency<?php printf('%1.0f', $add + $mul * log($count)) ?>">