Optimisation recherche et pagination

* Optimisation recherche SQL avec utilisation de HAVING plutôt que WHERE
* Simplification et amélioration des performances en supprimant de
RSSPaginator qui n'aidait plus vraiment et nécessitait plus de code et
des copies de données.
* Correction d'un bug dans le titre de la page introduit récemment, et
simplification
This commit is contained in:
Alexandre Alapetite
2013-11-30 22:47:48 +01:00
parent 37ce14c093
commit 1e077160fc
10 changed files with 36 additions and 77 deletions

View File

@@ -33,7 +33,6 @@ class App_FrontController extends FrontController {
include (APP_PATH . '/models/Category.php');
include (APP_PATH . '/models/Feed.php');
include (APP_PATH . '/models/Entry.php');
include (APP_PATH . '/models/RSSPaginator.php');
include (APP_PATH . '/models/Log_Model.php');
}

View File

@@ -46,8 +46,6 @@ class indexController extends ActionController {
'params' => $params
);
$this->view->rss_title = View::title();
if ($output === 'rss') {
// no layout for RSS output
$this->view->_useLayout (false);
@@ -67,19 +65,6 @@ class indexController extends ActionController {
$this->view->get_c = '';
$this->view->get_f = '';
// mise à jour des titres
$this->view->nb_not_read = HelperCategory::CountUnreads($this->view->cat_aside, 1);
if ($this->view->nb_not_read > 0) {
View::appendTitle (' (' . $this->view->nb_not_read . ')');
}
View::prependTitle (' - ');
$this->view->rss_title = $this->view->currentName . ' - ' . $this->view->rss_title;
View::prependTitle (
$this->view->currentName .
($this->nb_not_read_cat > 0 ? ' (' . $this->nb_not_read_cat . ')' : '')
);
$get = Request::param ('get', 'a');
$getType = $get[0];
$getId = substr ($get, 2);
@@ -92,6 +77,18 @@ class indexController extends ActionController {
return;
}
$this->view->nb_not_read = HelperCategory::CountUnreads($this->view->cat_aside, 1);
// mise à jour des titres
if ($this->view->nb_not_read > 0) {
View::appendTitle (' (' . $this->view->nb_not_read . ')');
}
View::prependTitle (
$this->view->currentName .
($this->nb_not_read_cat > 0 ? ' (' . $this->nb_not_read_cat . ')' : '') .
' - '
);
// On récupère les différents éléments de filtrage
$this->view->state = $state = Request::param ('state', $this->view->conf->defaultView ());
$filter = Request::param ('search', '');
@@ -138,13 +135,13 @@ class indexController extends ActionController {
}
if (count($entries) <= $nb) {
$next = '';
$this->view->nextId = '';
} else { //We have more elements for pagination
$lastEntry = array_pop($entries);
$next = $lastEntry->id();
$this->view->nextId = $lastEntry->id();
}
$this->view->entryPaginator = new RSSPaginator ($entries, $next);
$this->view->entries = $entries;
} catch (EntriesGetterException $e) {
Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE);
Error::error (

View File

@@ -10,10 +10,9 @@
<?php $this->renderHelper ('javascript_vars'); ?>
//]]></script>
<?php
$next = isset($this->entryPaginator) ? $this->entryPaginator->next() : '';
if (!empty($next)) {
if (!empty($this->nextId)) {
$params = Request::params ();
$params['next'] = $next;
$params['next'] = $this->nextId;
?>
<link id="prefetch" rel="next prefetch" href="<?php echo Url::display (array ('c' => Request::controllerName (), 'a' => Request::actionName (), 'params' => $params)); ?>" />
<?php } ?>

View File

@@ -17,8 +17,6 @@
$string_mark = Translate::t ('mark_cat_read');
}
$nextGet = $get;
$p = $this->entryPaginator->peek();
$idMax = $p === null ? '0' : $p->id();
if (($this->conf->onread_jump_next () === 'yes') && (strlen ($get) > 2)) {
$anotherUnreadId = '';
$foundCurrent = false;
@@ -54,6 +52,8 @@
break;
}
}
$p = isset($this->entries[0]) ? $this->entries[0] : null;
$idMax = $p === null ? '0' : $p->id();
$markReadUrl = _url ('entry', 'read', 'is_read', 1, 'get', $get, 'nextGet', $nextGet, 'idMax', $idMax);
Session::_param ('markReadUrl', $markReadUrl);
?>

View File

@@ -504,14 +504,18 @@ class EntryDAO extends Model_pdo {
if ($firstId > 0) {
$where .= 'AND e.id ' . ($order === 'DESC' ? '<=' : '>=') . $firstId . ' ';
}
$terms = explode(' ', trim($filter));
$terms = array_unique(explode(' ', trim($filter)));
sort($terms); //Put #tags first
$having = '';
foreach ($terms as $word) {
if (!empty($word)) {
if ($word[0] === '#' && isset($word[1])) {
$where .= 'AND tags LIKE "%' . $word . '%" ';
$having .= 'AND tags LIKE ? ';
$values[] = '%' . $word .'%';
} elseif (!empty($word)) {
$where .= 'AND (e.title LIKE "%' . $word . '%" OR UNCOMPRESS(e.content_bin) LIKE "%' . $word . '%") ';
$having .= 'AND (e.title LIKE ? OR content LIKE ?) ';
$values[] = '%' . $word .'%';
$values[] = '%' . $word .'%';
}
}
}
@@ -519,6 +523,7 @@ class EntryDAO extends Model_pdo {
$sql = 'SELECT e.id, e.guid, e.title, e.author, UNCOMPRESS(e.content_bin) AS content, e.link, e.date, e.is_read, e.is_favorite, e.id_feed, e.tags '
. 'FROM `' . $this->prefix . 'entry` e '
. 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE ' . $where
. (empty($having) ? '' : 'HAVING' . substr($having, 3))
. 'ORDER BY e.id ' . $order;
if ($limit > 0) {

View File

@@ -1,37 +0,0 @@
<?php
// Un système de pagination beaucoup plus simple que Paginator
// mais mieux adapté à nos besoins
class RSSPaginator {
private $items = array ();
private $next = '';
public function __construct ($items, $next) {
$this->items = $items;
$this->next = $next;
}
public function isEmpty () {
return empty ($this->items);
}
public function items () {
return $this->items;
}
public function next () {
return $this->next;
}
public function peek () {
return isset($this->items[0]) ? $this->items[0] : null;
}
public function render ($view, $getteur) {
$view = APP_PATH . '/views/helpers/'.$view;
if (file_exists ($view)) {
include ($view);
}
}
}

View File

@@ -8,8 +8,8 @@
<ul class="pagination">
<li class="item pager-next">
<?php if ($this->next != '') { ?>
<?php $params[$getteur] = $this->next; ?>
<?php if (!empty($this->nextId)) { ?>
<?php $params['next'] = $this->nextId; ?>
<a id="load_more" href="<?php echo Url::display (array ('c' => $c, 'a' => $a, 'params' => $params)); ?>"><?php echo Translate::t ('load_more'); ?></a>
<?php } elseif ($markReadUrl) { ?>
<a id="bigMarkAsRead" href="<?php echo $markReadUrl; ?>">

View File

@@ -3,8 +3,7 @@
$this->partial ('aside_flux');
$this->partial ('nav_menu');
if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
$items = $this->entryPaginator->items ();
if (!empty($this->entries)) {
?>
<div id="stream" class="normal<?php echo $this->conf->displayPosts () === 'no' ? ' hide_posts' : ''; ?>">
@@ -23,8 +22,7 @@ if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
$email = $this->conf->sharing ('email');
$print = $this->conf->sharing ('print');
?>
<?php foreach ($items as $item) { ?>
<?php foreach ($this->entries as $item) { ?>
<?php if ($display_today && $item->isDay (Days::TODAY)) { ?>
<div class="day" id="day_today">
@@ -199,7 +197,7 @@ if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
</div>
<?php } ?>
<?php $this->entryPaginator->render ('pagination.phtml', 'next'); ?>
<?php $this->renderHelper('pagination'); ?>
</div>
<?php $this->partial ('nav_entries'); ?>

View File

@@ -1,12 +1,11 @@
<?php
$this->partial ('nav_menu');
if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
$items = $this->entryPaginator->items ();
if (!empty($this->entries)) {
?>
<div id="stream" class="reader">
<?php foreach ($items as $item) { ?>
<?php foreach ($this->entries as $item) { ?>
<div class="flux<?php echo !$item->isRead () ? ' not_read' : ''; ?><?php echo $item->isFavorite () ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id (); ?>">
<div class="flux_content">
@@ -38,7 +37,7 @@ if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
</div>
<?php } ?>
<?php $this->entryPaginator->render ('pagination.phtml', 'next'); ?>
<?php $this->renderHelper('pagination'); ?>
</div>
<?php } else { ?>

View File

@@ -8,8 +8,7 @@
<lastBuildDate><?php echo gmdate('D, d M Y H:i:s'); ?> GMT</lastBuildDate>
<atom:link href="<?php echo Url::display ($this->rss_url, 'html', true); ?>" rel="self" type="application/rss+xml" />
<?php
$items = $this->entryPaginator->items ();
foreach ($items as $item) {
foreach ($this->entries as $item) {
?>
<item>
<title><?php echo $item->title (); ?></title>