Faster queries, fixed foreign keys

When user is removed, their posts and comments get null user ID now
This commit is contained in:
Marcin Kurczewski 2013-10-19 18:14:19 +02:00
parent 53f9076bff
commit ea463cb0db
6 changed files with 70 additions and 31 deletions

View file

@ -40,7 +40,7 @@ class CommentController
$comments = $searchDbQuery->get(); $comments = $searchDbQuery->get();
$comments = R::convertToBeans('comment', $comments); $comments = R::convertToBeans('comment', $comments);
R::preload($comments, ['commenter' => 'user']); R::preload($comments, ['commenter' => 'user', 'post', 'post.uploader' => 'user']);
$this->context->postGroups = true; $this->context->postGroups = true;
$this->context->transport->paginator = new StdClass; $this->context->transport->paginator = new StdClass;
$this->context->transport->paginator->page = $page; $this->context->transport->paginator->page = $page;

View file

@ -84,8 +84,34 @@ class PostController
$buildDbQuery = function($dbQuery, $query) $buildDbQuery = function($dbQuery, $query)
{ {
$dbQuery->from('post'); $dbQuery
->addSql(', ')
->open()
->select('COUNT(1)')
->from('comment')
->where('comment.post_id = post.id')
->close()
->as('comment_count');
$dbQuery
->addSql(', ')
->open()
->select('COUNT(1)')
->from('favoritee')
->where('favoritee.post_id = post.id')
->close()
->as('fav_count');
$dbQuery
->addSql(', ')
->open()
->select('COUNT(1)')
->from('post_tag')
->where('post_tag.post_id = post.id')
->close()
->as('tag_count');
$dbQuery->from('post');
/* safety */ /* safety */
$allowedSafety = array_filter(PostSafety::getAll(), function($safety) $allowedSafety = array_filter(PostSafety::getAll(), function($safety)
@ -121,12 +147,14 @@ class PostController
$page = max(1, min($pageCount, $page)); $page = max(1, min($pageCount, $page));
$searchDbQuery = R::$f->begin(); $searchDbQuery = R::$f->begin();
$searchDbQuery->select('*'); $searchDbQuery->select('post.*');
$buildDbQuery($searchDbQuery, $query); $buildDbQuery($searchDbQuery, $query);
$searchDbQuery->limit('?')->put($postsPerPage); $searchDbQuery->limit('?')->put($postsPerPage);
$searchDbQuery->offset('?')->put(($page - 1) * $postsPerPage); $searchDbQuery->offset('?')->put(($page - 1) * $postsPerPage);
$posts = $searchDbQuery->get(); $posts = $searchDbQuery->get();
$posts = R::convertToBeans('post', $posts);
R::preload($posts, ['uploader' => 'user']);
$this->context->transport->paginator = new StdClass; $this->context->transport->paginator = new StdClass;
$this->context->transport->paginator->page = $page; $this->context->transport->paginator->page = $page;
$this->context->transport->paginator->pageCount = $pageCount; $this->context->transport->paginator->pageCount = $pageCount;
@ -593,7 +621,7 @@ class PostController
private function decorateSearchQuery($dbQuery, $tokens) private function decorateSearchQuery($dbQuery, $tokens)
{ {
$orderColumn = 'id'; $orderColumn = 'post.id';
$orderDir = 1; $orderDir = 1;
$randomReset = true; $randomReset = true;
@ -601,13 +629,13 @@ class PostController
{ {
if ($token{0} == '-') if ($token{0} == '-')
{ {
$dbQuery->andNot(); $andFunc = 'andNot';
$token = substr($token, 1); $token = substr($token, 1);
$neg = true; $neg = true;
} }
else else
{ {
$dbQuery->and(); $andFunc = 'and';
$neg = false; $neg = false;
} }
@ -616,6 +644,7 @@ class PostController
{ {
$val = $token; $val = $token;
$dbQuery $dbQuery
->$andFunc()
->exists() ->exists()
->open() ->open()
->select('1') ->select('1')
@ -637,12 +666,7 @@ class PostController
case 'favmax': case 'favmax':
$operator = $key == 'favmin' ? '>=' : '<='; $operator = $key == 'favmin' ? '>=' : '<=';
$dbQuery $dbQuery
->open() ->$andFunc('fav_count ' . $operator . ' ?')->put(intval($val));
->select('COUNT(1)')
->from('favoritee')
->where('post_id = post.id')
->close()
->addSql($operator . ' ?')->put(intval($val));
break; break;
case 'type': case 'type':
@ -658,7 +682,7 @@ class PostController
throw new SimpleException('Unknown type "' . $val . '"'); throw new SimpleException('Unknown type "' . $val . '"');
} }
$dbQuery $dbQuery
->addSql('type = ?') ->$andFunc('type = ?')
->put($type); ->put($type);
break; break;
@ -679,7 +703,7 @@ class PostController
if ($key == 'date') if ($key == 'date')
{ {
$dbQuery $dbQuery
->addSql('upload_date >= ?') ->$andFunc('upload_date >= ?')
->and('upload_date <= ?') ->and('upload_date <= ?')
->put($timeMin) ->put($timeMin)
->put($timeMax); ->put($timeMax);
@ -687,13 +711,13 @@ class PostController
elseif ($key == 'datemin') elseif ($key == 'datemin')
{ {
$dbQuery $dbQuery
->addSql('upload_date >= ?') ->$andFunc('upload_date >= ?')
->put($timeMin); ->put($timeMin);
} }
elseif ($key == 'datemax') elseif ($key == 'datemax')
{ {
$dbQuery $dbQuery
->addSql('upload_date <= ?') ->$andFunc('upload_date <= ?')
->put($timeMax); ->put($timeMax);
} }
else else
@ -708,6 +732,7 @@ class PostController
case 'favoritee': case 'favoritee':
case 'favoriter': case 'favoriter':
$dbQuery $dbQuery
->$andFunc()
->exists() ->exists()
->open() ->open()
->select('1') ->select('1')
@ -724,7 +749,7 @@ class PostController
case 'uploader': case 'uploader':
case 'uploaded': case 'uploaded':
$dbQuery $dbQuery
->addSql('uploader_id = ') ->$andFunc('uploader_id = ')
->open() ->open()
->select('user.id') ->select('user.id')
->from('user') ->from('user')
@ -751,35 +776,30 @@ class PostController
if ($neg) if ($neg)
{ {
$orderDir *= -1; $orderDir *= -1;
$dbQuery->addSql('0');
}
else
{
$dbQuery->addSql('1');
} }
switch ($val) switch ($val)
{ {
case 'id': case 'id':
$orderColumn = 'id'; $orderColumn = 'post.id';
break; break;
case 'date': case 'date':
$orderColumn = 'upload_date'; $orderColumn = 'post.upload_date';
break; break;
case 'comment': case 'comment':
case 'comments': case 'comments':
case 'commentcount': case 'commentcount':
$orderColumn = '(SELECT COUNT(1) FROM comment WHERE post_id = post.id)'; $orderColumn = 'comment_count';
break; break;
case 'fav': case 'fav':
case 'favs': case 'favs':
case 'favcount': case 'favcount':
$orderColumn = '(SELECT COUNT(1) FROM favoritee WHERE post_id = post.id)'; $orderColumn = 'fav_count';
break; break;
case 'tag': case 'tag':
case 'tags': case 'tags':
case 'tagcount': case 'tagcount':
$orderColumn = '(SELECT COUNT(1) FROM post_tag WHERE post_id = post.id)'; $orderColumn = 'tag_count';
break; break;
case 'random': case 'random':
//seeding works like this: if you visit anything //seeding works like this: if you visit anything
@ -805,6 +825,11 @@ class PostController
if ($randomReset) if ($randomReset)
unset($_SESSION['browsing-seed']); unset($_SESSION['browsing-seed']);
$dbQuery->orderBy($orderColumn . ' ' . ($orderDir == 1? 'DESC' : 'ASC'));
$dbQuery->orderBy($orderColumn);
if ($orderDir == 1)
$dbQuery->desc();
else
$dbQuery->asc();
} }
} }

View file

@ -189,6 +189,16 @@ class UserController
if ($suppliedPasswordHash != $user->pass_hash) if ($suppliedPasswordHash != $user->pass_hash)
throw new SimpleException('Must supply valid password'); throw new SimpleException('Must supply valid password');
} }
foreach ($user->alias('commenter')->ownComment as $comment)
{
$comment->commenter = null;
R::store($comment);
}
foreach ($user->alias('uploader')->ownPost as $post)
{
$post->uploader = null;
R::store($post);
}
$user->ownFavoritee = []; $user->ownFavoritee = [];
R::store($user); R::store($user);
R::trash($user); R::trash($user);
@ -375,6 +385,8 @@ class UserController
->put(($page - 1) * $postsPerPage); ->put(($page - 1) * $postsPerPage);
$posts = $searchDbQuery->get(); $posts = $searchDbQuery->get();
$posts = R::convertToBeans('post', $posts);
R::preload($posts, ['uploader' => 'user']);
$this->context->transport->user = $user; $this->context->transport->user = $user;
$this->context->transport->tab = $tab; $this->context->transport->tab = $tab;
$this->context->transport->paginator = new StdClass; $this->context->transport->paginator = new StdClass;

View file

@ -52,6 +52,8 @@ class PrivilegesHelper
public static function getIdentitySubPrivilege($user) public static function getIdentitySubPrivilege($user)
{ {
if (!$user)
return false;
$userFromContext = \Chibi\Registry::getContext()->user; $userFromContext = \Chibi\Registry::getContext()->user;
return $user->id == $userFromContext->id ? 'own' : 'all'; return $user->id == $userFromContext->id ? 'own' : 'all';
} }

View file

@ -1,3 +1,3 @@
<a class="post post-type-<?php echo TextHelper::camelCaseToHumanCase(PostType::toString($this->context->post['type'])) ?>" href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $this->context->post['id']]) ?>"> <a class="post post-type-<?php echo TextHelper::camelCaseToHumanCase(PostType::toString($this->context->post->type)) ?>" href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $this->context->post->id]) ?>">
<img src="<?php echo \Chibi\UrlHelper::route('post', 'thumb', ['id' => $this->context->post['id']]) ?>" alt="@<?php echo $this->context->post['id'] ?>"/> <img src="<?php echo \Chibi\UrlHelper::route('post', 'thumb', ['id' => $this->context->post->id]) ?>" alt="@<?php echo $this->context->post->id ?>"/>
</a> </a>

View file

@ -53,7 +53,7 @@
<div class="key-value uploader"> <div class="key-value uploader">
<span class="key">Uploader:</span> <span class="key">Uploader:</span>
<?php if ($this->context->transport->post->uploader->id): ?> <?php if ($this->context->transport->post->uploader): ?>
<span class="value" title="<?php echo $val = $this->context->transport->post->uploader->name ?>"> <span class="value" title="<?php echo $val = $this->context->transport->post->uploader->name ?>">
<a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['name' => $this->context->transport->post->uploader->name]) ?>"> <a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['name' => $this->context->transport->post->uploader->name]) ?>">
<?php echo $val ?> <?php echo $val ?>