perfs + new database access
authorPierre Habouzit (MadCoder <pierre.habouzit@m4x.org>
Tue, 28 Dec 2004 12:50:49 +0000 (12:50 +0000)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Thu, 26 Jun 2008 21:26:55 +0000 (23:26 +0200)
 * improve perfs wrt html escaping :
    1. I do NOT understand php refs at all : call by ref seems to be slower than call by value !?
    2. Based on (1), escape_html do not pass args by refs, but by value.
       -> 25% of pure speed gain on mescontacts.php

 * create {iterate ...} compiler function :
    - works like {foreach} but you give a XOrgIterator for 'from'
    - very very very nice for database lazy copying (we don't need mysql_assign anymore).
    - mescontacts.php as a proof of concept.

 * database access class :
    - SQL abstractors sux, they are too complex
    - drupal has nice things, I've inspired myself. The desired things are :
        . drop magic_quotes_gpc
        . maybe have one day some features wrt table names (some ACLs ?)
        -> for that, our tiny engine is enough.
        -> if it's sexy enough, I plan to make it enter diogenes.
    - create SQL Iterators.  nice, clears the mysql_datas.
        -> make them lazy would be great though (memory ...)

git-archimport-id: opensource@polytechnique.org--2005/platal--mainline--0.9--patch-154

htdocs/carnet/mescontacts.php
include/xorg.globals.inc.php.in
include/xorg.inc.php
include/xorg/database.inc.php [new file with mode: 0644]
include/xorg/iterator.inc.php [new file with mode: 0644]
include/xorg/page.inc.php
include/xorg/smarty.plugins.inc.php
plugins/compiler.iterate.php [new file with mode: 0644]
templates/carnet/mescontacts.tpl

index 442abcf..fcf74b9 100644 (file)
@@ -115,7 +115,8 @@ if(Get::has('trombi')) {
            LEFT  JOIN geoloc_region  AS gr  ON (adr.pays = gr.a2 AND adr.region = gr.region)
            WHERE c.uid = $uid
            ORDER BY sortkey, a.prenom";
-    $page->mysql_assign($sql,'contacts','nb_contacts');
+    
+    $page->assign_by_ref('citer', $globals->xdb->iterator($sql));
 }
 
 $page->run();
index 4bc0f9d..8cf171f 100644 (file)
@@ -19,8 +19,7 @@
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-require_once("diogenes.core.globals.inc.php");
-require_once("diogenes.database.inc.php");
+require_once('diogenes.core.globals.inc.php');
 
 // {{{ class XorgGlobals
 
@@ -32,7 +31,7 @@ class XorgGlobals extends DiogenesCoreGlobals
     var $hook;
 
     /** The x.org version */
-    var $version = "@VERSION@";
+    var $version = '@VERSION@';
     var $debug   = false;
 
     /** db params */
@@ -47,19 +46,19 @@ class XorgGlobals extends DiogenesCoreGlobals
     var $table_log_events   = 'logger.events';
 
     /** logger */
-    var $tauth  = array('native'=>"auth_user_md5");
-    var $tlabel = array('native'=>"X.Org");
+    var $tauth  = array('native'=>'auth_user_md5');
+    var $tlabel = array('native'=>'X.Org');
 
     /** paths */
-    var $baseurl   = "http://localhost/xorg";
-    var $spoolroot = "/var/spool/xorg";
+    var $baseurl   = 'http://localhost/xorg';
+    var $spoolroot = '/var/spool/xorg';
     var $root      = null;
 
     function init()
     {
         global $globals;
-        require_once("xorg/hook.inc.php");
-        require_once("xorg/menu.inc.php");
+        require_once('xorg/hook.inc.php');
+        require_once('xorg/menu.inc.php');
 
         $globals       = new XorgGlobals;
         $globals->root = dirname(dirname(__FILE__));
@@ -91,6 +90,12 @@ class XorgGlobals extends DiogenesCoreGlobals
             $globals->db->trace_on();
         }
     }
+
+    function dbconnect()
+    {
+        parent::dbconnect();
+        $this->xdb =& new XOrgDB($this->db);
+    }
 }
 
 // }}}
index 4068be4..6c3daea 100644 (file)
@@ -43,9 +43,11 @@ define('NO_SKIN', 1);
 // }}}
 // {{{ globals + session init
 
-require_once("xorg.globals.inc.php");
-require_once('xorg/session.inc.php');
 require_once('xorg/env.inc.php');
+require_once('xorg/iterator.inc.php');
+require_once('xorg/database.inc.php');
+require_once('xorg.globals.inc.php');
+require_once('xorg/session.inc.php');
 XorgGlobals::init();
 XorgSession::init();
 
diff --git a/include/xorg/database.inc.php b/include/xorg/database.inc.php
new file mode 100644 (file)
index 0000000..7eaf0fe
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2004 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ **************************************************************************/
+
+require_once('diogenes.database.inc.php');
+
+// {{{ class XOrgDB
+
+class XOrgDB
+{
+    // {{{ properties
+   
+    var $_db;
+    
+    // }}}
+    // {{{ constructor
+
+    function XOrgDB(&$diog_db)
+    {
+        $this->_db =& $diog_db;
+    }
+
+    // }}}
+    // {{{ function query
+
+    function &query()
+    {
+        $args     = func_get_args();
+        $query    = array_map(Array($this, '_db_escape'), $args);
+        $query[0] = $args[0];
+        return new XOrgDBResult(call_user_func_array('sprintf', $query), $this->_db);
+    }
+
+    // }}}
+    // {{{ function iterator()
+
+    function &iterator()
+    {
+        $args     = func_get_args();
+        $query    = array_map(Array($this, '_db_escape'), $args);
+        $query[0] = $args[0];
+        return new XOrgDBIterator(call_user_func_array('sprintf', $query), $this->_db);
+    }
+    
+    // }}}
+    // {{{ function _db_escape
+
+    function _db_escape(&$var)
+    {
+        switch (gettype($var)) {
+            case 'boolean':
+                return $var ? 1 : 0;
+            
+            case 'integer':
+            case 'double':
+            case 'float':
+                return $var;
+
+            case 'string':
+                if (get_magic_quotes_gpc()) {
+                    return addslashes(stripslashes($var));
+                } else {
+                    return addslashes($var);
+                }
+
+            case 'NULL':
+                return 'NULL';
+
+            case 'object':
+            case 'array':
+                return addslashes(serialize($var));
+
+            default:
+                die(var_export($var, true).' is not a valid for a database entry');
+        }
+    }
+
+    // }}}
+}
+
+// }}}
+// {{{ class XOrgDBResult
+
+class XOrgDBResult
+{
+    // {{{ properties
+
+    var $_res;
+
+    // }}}
+    // {{{ constructor
+
+    function XOrgDBResult($query, &$db)
+    {
+        $this->_res =& $db->query($query);
+    }
+
+    // }}}
+    // {{{ destructor
+
+    function free()
+    {
+        mysql_free_result($this->_res);
+        unset($this);
+    }
+
+    // }}}
+    // {{{ function fetchRow
+
+    function &fetchRow()
+    {
+        return mysql_fetch_row($this->_res);
+    }
+
+    // }}}
+    // {{{ function fetchAssoc
+
+    function &fetchAssoc()
+    {
+        return mysql_fetch_assoc($this->_res);
+    }
+
+    // }}}
+    // {{{ function fetchAllRow
+
+    function &fetchAllRow()
+    {
+        $result = Array();
+        while ($result[] = mysql_fetch_row($this->_res)) { }
+        array_pop($result);
+        return $result;
+    }
+
+    // }}}
+    // {{{ function fetchAssoc
+
+    function &fetchAllAssoc()
+    {
+        $result = Array();
+        while ($result[] = mysql_fetch_assoc($this->_res)) { }
+        array_pop($result);
+        return $result;
+    }
+
+    // }}}
+    // {{{ function numRows
+    
+    function numRows()
+    {
+        return mysql_num_rows($this->_res);
+    }
+
+    // }}}
+}
+
+// }}}
+// {{{ class XOrgDBIterator
+
+class XOrgDBIterator extends XOrgIterator
+{
+    // {{{ properties
+
+    var $_result;
+    var $_pos;
+    var $_total;
+    var $_mode = MYSQL_ASSOC;
+
+    // }}}
+    // {{{
+    
+    function XOrgDBIterator($query, &$db, $mode = MYSQL_ASSOC)
+    {
+        $this->_result =& new XOrgDBResult($query, $db);
+        $this->_pos    = 0;
+        $this->_total  = $this->_result->numRows();
+        $this->_mode   = $mode;
+    }
+
+    // }}}
+    // {{{ function next ()
+    
+    function &next()
+    {
+        $this->_pos ++;
+        if ($this->_pos > $this->_total) {
+            $this->_result->free();
+            unset($this);
+            return null;
+        }
+        return $this->_mode != MYSQL_ASSOC ? $this->_result->fetchRow() : $this->_result->fetchAssoc();
+    }
+
+    // }}}
+    // {{{ function first
+
+    function first()
+    {
+        return $this->_pos == 1;
+    }
+
+    // }}}
+    // {{{ function last
+
+    function last()
+    {
+        return $this->_last == $this->_total;
+    }
+
+    // }}}
+    // {{{ function total()
+
+    function total()
+    {
+        return $this->_total;
+    }
+
+    // }}}
+}
+
+// }}}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker:
+?>
diff --git a/include/xorg/iterator.inc.php b/include/xorg/iterator.inc.php
new file mode 100644 (file)
index 0000000..9b85438
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2004 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ **************************************************************************/
+
+// {{{ class XOrgIterator
+
+class XOrgIterator
+{
+    // {{{ function next
+    
+    function &next()
+    {
+        return null;
+    }
+
+    // }}}
+    // {{{ function first
+
+    function first()
+    {
+        return false;
+    }
+
+    // }}}
+    // {{{ function last
+
+    function last()
+    {
+        return false;
+    }
+
+    // }}}
+    // {{{ function total
+
+    function total()
+    {
+        return 0;
+    }
+
+    // }}}
+    
+}
+
+// }}}
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker:
+?>
index 9c481fa..a29ee48 100644 (file)
@@ -57,14 +57,14 @@ class XorgPage extends DiogenesCorePage
         $this->cache_dir     = $globals->spoolroot."/cache/";
        $this->use_sub_dirs  = false;
 
-
         $this->config_overwrite  = false;
         $this->compile_check     = !empty($globals->debug);
         $this->caching          = ($type == SKINNED);
-       if ($type == SKINNED) {
-           $this->register_modifier('escape_html', 'escape_html');
-           $this->default_modifiers = Array('escape_html');
-       }
+
+        if ($type == SKINNED) {
+            $this->register_modifier('escape_html', 'escape_html');
+            $this->default_modifiers[] = '@escape_html';
+        }
 
         $this->_page_type = $type;
         $this->_tpl       = $tpl;
@@ -90,7 +90,7 @@ class XorgPage extends DiogenesCorePage
         $this->caching   = ($type == SKINNED);
        if ($type == SKINNED) {
            $this->register_modifier('escape_html', 'escape_html');
-           $this->default_modifiers = Array('escape_html');
+           $this->default_modifiers = Array('@escape_html');
        }
 
         $this->_page_type = $type;
index fb823b4..eb7385e 100644 (file)
@@ -40,7 +40,7 @@ function block_dynamic($param, $content, &$smarty)
  * " --> &quot;
  * & not followed by some entity --> &amp;
  */
-function escape_html(&$string)
+function escape_html($string)
 {
     if(is_string($string)) {
        $transtbl = Array('<' => '&lt;', '>' => '&gt;', '"' => '&quot;');
diff --git a/plugins/compiler.iterate.php b/plugins/compiler.iterate.php
new file mode 100644 (file)
index 0000000..97d3026
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2004 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ ***************************************************************************/
+
+function iterate_end($tag_attrs, &$compiler) {
+    return 'endwhile;';
+}
+
+function smarty_compiler_iterate($tag_attrs, &$compiler)
+{
+    static $reg = false;
+    if (!$reg) {
+        $reg = true;
+        $compiler->register_compiler_function("/iterate", 'iterate_end');
+    }
+
+    $_params = $compiler->_parse_attrs($tag_attrs);
+
+    if (!isset($_params['from'])) {
+        $compiler->_syntax_error("iterate: missing 'from' parameter", E_USER_ERROR, __FILE__, __LINE__);
+        return;
+    }
+
+    if (empty($_params['item'])) {
+        $compiler->_syntax_error("iterate: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        return;
+    }
+
+    $_from = $compiler->_dequote($_params['from']);
+    $_item = $compiler->_dequote($_params['item']);
+
+    if (!is_subclass_of($compiler->_tpl_vars[$_from], 'XOrgIterator')) {
+        $compiler->_syntax_error("iterate: 'from' parameter has to be a instance of an XOrgIterator Object",
+                E_USER_ERROR, __FILE__, __LINE__);
+        return;
+    }
+
+
+    return "while ((\$this->_tpl_vars['$_item'] =& \$this->_tpl_vars['$_from']->next()) !== null):";
+}
+
+/* vim: set expandtab: */
+
+?>
index a605570..f26d995 100644 (file)
@@ -38,7 +38,7 @@
   il te suffit de cliquer sur l'icône <img src="{"images/ajouter.gif"|url}" alt="ajout contact" /> en face de son nom dans les résultats !
 </p>  
 
-{if $nb_contacts || $trombi}
+{if $citer->total()}
 <p>
   Pour récupérer ta liste de contacts dans un PDF imprimable :<br />
   [<a href="mescontacts_pdf.php/mes_contacts.pdf?order=promo" class='popup'><strong>Triée par promo</strong></a>]
@@ -70,9 +70,9 @@ Pour afficher le trombi de tes contacts : [<a href="?trombi=1"><strong>vue sous
 <br />
 
 <div class="contact-list">
-{foreach item=contact from=$contacts}
+{iterate from=citer item=contact}
 {include file=include/minifiche.tpl c=$contact show_action="retirer"}
-{/foreach}
+{/iterate}
 </div>
 
 {/if}