Location: PHPKode > projects > crVCL PHP Framework > sphinxapi.lib.php
<?PHP

/*

  The contents of this file are subject to the Mozilla Public License
  Version 1.1 (the "License"); you may not use this file except in compliance
  with the License. You may obtain a copy of the License at
  http://www.mozilla.org/MPL/MPL-1.1.html or see MPL-1.1.txt in directory "license"

  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
  the specific language governing rights and limitations under the License.

  The Initial Developers of the Original Code are:
  Copyright (c) 2003-2012, CR-Solutions (http://www.cr-solutions.net), Ricardo Cescon
  All Rights Reserved.

  Contributor(s): Andrew Aksyonoff (http://wwwsphinxsearchcom), PanterMedia GmbH (http://wwwpanthermedianet), Peter Ammel

  crVCL PHP Framework Version 2.4
 */




############################################################
if (!defined("SPHINXAPI_LIB")) {
   define("SPHINXAPI_LIB", 1);
############################################################

   if (!isset($GLOBALS["CRVCL"]["SPHINX_VERSION"]) || !is_file($GLOBALS["CRVCL"]["PATH"] . "/external/sphinx/sphinxapi" . $GLOBALS["CRVCL"]["SPHINX_VERSION"] . ".php")) {
      $GLOBALS["CRVCL"]["SPHINX_VERSION"] = "3087";
   }

   require($GLOBALS["CRVCL"]["PATH"] . "/external/sphinx/sphinxapi" . $GLOBALS["CRVCL"]["SPHINX_VERSION"] . ".php");



   $old_error_report = error_reporting(E_ALL & ~E_STRICT); // to overwrite methods of SphinxClient
################
   try { // fix bug E_STRICT notice when overriding methods
################
      /**
       * Sphinx PHP searchd client API, derived from sphinxapi.php of Andrew Aksyonoff (http://www.sphinxsearch.com/)
       *
       */

      class sphinxAPI extends SphinxClient {

         private $_version = 0;
         private $_timeout_sec = 10;
         private $_servers = array();
         private $_lb_reconnect_time_sec = 60;
         private $_retry_on_connection_lost_ms = 1000;
         private $_sphinxQL = false;
         private $_sphinxQL_mysql = null;
         private $_ql_error = "";

         /**
         * return the last query execution time
         *
         * @var int
         */
         public $m_last_query_ms = 0;
         //-------------------------------------------------------------------------------------------------------------------------------------
         // constructor

         /**
          *
          * @param bool $useQL (sphinxQL implementation require sphinx version >= 2.0.1-beta)
          */
         function __construct($useQL = false) {
            parent::SphinxClient();

            $version = $GLOBALS["CRVCL"]["SPHINX_VERSION"];
            $this->_version = $version;

            $this->_sphinxQL = $useQL;
         }
         //-------------------------------------------------------------------------------------------------------------------------------------
         function EscapeString($string){
            $string = parent::EscapeString($string);
            if ($this->_sphinxQL) {
               if($this->_sphinxQL_mysql instanceof mysqli){                  
                  $string = $this->_sphinxQL_mysql->real_escape_string($string);
               }else{                  
                  $string = mysql_real_escape_string($string, $this->_sphinxQL_mysql);
               }
            }
            return $string;
         }
         //-------------------------------------------------------------------------------------------------------------------------------------
         function GetLastError() {
            if ($this->_sphinxQL) {
               return $this->_ql_error;
            }
            return parent::GetLastWarning();
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         function GetLastWarning() {
            if ($this->_sphinxQL) {
               return "";
            }
            return parent::GetLastError();
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * get the used version of the PHP Sphinx API
          *
          * @return int
          */
         function getVersion() {
            return $this->_version;
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * set the server ip/port (if you set more than one server, loadbalancing is active, to deactivate set only one server) <br><br>!!! use small values for the connection timeout if loadbalacing is active !!!
          *
          * @param mixed $host as string
          * @param mixed $port as int
          */
         function SetServer($host, $port = null) {
            $this->_servers = array();

            if ($port === null) {
               if ($this->_sphinxQL) {
                  $port = 9306;
               } else {
                  $port = 9312;
               }
            }

            if (!is_array($host)) {
               $host = array($host);
            }
            if (!is_array($port)) {
               $port = array($port);
            }

            for ($i = 0; $i < acount($host); $i++) {
               if ($this->_sphinxQL) {
                  $p = 9306;
               } else {
                  $p = 9312;
               }
               if (isset($port[$i])) {
                  $p = $port[$i];
               }
               $this->_servers[] = array($host[$i], $p);
            }

            if (acount($this->_servers) > 1) {
               // use loadbalancing and set primary host
               parent::SetServer($this->_servers[0][0], $this->_servers[0][1]);
            } else {
               if (!$this->_sphinxQL) {
                  parent::SetServer($this->_servers[0][0], $this->_servers[0][1]);
               }
            }
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * set the offset/limit for a search
          *
          * @param int $offset
          * @param int $limit
          */
         function SetLimits($offset, $limit = 1000, $max = 0, $cutoff = 0) {
            parent::SetLimits(intval($offset), intval($limit), $max, $cutoff);
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * reconnect time after failover
          *
          * @param mixed $time => "2minutes" as string or 300 as int (sec.)
          */
         function lbReconnectTime($time) {
            $time = str2sec($time);
            $this->_lb_reconnect_time_sec = $time;
         }

         /**
          * time for retry a lost connection, or if sphinx daemon busy
          *
          * @param int $ms
          */
         function retryTime($ms) {
            $this->_retry_on_connection_lost_ms = $ms;
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * connect the server
          *
          * @return resource
          */
         function Connect() {
            $c_servers = acount($this->_servers);

            if ($c_servers > 1) { // use loadbalancing
               $ret = false;

               for ($h = 0; $h < $c_servers; $h++) {
                  $host = $this->_servers[$h][0];
                  $port = $this->_servers[$h][1];

                  $key = str_replace('.', '_', $host);

                  // failover
                  if (isset($_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"])) {
                     if (diffSec("", $_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"]) < $this->_lb_reconnect_time_sec) {
                        continue;
                     } else {
                        unset($_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"]);
                     }
                  }

                  // round robin for sphinx
                  if (isset($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"])) {
                     if ($h == $c_servers - 1) {
                        $_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"] = "";
                     }
                     if ($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"] == $host && !isset($_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"])) {
                        continue;
                     }
                  }

                  parent::SetServer($host, $port);

                  $ret = false;
                  if ($this->_sphinxQL) {                
                     if (!is_callable("mysqli_init")) {
                        @ini_set('mysql.connect_timeout', $this->_timeout_sec);
                        $this->_sphinxQL_mysql = @mysql_connect($host . ':' . $port, null, null, null, MYSQL_CLIENT_COMPRESS);
                     }else{
                        $mysql = mysqli_init();
                        if (!$mysql)
                           return false;

                        $mysql->options(MYSQLI_OPT_CONNECT_TIMEOUT, $this->_timeout_sec);
                        if (!$mysql->real_connect($host, null, null, null, $port, null, MYSQLI_CLIENT_COMPRESS)) {
                           return false;
                        }
                        $this->_sphinxQL_mysql = $mysql;
                     }
                     
                     if (!is_resource($this->_sphinxQL_mysql) && !is_object($this->_sphinxQL_mysql)) {
                        if($this->_sphinxQL_mysql instanceof mysqli){
                           $this->_sphinxQL_mysql->error;
                        }else{
                           $this->_ql_error = mysql_error();
                        }
                        return false;
                     }
                     return true;
                  } else {
                     $ret = $this->_Connect();
                  }

                  if ($ret !== false) {
                     $_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"] = $host;
                     break;
                  } else {
                     $_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"] = date2MySQLDate();
                  }
               }

               return $ret;
            } else {
               $ret = false;
               
               if ($this->_sphinxQL) {
                  if (!is_callable("mysqli_init")) {
                     @ini_set('mysql.connect_timeout', $this->_timeout_sec);
                     $this->_sphinxQL_mysql = @mysql_connect($this->_servers[0][0] . ':' . $this->_servers[0][1], null, null, null, MYSQL_CLIENT_COMPRESS);
                  }else{
                     $mysql = mysqli_init();
                     if (!$mysql)
                        return false;

                     $mysql->options(MYSQLI_OPT_CONNECT_TIMEOUT, $this->_timeout_sec);
                     if (!$mysql->real_connect($this->_servers[0][0], null, null, null, $this->_servers[0][1], null, MYSQLI_CLIENT_COMPRESS)) {
                        return false;
                     }
                     $this->_sphinxQL_mysql = $mysql;
                  }
                  
                  if (!is_resource($this->_sphinxQL_mysql) && !is_object($this->_sphinxQL_mysql)) {
                     if($this->_sphinxQL_mysql instanceof mysqli){
                        $this->_sphinxQL_mysql->error;
                     }else{
                        $this->_ql_error = mysql_error();
                     }
                     return false;
                  }
                  return true;
               } else {
                  $ret = $this->_Connect();
               }
               return $ret;
            }
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * connect to searchd server, run given search query through given indexes and return the search results
          *
          * @param mixed $query string for sphinx client API / string or sphinxQLBuilder object for sphinxQL
          * @param string $index (not for QL)
          * @param string $comment (not for QL)
          * @return array
          */
         function Query($query, $index = "*", $comment = "") {
            $stick = 0;
            
            if ($GLOBALS["CRVCL"]["CHARSET"] == "UTF-8" && !is_object($query)) {
               $query = utf8_fix($query);
            }
            
            if ($this->_sphinxQL) {
               if(is_object($query) && $query instanceof sphinxQLBuilder){
                  $query = $query->query();
               }

               if ($GLOBALS["CRVCL"]["CHARSET"] == "UTF-8") {
                  $query = utf8_fix($query);
               }

               try {
                  $array_result = array();

                  $stick = gettickcount();

                  if($this->_sphinxQL_mysql instanceof mysqli){
                     while(true){
                        $result = $this->_sphinxQL_mysql->query($query);

                        $this->_ql_error = $this->_sphinxQL_mysql->errno;
                        if ($this->_sphinxQL_mysql->errno != 0) {
                           break;
                        }

                        if (stripos($query, "select") !== false) {
                           while ($row = $result->fetch_assoc()) {
                              $attrs = $row;
                              unset($attrs['id']);
                              $array_result['matches'][$row['id']] = array('attrs' => $attrs);
                           }                           
                           free($result);


                           $result = $this->_sphinxQL_mysql->query("SHOW META");

                           $this->_ql_error = $this->_sphinxQL_mysql->errno;
                           if ($this->_sphinxQL_mysql->errno != 0) {
                              break;
                           }

                           while ($row = $result->fetch_assoc()) {
                              if (isset($row['Variable_name']) && $row['Variable_name'] == 'total_found') {
                                 $array_result['total_found'] = $row['Value'];
                              }
                           }                           
                           free($result);
                           gc_collect_cycles_overX($GLOBALS['CRVCL']['GC_COLLECT_CYCLES_PERCENT']);
                        }
                        break;
                     } // while
                     $this->m_last_query_ms = gettickcount()-$stick;

                     if($this->_sphinxQL_mysql->errno != 0)return false;
                     return $array_result;

                  }else{
                     while(true){
                        $result = mysql_query($query, $this->_sphinxQL_mysql);
                        $this->_ql_error = mysql_error($this->_sphinxQL_mysql);
                        if (mysql_errno($this->_sphinxQL_mysql) != 0) {
                           break;
                        }

                        if (stripos($query, "select") !== false) {
                           while ($row = mysql_fetch_assoc($result)) {
                              $attrs = $row;
                              unset($attrs['id']);
                              $array_result['matches'][$row['id']] = array('attrs' => $attrs);
                           }
                           mysql_free_result($result);
                           free($result);

                           $result = mysql_query("SHOW META", $this->_sphinxQL_mysql);
                           $this->_ql_error = mysql_error($this->_sphinxQL_mysql);
                           if (mysql_errno($this->_sphinxQL_mysql) != 0) {
                              break;
                           }

                           while ($row = mysql_fetch_assoc($result)) {
                              if (isset($row['Variable_name']) && $row['Variable_name'] == 'total_found') {
                                 $array_result['total_found'] = $row['Value'];
                              }
                           }
                           mysql_free_result($result);
                           free($result);
                           gc_collect_cycles_overX($GLOBALS['CRVCL']['GC_COLLECT_CYCLES_PERCENT']);
                        }
                        break;
                     }

                     $this->m_last_query_ms = gettickcount()-$stick;

                     if(mysql_errno($this->_sphinxQL_mysql) != 0){
                        
                        if (acount($this->_servers) > 1) { // use loadbalancing
                           $host = $this->_host;
                           $key = str_replace('.', '_', $host);

                           $_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"] = date2MySQLDate();
                           $ret = $this->Connect();
                           if ($ret) {
                              return $this->Query($query, $index, $comment);
                           }
                        }                        
                        
                       return false;
                     }
                     return $array_result;
                  }

                  $this->m_last_query_ms = gettickcount()-$stick;

                  return $result;
               } catch (Exception $e) {
                  return false;
               }
            } // end sphinxQL
            #################


            if ($GLOBALS["CRVCL"]["CHARSET"] == "UTF-8") {
               $query = utf8_fix($query);
            }

            $stick = gettickcount();
            $ret = parent::Query($query, $index, $comment);

            $spherr = $this->getLastError();

            // retry if daemon busy
            if (strpos($spherr, "server maxed out, retry in a second") !== false) {
               mssleep($this->_retry_on_connection_lost_ms);
               $ret = parent::Query($query, $index, $comment);
               $spherr = $this->getLastError();
            }

            if ((strpos($spherr, "timed out" !== false || strpos($spherr, "Connection refused") !== false)) && acount($this->_servers) > 1) { // use loadbalancing
               $host = $this->_host;
               $key = str_replace('.', '_', $host);

               $_SESSION["CRVCL"]["SPH"]["SERVER"][$key]["LAST_FAILOVER_TIME"] = date2MySQLDate();
               $ret = $this->Connect();
               if ($ret) {
                  $ret = parent::Query($query, $index, $comment);
               }
            }

            $this->m_last_query_ms = gettickcount()-$stick;
            return $ret;
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * connect to searchd server, run given search query through given indexes and return the search results
          *
          * @param mixed $query
          * @param string $index
          * @param string $comment
          * @return sphinxResult
          */
         function rQuery($query, $index = "*", $comment = "") {
            $ret = $this->Query($query, $index, $comment);

            $spherr = $this->getLastError();

            if (empty($spherr)) {
               return new sphinxResult($ret);
            }
            return null;
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         /**
          * set the connection timeout
          *
          * @param int $timeout_sec
          */
         function SetConnectTimeout($timeout_sec) {
            $this->_timeout_sec = $timeout_sec;
            if (!method_exists("SphinxClient", "SetConnectTimeout")) {
               parent::SetConnectTimeout($this->_timeout_sec);
            }
            $sph = null;
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
         function _Connect() {
            $sph = new SphinxClient();
            if (!method_exists("SphinxClient", "SetConnectTimeout")) {
               return parent::_Connect($this->_timeout_sec); // timeout mod. of original file
            } else {
               return parent::_Connect();
            }
            $sph = null;
         }

         //-------------------------------------------------------------------------------------------------------------------------------------
      }

################
   } catch (Exception $e) {
      if (version_compare(PHP_VERSION, "5.2.10", ">=") || version_compare(PHP_VERSION, "5.3.0", "<=") && strpos($e->getMessage(), 'should be compatible with that of') !== false) {
         // fix it
      } else {
         throw $e;
      }
   }
################

   error_reporting($old_error_report);
   unset($old_error_report);

//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
   /**
    * create a object from the sphinx api array result
    *
    */
   class sphinxResult {

      private $m_result = null;

      const DocIdsOnly = 0;
      const DocIdsWithAttr = 1;

      function __construct(&$a) {
         if (!is_array($a)) {
            throw new Exception('sphinxResult Error, result of sphinx api / client is not an array');
         }

         if (!isset($a['total_found'])) {
            throw new Exception('sphinxResult Error, result of sphinx api / client is corrupt');
         }

         $this->m_result = &$a;
      }

      //-------------------------------------------------------------------------------------------------------------------------------------
      function __destruct() {
         free($this->m_result);
         gc_collect_cycles_overX($GLOBALS['CRVCL']['GC_COLLECT_CYCLES_PERCENT']);
      }

      //-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * return the number of found doc id's
       *
       * @return int
       */
      function found() {
         return $this->m_result['total_found'];
      }

      //-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * return an array with the doc id's<br><br><b>mode:</b><br> sphinxResult::DocIdsOnly => array(4232, 4356, 3535, &#46;&#46;&#46;)<br>sphinxResult::DocIdsWithAttr = array(   3245=>array('weight' => 1, 'attrs' => array(&#46;&#46;&#46;)), &#46;&#46;&#46;   )
       *
       * @param const $mode as sample sphinxResult::DocIdsOnly
       * @return array
       */
      function &getDocIds($mode = 0) {
         $res = &$this->m_result;

         $ids = array();


         if (array_key_exists("matches", $res)) {
            if ($mode == sphinxResult::DocIdsWithAttr) {
               return $res["matches"];
            }

            reset($res);
            while (list($id, $docinfo) = each($res["matches"])) {
               $ids[] = $id;
            }
         }

         return $ids;
      }

      //-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * return the doc id's as seperated string, useful for a database where clause if you seperate it by " OR "
       *
       * @param string $sep
       * @return string
       */
      function getDocIdsAsString($sep = ',') {
         $a = $this->getDocIds(0);

         if (!empty($a)) {
            return implode($sep, $a);
         }
         return false;
      }

      //-------------------------------------------------------------------------------------------------------------------------------------
   }

//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
   /**
    * Alias for sphinxAPI with extended methods for sphinxQL
    */
   class sphinxQL extends sphinxAPI {
      private $m_transaction = array();
      
      function __construct() {
         parent::__construct(true);
      }
//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * start a transaction and disable the auto commit
       */
      function begin() {
         $id = '127_0_0_1';
         if(isset($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"]) && !empty($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"])){
            $id = $_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"];
         }

         if (isset($this->m_transaction[$id]) && $this->m_transaction[$id][0] == true) {
            $this->commit($id);
         }

         // Autocommit mode is on by default. Autocommit mode is disabled by a BEGIN statement. Autocommit mode is re-enabled by a COMMIT or ROLLBACK
         
         $this->Query($id, "SET AUTOCOMMIT = 0");
         
         $this->Query($id, "BEGIN");
         
         $this->m_transaction[$id] = array(true);
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * rollback a transaction 
       *
       * @param string $id
       */
      function rollback($id = "master") {
         $id = '127_0_0_1';
         if(isset($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"]) && !empty($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"])){
            $id = $_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"];
         }

         if (!isset($this->m_transaction[$id]) || $this->m_transaction[$id][0] != true) {
            return;
         }

         $this->Query($id, "ROLLBACK");

         $this->Query($id, "SET AUTOCOMMIT = 1");

         $this->m_transaction[$id][0] = false;
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * commit a transaction 
       */
      function commit() {
         $id = '127_0_0_1';
         if(isset($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"]) && !empty($_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"])){
            $id = $_SESSION["CRVCL"]["SPH"]["SERVER"]["LAST_HOST"];
         }
         
         if (!isset($this->m_transaction[$id]) || $this->m_transaction[$id][0] != true) {
            return;
         }

         $this->Query($id, "COMMIT");

         $this->Query($id, "SET SESSION AUTOCOMMIT = 1");

         $this->m_transaction[$id][0] = false;
      }

//-------------------------------------------------------------------------------------------------------------------------------------
   }
//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------
   class sphinxQLBuilder {

      private $m_index = array();
      private $m_where = "";

      protected $m_fields = array();
      protected $m_values = array();
      protected $m_type = "";
      protected $m_limit = "";
      protected $m_options = "";
      protected $m_order = "";
      protected $m_group = "";
      protected $m_within_group_order = "";

      const ID = '@id';
      const WEIGHT = '@weight';
      const OPT_RANKER_BM25 = 'ranker=bm25';
      const OPT_RANKER_PROXIMITY_BM25 = 'ranker=proximity_bm25';
      const OPT_RANKER_NONE = 'ranker=none';
      const OPT_RANKER_WORDCOUNT = 'ranker=wordcount';
      const OPT_RANKER_MATCHANY = 'ranker=matchany';
      const OPT_RANKER_PROXIMITY = 'ranker=proximity';
      const OPT_RANKER_FIELDMASK = 'ranker=fieldmask';
      const OPT_MAX_MATCHES = 'max_matches';
      const OPT_CUTOFF = 'cutoff';
      const OPT_MAX_QUERY_TIME_MSEC = 'max_query_time';
      const OPT_RETRY_COUNT = 'retry_count';
      const OPT_RETRY_DELAY = 'retry_delay';
      const OPT_FIELD_WEIGHTS = 'field_weights';
      const OPT_INDEX_WEIGHTS = 'index_weights';
      const OPT_REVERSE_SCAN_ENABLED = 'reverse_scan=1';
      const OPT_REVERSE_SCAN_DISABLED = 'reverse_scan=0';

//-------------------------------------------------------------------------------------------------------------------------------------
    /**
    * create a sphinxQLBuilder object
    *
    * @param int $SPHQL_EXEC_TYPE
    * @param mixed $indecies as string or array
    * @param string $where
    * @return sphinxQLBuilder
    */
      function __construct($SHPQL_EXEC_TYPE, $indecies="", $where = "") {
         $this->m_type = $SHPQL_EXEC_TYPE;
         $this->setIndecies($indecies);
         $this->setWhere($where); 
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
    * return the sql query
    *
    * @return string
    */
      function query() {
         $sql = "";

         if ($this->m_type == SPHQL_SELECT) {
            $fcount = acount($this->m_fields);

            $sql .= "SELECT ";

            if ($fcount == 0) {
               $sql .= "* ";
            } else {
               for ($f = 0; $f < $fcount; $f++) {
                  $field = $this->m_fields[$f]["field"];
                  $sql .= $field;
                  if ($f != $fcount - 1) {
                     $sql .= ", ";
                  }
               }// for
            }

            $sql .= " FROM " . implode(',', $this->m_index);


            if (!empty($this->m_where)) {
               $sql .= " WHERE " . $this->m_where;
            }

            if ($this->m_group != "") {
               $sql .= $this->m_group;
            }
            if ($this->m_order != "") {
               $sql .= $this->m_order;
            }
            if ($this->m_within_group_order != "") {
               $sql .= $this->m_within_group_order;
            }
            if ($this->m_limit != "") {
               $sql .= $this->m_limit;
            }
            if ($this->m_options != "") {
               $sql .= ' OPTION ' . trim($this->m_options, ',');
            }

         ########################################
         }else if($this->m_type == SPHQL_DELETE){
            trigger_error('DELETE data on all sphinx client\'s in cluster mode (loadbalancing) is not implement yet', E_USER_WARNING);

            $sql .= "DELETE ";

            $sql .= "FROM ";

            $sql .= $this->m_index;

            if(!empty($this->m_where)){
               $sql .= " WHERE ".$this->m_where;
            }
         ########################################
         }else{
            trigger_error('INSERT/UPDATE data on all sphinx client\'s in cluster mode (loadbalancing) is not implement yet', E_USER_WARNING);

            $fcount = acount($this->m_values);

            if($this->m_type == SPHQL_INSERT){
               $sql .= "INSERT ";
            }else if($this->m_type == SPHQL_UPDATE){
               $sql .= "UPDATE ";
            }

            if($this->m_type == SQLITE_INSERT){
               $sql .= "INTO ".$this->m_index;
            }else if($this->m_type == SQLITE_UPDATE){
               $sql .= $this->m_table . " SET ";
            }
            
            // used by insert
            $colnames = " (";
            $values = " VALUES(";
            /////////////////
            for ($f = 0; $f < $fcount; $f++) {
               $field = $this->m_values[$f]["field"];
               $val = $this->m_values[$f]["val"];

               if ($this->m_type == SPHQL_INSERT) {

                  $colnames .= $field;
                  
                  if ($f != $fcount - 1) {
                     $colnames .= ", ";
                  } else {
                     $colnames .= ")";
                  }

                  $values .= $val;
                  if ($f != $fcount - 1) {
                     $values .= ", ";
                  } else {
                     $values .= ")";

                     $sql .= $colnames . $values;
                  }
            ########################################
               } else if ($this->m_type == SPHQL_UPDATE) {
                  $sql .= $field . " = " . $val;
               }
            }

            if ($this->m_type == SPHQL_UPDATE && !empty($this->m_where)) {
               $sql .= " WHERE " . $this->m_where;
            }
         }
              
         return $sql;
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      protected function prepareGroupOrder($column, $sortOrder = null) {
         if (!is_array($column)) {
            $column = array($column);
         }

         if (!is_array($sortOrder)) {
            $sortOrder = array($sortOrder);
         }

         $tmp = '';
         for ($i = 0; $i < acount($column); $i++) {
            $tmp .= $column[$i] . ' ' . (isset($sortOrder[$i]) && $sortOrder[$i] !== null ? $sortOrder[$i] : $sortOrder[0]) . ', ';
         }
         return trim($tmp, ', ');
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       *
       * @param string $where
       */
      function setWhere($where)
      {
         $this->m_where = $where;
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       *
       * @param mixed $indecies as string or array
       */
      function setIndecies($indecies)
      {
         if (!is_array($indecies)) {
            $indecies = array($indecies);
         }

         $this->m_index = $indecies;
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * <b>Sample:</b><br> sphql->setOrder('mycolumn');<br>OR<br>sphql->setOrder(array('mycolumn', &middot;&middot;&middot;), array('ASC', &middot;&middot;&middot;));
       *
       * @param mixed $column
       * @param mixed $sortOrder
       */
      function setOrder($column, $sortOrder = 'ASC') {
         $this->m_order = ' ORDER BY ' . $this->prepareGroupOrder($column, $sortOrder);
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * <b>Sample:</b><br> sphql->setGroup('mycolumn');<br>OR<br>sphql->setGroup(array('mycolumn', &middot;&middot;&middot;));
       *
       * @param mixed $column
       */
      function setGroup($column) {
         $this->m_group = ' GROUP BY ' . $this->prepareGroupOrder($column, null);
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * <b>Sample:</b><br> sphql->setWithinGroupOrder('mycolumn');<br>OR<br>sphql->setWithinGroupOrder(array('mycolumn', &middot;&middot;&middot;), array('ASC', &middot;&middot;&middot;));
       *
       * @param mixed $column
       * @param mixed $sortOrder
       */
      function setWithinGroupOrder($column, $sortOrder = 'ASC') {
         $this->m_within_group_order = ' WITHIN GROUP ORDER BY ' . $this->prepareGroupOrder($column, $sortOrder);
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       *
       * @param int $rowCount
       * @param int $offset
       */
      function setLimit($rowCount, $offset = 0) {
         $this->m_limit = ' LIMIT ' . $offset . ', ' . $rowCount;
      }

//-------------------------------------------------------------------------------------------------------------------------------------
      /**
       * <b>Sample:</b><br>sphql->addOption(sphinxQLBuilder::OPT_RANKER_MATCHANY);<br>sphql->addOption(sphinxQLBuilder::OPT_MAX_MATCHES, 1000);<br>sphql->addOption(sphinxQLBuilder::OPT_FIELD_WEIGHTS, array('title'=>10, 'body'=>3));
       *
       * @param string $s
       * @param mixed $additional_val
       */
      function addOption($s, $additional_val=''){
         if(is_array($additional_val)){
            $tmp = '';
            reset($additional_val);
            while (list($key, $val) = each($additional_val)) {
               $tmp .= $key.'='.$val.',';
            }
            $tmp = '=('.trim($tmp, ',').')';
         }
         if(is_int($additional_val)){
            $additional_val = '='.$additional_val;
         }

         $this->m_options .= $s.$additional_val . ',';
      }
//-------------------------------------------------------------------------------------------------------------------------------------
      /**
    * add a field for SELECT
    *
    * @param mixed $name
    */
      function addField($name) {
         $this->m_fields[] = array("field" => $name);
      }

//-------------------------------------------------------------------------------------------------------------------------------------
/**
    * add a value for INSERT or UPDATE
    *
    * @param string $field
    * @param mixed $value
    */
   function addValue($field, $value){
      $this->m_values[] = array("field"=>$field,"val"=>$value);
   }
//-------------------------------------------------------------------------------------------------------------------------------------
   }

############################################################
}
############################################################
?>
Return current item: crVCL PHP Framework