• Forum
  • Doc
  • Screenshots
  • Download
  • Donate
  • Contributors
  • Contact
  • Follow @phpfreechat
  • DEMO
  • Board index ‹ Version 1.x branch ‹ Contributions (v1.x)
  • Change font size
  • FAQ
  • Register
  • Login

Mysql container

Post a bug fix, a new feature, a theme ...

Moderators: OldWolf, re*s.t.a.r.s.*2

Post a reply
7 posts • Page 1 of 1

Postby HenkBB » Sun Dec 03, 2006 9:50 am

Hi kerphi/Stéphane,

First of all thank you very much for the phpfreechat it does perfectly fill our needs as most java chats gave much of our visitors a headache.

I've been thinking of ways to store the data into memory instead of on HD and came up with mysql using table type HEAP or MEMORY.
Thanks to your new storage methode with only 3 functions to rewrite (setMeta, getMeta and rmMeta) I was able to store all data in a single table residing in memory making it very fast.

Here's my little container:

Code: Select all
<?php
/**
 * mysql.class.php
 *
 * Copyright © 2006 Stephane Gully <stephane.gully@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 
Here's your single mysql table.
Because of the new storage functions (setMeta, getMeta, rmMeta)
everything can be stored in just one single table
Giving it type "HEAP" or "MEMORY" mysql loads this table into memory making it very fast
The old (file)code is still in there as reference
You also need a container line in your chat index file:
$params["container_type"] = "mysql";
 

 
 */

require_once dirname(__FILE__)."/../pfccontainer.class.php";

/**
 * pfcContainer_mysql is a concret container which stock data into mysql
 *
 * @author Stephane Gully <stephane.gully@gmail.com>
 */
class pfcContainer_mysql extends pfcContainer{

  //database stuff +++++++++++++++++++++++++++++++++++++++
 
  var $dbServer = 'localhost';
  var $dbPort = 3306;
  var $dbName = 'chat';
  var $dbUser = 'root';
  var $dbPass = '';
  var $dbTable = 'phpfreechat';
  var $nConnID;
  var $bCheck;
 
  function OpenDatabase(){
     $nConnID = mysql_connect($this->dbServer, $this->dbUser, $this->dbPass)
        or die ("No connection with database.");

   $bCheck = mysql_select_db($this->dbName)
        or die ("No database selected.");

   return $nConnID;
  }
 
  function todb($sql){
   global $debug, $nConnID;
   $result = mysql_query($sql);
   if ($result <= 0) {
      echo "This has gone terribly wrong...";
      //echo "<BR>".mysql_error()."<BR>$sql";
      exit();
   };
   return $result;
  }
 
//old stuff +++++++++++++++++++++++++++++++++++++++++++++
   

  var $_users = array("nickid"    => array(),
                      "timestamp" => array());
  var $_meta = array();
 
  function pfcContainer_File(&$config)
  {
    pfcContainer::pfcContainer($config);
  }

  function loadPaths()
  {
    $c =& $this->c;
    $c->container_cfg_chat_dir   = $c->data_private_path."/chat";
    $c->container_cfg_server_dir = $c->container_cfg_chat_dir."/s_".$c->serverid;
  }
 
  function getDefaultConfig()
  {
    $c =& $this->c;
   
    $cfg = pfcContainer::getDefaultConfig();
    $cfg["chat_dir"]   = ''; // will be generated from the other parameters into the init step
    $cfg["server_dir"] = ''; // will be generated from the other parameters into the init step
    return $cfg;
  }
 
  function init()
  {
    $errors = pfcContainer::init();
    $c =& $this->c;

    // generate the container parameters from other config parameters
    if ($c->container_cfg_chat_dir == "")
      $c->container_cfg_chat_dir = $c->data_private_path."/chat";
    $this->loadPaths();
   
    $errors = array_merge($errors, @test_writable_dir($c->container_cfg_chat_dir,   "container_cfg_chat_dir"));
    $errors = array_merge($errors, @test_writable_dir($c->container_cfg_server_dir, "container_cfg_chat_dir/serverid"));
   
    return $errors;
  }


  function setMeta($group, $subgroup, $leaf, $leafvalue = NULL)
  {
    $c =& $this->c;

    if ($c->debug)
      file_put_contents("tmp/debug.txt", "nsetMeta(".$group.",".$subgroup.",".$leaf.",".$leafvalue.")", FILE_APPEND);
   
   //new mysql code +++++++++++++++++++++++++++++++++++++++++++
   
   $server = $c->serverid;   
   $nConnID=$this->OpenDatabase();

   if ($leafvalue == NULL){$leafvalue="";};
   
   $sql_select="SELECT * FROM ".$this->dbTable." WHERE `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf'";
   $sql_insert="REPLACE INTO ".$this->dbTable." (`server`, `group`, `subgroup`, `leaf`, `leafvalue`, `timestamp`) VALUES('$server', '$group', '$subgroup', '$leaf', '".addslashes($leafvalue)."', '".time()."')";
   $sql_update="UPDATE ".$this->dbTable." SET `leafvalue`='".addslashes($leafvalue)."', `timestamp`='".time()."' WHERE  `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf'";
   
   $thisresult = $this->todb($sql_select);
   
   if(!mysql_num_rows($thisresult)){
      if ($c->debug)
            file_put_contents("tmp/debug.txt", "nsetSQL(".$sql_insert.")", FILE_APPEND);
      
      $this->todb($sql_insert);
      return 0; // value created
   }else{
      if($sql_update!=""){
         if ($c->debug)
            file_put_contents("tmp/debug.txt", "nsetSQL(".$sql_update.")", FILE_APPEND);
         
         $this->todb($sql_update);
      }
      return 1; // value overwritten
   }
   
   
   //old file code +++++++++++++++++++++++++++++++++++++++++++
   /*
    // create directories
    $dir_base = $c->container_cfg_server_dir;
    $dir = $dir_base.'/'.$group.'/'.$subgroup;
    if (!is_dir($dir)) mkdir_r($dir);
   
    // create or replace metadata file
    $leaffilename = $dir."/".$leaf;
    $leafexists = file_exists($leaffilename);
    if ($leafvalue == NULL)
    {
      if (file_exists($leaffilename) &&
          filesize($leaffilename)>0) unlink($leaffilename);
      touch($leaffilename);
    }
    else
    {
      file_put_contents($leaffilename, $leafvalue);
    }

    // store the value in the memory cache
    //@todo
    //    $this->_meta[$enc_type][$enc_subtype][$enc_key] = $value;
   
    if ($leafexists)
      return 1; // value overwritten
    else
      return 0; // value created
   */ 
  }

 
  function getMeta($group, $subgroup = null, $leaf = null, $withleafvalue = false)
  {
    $c =& $this->c;
    if ($c->debug)
      file_put_contents("tmp/debug.txt", "ngetMeta(".$group.",".$subgroup.",".$leaf.",".$withleafvalue.")", FILE_APPEND);
   
    // read data from metadata file
    $ret = array();
    $ret["timestamp"] = array();
    $ret["value"]     = array();
   
   //new mysql code +++++++++++++++++++++++++++++++++++++++++++
   
   $server = $c->serverid;   
   $nConnID=$this->OpenDatabase();
   
   $sql_where="";
   $value="leafvalue";
   
    if ($group != NULL){
      $sql_where.=" AND `group`='$group'";
      $value="subgroup";      
   }   
   
    if ($subgroup != NULL){
      $sql_where.=" AND `subgroup`='$subgroup'";
      $value="leaf";      
   }
   
   if ($leaf != NULL){
      $sql_where.=" AND `leaf`='$leaf'";
      $value="leafvalue";   
   };
   
   $sql_select="SELECT `".$value."`, `timestamp` FROM ".$this->dbTable." WHERE `server`='$server'".$sql_where." ORDER BY timestamp";
   
   if ($c->debug)
      file_put_contents("tmp/debug.txt", "ngetSQL(".$sql_select.")", FILE_APPEND);
   
   if($sql_select!=""){
   //file_put_contents("tmp/debug.txt", "ngetSQL(".$sql_select.")", FILE_APPEND);   
      $thisresult = $this->todb($sql_select);
      if(mysql_num_rows($thisresult)){      
         while ($regel = mysql_fetch_array($thisresult)) {
             $ret["timestamp"][] = $regel["timestamp"];
            if($value=="leafvalue"){
               if($withleafvalue){
                      $ret["value"][]     = $regel[$value];
               }else{
                  $ret["value"][]     = NULL;
               };
            }else{
               $ret["value"][] = $regel[$value];
            };      
         };//einde while lus      
      }else{
         return $ret;
      }
   }   
   
   return $ret;
   
   //old file code +++++++++++++++++++++++++++++++++++++++++++
   /*
    $dir_base = $c->container_cfg_server_dir;

    $dir = $dir_base.'/'.$group;

    if ($subgroup == NULL)
    {
      if (is_dir($dir))
      {
        $dh = opendir($dir);
        while (false !== ($file = readdir($dh)))
        {
          if ($file == "." || $file == "..") continue; // skip . and .. generic files
          $ret["timestamp"][] = filemtime($dir.'/'.$file);
          $ret["value"][]     = $file;
        }
      }
      return $ret;
    }
   
    $dir .= '/'.$subgroup;

    if ($leaf == NULL)
    {
      if (is_dir($dir))
      {
        $dh = opendir($dir);
        while (false !== ($file = readdir($dh)))
        {
          if ($file == "." || $file == "..") continue; // skip . and .. generic files
          $ret["timestamp"][] = filemtime($dir.'/'.$file);
          $ret["value"][]     = $file;
        }
      }
      return $ret;
    }
   
    $leaffilename = $dir."/".$leaf;

    if (!file_exists($leaffilename)) return $ret;
    if ($withleafvalue)
      $ret["value"][] = file_get_contents($leaffilename);
    else
      $ret["value"][] = NULL;
    $ret["timestamp"][] = filemtime($leaffilename);
   
   if ($c->debug)
      file_put_contents("tmp/debug.txt", "ngetDir(".$dir."/".$leaf.")", FILE_APPEND);
    
   if ($c->debug){
      for($i=0;$i<count($ret["timestamp"]);$i++){
         file_put_contents("tmp/debug.txt", "nanswerMeta(".$ret["value"][$i].")", FILE_APPEND);   
      };         
   };

    return $ret;
     */
  }

  function rmMeta($group, $subgroup = null, $leaf = null)
  {
    $c =& $this->c;
    if ($c->debug)
      file_put_contents("tmp/debug.txt", "nrmMeta(".$group.",".$subgroup.",".$leaf.")", FILE_APPEND);
   
    //new mysql code +++++++++++++++++++++++++++++++++++++++++++
   
   $server = $c->serverid;   
   $nConnID=$this->OpenDatabase();
   
   $sql_delete="DELETE FROM ".$this->dbTable." WHERE `server`='$server'";
   
   if($group != NULL){
      $sql_delete.=" AND `group`='$group'";
    }   
   
   if($subgroup != NULL){
      $sql_delete.=" AND `subgroup`='$subgroup'";
    }

    if ($leaf != NULL) {
      $sql_delete.=" AND `leaf`='$leaf'";
    }
   
   if ($c->debug)
      file_put_contents("tmp/debug.txt", "nrmSQL(".$sql_delete.")", FILE_APPEND);
   
   $this->todb($sql_delete);
   return true;
   
   //old file code +++++++++++++++++++++++++++++++++++++++++++
   /*
   $dir = $c->container_cfg_server_dir;

    if ($group == NULL)
    {
      rm_r($dir);
      return true;
    }

    $dir .= '/'.$group;

    if ($subgroup == NULL)
    {
      rm_r($dir);
      return true;
    }
   
    $dir .= '/'.$subgroup;

    if ($leaf == NULL)
    {
      rm_r($dir);
      return true;
    }
   
    $leaffilename = $dir.'/'.$leaf;
   
    if (!file_exists($leaffilename)) return false;
    unlink($leaffilename);
    return true;
     */
  }


  /**
   * Used to encode UTF8 strings to ASCII filenames
   */ 
  function encode($str)
  {
    return urlencode($str);
  }
 
  /**
   * Used to decode ASCII filenames to UTF8 strings
   */ 
  function decode($str)
  {
    return urldecode($str);
  }

}

?>
HenkBB
New member
 
Posts: 3
Joined: Sun Dec 03, 2006 9:13 am
Top

Postby phpfreechat » Sun Dec 03, 2006 7:31 pm

Thank you HenkBB.
Did you test your container with the generic testcase ? (look into testcase/ directory)
Moreover, could you cleanup the code : remove the old file container code ?

regards,
phpfreechat
Site Admin
 
Posts: 2657
Joined: Tue Feb 07, 2006 3:35 pm
Location: France
Top

Postby HenkBB » Tue Dec 05, 2006 8:33 pm

Here's the "cleanuped" code.

The testcase requires writing of a container_mysql.php i'm afraid and I haven't had the time to do so, but I can insure you it is working fine as it is fully functional on my website.


Code: Select all
<?php
/**
 * mysql.class.php
 *
 * Copyright © 2006 Stephane Gully <stephane.gully@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 
 * MYSQL DATABASE INFO
 * Because of the new storage functions (setMeta, getMeta, rmMeta)
 * everything can be stored in just one single table.
 * Using type "HEAP" or "MEMORY" mysql loads this table into memory making it very fast
 * There is no routine to create the table if it does not exists so you have to create it by hand
 * Replace the database login info at the top of pfcContainer_mysql class with your own
 * You also need a container line in your chat index file:
 * $params["container_type"] = "mysql";
 

 
 */

require_once dirname(__FILE__)."/../pfccontainer.class.php";

/**
 * pfcContainer_mysql is a concret container which stock data into mysql
 *
 * @author Stephane Gully <stephane.gully@gmail.com>
 */
class pfcContainer_mysql extends pfcContainer{

  var $dbServer = 'localhost';
  var $dbPort = 3306;
  var $dbName = 'chat';
  var $dbUser = 'root';
  var $dbPass = '';
  var $dbTable = 'phpfreechat';
  var $nConnID;
  var $bCheck;
 
  function OpenDatabase(){
     $nConnID = mysql_connect($this->dbServer, $this->dbUser, $this->dbPass)
        or die ("No connection with database.");

   $bCheck = mysql_select_db($this->dbName)
        or die ("No database selected.");

   return $nConnID;
  }
 
  function todb($sql){
   global $nConnID;
   $result = mysql_query($sql);
   if ($result <= 0) {
      echo "Mysql error ...";
      if ($c->debug){
         echo "<BR>".mysql_error()."<BR>$sql";
      }
      exit();
   };
   return $result;
  }
 
  var $_users = array("nickid"    => array(),
                      "timestamp" => array());
  var $_meta = array();
 
  function pfcContainer_File(&$config)
  {
    pfcContainer::pfcContainer($config);
  }

  function getDefaultConfig()
  {
    $c =& $this->c;
   
    $cfg = pfcContainer::getDefaultConfig();
    return $cfg;
  }
 

  function setMeta($group, $subgroup, $leaf, $leafvalue = NULL)
  {
    $c =& $this->c;

    if ($c->debug)
      file_put_contents("tmp/debug.txt", "nsetMeta(".$group.",".$subgroup.",".$leaf.",".$leafvalue.")", FILE_APPEND);
   
   $server = $c->serverid;   
   $nConnID=$this->OpenDatabase();

   if ($leafvalue == NULL){$leafvalue="";};
   
   $sql_select="SELECT * FROM ".$this->dbTable." WHERE `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf'";
   $sql_insert="REPLACE INTO ".$this->dbTable." (`server`, `group`, `subgroup`, `leaf`, `leafvalue`, `timestamp`) VALUES('$server', '$group', '$subgroup', '$leaf', '".addslashes($leafvalue)."', '".time()."')";
   $sql_update="UPDATE ".$this->dbTable." SET `leafvalue`='".addslashes($leafvalue)."', `timestamp`='".time()."' WHERE  `server`='$server' AND `group`='$group' AND `subgroup`='$subgroup' AND `leaf`='$leaf'";
   
   $thisresult = $this->todb($sql_select);
   
   if(!mysql_num_rows($thisresult)){
      if ($c->debug)
            file_put_contents("tmp/debug.txt", "nsetSQL(".$sql_insert.")", FILE_APPEND);
      
      $this->todb($sql_insert);
      return 0; // value created
   }else{
      if($sql_update!=""){
         if ($c->debug)
            file_put_contents("tmp/debug.txt", "nsetSQL(".$sql_update.")", FILE_APPEND);
         
         $this->todb($sql_update);
      }
      return 1; // value overwritten
   } 
  }

 
  function getMeta($group, $subgroup = null, $leaf = null, $withleafvalue = false)
  {
    $c =& $this->c;
    if ($c->debug)
      file_put_contents("tmp/debug.txt", "ngetMeta(".$group.",".$subgroup.",".$leaf.",".$withleafvalue.")", FILE_APPEND);
   
    $ret = array();
    $ret["timestamp"] = array();
    $ret["value"]     = array();
   
   $server = $c->serverid;   
   $nConnID=$this->OpenDatabase();
   
   $sql_where="";
   $value="leafvalue";
   
    if ($group != NULL){
      $sql_where.=" AND `group`='$group'";
      $value="subgroup";      
   }   
   
    if ($subgroup != NULL){
      $sql_where.=" AND `subgroup`='$subgroup'";
      $value="leaf";      
   }
   
   if ($leaf != NULL){
      $sql_where.=" AND `leaf`='$leaf'";
      $value="leafvalue";   
   };
   
   $sql_select="SELECT `".$value."`, `timestamp` FROM ".$this->dbTable." WHERE `server`='$server'".$sql_where." ORDER BY timestamp";
   
   if ($c->debug)
      file_put_contents("tmp/debug.txt", "ngetSQL(".$sql_select.")", FILE_APPEND);
   
   if($sql_select!=""){
      $thisresult = $this->todb($sql_select);
      if(mysql_num_rows($thisresult)){      
         while ($regel = mysql_fetch_array($thisresult)) {
             $ret["timestamp"][] = $regel["timestamp"];
            if($value=="leafvalue"){
               if($withleafvalue){
                      $ret["value"][]     = $regel[$value];
               }else{
                  $ret["value"][]     = NULL;
               };
            }else{
               $ret["value"][] = $regel[$value];
            };      
         };//end while   
      }else{
         return $ret;
      }
   }   
   return $ret;
  }

  function rmMeta($group, $subgroup = null, $leaf = null)
  {
    $c =& $this->c;
    if ($c->debug)
      file_put_contents("tmp/debug.txt", "nrmMeta(".$group.",".$subgroup.",".$leaf.")", FILE_APPEND);
   
   $server = $c->serverid;   
   $nConnID=$this->OpenDatabase();
   
   $sql_delete="DELETE FROM ".$this->dbTable." WHERE `server`='$server'";
   
   if($group != NULL){
      $sql_delete.=" AND `group`='$group'";
    }   
   
   if($subgroup != NULL){
      $sql_delete.=" AND `subgroup`='$subgroup'";
    }

    if ($leaf != NULL) {
      $sql_delete.=" AND `leaf`='$leaf'";
    }
   
   if ($c->debug)
      file_put_contents("tmp/debug.txt", "nrmSQL(".$sql_delete.")", FILE_APPEND);
   
   $this->todb($sql_delete);
   return true;
  }


  /**
   * Used to encode UTF8 strings to ASCII filenames
   */ 
  function encode($str)
  {
    return urlencode($str);
  }
 
  /**
   * Used to decode ASCII filenames to UTF8 strings
   */ 
  function decode($str)
  {
    return urldecode($str);
  }

}

?>
HenkBB
New member
 
Posts: 3
Joined: Sun Dec 03, 2006 9:13 am
Top

Postby phpfreechat » Wed Dec 06, 2006 4:38 pm

Thank you HenkBB for your work.
I just integrated it in the official source code. I also wrote the associated testcase.
phpfreechat
Site Admin
 
Posts: 2657
Joined: Tue Feb 07, 2006 3:35 pm
Location: France
Top

Postby phpfreechat » Wed Dec 06, 2006 4:45 pm

I setup a demo here : http://www.phpfreechat.net/demo/pfc-1.x ... tainer.php
phpfreechat
Site Admin
 
Posts: 2657
Joined: Tue Feb 07, 2006 3:35 pm
Location: France
Top

Postby MusicalBox » Sat Dec 09, 2006 2:48 am

What is the advantage of using a MySQL db instead of the default one ?
MusicalBox
Member
 
Posts: 13
Joined: Sun Nov 05, 2006 10:08 pm
Location: Québec city
Top

Postby mikez » Wed Dec 13, 2006 7:00 am

Thanks for the MySQL container. It's a great piece of code, especially if the shared memory option isn't available.

The only thing I would warn about is that **some** shared hosting plans will limit the number of sql conqueries issued by your scripts. Too many conqueries and you may find your site getting suspended.
mikez
Member
 
Posts: 29
Joined: Wed Dec 13, 2006 1:24 am
Top


Post a reply
7 posts • Page 1 of 1

Return to Contributions (v1.x)

Who is online

Users browsing this forum: No registered users and 8 guests

  • Board index
  • The team • Delete all board cookies • All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
Sign in
Wrong credentials
Sign up I forgot my password
.
jeu-gratuit.net | more partners
Fork me on GitHub