[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/classes/ -> query.class.php (source)

   1  <?php /* $Id: query.class.php 139 2008-04-05 14:21:51Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/classes/query.class.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly');
   4  }
   5  
   6  /* Copyright 2003,2004 Adam Donnison <adam@saki.com.au>
   7  
   8  This file is part of the collected works of Adam Donnison.
   9  
  10  This is free software; you can redistribute it and/or modify
  11  it under the terms of the GNU General Public License as published by
  12  the Free Software Foundation; either version 2 of the License, or
  13  (at your option) any later version.
  14  
  15  This is distributed in the hope that it will be useful,
  16  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  GNU General Public License for more details.
  19  
  20  You should have received a copy of the GNU General Public License
  21  along with this; if not, write to the Free Software
  22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23  */
  24  
  25  require_once  W2P_BASE_DIR . '/lib/adodb/adodb.inc.php';
  26  
  27  define('QUERY_STYLE_ASSOC', ADODB_FETCH_ASSOC);
  28  define('QUERY_STYLE_NUM', ADODB_FETCH_NUM);
  29  define('QUERY_STYLE_BOTH', ADODB_FETCH_BOTH);
  30  /**
  31   * Database query class
  32   *
  33   * Container for creating prefix-safe queries.  Allows build up of
  34   * a select statement by adding components one at a time.
  35   *
  36   * @version    $Id: query.class.php 139 2008-04-05 14:21:51Z pedroix $
  37   * @package    web2Project
  38   * @access    public
  39   * @author    Adam Donnison <adam@saki.com.au>
  40   * @license    GPL version 2 or later.
  41   * @copyright    (c) 2003 Adam Donnison
  42   */
  43  class DBQuery {
  44      var $query;
  45      /**< Contains the query after it has been built. */
  46      var $table_list;
  47      /**< Array of tables to be queried */
  48      var $where;
  49      /**< WHERE component of the query */
  50      var $order_by;
  51      /**< ORDER BY component of the query */
  52      var $group_by;
  53      /**< GROUP BY component of the query */
  54      var $having;
  55      /**< HAVING component of the query */
  56      var $limit;
  57      /**< LIMIT component of the query */
  58      var $offset;
  59      /**< offset of the LIMIT component */
  60      var $join;
  61      /**< JOIN component of the query */
  62      var $type;
  63      /**< Query type eg. 'select', 'update' */
  64      var $update_list;
  65      /**< Array of fields->values to update */
  66      var $value_list;
  67      /**< Array of values used in INSERT or REPLACE statements */
  68      var $create_table;
  69      /**< Name of the table to create */
  70      var $create_definition;
  71      /**< Array containing information about the table definition */
  72      var $include_count = false;
  73      /**< Bollean to count of rows in query */
  74      var $_table_prefix;
  75      /**< Internal string, table prefix, prepended to all queries */
  76      var $_query_id = null;
  77      /**< Handle to the query result */
  78      var $_old_style = null;
  79      /**< Use the old style of fetch mode with ADODB */
  80      var $_db = null;
  81      /**< Handle to the database connection */
  82  
  83      /** DBQuery constructor
  84       *
  85       * @param $prefix Database table prefix - will be appended to all web2project table names
  86       * @param $query_db Database type
  87       */
  88  	function DBQuery($prefix = null, $query_db = null) {
  89          global $db;
  90  
  91          if (isset($prefix)) {
  92              $this->_table_prefix = $prefix;
  93          } else {
  94              $this->_table_prefix = w2PgetConfig('dbprefix', '');
  95          }
  96          $this->_db = isset($query_db) ? $query_db : $db;
  97  
  98          $this->clear();
  99      }
 100  
 101      /** Clear the current query and all set options
 102       */
 103  	function clear() {
 104          global $ADODB_FETCH_MODE;
 105          if (isset($this->_old_style)) {
 106              $ADODB_FETCH_MODE = $this->_old_style;
 107              $this->_old_style = null;
 108          }
 109          $this->type = 'select';
 110          $this->query = null;
 111          $this->table_list = null;
 112          $this->where = null;
 113          $this->order_by = null;
 114          $this->group_by = null;
 115          $this->limit = null;
 116          $this->offset = -1;
 117          $this->join = null;
 118          $this->value_list = null;
 119          $this->update_list = null;
 120          $this->create_table = null;
 121          $this->create_definition = null;
 122          if ($this->_query_id) {
 123              $this->_query_id->Close();
 124          }
 125          $this->_query_id = null;
 126      }
 127  
 128  	function clearQuery() {
 129          if ($this->_query_id) {
 130              $this->_query_id->Close();
 131          }
 132          $this->_query_id = null;
 133      }
 134  
 135      /** Get database specific SQL used to concatenate strings.
 136       * @return String containing SQL to concatenate supplied strings
 137       */
 138  	function concat() {
 139          $arr = func_get_args();
 140          $conc_str = call_user_func_array(array(&$this->_db, 'Concat'), $arr);
 141          return $conc_str;
 142      }
 143  
 144      /** Get database specific SQL used to check for null values.
 145       *
 146       * Calls the ADODB IfNull method
 147       * @return String containing SQL to check for null field value
 148       */
 149  	function ifNull($field, $nullReplacementValue) {
 150          return $this->_db->IfNull($field, $nullReplacementValue);
 151      }
 152  
 153      /** Add item to an internal associative array
 154       * 
 155       * Used internally with DBQuery
 156       *
 157       * @param    $varname    Name of variable to add/create
 158       * @param    $name    Data to add
 159       * @param    $id    Index to use in array.
 160       */
 161  	function addMap($varname, $name, $id) {
 162          if (!isset($this->$varname)) {
 163              $this->$varname = array();
 164          }
 165          if (isset($id)) {
 166              $this->{$varname}[$id] = $name;
 167          } else {
 168              $this->{$varname}[] = $name;
 169          }
 170      }
 171  
 172      /** Add a table to the query
 173       *
 174       * A table is normally addressed by an
 175       * alias.  If you don't supply the alias chances are your code will
 176       * break.  You can add as many tables as are needed for the query.
 177       * E.g. addTable('something', 'a') will result in an SQL statement
 178       * of {PREFIX}table as a.
 179       * Where {PREFIX} is the system defined table prefix.
 180       *
 181       * @param    $name    Name of table, without prefix.
 182       * @param    $id    Alias for use in query/where/group clauses.
 183       */
 184  	function addTable($name, $id = null) {
 185          $this->addMap('table_list', $name, ($id ? $id : $name));
 186      }
 187  
 188      /** Add a clause to an internal array
 189       *
 190       * Checks to see variable exists first.
 191       * then pushes the new data onto the end of the array.
 192       * @param $clause the type of clause to add
 193       * @param $value the clause value
 194       * @param $check_array defaults to true, iterates through each element in $value and adds them seperately to the clause
 195       */
 196  	function addClause($clause, $value, $check_array = true) {
 197          //dprint(__file__, __line__, 8, "Adding '$value' to $clause clause");
 198          if (!isset($this->$clause)) {
 199              $this->$clause = array();
 200          }
 201          if ($check_array && is_array($value)) {
 202              foreach ($value as $v) {
 203                  array_push($this->$clause, $v);
 204              }
 205          } else {
 206              array_push($this->$clause, $value);
 207          }
 208      }
 209  
 210      /** Add the select part (fields, functions) to the query
 211       *
 212       * E.g. '*', or 'a.*'
 213       * or 'a.field, b.field', etc.  You can call this multiple times
 214       * and it will correctly format a combined query.
 215       *
 216       * @param    $query    Query string to use.
 217       */
 218  	function addQuery($query) {
 219          $this->addClause('query', $query);
 220      }
 221  
 222      /** Insert a value into the database
 223       * @param $field The field to insert the value into
 224       * @param $value The specified value
 225       * @param $set Defaults to false. If true will check to see if the fields or values supplied are comma delimited strings instead of arrays
 226       * @param $func Defaults to false. If true will not use quotation marks around the value - to be used when the value being inserted includes a function
 227       */
 228  	function addInsert($field, $value = null, $set = false, $func = false) {
 229          if (is_array($field) && $value == null) {
 230              foreach ($field as $f => $v) {
 231                  $this->addMap('value_list', $f, $v);
 232              }
 233          } elseif ($set) {
 234              if (is_array($field)) {
 235                  $fields = $field;
 236              } else {
 237                  $fields = explode(',', $field);
 238              }
 239  
 240              if (is_array($value)) {
 241                  $values = $value;
 242              } else {
 243                  $values = explode(',', $value);
 244              }
 245  
 246              for ($i = 0, $i_cmp = count($fields); $i < $i_cmp; $i++) {
 247                  $this->addMap('value_list', $this->quote($values[$i]), $fields[$i]);
 248              }
 249          } else
 250              if (!$func) {
 251                  $this->addMap('value_list', $this->quote($value), $field);
 252              } else {
 253                  $this->addMap('value_list', $value, $field);
 254              }
 255              $this->type = 'insert';
 256      }
 257  
 258  	function addInsertSelect($table) {
 259          $this->create_table = $table;
 260          $this->type = 'insert_select';
 261      }
 262  
 263      // implemented addReplace() on top of addInsert()
 264      /** Insert a value into the database, to replace an existing row.
 265       * @param $field The field to insert the value into
 266       * @param $value The specified value
 267       * @param $set Defaults to false. If true will check to see if the fields or values supplied are comma delimited strings instead of arrays
 268       * @param $func Defaults to false. If true will not use quotation marks around the value - to be used when the value being inserted includes a function
 269       */
 270  	function addReplace($field, $value, $set = false, $func = false) {
 271          $this->addInsert($field, $value, $set, $func);
 272          $this->type = 'replace';
 273      }
 274  
 275      /** Update a database value
 276       * @param $field The field to update
 277       * @param $value The value to set $field to
 278       * @param $set Defaults to false. If true will check to see if the fields or values supplied are comma delimited strings instead of arrays
 279       */
 280  	function addUpdate($field, $value = null, $set = false) {
 281          if (is_array($field) && $value == null) {
 282              foreach ($field as $f => $v) {
 283                  $this->addMap('update_list', $f, $v);
 284              }
 285          } elseif ($set) {
 286              if (is_array($field)) {
 287                  $fields = $field;
 288              } else {
 289                  $fields = explode(',', $field);
 290              }
 291  
 292              if (is_array($value)) {
 293                  $values = $value;
 294              } else {
 295                  $values = explode(',', $value);
 296              }
 297  
 298              for ($i = 0, $i_cmp = count($fields); $i < $i_cmp; $i++) {
 299                  $this->addMap('update_list', $values[$i], $fields[$i]);
 300              }
 301          } else {
 302              $this->addMap('update_list', $value, $field);
 303          }
 304          $this->type = 'update';
 305      }
 306  
 307      /** Create a database table
 308       * @param $table the name of the table to create
 309       */
 310  	function createTable($table, $def = null) {
 311          $this->type = 'createPermanent';
 312          $this->create_table = $table;
 313          if ($def) {
 314              $this->create_definition = $def;
 315          }
 316      }
 317  
 318  	function createDatabase($database) {
 319          $dict = NewDataDictionary($this->_db, w2PgetConfig('dbtype'));
 320          $dict->CreateDatabase($database);
 321      }
 322  
 323  	function DDcreateTable($table, $def, $opts) {
 324          $dict = NewDataDictionary($this->_db, w2PgetConfig('dbtype'));
 325          $query_array = $dict->ChangeTableSQL(w2PgetConfig('dbprefix') . $table, $def, $opts);
 326          //returns 0 - failed, 1 - executed with errors, 2 - success
 327          return $dict->ExecuteSQLArray($query_array);
 328      }
 329  
 330  	function DDcreateIndex($name, $table, $cols, $opts) {
 331          $dict = NewDataDictionary($this->_db, w2PgetConfig('dbtype'));
 332          $query_array = $dict->CreateIndexSQL($name, $table, $cols, $opts);
 333          //returns 0 - failed, 1 - executed with errors, 2 - success
 334          return $dict->ExecuteSQLArray($query_array);
 335      }
 336  
 337      /** Create a temporary database table
 338       * @param $table the name of the temporary table to create.
 339       */
 340  	function createTemp($table) {
 341          $this->type = 'create';
 342          $this->create_table = $table;
 343      }
 344  
 345      /** Drop a table from the database
 346       *
 347       * Use dropTemp() to drop temporary tables
 348       * @param $table the name of the table to drop.
 349       */
 350  	function dropTable($table) {
 351          $this->type = 'drop';
 352          $this->create_table = $table;
 353      }
 354  
 355      /** Drop a temporary table from the database
 356       * @param $table the name of the temporary table to drop
 357       */
 358  	function dropTemp($table) {
 359          $this->type = 'drop';
 360          $this->create_table = $table;
 361      }
 362  
 363      /** Alter a database table
 364       * @param $table the name of the table to alter
 365       */
 366  	function alterTable($table) {
 367          $this->create_table = $table;
 368          $this->type = 'alter';
 369      }
 370  
 371      /** Add a field definition for usage with table creation/alteration
 372       * @param $name The name of the field
 373       * @param $type The type of field to create
 374       */
 375  	function addField($name, $type) {
 376          if (!is_array($this->create_definition)) {
 377              $this->create_definition = array();
 378          }
 379          $this->create_definition[] = array('action' => 'ADD', 'type' => '', 'spec' => $name . ' ' . $type);
 380      }
 381  
 382      /**
 383       * Alter a field definition for usage with table alteration
 384       * @param $name The name of the field
 385       * @param $type The type of the field
 386       */
 387  	function alterField($name, $type) {
 388          if (!is_array($this->create_definition)) {
 389              $this->create_definition = array();
 390          }
 391          $this->create_definition[] = array('action' => 'CHANGE', 'type' => '', 'spec' => $name . ' ' . $name . ' ' . $type);
 392      }
 393  
 394      /** Drop a field from table definition or from an existing table
 395       * @param $name The name of the field to drop
 396       */
 397  	function dropField($name) {
 398          if (!is_array($this->create_definition)) {
 399              $this->create_definition = array();
 400          }
 401          $this->create_definition[] = array('action' => 'DROP', 'type' => '', 'spec' => $name);
 402      }
 403  
 404      /** Add an index
 405       */
 406  	function addIndex($name, $type) {
 407          if (!is_array($this->create_definition)) {
 408              $this->create_definition = array();
 409          }
 410          $this->create_definition[] = array('action' => 'ADD', 'type' => 'INDEX', 'spec' => $name . ' ' . $type);
 411      }
 412  
 413      /** Drop an index
 414       */
 415  	function dropIndex($name) {
 416          if (!is_array($this->create_definition)) {
 417              $this->create_definition = array();
 418          }
 419          $this->create_definition[] = array('action' => 'DROP', 'type' => 'INDEX', 'spec' => $name);
 420      }
 421  
 422      /** Remove a primary key attribute from a field
 423       */
 424  	function dropPrimary() {
 425          if (!is_array($this->create_definition)) {
 426              $this->create_definition = array();
 427          }
 428          $this->create_definition[] = array('action' => 'DROP', 'type' => 'PRIMARY KEY', 'spec' => '');
 429      }
 430  
 431      /** Set a table creation definition from supplied array
 432       * @param $def Array containing table definition
 433       */
 434  	function createDefinition($def) {
 435          $this->create_definition = $def;
 436      }
 437  
 438  	function setDelete($table) {
 439          $this->type = 'delete';
 440          $this->addMap('table_list', $table, null);
 441      }
 442  
 443      /** Add a WHERE sub clause
 444       * 
 445       * The where clause can be built up one
 446       * part at a time and the resultant query will put in the 'and'
 447       * between each component.
 448       *
 449       * Make sure you use table aliases.
 450       *
 451       * @param    $query    Where subclause to use, not including WHERE keyword
 452       */
 453  	function addWhere($query) {
 454          if (isset($query)) {
 455              $this->addClause('where', $query);
 456          }
 457      }
 458  
 459      /** Add a JOIN condition
 460       *
 461       * Add a join condition to the query.  This only implements
 462       * left join, however most other joins are either synonymns or
 463       * can be emulated with where clauses.
 464       *
 465       * @param    $table    Name of table (without prefix)
 466       * @param    $alias    Alias to use instead of table name (required).
 467       * @param    $join    Join condition (e.g. 'a.id = b.other_id')
 468       *                or array of join fieldnames, e.g. array('id', 'name);
 469       *                Both are correctly converted into a join clause.
 470       */
 471  	function addJoin($table, $alias, $join, $type = 'left') {
 472          $var = array('table' => $table, 'alias' => $alias, 'condition' => $join, 'type' => $type);
 473  
 474          $this->addClause('join', $var, false);
 475      }
 476  
 477      /** Add a left join condition
 478       *
 479       * Helper method to add a left join
 480       * @see addJoin()
 481       * @param $table Name of table (without prefix)
 482       * @param $alias Alias to use instead of table name
 483       * @param $join Join condition
 484       */
 485  	function leftJoin($table, $alias, $join) {
 486          $this->addJoin($table, $alias, $join, 'left');
 487      }
 488  
 489      /** Add a right join condition
 490       *
 491       * Helper method to add a right join
 492       * @see addJoin()
 493       * @param $table Name of table (without prefix)
 494       * @param $alias Alias to use instead of table name
 495       * @param $join Join condition
 496       */
 497  	function rightJoin($table, $alias, $join) {
 498          $this->addJoin($table, $alias, $join, 'right');
 499      }
 500  
 501      /** Add an inner join condition
 502       *
 503       * Helper method to add an inner join
 504       * @see addJoin()
 505       * @param $table Name of table (without prefix)
 506       * @param $alias Alias to use instead of table name
 507       * @param $join Join condition
 508       */
 509  	function innerJoin($table, $alias, $join) {
 510          $this->addJoin($table, $alias, $join, 'inner');
 511      }
 512  
 513      /** Add an ORDER BY clause
 514       *
 515       * Again, only the fieldname is required, and
 516       * it should include an alias if a table has been added.
 517       * May be called multiple times.
 518       *
 519       * @param    $order    Order by field.
 520       */
 521  	function addOrder($order) {
 522          if (isset($order)) {
 523              $this->addClause('order_by', $order);
 524          }
 525      }
 526  
 527      /** Add a GROUP BY clause
 528       *
 529       * Only the fieldname is required.
 530       * May be called multiple times.  Use table aliases as required.
 531       *
 532       * @param    $group    Field name to group by.
 533       */
 534  	function addGroup($group) {
 535          $this->addClause('group_by', $group);
 536      }
 537  
 538      /** Add a HAVING sub clause
 539       * 
 540       * The having clause can be built up one
 541       * part at a time and the resultant query will put in the 'and'
 542       * between each component.
 543       *
 544       * Remember: 
 545       * "the SQL standard requires that HAVING must reference only columns in the 
 546       * GROUP BY clause or columns used in aggregate functions"
 547       *
 548       * @param    $query    HAVING subclause to use, not including HAVING keyword
 549       */
 550  	function addHaving($query) {
 551          $this->addClause('having', $query);
 552      }
 553  
 554      /** Set a row limit on the query
 555       *
 556       * Set a limit on the query.  This is done in a database-independent
 557       * fashion.
 558       *
 559       * @param    $limit    Number of rows to limit.
 560       * @param    $start    First row to start extraction(row offset).
 561       */
 562  	function setLimit($limit, $start = -1) {
 563          $this->limit = $limit;
 564          $this->offset = $start;
 565      }
 566  
 567      /**
 568       * Set include count feature, grabs the count of rows that
 569       * would have been returned had no limit been set.
 570       */
 571  	function includeCount() {
 572          $this->include_count = true;
 573      }
 574      /** Set a limit on the query based on pagination.
 575       *
 576       * @param $page     the current page
 577       * @param $pagesize the size of pages
 578       */
 579  	function setPageLimit($page = 0, $pagesize = 0) {
 580          if ($page == 0) {
 581              global $tpl;
 582              $page = $tpl->page;
 583          }
 584  
 585          if ($pagesize == 0) {
 586              $pagesize = w2PgetConfig('page_size');
 587          }
 588  
 589          $this->setLimit($pagesize, ($page - 1) * $pagesize);
 590      }
 591  
 592      /** Prepare query for execution
 593       * @param $clear Boolean, Clear the query after it has been executed
 594       * @return String containing the SQL statement
 595       */
 596  	function prepare($clear = false) {
 597          switch ($this->type) {
 598              case 'select':
 599                  $q = $this->prepareSelect();
 600                  break;
 601              case 'update':
 602                  $q = $this->prepareUpdate();
 603                  break;
 604              case 'insert':
 605                  $q = $this->prepareInsert();
 606                  break;
 607              case 'insert_select':
 608                  $s = $this->prepareSelect();
 609                  $q = 'INSERT INTO ' . $this->_table_prefix . $this->create_table;
 610                  $q .= ' ' . $s;
 611                  break;
 612              case 'replace':
 613                  $q = $this->prepareReplace();
 614                  break;
 615              case 'delete':
 616                  $q = $this->prepareDelete();
 617                  break;
 618              case 'create': // Create a temporary table
 619                  $s = $this->prepareSelect();
 620                  $q = 'CREATE TEMPORARY TABLE ' . $this->_table_prefix . $this->create_table;
 621                  if (!empty($this->create_definition))
 622                      $q .= ' ' . $this->create_definition;
 623                  $q .= ' ' . $s;
 624                  break;
 625              case 'alter':
 626                  $q = $this->prepareAlter();
 627                  break;
 628              case 'createPermanent': // Create a temporary table
 629                  //$s = $this->prepareSelect();
 630                  $q = 'CREATE TABLE ' . $this->_table_prefix . $this->create_table;
 631                  if (!empty($this->create_definition)) {
 632                      $q .= ' ' . $this->create_definition;
 633                  }
 634                  //$q .= ' ' . $s;
 635                  /*$q = array( 'table' => $this->_table_prefix . $this->create_table,
 636                  'definition' => $this->create_definition,
 637                  );*/
 638                  break;
 639              case 'drop':
 640                  $q = 'DROP TABLE IF EXISTS ' . $this->_table_prefix . $this->create_table;
 641                  break;
 642          }
 643          if ($clear) {
 644              $this->clear();
 645          }
 646          return $q;
 647          dprint(__file__, __line__, 2, $q);
 648      }
 649  
 650      /** Prepare the SELECT component of the SQL query
 651       */
 652  	function prepareSelect() {
 653          switch (strtolower(trim(w2PgetConfig('dbtype')))) {
 654              case 'oci8':
 655              case 'oracle':
 656                  $q = 'SELECT ';
 657                  if ($this->include_count) {
 658                      //$q .= 'SQL_CALC_FOUND_ROWS ';
 659                  }
 660                  if (isset($this->query)) {
 661                      if (is_array($this->query)) {
 662                          $inselect = false;
 663                          $q .= implode(',', $this->query);
 664                      } else {
 665                          $q .= $this->query;
 666                      }
 667                  } else {
 668                      $q .= '*';
 669                  }
 670                  $q .= ' FROM ';
 671                  if (isset($this->table_list)) {
 672                      if (is_array($this->table_list)) {
 673                          $intable = false;
 674                          foreach ($this->table_list as $table_id => $table) {
 675                              if ($intable) {
 676                                  $q .= ',';
 677                              } else {
 678                                  $intable = true;
 679                              }
 680                              $q .= $this->_table_prefix . $table;
 681                              if (!is_numeric($table_id)) {
 682                                  $q .= ' ' . $table_id;
 683                              }
 684                          }
 685                      } else {
 686                          $q .= $this->_table_prefix . $this->table_list;
 687                      }
 688                  } else {
 689                      return false;
 690                  }
 691                  $q .= $this->make_join($this->join);
 692                  $q .= $this->make_where_clause($this->where);
 693                  $q .= $this->make_group_clause($this->group_by);
 694                  $q .= $this->make_having_clause($this->having);
 695                  $q .= $this->make_order_clause($this->order_by);
 696                  $q .= $this->make_limit_clause($this->limit, $this->offset);
 697                  return $q;
 698                  break;
 699              default:
 700              //mySQL
 701                  $q = 'SELECT ';
 702                  if ($this->include_count) {
 703                      $q .= 'SQL_CALC_FOUND_ROWS ';
 704                  }
 705                  if (isset($this->query)) {
 706                      if (is_array($this->query)) {
 707                          $inselect = false;
 708                          $q .= implode(',', $this->query);
 709                      } else {
 710                          $q .= $this->query;
 711                      }
 712                  } else {
 713                      $q .= '*';
 714                  }
 715                  $q .= ' FROM (';
 716                  if (isset($this->table_list)) {
 717                      if (is_array($this->table_list)) {
 718                          $intable = false;
 719                          /* added brackets for MySQL > 5.0.12 compatibility
 720                          ** patch #1358907 submitted to sf.net on 2005-11-17 04:12 by ilgiz
 721                          */
 722                          $q .= '(';
 723                          foreach ($this->table_list as $table_id => $table) {
 724                              if ($intable) {
 725                                  $q .= ',';
 726                              } else {
 727                                  $intable = true;
 728                              }
 729                              $q .= $this->quote_db($this->_table_prefix . $table);
 730                              if (!is_numeric($table_id)) {
 731                                  $q .= ' AS ' . $table_id;
 732                              }
 733                          }
 734                          /* added brackets for MySQL > 5.0.12 compatibility
 735                          ** patch #1358907 submitted to sf.net on 2005-11-17 04:12 by ilgiz
 736                          */
 737                          $q .= ')';
 738                      } else {
 739                          $q .= $this->_table_prefix . $this->table_list;
 740                      }
 741                      $q .= ')';
 742                  } else {
 743                      return false;
 744                  }
 745                  $q .= $this->make_join($this->join);
 746                  $q .= $this->make_where_clause($this->where);
 747                  $q .= $this->make_group_clause($this->group_by);
 748                  $q .= $this->make_having_clause($this->having);
 749                  $q .= $this->make_order_clause($this->order_by);
 750                  $q .= $this->make_limit_clause($this->limit, $this->offset);
 751                  return $q;
 752          }
 753      }
 754  
 755      /** Prepare the UPDATE component of the SQL query
 756       */
 757  	function prepareUpdate() {
 758          // You can only update one table, so we get the table detail
 759          switch (strtolower(trim(w2PgetConfig('dbtype')))) {
 760              case 'oci8':
 761              case 'oracle':
 762                  $q = 'UPDATE ';
 763                  if (isset($this->table_list)) {
 764                      if (is_array($this->table_list)) {
 765                          reset($this->table_list);
 766                          // Grab the first record
 767                          list($key, $table) = each($this->table_list);
 768                      } else {
 769                          $table = $this->table_list;
 770                      }
 771                  } else {
 772                      return false;
 773                  }
 774                  $q .= $this->_table_prefix . $table;
 775          
 776                  $q .= ' SET ';
 777                  $sets = '';
 778                  foreach ($this->update_list as $field => $value) {
 779                      if ($sets) {
 780                          $sets .= ', ';
 781                      }
 782                      $sets .= $field . ' = ' . $this->quote($value);
 783                  }
 784                  $q .= $sets;
 785                  $q .= $this->make_where_clause($this->where);
 786                  return $q;
 787                  break;
 788              default:
 789              //mySQL
 790                  $q = 'UPDATE ';
 791                  if (isset($this->table_list)) {
 792                      if (is_array($this->table_list)) {
 793                          reset($this->table_list);
 794                          // Grab the first record
 795                          list($key, $table) = each($this->table_list);
 796                      } else {
 797                          $table = $this->table_list;
 798                      }
 799                  } else {
 800                      return false;
 801                  }
 802                  $q .= $this->quote_db($this->_table_prefix . $table);
 803          
 804                  $q .= ' SET ';
 805                  $sets = '';
 806                  foreach ($this->update_list as $field => $value) {
 807                      if ($sets) {
 808                          $sets .= ', ';
 809                      }
 810                      $sets .= $this->quote_db($field) . ' = ' . $this->quote($value);
 811                  }
 812                  $q .= $sets;
 813                  $q .= $this->make_where_clause($this->where);
 814                  return $q;
 815          }
 816      }
 817  
 818      /** Prepare the INSERT component of the SQL query
 819       */
 820  	function prepareInsert() {
 821          switch (strtolower(trim(w2PgetConfig('dbtype')))) {
 822              case 'oci8':
 823              case 'oracle':
 824                  $q = 'INSERT INTO ';
 825                  if (isset($this->table_list)) {
 826                      if (is_array($this->table_list)) {
 827                          reset($this->table_list);
 828                          // Grab the first record
 829                          list($key, $table) = each($this->table_list);
 830                      } else {
 831                          $table = $this->table_list;
 832                      }
 833                  } else {
 834                      return false;
 835                  }
 836                  $q .= $this->_table_prefix . $table;
 837          
 838                  $fieldlist = '';
 839                  $valuelist = '';
 840                  foreach ($this->value_list as $field => $value) {
 841                      if ($fieldlist) {
 842                          $fieldlist .= ',';
 843                      }
 844                      if ($valuelist) {
 845                          $valuelist .= ',';
 846                      }
 847                      $fieldlist .= trim($field);
 848                      $valuelist .= $value;
 849                  }
 850                  $q .= '(' . $fieldlist . ') VALUES (' . $valuelist . ')';
 851                  return $q;
 852                  break;
 853              default:
 854              //mySQL
 855                  $q = 'INSERT INTO ';
 856                  if (isset($this->table_list)) {
 857                      if (is_array($this->table_list)) {
 858                          reset($this->table_list);
 859                          // Grab the first record
 860                          list($key, $table) = each($this->table_list);
 861                      } else {
 862                          $table = $this->table_list;
 863                      }
 864                  } else {
 865                      return false;
 866                  }
 867                  $q .= $this->quote_db($this->_table_prefix . $table);
 868          
 869                  $fieldlist = '';
 870                  $valuelist = '';
 871                  foreach ($this->value_list as $field => $value) {
 872                      if ($fieldlist) {
 873                          $fieldlist .= ',';
 874                      }
 875                      if ($valuelist) {
 876                          $valuelist .= ',';
 877                      }
 878                      $fieldlist .= $this->quote_db(trim($field));
 879                      $valuelist .= $value;
 880                  }
 881                  $q .= '(' . $fieldlist . ') VALUES (' . $valuelist . ')';
 882                  return $q;
 883          }
 884      }
 885  
 886      /** Prepare the INSERT component of the SQL query
 887       */
 888  	function prepareInsertSelect() {
 889          $q = 'INSERT INTO ';
 890          if (isset($this->table_list)) {
 891              if (is_array($this->table_list)) {
 892                  reset($this->table_list);
 893                  // Grab the first record
 894                  list($key, $table) = each($this->table_list);
 895              } else {
 896                  $table = $this->table_list;
 897              }
 898          } else {
 899              return false;
 900          }
 901          $q .= $this->quote_db($this->_table_prefix . $table);
 902  
 903          $fieldlist = '';
 904          $valuelist = '';
 905          foreach ($this->value_list as $field => $value) {
 906              if ($fieldlist) {
 907                  $fieldlist .= ',';
 908              }
 909              if ($valuelist) {
 910                  $valuelist .= ',';
 911              }
 912              $fieldlist .= $this->quote_db(trim($field));
 913              $valuelist .= $value;
 914          }
 915          $q .= '(' . $fieldlist . ') VALUES (' . $valuelist . ')';
 916          return $q;
 917      }
 918  
 919      /** Prepare the REPLACE component of the SQL query
 920       */
 921  	function prepareReplace() {
 922          switch (strtolower(trim(w2PgetConfig('dbtype')))) {
 923              case 'oci8':
 924              case 'oracle':
 925                  $q = 'REPLACE INTO ';
 926                  if (isset($this->table_list)) {
 927                      if (is_array($this->table_list)) {
 928                          reset($this->table_list);
 929                          // Grab the first record
 930                          list($key, $table) = each($this->table_list);
 931                      } else {
 932                          $table = $this->table_list;
 933                      }
 934                  } else {
 935                      return false;
 936                  }
 937                  $q .= $this->_table_prefix . $table;
 938          
 939                  $fieldlist = '';
 940                  $valuelist = '';
 941                  foreach ($this->value_list as $field => $value) {
 942                      if ($fieldlist) {
 943                          $fieldlist .= ',';
 944                      }
 945                      if ($valuelist) {
 946                          $valuelist .= ',';
 947                      }
 948                      $fieldlist .= trim($field);
 949                      $valuelist .= $value;
 950                  }
 951                  $q .= '(' . $fieldlist . ') VALUES (' . $valuelist . ')';
 952                  return $q;
 953                  break;
 954              default:
 955              //mySQL
 956                  $q = 'REPLACE INTO ';
 957                  if (isset($this->table_list)) {
 958                      if (is_array($this->table_list)) {
 959                          reset($this->table_list);
 960                          // Grab the first record
 961                          list($key, $table) = each($this->table_list);
 962                      } else {
 963                          $table = $this->table_list;
 964                      }
 965                  } else {
 966                      return false;
 967                  }
 968                  $q .= $this->quote_db($this->_table_prefix . $table);
 969          
 970                  $fieldlist = '';
 971                  $valuelist = '';
 972                  foreach ($this->value_list as $field => $value) {
 973                      if ($fieldlist) {
 974                          $fieldlist .= ',';
 975                      }
 976                      if ($valuelist) {
 977                          $valuelist .= ',';
 978                      }
 979                      $fieldlist .= $this->quote_db(trim($field));
 980                      $valuelist .= $value;
 981                  }
 982                  $q .= '(' . $fieldlist . ') VALUES (' . $valuelist . ')';
 983                  return $q;
 984          }
 985      }
 986  
 987      /** Prepare the DELETE component of the SQL query
 988       */
 989  	function prepareDelete() {
 990          switch (strtolower(trim(w2PgetConfig('dbtype')))) {
 991              case 'oci8':
 992              case 'oracle':
 993                  $q = 'DELETE FROM ';
 994                  if (isset($this->table_list)) {
 995                      if (is_array($this->table_list)) {
 996                          // Grab the first record
 997                          list($key, $table) = each($this->table_list);
 998                      } else {
 999                          $table = $this->table_list;
1000                      }
1001                  } else {
1002                      return false;
1003                  }
1004                  $q .= $this->_table_prefix . $table;
1005                  $q .= $this->make_where_clause($this->where);
1006                  return $q;
1007                  break;
1008              default:
1009              //mySQL
1010                  $q = 'DELETE FROM ';
1011                  if (isset($this->table_list)) {
1012                      if (is_array($this->table_list)) {
1013                          // Grab the first record
1014                          list($key, $table) = each($this->table_list);
1015                      } else {
1016                          $table = $this->table_list;
1017                      }
1018                  } else {
1019                      return false;
1020                  }
1021                  $q .= $this->quote_db($this->_table_prefix . $table);
1022                  $q .= $this->make_where_clause($this->where);
1023                  return $q;
1024          }
1025      }
1026  
1027      /** Prepare the ALTER component of the SQL query
1028       * @todo add ALTER DROP/CHANGE/MODIFY/IMPORT/DISCARD/.. definitions: http://dev.mysql.com/doc/mysql/en/alter-table.html
1029       */
1030  	function prepareAlter() {
1031          $q = 'ALTER TABLE ' . $this->quote_db($this->_table_prefix . $this->create_table) . ' ';
1032          if (isset($this->create_definition)) {
1033              if (is_array($this->create_definition)) {
1034                  $first = true;
1035                  foreach ($this->create_definition as $def) {
1036                      if ($first) {
1037                          $first = false;
1038                      } else {
1039                          $q .= ', ';
1040                      }
1041                      $q .= $def['action'] . ' ' . $def['type'] . ' ' . $def['spec'];
1042                  }
1043              } else {
1044                  $q .= 'ADD ' . $this->create_definition;
1045              }
1046          }
1047          return $q;
1048      }
1049  
1050      /** Execute the query
1051       *
1052       * Execute the query and return a handle.  Supplants the db_exec query
1053       * @param $style ADODB fetch style. Can be ADODB_FETCH_BOTH, ADODB_FETCH_NUM or ADODB_FETCH_ASSOC
1054       * @param $debug Defaults to false. If true, debug output includes explanation of query
1055       * @return Handle to the query result
1056       */
1057      function &exec($style = ADODB_FETCH_BOTH, $debug = false) {
1058          global $ADODB_FETCH_MODE, $w2p_performance_dbtime, $w2p_performance_dbqueries;
1059  
1060          if (W2P_PERFORMANCE_DEBUG) {
1061              $startTime = array_sum(explode(' ', microtime()));
1062          }
1063          if (!isset($this->_old_style)) {
1064              $this->_old_style = $ADODB_FETCH_MODE;
1065          }
1066          $ADODB_FETCH_MODE = $style;
1067          $this->clearQuery();
1068          if ($q = $this->prepare()) {
1069              /*echo('<pre>');
1070              print_r('executing query(' . $q . ')');
1071              print_r(debug_backtrace());
1072              echo('</pre>');*/
1073              if ($debug) {
1074                  // Before running the query, explain the query and return the details.
1075                  $qid = $this->_db->Execute('EXPLAIN ' . $q);
1076                  if ($qid) {
1077                      $res = array();
1078                      while ($row = $this->fetchRow()) {
1079                          $res[] = $row;
1080                      }
1081                      dprint(__file__, __line__, 0, 'QUERY DEBUG: ' . var_export($res, true));
1082                      $qid->Close();
1083                  }
1084              }
1085              $this->_query_id = $this->_db->Execute($q);
1086              if (!$this->_query_id) {
1087                  $error = $this->_db->ErrorMsg();
1088                  dprint(__file__, __line__, 0, "query failed($q)" . ' - error was: <span style="color:red">' . $error . '</span>');
1089                  return $this->_query_id;
1090              }
1091              if (W2P_PERFORMANCE_DEBUG) {
1092                  ++$w2p_performance_dbqueries;
1093                  $w2p_performance_dbtime += array_sum(explode(' ', microtime())) - $startTime;
1094              }
1095              return $this->_query_id;
1096          } else {
1097              if (W2P_PERFORMANCE_DEBUG) {
1098                  ++$w2p_performance_dbqueries;
1099                  $w2p_performance_dbtime += array_sum(explode(' ', microtime())) - $startTime;
1100              }
1101              return $this->_query_id;
1102          }
1103      }
1104  
1105      /** Fetch the first row of the results
1106       * @return First row as array
1107       */
1108  	function fetchRow() {
1109          if (!$this->_query_id) {
1110              return false;
1111          }
1112          return $this->_query_id->FetchRow();
1113      }
1114  
1115      /** Load database results as an array of associative arrays
1116       *
1117       * Replaces the db_loadList() function
1118       * @param $maxrows Maximum number of rows to return
1119       * @return Array of associative arrays containing row field values
1120       */
1121  	function loadList($maxrows = null) {
1122          global $AppUI;
1123  
1124          if (!$this->exec(ADODB_FETCH_ASSOC)) {
1125              $AppUI->setMsg($this->_db->ErrorMsg(), UI_MSG_ERROR);
1126              $this->clear();
1127              return false;
1128          }
1129  
1130          $list = array();
1131          $cnt = 0;
1132          while ($hash = $this->fetchRow()) {
1133              $list[] = $hash;
1134              if ($maxrows && $maxrows == $cnt++) {
1135                  break;
1136              }
1137          }
1138          $this->clear();
1139          return $list;
1140      }
1141  
1142      /** Load database results as an associative array, using the supplied field name as the array's keys
1143       *
1144       * Replaces the db_loadHashList() function
1145       * @param $index Defaults to null, the field to use for array keys
1146       * @return Associative array of rows, keyed with the field indicated by the $index parameter
1147       */
1148  	function loadHashList($index = null) {
1149  
1150          if (!$this->exec(ADODB_FETCH_ASSOC)) {
1151              exit($this->_db->ErrorMsg());
1152          }
1153          $hashlist = array();
1154          $keys = null;
1155          while ($hash = $this->fetchRow()) {
1156              if ($index) {
1157                  $hashlist[$hash[$index]] = $hash;
1158                  //Lets add the hash fields in numerial keys:
1159                  //This is so that the arraySelectList works correctly with the results of DBQueries loadHashList method
1160                  $key = 0;
1161                  foreach ($hash as $field) {
1162                      $hashlist[$hash[$index]][$key] = $field;
1163                      $key++;
1164                  }
1165              } else {
1166                  // If we are using fetch mode of ASSOC, then we don't
1167                  // have an array index we can use, so we need to get one
1168                  if (!$keys) {
1169                      $keys = array_keys($hash);
1170                  }
1171                  $hashlist[$hash[$keys[0]]] = $hash[$keys[1]];
1172              }
1173          }
1174          $this->clear();
1175          return $hashlist;
1176      }
1177  
1178      /** Load a single result row as an associative array
1179       * @return Associative array of field names to values
1180       */
1181  	function loadHash() {
1182          if (!$this->exec(ADODB_FETCH_ASSOC)) {
1183              exit($this->_db->ErrorMsg());
1184          }
1185          $hash = $this->fetchRow();
1186          $this->clear();
1187          return $hash;
1188      }
1189  
1190      /** Load database results as an associative array
1191       * 
1192       * @note To devs: is this functionally different to loadHashList() ?
1193       * @param $index Field index to use for naming the array keys.
1194       * @return Associative array containing result rows
1195       */
1196  	function loadArrayList($index = 0) {
1197  
1198          if (!$this->exec(ADODB_FETCH_NUM)) {
1199              exit($this->_db->ErrorMsg());
1200          }
1201          $hashlist = array();
1202          $keys = null;
1203          while ($hash = $this->fetchRow()) {
1204              $hashlist[$hash[$index]] = $hash;
1205          }
1206          $this->clear();
1207          return $hashlist;
1208      }
1209  
1210      /** Load an indexed array containing the first column of results only
1211       * @return Indexed array of first column values
1212       */
1213  	function loadColumn() {
1214          if (!$this->exec(ADODB_FETCH_NUM)) {
1215              die($this->_db->ErrorMsg());
1216          }
1217          $result = array();
1218          while ($row = $this->fetchRow()) {
1219              $result[] = $row[0];
1220          }
1221          $this->clear();
1222          return $result;
1223      }
1224  
1225      /** Load database results into a CW2pObject based object
1226       * @param &$object Reference to the object to propagate with database results
1227       * @param $bindAll Defaults to false, Bind every field returned to the referenced object
1228       * @param $strip Defaults to true
1229       * @return True on success.
1230       */
1231  	function loadObject(&$object, $bindAll = false, $strip = true) {
1232          if (!$this->exec(ADODB_FETCH_NUM)) {
1233              die($this->_db->ErrorMsg());
1234          }
1235          if ($object != null) {
1236              $hash = $this->loadHash();
1237              $this->clear();
1238              if (!$hash) {
1239                  return false;
1240              }
1241              $this->bindHashToObject($hash, $object, null, $strip, $bindAll);
1242              return true;
1243          } else {
1244              if ($object = $this->_query_id->FetchNextObject(false)) {
1245                  $this->clear();
1246                  return true;
1247              } else {
1248                  $object = null;
1249                  return false;
1250              }
1251          }
1252      }
1253  
1254      /** Bind a hash to an object
1255       *
1256       * Takes the hash/associative array specified by $hash and turns the fields into instance properties of $obj
1257       * @param $hash The hash to bind
1258       * @param &$obj A reference to the object to bind the hash to
1259       * @param $prefix Defaults to null, prefix to use with hash keys
1260       * @param $checkSlashes Defaults to true, strip any slashes from the hash values
1261       * @param $bindAll Bind all values regardless of their existance as defined instance variables
1262       */
1263  	function bindHashToObject($hash, &$obj, $prefix = null, $checkSlashes = true, $bindAll = false) {
1264          is_array($hash) or die('bindHashToObject : hash expected');
1265          is_object($obj) or die('bindHashToObject : object expected');
1266  
1267          if ($bindAll) {
1268              foreach ($hash as $k => $v) {
1269                  //$obj->$k = ($checkSlashes && get_magic_quotes_gpc()) ? stripslashes( $hash[$k] ) : $hash[$k];
1270                  $obj->$k = ($checkSlashes && get_magic_quotes_gpc()) ? stripslashes(w2PHTMLDecode($hash[$k])) : w2PHTMLDecode($hash[$k]);
1271              }
1272          } else {
1273              if ($prefix) {
1274                  foreach (get_object_vars($obj) as $k => $v) {
1275                      if (isset($hash[$prefix . $k])) {
1276                          //$obj->$k = ($checkSlashes && get_magic_quotes_gpc()) ? stripslashes( $hash[$k] ) : $hash[$k];
1277                          $obj->$k = ($checkSlashes && get_magic_quotes_gpc()) ? stripslashes(w2PHTMLDecode($hash[$k])) : w2PHTMLDecode($hash[$k]);
1278                      }
1279                  }
1280              } else {
1281                  foreach (get_object_vars($obj) as $k => $v) {
1282                      if (isset($hash[$k])) {
1283                          //$obj->$k = ($checkSlashes && get_magic_quotes_gpc()) ? stripslashes( $hash[$k] ) : $hash[$k];
1284                          $obj->$k = ($checkSlashes && get_magic_quotes_gpc()) ? stripslashes(w2PHTMLDecode($hash[$k])) : w2PHTMLDecode($hash[$k]);
1285                      }
1286                  }
1287              }
1288          }
1289      }
1290  
1291      /** Build or update a table using an XML string
1292       *
1293       * @param $xml XML string describing table structure
1294       * @param $mode Defaults to 'REPLACE'
1295       * @return True on success, false if there was an error.
1296       */
1297  	function execXML($xml, $mode = 'REPLACE') {
1298          global $AppUI;
1299  
1300          include_once  W2P_BASE_DIR . '/lib/adodb/adodb-xmlschema.inc.php';
1301          $schema = new adoSchema($this->_db);
1302          $schema->setUpgradeMode($mode);
1303          if (isset($this->_table_prefix) && $this->_table_prefix) {
1304              $schema->setPrefix($this->_table_prefix, false);
1305          }
1306          $schema->ContinueOnError(true);
1307          if (($sql = $scheme->ParseSchemaString($xml)) == false) {
1308              $AppUI->setMsg(array('Error in XML Schema', 'Error', $this->_db->ErrorMsg()), UI_MSG_ERR);
1309              return false;
1310          }
1311          if ($schema->ExecuteSchema($sql, true)) {
1312              return true;
1313          } else {
1314              return false;
1315          }
1316      }
1317  
1318      /** Load a single column result from a single row
1319       * @return Value of the row column
1320       */
1321  	function loadResult() {
1322          global $AppUI;
1323  
1324          $result = false;
1325  
1326          if (!$this->exec(ADODB_FETCH_NUM)) {
1327              $AppUI->setMsg($this->_db->ErrorMsg(), UI_MSG_ERROR);
1328          } elseif ($data = $this->fetchRow()) {
1329              $result = $data[0];
1330          }
1331          $this->clear();
1332          return $result;
1333      }
1334  
1335      /** Create a where clause based upon supplied field.
1336       *
1337       * @param    $where_clause Either string or array of subclauses.
1338       * @return SQL WHERE clause as a string.
1339       */
1340  	function make_where_clause($where_clause) {
1341          $result = '';
1342          if (!isset($where_clause)) {
1343              return $result;
1344          }
1345          if (is_array($where_clause)) {
1346              if (count($where_clause)) {
1347                  $started = false;
1348                  $result = ' WHERE ' . implode(' AND ', $where_clause);
1349              }
1350          } elseif (strlen($where_clause) > 0) {
1351              $result = ' WHERE ' . $where_clause;
1352          }
1353          return $result;
1354      }
1355  
1356      /** Create an order by clause based upon supplied field.
1357       *
1358       * @param    $order_clause    Either string or array of subclauses.
1359       * @return SQL ORDER BY clause as a string.
1360       */
1361  	function make_order_clause($order_clause) {
1362          $result = '';
1363          if (!isset($order_clause)) {
1364              return $result;
1365          }
1366  
1367          if (is_array($order_clause)) {
1368              $started = false;
1369              $result = ' ORDER BY ' . implode(',', $order_clause);
1370          } elseif (strlen($order_clause) > 0) {
1371              $result = ' ORDER BY ' . $order_clause;
1372          }
1373          return $result;
1374      }
1375  
1376      /** Create a group by clause based upon supplied field.
1377       *
1378       * @param    $group_clause    Either string or array of subclauses.
1379       * @return SQL GROUP BY clause as a string.
1380       */
1381  	function make_group_clause($group_clause) {
1382          $result = '';
1383          if (!isset($group_clause)) {
1384              return $result;
1385          }
1386  
1387          if (is_array($group_clause)) {
1388              $started = false;
1389              $result = ' GROUP BY ' . implode(',', $group_clause);
1390          } elseif (strlen($group_clause) > 0) {
1391              $result = ' GROUP BY ' . $group_clause;
1392          }
1393          return $result;
1394      }
1395  
1396      /** Create a join condition based upon supplied fields.
1397       *
1398       * @param    $join_clause    Either string or array of subclauses.
1399       * @return SQL JOIN condition as a string.
1400       */
1401  	function make_join($join_clause) {
1402          $result = '';
1403          if (!isset($join_clause)) {
1404              return $result;
1405          }
1406          if (is_array($join_clause)) {
1407              foreach ($join_clause as $join) {
1408                  $result .= ' ' . strtoupper($join['type']) . ' JOIN ' . $this->quote_db($this->_table_prefix . $join['table']);
1409                  if ($join['alias']) {
1410                      $result .= ' AS ' . $join['alias'];
1411                  } else {
1412                      $result .= ' AS ' . $join['table'];
1413                  }
1414                  if (is_array($join['condition'])) {
1415                      $result .= ' USING (' . implode(',', $join['condition']) . ')';
1416                  } else {
1417                      $result .= ' ON ' . $join['condition'];
1418                  }
1419              }
1420          } else {
1421              $result .= ' LEFT JOIN ' . $this->quote_db($this->_table_prefix . $join_clause);
1422          }
1423          return $result;
1424      }
1425  
1426      /** Create a having clause based upon supplied field.
1427       *
1428       * @param    $having_clause Either string or array of subclauses.
1429       * @return SQL HAVING clause as a string.
1430       */
1431  	function make_having_clause($having_clause) {
1432          $result = '';
1433          if (!isset($having_clause)) {
1434              return $result;
1435          }
1436          if (is_array($having_clause)) {
1437              if (count($having_clause)) {
1438                  $started = false;
1439                  $result = ' HAVING ' . implode(' AND ', $having_clause);
1440              }
1441          } elseif (strlen($having_clause) > 0) {
1442              $result = ' HAVING ' . $having_clause;
1443          }
1444          return $result;
1445      }
1446  
1447      /** Create a limit clause
1448       *
1449       * @param    $order_clause    Either string or array of subclauses.
1450       * @return SQL ORDER BY clause as a string.
1451       */
1452  	function make_limit_clause($limit, $offset) {
1453          $result = '';
1454          if (!isset($limit)) {
1455              return $result;
1456          }
1457  
1458          if (is_array($limit) && (count($limit) == 2)) {
1459              $result = ' LIMIT ' . implode(',', $limit);
1460          } elseif (isset($limit) && ($offset <= 0)) {
1461              $result = ' LIMIT ' . intval($limit);
1462          } elseif (isset($limit) && ($offset > 0)) {
1463              $result = ' LIMIT ' . intval($offset) . ', ' . intval($limit);
1464          }
1465          return $result;
1466      }
1467  
1468  	function foundRows() {
1469          global $db;
1470          $result = false;
1471          if ($this->include_count) {
1472              if ($qid = $db->Execute('SELECT FOUND_ROWS() as rc')) {
1473                  $data = $qid->FetchRow();
1474                  $result = isset($data['rc']) ? $data['rc'] : $data[0];
1475              }
1476          }
1477          return $result;
1478      }
1479  
1480      /** Add quotes to a string
1481       *
1482       * @param    $string    A string to add quotes to.
1483       * @return The quoted string
1484       */
1485  	function quote($string) {
1486          if (is_int($string)) {
1487              return $string;
1488          } else {
1489              return $this->_db->qstr($string, get_magic_quotes_runtime());
1490          }
1491      }
1492  
1493      /** Add quotes to a database identifier
1494       * @param $string The identifier to quote
1495       * @return The quoted identifier
1496       */
1497  	function quote_db($string) {
1498          return $this->_db->nameQuote . $string . $this->_db->nameQuote;
1499      }
1500  
1501      /**
1502       * Document::insertArray()
1503       *
1504       * { Description }
1505       *
1506       * @param [type] $verbose
1507       */
1508  	function insertArray($table, &$hash, $verbose = false) {
1509          $this->addTable($table);
1510          foreach ($hash as $k => $v) {
1511              if (is_array($v) or is_object($v) or $v == null) {
1512                  continue;
1513              }
1514              $fields[] = $k;
1515              $values[$k] = w2Phtmlspecialchars($v);
1516          }
1517          foreach ($fields as $field) {
1518              $this->addInsert($field, $values[$field]);
1519          }
1520  
1521          if (!$this->exec()) {
1522              return false;
1523          }
1524          $id = db_insert_id();
1525          return true;
1526      }
1527  
1528      /**
1529       * Document::updateArray()
1530       *
1531       * { Description }
1532       *
1533       * @param [type] $verbose
1534       */
1535  	function updateArray($table, &$hash, $keyName, $verbose = false) {
1536          $this->addTable($table);
1537          foreach ($hash as $k => $v) {
1538              if (is_array($v) or is_object($v) or $k[0] == '_') { // internal or NA field
1539                  continue;
1540              }
1541  
1542              if ($k == $keyName) { // PK not to be updated
1543                  $this->addWhere($keyName . ' = \'' . db_escape($v) . '\'');
1544                  continue;
1545              }
1546              $fields[] = $k;
1547              if ($v == '') {
1548                  $values[$k] = 'NULL';
1549              } else {
1550                  $values[$k] = w2Phtmlspecialchars($v);
1551              }
1552          }
1553          if (count($values)) {
1554              foreach ($fields as $field) {
1555                  $this->addUpdate($field, $values[$field]);
1556              }
1557              $ret = $this->exec();
1558          }
1559          return $ret;
1560      }
1561  
1562      /**
1563       * Document::insertObject()
1564       *
1565       * { Description }
1566       *
1567       * @param [type] $keyName
1568       * @param [type] $verbose
1569       */
1570  	function insertObject($table, &$object, $keyName = null, $verbose = false) {
1571          $this->addTable($table);
1572          foreach (get_object_vars($object) as $k => $v) {
1573              if (is_array($v) or is_object($v) or $v == null) {
1574                  continue;
1575              }
1576              if ($k[0] == '_') { // internal field
1577                  continue;
1578              }
1579              $fields[] = $k;
1580              $values[$k] = w2Phtmlspecialchars($v);
1581          }
1582          foreach ($fields as $field) {
1583              $this->addInsert($field, $values[$field]);
1584          }
1585          if (!$this->exec()) {
1586              return false;
1587          }
1588          $id = db_insert_id();
1589          ($verbose) && print 'id=[' . $id . '] ';
1590          if ($keyName && $id) {
1591              $object->$keyName = $id;
1592          }
1593          return true;
1594      }
1595  
1596      /**
1597       * Document::updateObject()
1598       *
1599       * { Description }
1600       *
1601       * @param [type] $updateNulls
1602       */
1603  	function updateObject($table, &$object, $keyName, $updateNulls = true) {
1604          $this->addTable($table);
1605          foreach (get_object_vars($object) as $k => $v) {
1606              if (is_array($v) or is_object($v) or $k[0] == '_') { // internal or NA field
1607                  continue;
1608              }
1609              if ($k == $keyName) { // PK not to be updated
1610                  $this->addWhere($keyName . ' = \'' . db_escape($v) . '\'');
1611                  continue;
1612              }
1613              if ($v === null && !$updateNulls) {
1614                  continue;
1615              }
1616              $fields[] = $k;
1617              $values[$k] = w2Phtmlspecialchars($v);
1618          }
1619          if (count($values)) {
1620              foreach ($fields as $field) {
1621                  $this->addUpdate($field, $values[$field]);
1622              }
1623              return $this->exec();
1624          } else {
1625              return true;
1626          }
1627      }
1628  
1629      /**
1630       *    Clone the current query
1631       *
1632       *    @return    object    The new record object or null if error
1633       **/
1634  	function duplicate() {
1635  
1636          // In php4 assignment does a shallow copy
1637          // in php5 clone is required
1638          if (version_compare(phpversion(), '5') >= 0) {
1639              $newObj = clone($this);
1640          } else {
1641              $newObj = $this;
1642          }
1643  
1644          return $newObj;
1645      }
1646  
1647  }
1648  ?>


Generated: Sat Jul 17 03:00:04 2010 Cross-referenced by PHPXref 0.7