Overview

Packages

  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Datatype
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cDb
  • cDbDriverAbstract
  • cDbDriverHandler
  • cDbDriverMysql
  • cDbDriverMysqli

Exceptions

  • cDbException
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
   1: <?php
   2: /**
   3:  * This file contains the database driver handler class.
   4:  *
   5:  * @package    Core
   6:  * @subpackage Database
   7:  * @version    SVN Revision $Rev:$
   8:  *
   9:  * @author     Dominik Ziegler
  10:  * @copyright  four for business AG <www.4fb.de>
  11:  * @license    http://www.contenido.org/license/LIZENZ.txt
  12:  * @link       http://www.4fb.de
  13:  * @link       http://www.contenido.org
  14:  */
  15: 
  16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  17: 
  18: /**
  19:  * This class contains functions for database driver handling in CONTENIDO.
  20:  *
  21:  * @package    Core
  22:  * @subpackage Database
  23:  */
  24: abstract class cDbDriverHandler {
  25: 
  26:     /**
  27:      *
  28:      * @var string
  29:      */
  30:     const HALT_YES = 'yes';
  31: 
  32:     /**
  33:      *
  34:      * @var string
  35:      */
  36:     const HALT_NO = 'no';
  37: 
  38:     /**
  39:      *
  40:      * @var string
  41:      */
  42:     const HALT_REPORT = 'report';
  43: 
  44:     /**
  45:      *
  46:      * @var string
  47:      */
  48:     const FETCH_NUMERIC = 'numeric';
  49: 
  50:     /**
  51:      *
  52:      * @var string
  53:      */
  54:     const FETCH_ASSOC = 'assoc';
  55: 
  56:     /**
  57:      *
  58:      * @var string
  59:      */
  60:     const FETCH_BOTH = 'both';
  61: 
  62:     /**
  63:      * Loader database driver.
  64:      *
  65:      * @var cDbDriverAbstract
  66:      */
  67:     protected $_driver = NULL;
  68: 
  69:     /**
  70:      * Driver type
  71:      *
  72:      * @var string
  73:      */
  74:     protected $_driverType = '';
  75: 
  76:     /**
  77:      * Default database connection for all instances
  78:      *
  79:      * @var array
  80:      */
  81:     protected static $_defaultDbCfg = array();
  82: 
  83:     /**
  84:      * Assoziative list of database connections
  85:      * @var array
  86:      */
  87:     protected static $_connectionCache = array();
  88: 
  89:     /**
  90:      * Assoziative list of database tables metadata
  91:      * @var array
  92:      */
  93:     protected static $_metaCache = array();
  94: 
  95:     /**
  96:      * Database connection configuration for current instance
  97:      *
  98:      * @var array
  99:      */
 100:     protected $_dbCfg = array();
 101: 
 102:     /**
 103:      * Halt status during occured errors.
 104:      * Feasible values are
 105:      * - "yes" (halt with message)
 106:      * - "no" (ignore errors quietly)
 107:      * - "report" (ignore errror, but spit a warning)
 108:      *
 109:      * @var string
 110:      */
 111:     protected $_haltBehaviour = 'no';
 112: 
 113:     /**
 114:      * Text to prepend to the halt message
 115:      *
 116:      * @var string
 117:      */
 118:     protected $_haltMsgPrefix = '';
 119: 
 120:     /**
 121:      * Profile data array
 122:      *
 123:      * @var array
 124:      */
 125:     protected static $_profileData = array();
 126: 
 127:     /**
 128:      * Constructor, sets passed options and connects to the DBMS, if not done
 129:      * before.
 130:      *
 131:      * Uses default connection settings, passed $options['connection'] settings
 132:      * will overwrite connection settings for current instance.
 133:      *
 134:      * @param array $options Assoziative options as follows:
 135:      *        - $options['haltBehavior'] (string) Optional, halt behavior on
 136:      *                       occured errors
 137:      *        - $options['haltMsgPrefix'] (string) Optional, Text to prepend to
 138:      *                       the halt message
 139:      *        - $options['enableProfiling'] (bool) Optional, flag to enable
 140:      *                       profiling
 141:      *        - $options['connection'] (array) Optional, assoziative connection
 142:      *                       settings
 143:      *        - $options['connection']['host'] (string) Hostname or ip
 144:      *        - $options['connection']['database'] (string) Database name
 145:      *        - $options['connection']['user'] (string) User name
 146:      *        - $options['connection']['password'] (string) User password
 147:      * @throws cDbException
 148:      */
 149:     public function __construct($options = array()) {
 150:         // use default connection configuration, but overwrite it by passed
 151:         // options
 152:         $this->_dbCfg = array_merge(self::$_defaultDbCfg, $options);
 153: 
 154:             // in case we do not have any configuration for database, try to load it from configuration
 155:         if (count($this->_dbCfg) == 0) {
 156:             $cfg = cRegistry::getConfig();
 157:             if (isset($cfg['db']) && count($cfg['db']) > 0) {
 158:                 $this->_dbCfg = $cfg['db'];
 159:             } else {
 160:                 throw new cDbException("Unable to establish a database connection without options!");
 161:             }
 162:         }
 163: 
 164:         if (isset($this->_dbCfg['haltBehavior'])) {
 165:             switch ($this->_dbCfg['haltBehavior']) {
 166:                 case self::HALT_YES:
 167:                     $this->_haltBehaviour = self::HALT_YES;
 168:                     break;
 169:                 case self::HALT_NO:
 170:                     $this->_haltBehaviour = self::HALT_NO;
 171:                     break;
 172:                 case self::HALT_REPORT:
 173:                     $this->_haltBehaviour = self::HALT_REPORT;
 174:                     break;
 175:             }
 176:         }
 177: 
 178:         if (isset($this->_dbCfg['haltMsgPrefix']) && is_string($this->_dbCfg['haltMsgPrefix'])) {
 179:             $this->_haltMsgPrefix = $this->_dbCfg['haltMsgPrefix'];
 180:         }
 181: 
 182:         $cfg = cRegistry::getConfig();
 183:         $this->_driverType = $cfg['database_extension'];
 184: 
 185:         $this->loadDriver();
 186: 
 187:         if ($this->connect() == NULL) {
 188:             $this->setErrorNumber(1);
 189:             $this->setErrorMessage("Could not connect to database");
 190: 
 191:             throw new cDbException($this->getErrorMessage());
 192:         }
 193:     }
 194: 
 195:     /**
 196:      * Checks if profiling was enabled via configuration.
 197:      *
 198:      * @return bool
 199:      */
 200:     public function isProfilingEnabled() {
 201:         return (bool)$this->_dbCfg['enableProfiling'];
 202:     }
 203: 
 204:     /**
 205:      * Returns the halt behaviour setting.
 206:      *
 207:      * @return string
 208:      */
 209:     public function getHaltBehaviour() {
 210:         return $this->_haltBehaviour;
 211:     }
 212: 
 213:     /**
 214:      * Loads the database driver and checks its base functionality.
 215:      *
 216:      * @throws cDbException
 217:      */
 218:     public function loadDriver() {
 219:         if ($this->_driver != NULL) {
 220:             return;
 221:         }
 222: 
 223:         $classNameSuffix = ucfirst($this->_driverType);
 224: 
 225:         $driverName = 'cDbDriver' . $classNameSuffix;
 226: 
 227:         if (class_exists($driverName) === false) {
 228:             throw new cDbException("Database driver was not found.");
 229:         }
 230: 
 231:         $this->_driver = new $driverName($this->_dbCfg);
 232: 
 233:         if (($this->getDriver() instanceof cDbDriverAbstract) === false) {
 234:             $this->_driver = NULL;
 235:             throw new cDbException("Database driver must extend cDbDriverAbstract");
 236:         }
 237: 
 238:         $this->getDriver()->setHandler($this);
 239: 
 240:         if ($this->getDriver()->check() === false) {
 241:             throw new cDbException("Database driver check failed.");
 242:         }
 243:     }
 244: 
 245:     /**
 246:      * Returns the database driver instance.
 247:      *
 248:      * @return cDbDriverAbstract
 249:      */
 250:     public function getDriver() {
 251:         return $this->_driver;
 252:     }
 253: 
 254:     /**
 255:      * Setter for default database configuration, the connection values.
 256:      *
 257:      * @param array $defaultDbCfg
 258:      */
 259:     public static function setDefaultConfiguration(array $defaultDbCfg) {
 260:         self::$_defaultDbCfg = $defaultDbCfg;
 261:     }
 262: 
 263:     /**
 264:      * Returns connection from connection cache
 265:      *
 266:      * @param mixed $data Connection data array or variable
 267:      *
 268:      * @return mixed Either The connection (object, resource, integer) or NULL
 269:      */
 270:     protected function _getConnection($data) {
 271:         $hash = md5($this->_driverType . '-' . (is_array($data) ? implode('-', $data) : (string)$data));
 272: 
 273:         return (isset(self::$_connectionCache[$hash])) ? self::$_connectionCache[$hash] : NULL;
 274:     }
 275: 
 276:     /**
 277:      * Stores connection in connection cache
 278:      *
 279:      * @param mixed $data       Connection data array
 280:      * @param mixed $connection The connection to store in cache
 281:      */
 282:     protected function _setConnection($data, $connection) {
 283:         $hash = md5($this->_driverType . '-' . (is_array($data) ? implode('-', $data) : (string)$data));
 284:         self::$_connectionCache[$hash] = $connection;
 285:     }
 286: 
 287:     /**
 288:      * Removes connection from cache
 289:      *
 290:      * @param mixed $connection The connection to remove in cache
 291:      */
 292:     protected function _removeConnection($connection) {
 293:         foreach (self::$_connectionCache as $hash => $res) {
 294:             if ($res == $connection) {
 295:                 unset(self::$_connectionCache[$hash]);
 296: 
 297:                 return;
 298:             }
 299:         }
 300:     }
 301: 
 302:     /**
 303:      * Adds a entry to the profile data.
 304:      *
 305:      * @param float  $timeStart
 306:      * @param float  $timeEnd
 307:      * @param string $statement
 308:      */
 309:     protected static function _addProfileData($timeStart, $timeEnd, $statement) {
 310:         self::$_profileData[] = array(
 311:             'time' => $timeEnd - $timeStart, 'query' => $statement
 312:         );
 313:     }
 314: 
 315:     /**
 316:      * Returns collected profile data.
 317:      *
 318:      * @return array Profile data array like:
 319:      *         - $arr[$i]['time'] (float) Elapsed time to execute the query
 320:      *         - $arr[$i]['query'] (string) The query itself
 321:      */
 322:     public static function getProfileData() {
 323:         return self::$_profileData;
 324:     }
 325: 
 326:     /**
 327:      * Prepares the statement for execution and returns it back.
 328:      * Accepts multiple parameter, where the first parameter should be the query
 329:      * and any additional parameter should be the values to replace in format
 330:      * definitions.
 331:      * As an alternative the second parameter cound be also a indexed array with
 332:      * values to replace in format definitions.
 333:      *
 334:      * Other option is to call this function with the statement containing named
 335:      * parameter
 336:      * and the second parameter as a assoziative array with key/value pairs to
 337:      * set in statement.
 338:      *
 339:      * Examples:
 340:      * <pre>
 341:      * // multiple parameter
 342:      * $sql = $obj->prepare('SELECT * FROM `%s` WHERE id = %d', 'tablename',
 343:      * 123);
 344:      *
 345:      * // 2 parameter where the first is the statement with formatting signs and
 346:      * the second the entries array
 347:      * $sql = $obj->prepare('SELECT * FROM `%s` WHERE id = %d',
 348:      * array('tablename', 123));
 349:      *
 350:      * // 2 parameter where the first is the statement with named parameter and
 351:      * the second the assoziative entries array
 352:      * $sql = $obj->prepare('SELECT * FROM `:mytab` WHERE id = :myid',
 353:      * array('mytab' => 'tablename', 'myid' => 123));
 354:      * </pre>
 355:      *
 356:      * Accepts additional unlimited parameter, where the parameter will be
 357:      * replaced against formatting sign in query.
 358:      *
 359:      * @param string $statement The sql statement to prepare.
 360:      *
 361:      * @return string The prepared sql statement
 362:      * @throws Exception If statement is empty or function is called with less
 363:      *         than 2 parameters
 364:      */
 365:     public function prepare($statement) {
 366:         // No empty queries
 367:         if (empty($statement)) {
 368:             throw new cDbException('Empty statement!');
 369:         }
 370: 
 371:         $arguments = func_get_args();
 372:         if (count($arguments) <= 1) {
 373:             throw new cDbException('Wrong number of parameter!');
 374:         }
 375: 
 376:         array_shift($arguments);
 377:         $statement = $this->_prepareStatement($statement, $arguments);
 378: 
 379:         return $statement;
 380:     }
 381: 
 382:     /**
 383:      * Prepares the passed statement.
 384:      *
 385:      * @param string $statement
 386:      * @param array  $arguments
 387:      *
 388:      * @return string
 389:      */
 390:     protected function _prepareStatement($statement, array $arguments) {
 391:         if (count($arguments) == 1 && is_array($arguments[0])) {
 392:             $arguments = $arguments[0];
 393:             if (count(array_filter(array_keys($arguments), 'is_string')) > 0) {
 394:                 // we have at least one key being string, it is an assoc array
 395:                 $statement = $this->_prepareStatementA($statement, $arguments);
 396:             } else {
 397:                 // it is an indexed array
 398:                 $statement = $this->_prepareStatementF($statement, $arguments);
 399:             }
 400:         } else {
 401:             $statement = $this->_prepareStatementF($statement, $arguments);
 402:         }
 403: 
 404:         return $statement;
 405:     }
 406: 
 407:     /**
 408:      * Prepares a statement with parameter for execution.
 409:      *
 410:      * Examples:
 411:      * <pre>
 412:      * $obj->_prepareStatementF('SELECT * FROM `%s` WHERE id = %d', 'tablename',
 413:      * 123);
 414:      * $obj->_prepareStatementF('SELECT * FROM `%s` WHERE id = %d AND user =
 415:      * %d', 'tablename', 123, 3);
 416:      * </pre>
 417:      *
 418:      * @param string $statement
 419:      * @param array  $arguments Arguments array containing the query with
 420:      *                          formatting
 421:      *                          signs and the entries.
 422:      *
 423:      * @return string
 424:      */
 425:     protected function _prepareStatementF($statement, array $arguments) {
 426:         if (count($arguments) > 0) {
 427:             $arguments = array_map(array(
 428:                 $this, 'escape'
 429:             ), $arguments);
 430:             array_unshift($arguments, $statement);
 431:             $statement = call_user_func_array('sprintf', $arguments);
 432:         }
 433: 
 434:         return $statement;
 435:     }
 436: 
 437:     /**
 438:      * Prepares a statement with named parameter for execution.
 439:      *
 440:      * Examples:
 441:      * <pre>
 442:      * // named parameter and assoziative entries array
 443:      * $sql = $obj->_prepareStatementA('SELECT * FROM `:mytab` WHERE id =
 444:      * :myid', array('mytab' => 'tablename', 'myid' => 123));
 445:      * $sql = $obj->_prepareStatementA('SELECT * FROM `:mytab` WHERE id = :myid
 446:      * AND user = :myuser', array('mytab' => 'tablename', 'myid' => 123,
 447:      * 'myuser' => 3));
 448:      * </pre>
 449:      *
 450:      * @param string $statement
 451:      * @param array  $arguments Arguments array containing the query with named
 452:      *                          parameter and assoziative entries array
 453:      *
 454:      * @return string
 455:      */
 456:     protected function _prepareStatementA($statement, array $arguments) {
 457:         if (count($arguments) > 0) {
 458:             foreach ($arguments as $key => $value) {
 459:                 $param = ':' . $key;
 460:                 if (is_int($value)) {
 461:                     $statement = str_replace($param, $value, $statement);
 462:                 } else {
 463:                     $param = (string)$param;
 464:                     $statement = str_replace($param, $this->escape($value), $statement);
 465:                 }
 466:             }
 467:         }
 468: 
 469:         return $statement;
 470:     }
 471: 
 472:     /**
 473:      * Establishes a connection to the database server.
 474:      *
 475:      * @return object resource int NULL value depends on
 476:      *         used driver and is NULL in case of an error.
 477:      */
 478:     public function connect() {
 479:         if (isset($this->_dbCfg['connection']) && $this->_linkId = $this->_getConnection($this->_dbCfg['connection'])) {
 480:             return $this->_linkId;
 481:         } else {
 482:             if ($this->_linkId = $this->getDriver()->connect()) {
 483:                 $this->_setConnection($this->_dbCfg['connection'], $this->_linkId);
 484: 
 485:                 return $this->_linkId;
 486:             }
 487:         }
 488: 
 489:         return NULL;
 490:     }
 491: 
 492:     /**
 493:      * Builds and executes a insert query.
 494:      * String values in passed aFields
 495:      * parameter will be escaped automatically.
 496:      *
 497:      * Example:
 498:      * <pre>
 499:      * $db = cRegistry::getDb();
 500:      * $fields = array(
 501:      * 'idcatart' => $idcatart,
 502:      * 'idlang' => $lang,
 503:      * 'idclient' => $client,
 504:      * 'code' => "<html>... code n' fun ...</html>",
 505:      * );
 506:      * $result = $db->insert($cfg['tab']['code'], $fields);
 507:      * </pre>
 508:      *
 509:      * @param string $tableName The table name
 510:      * @param array  $fields    Assoziative array of fields to insert
 511:      *
 512:      * @return bool
 513:      */
 514:     public function insert($tableName, array $fields) {
 515:         $statement = $this->buildInsert($tableName, $fields);
 516: 
 517:         return $this->query($statement);
 518:     }
 519: 
 520:     /**
 521:      * Builds and returns a insert query.
 522:      * String values in passed fields
 523:      * parameter will be escaped automatically.
 524:      *
 525:      * Example:
 526:      * <pre>
 527:      * $db = cRegistry::getDb();
 528:      * $fields = array(
 529:      * 'idcode' => $idcode,
 530:      * 'idcatart' => $idcatart,
 531:      * 'idlang' => $lang,
 532:      * 'idclient' => $client,
 533:      * 'code' => "<html>... code n' fun ...</html>",
 534:      * );
 535:      * $statement = $db->buildInsert($cfg['tab']['code'], $fields);
 536:      * $db->query($statement);
 537:      * </pre>
 538:      *
 539:      * @param string $tableName The table name
 540:      * @param array  $fields    Assoziative array of fields to insert
 541:      *
 542:      * @return string
 543:      */
 544:     public function buildInsert($tableName, array $fields) {
 545:         return $this->getDriver()->buildInsert($tableName, $fields);
 546:     }
 547: 
 548:     /**
 549:      * Builds and executes a update query.
 550:      * String values in passed fields
 551:      * and whereClauses parameter will be escaped automatically.
 552:      *
 553:      * Example:
 554:      * <pre>
 555:      * $db = cRegistry::getDb();
 556:      * $fields = array('code' => "<html>... some new code n' fun ...</html>");
 557:      * $whereClauses = array('idcode' => 123);
 558:      * $result = $db->update($cfg['tab']['code'], $fields, $whereClauses);
 559:      * </pre>
 560:      *
 561:      * @param string $tableName    The table name
 562:      * @param array  $fields       Assoziative array of fields to update
 563:      * @param array  $whereClauses Assoziative array of field in where clause.
 564:      *                             Multiple entries will be concatenated with AND
 565:      *
 566:      * @return bool
 567:      */
 568:     public function update($tableName, array $fields, array $whereClauses) {
 569:         $statement = $this->buildUpdate($tableName, $fields, $whereClauses);
 570: 
 571:         return $this->query($statement);
 572:     }
 573: 
 574:     /**
 575:      * Builds and returns a update query.
 576:      * String values in passed aFields
 577:      * and aWhere parameter will be escaped automatically.
 578:      *
 579:      * Example:
 580:      * <pre>
 581:      * $db = cRegistry::getDb();
 582:      * $fields = array('code' => "<html>... some new code n' fun ...</html>");
 583:      * $whereClauses = array('idcode' => 123);
 584:      * $statement = $db->buildUpdate($cfg['tab']['code'], $fields,
 585:      * $whereClauses);
 586:      * $db->query($statement);
 587:      * </pre>
 588:      *
 589:      * @param string $tableName    The table name
 590:      * @param array  $fields       Assoziative array of fields to update
 591:      * @param array  $whereClauses Assoziative array of field in where clause.
 592:      *                             Multiple entries will be concatenated with AND
 593:      *
 594:      * @return string
 595:      */
 596:     public function buildUpdate($tableName, array $fields, array $whereClauses) {
 597:         return $this->getDriver()->buildUpdate($tableName, $fields, $whereClauses);
 598:     }
 599: 
 600:     /**
 601:      * Executes the statement.
 602:      * If called with one parameter, it executes the statement directly.
 603:      *
 604:      * Accepts multiple parameter, where the first parameter should be the query
 605:      * and any additional parameter should be the values to replace in format
 606:      * definitions.
 607:      * As an alternative the second parameter cound be also a indexed array with
 608:      * values to replace in format definitions.
 609:      *
 610:      * Other option is to call this function with the statement containing named
 611:      * parameter
 612:      * and the second parameter as a assoziative array with key/value pairs to
 613:      * set in statement.
 614:      *
 615:      * Examples:
 616:      * <pre>
 617:      * // call with one parameter
 618:      * $obj->query('SELECT * FROM `tablename` WHERE id = 123');
 619:      *
 620:      * // call with multiple parameter
 621:      * $obj->query('SELECT * FROM `%s` WHERE id = %d', 'tablename', 123);
 622:      *
 623:      * // 2 parameter where the first is the statement with formatting signs and
 624:      * the second the entries array
 625:      * $obj->query('SELECT * FROM `%s` WHERE id = %d', array('tablename', 123));
 626:      *
 627:      * // 2 parameter where the first is the statement with named parameter and
 628:      * the second the assoziative entries array
 629:      * $obj->query('SELECT * FROM `:mytab` WHERE id = :myid', array('mytab' =>
 630:      * 'tablename', 'myid' => 123));
 631:      * </pre>
 632:      *
 633:      * Accepts additional unlimited parameter, where the parameter will be
 634:      * replaced against formatting sign in query.
 635:      *
 636:      * @param string $statement The SQL statement to execute.
 637:      *
 638:      * @return resource int object bool database driver, false on error
 639:      */
 640:     public function query($statement) {
 641:         // No empty queries, please, since PHP4 chokes on them
 642:         if ($statement == '') {
 643:             // The empty query string is passed on from the constructor, when
 644:             // calling
 645:             // the class without a query, e.g. in situations '$db = new
 646:             // DB_Sql_Subclass;'
 647:             return false;
 648:         }
 649: 
 650:         $arguments = func_get_args();
 651:         if (count($arguments) > 1) {
 652:             array_shift($arguments);
 653:             $statement = $this->_prepareStatement($statement, $arguments);
 654:         }
 655: 
 656:         if (!$this->connect()) {
 657:             return false;
 658:         }
 659: 
 660:         // new query, discard previous result
 661:         if ($this->getQueryId()) {
 662:             $this->free();
 663:         }
 664: 
 665:         if ($this->isProfilingEnabled() === true) {
 666:             $timeStart = microtime(true);
 667:         }
 668: 
 669:         $this->getDriver()->query($statement);
 670: 
 671:         if ($this->isProfilingEnabled() === true) {
 672:             $timeEnd = microtime(true);
 673:             $this->_addProfileData($timeStart, $timeEnd, $statement);
 674:         }
 675: 
 676:         if (!$this->getQueryId()) {
 677:             $this->halt($statement);
 678:         }
 679: 
 680:         // Will return nada if it fails. That's fine.
 681:         return $this->getQueryId();
 682:     }
 683: 
 684:     /**
 685:      * Fetches the next record set from result set
 686:      *
 687:      * @return bool
 688:      */
 689:     public function nextRecord() {
 690:         if (!$this->getQueryId()) {
 691:             $currentModule = cRegistry::getCurrentModuleId();
 692:             if ($currentModule > 0) {
 693:                 $this->halt('next_record called with no query pending in Module ID ' . $currentModule . '.');
 694:             } else {
 695:                 $this->halt('next_record called with no query pending.');
 696:             }
 697: 
 698:             return false;
 699:         }
 700: 
 701:         return $this->getDriver()->nextRecord();
 702:     }
 703: 
 704:     /**
 705:      * This method returns the current result set as object or NULL if no result
 706:      * set is left.
 707:      * If optional param $className is set, the result object is an instance of
 708:      * class $className.
 709:      *
 710:      * @param string $className
 711:      * @return object
 712:      */
 713:     public function getResultObject($className = NULL) {
 714:         return $this->getDriver()->getResultObject($className);
 715:     }
 716: 
 717:     /**
 718:      * Returns number of affected rows from last executed query (update, delete)
 719:      *
 720:      * @return int Number of affected rows
 721:      */
 722:     public function affectedRows() {
 723:         return $this->getDriver()->affectedRows();
 724:     }
 725: 
 726:     /**
 727:      * Returns the number of rows from last executed select query.
 728:      *
 729:      * @return int The number of rows from last select query result
 730:      */
 731:     public function numRows() {
 732:         return $this->getDriver()->numRows();
 733:     }
 734: 
 735:     /**
 736:      * Returns the number of fields (columns) from current record set
 737:      *
 738:      * @return int Number of fields
 739:      */
 740:     public function numFields() {
 741:         return $this->getDriver()->numFields();
 742:     }
 743: 
 744:     /**
 745:      * Discard the query result
 746:      *
 747:      * @return int
 748:      */
 749:     public function free() {
 750:         return $this->getDriver()->free();
 751:     }
 752: 
 753:     /**
 754:      * Escape string for using in SQL-Statement.
 755:      *
 756:      * @param string $string The string to escape
 757:      *
 758:      * @return string Escaped string
 759:      */
 760:     public function escape($string) {
 761:         if (!$this->getLinkId()) {
 762:             $this->connect();
 763:         }
 764: 
 765:         return $this->getDriver()->escape($string);
 766:     }
 767: 
 768:     /**
 769:      * Moves the cursor (position inside current result sets).
 770:      *
 771:      * @param int $iPos The positon to move to inside the current result set
 772:      * @return int
 773:      */
 774:     public function seek($pos) {
 775:         $status = $this->getDriver()->seek($pos);
 776:         if ($status == 0) {
 777:             $this->halt("seek($pos) failed: result has " . $this->numRows() . " rows.");
 778:         }
 779: 
 780:         return $status;
 781:     }
 782: 
 783:     /**
 784:      * Get last inserted id of given table name
 785:      *
 786:      * @param string $tableName
 787:      *
 788:      * @return int NULL id of table
 789:      */
 790:     public function getLastInsertedId($tableName = '') {
 791:         $lastId = NULL;
 792: 
 793:         if (strlen($tableName) == 0) {
 794:             return $lastId;
 795:         }
 796: 
 797:         $this->query('SELECT LAST_INSERT_ID() as last_id FROM ' . $tableName);
 798:         if ($this->nextRecord()) {
 799:             $lastId = $this->f('last_id');
 800:         }
 801: 
 802:         return $lastId;
 803:     }
 804: 
 805:     /**
 806:      * Parses te table structure and generates a metadata from it.
 807:      *
 808:      * @param string $tableName The table to get metadata or empty string to
 809:      *                          retrieve
 810:      *                          metadata of all tables
 811:      * @param bool   $full      Flag to load full metadata
 812:      *
 813:      * @return array Depends on used database and on parameter $full
 814:      */
 815:     public function getMetaData($tableName = '', $full = false) {
 816:         $databaseName = '';
 817:         $key = (string)$databaseName . '_' . $tableName . '_' . (($full) ? '1' : '0');
 818: 
 819:         if (!isset(self::$_metaCache[$key])) {
 820:             // get meta data
 821:             self::$_metaCache[$key] = $this->getDriver()->getMetaData($tableName, $full);
 822:         }
 823: 
 824:         return self::$_metaCache[$key];
 825:     }
 826: 
 827:     /**
 828:      * Returns names of existing tables.
 829:      *
 830:      * @return array NULL array containing assoziative table data as
 831:      *         follows or NULL:
 832:      *         - $info[$i]['table_name']
 833:      *         - $info[$i]['tablespace_name']
 834:      *         - $info[$i]['database']
 835:      */
 836:     public function getTableNames() {
 837:         if (!$this->connect()) {
 838:             return NULL;
 839:         }
 840: 
 841:         return $this->getDriver()->getTableNames();
 842:     }
 843: 
 844:     /**
 845:      * Returns information about DB server.
 846:      * The return value depends always on
 847:      * used DBMS.
 848:      *
 849:      * @return array NULL array as follows or NULL:
 850:      *         - $arr['description'] (string) Optional, server description
 851:      *         - $arr['version'] (string) Optional, server version
 852:      */
 853:     public function getServerInfo() {
 854:         if (!$this->connect()) {
 855:             return NULL;
 856:         }
 857: 
 858:         return $this->getDriver()->getServerInfo();
 859:     }
 860: 
 861:     /**
 862:      * Closes the connection and frees the query id.
 863:      */
 864:     public function disconnect() {
 865:         $linkId = $this->getLinkId();
 866: 
 867:         if (is_resource($linkId)) {
 868:             $this->getDriver()->disconnect();
 869:             $this->_removeConnection($linkId);
 870:         }
 871: 
 872:         $this->setLinkId(0);
 873:         $this->setQueryId(0);
 874:     }
 875: 
 876:     /**
 877:      * Returns the desired field value from current record set.
 878:      *
 879:      * @param mixed $name    The field name or index position
 880:      * @param mixed $default The default value to return
 881:      *
 882:      * @return mixed The value of field
 883:      */
 884:     public function f($name, $default = NULL) {
 885:         $record = $this->getRecord();
 886: 
 887:         return (isset($record[$name])) ? $record[$name] : $default;
 888:     }
 889: 
 890:     /**
 891:      * Returns current record set as a associative and/or indexed array.
 892:      *
 893:      * @param string $fetchMode One of cDbDriverHandler::FETCH_* constants
 894:      *
 895:      * @return array
 896:      */
 897:     public function toArray($fetchMode = self::FETCH_ASSOC) {
 898:         switch ($fetchMode) {
 899:             case self::FETCH_NUMERIC:
 900:             case self::FETCH_ASSOC:
 901:             case self::FETCH_BOTH:
 902:                 // donut
 903:                 break;
 904:             default:
 905:                 $fetchMode = self::FETCH_ASSOC;
 906:                 break;
 907:         }
 908: 
 909:         $result = array();
 910:         if (is_array($this->getRecord())) {
 911:             foreach ($this->getRecord() as $key => $value) {
 912:                 if ($fetchMode == self::FETCH_ASSOC && !is_numeric($key)) {
 913:                     $result[$key] = $value;
 914:                 } elseif ($fetchMode == self::FETCH_NUMERIC && is_numeric($key)) {
 915:                     $result[$key] = $value;
 916:                 } elseif ($fetchMode == self::FETCH_BOTH) {
 917:                     $result[$key] = $value;
 918:                 }
 919:             }
 920:         }
 921: 
 922:         return $result;
 923:     }
 924: 
 925:     /**
 926:      * Returns current record set as a object
 927:      *
 928:      * @return stdClass
 929:      */
 930:     public function toObject() {
 931:         return (object)$this->toArray(self::FETCH_ASSOC);
 932:     }
 933: 
 934:     /**
 935:      * Error handling
 936:      *
 937:      * Error handler function, delegates passed message to the function
 938:      * reportHalt() if property
 939:      * $this->_haltBehaviour is not set to self::HALT_REPORT.
 940:      *
 941:      * Terminates further script execution if $this->_haltBehaviour is set to
 942:      * self::HALT_YES
 943:      *
 944:      * @param string $message The message to use for error handling
 945:      * @throws cDbException
 946:      */
 947:     public function halt($message) {
 948:         if ($this->_haltBehaviour == self::HALT_REPORT) {
 949:             $this->reportHalt($this->_haltMsgPrefix . $message);
 950:         }
 951: 
 952:         if ($this->_haltBehaviour == self::HALT_YES) {
 953:             throw new cDbException($message);
 954:         }
 955:     }
 956: 
 957:     /**
 958:      * Logs passed message, basically the last db error to the error log.
 959:      * Concatenates a detailed error message and invoke PHP's error_log()
 960:      * method.
 961:      *
 962:      * @param string $message
 963:      */
 964:     public function reportHalt($message) {
 965:         $errorNumber = $this->getErrorNumber();
 966:         $errorMessage = $this->getErrorMessage();
 967: 
 968:         if (!$errorMessage) {
 969:             $errorMessage = $this->getDriver()->getErrorMessage();
 970:         }
 971: 
 972:         if (!$errorNumber) {
 973:             $errorNumber = $this->getDriver()->getErrorNumber();
 974:         }
 975: 
 976:         $message = sprintf("Database failure: %s (%s) - %s\n", $errorNumber, $errorMessage, $message);
 977:         cWarning(__FILE__, __LINE__, $message);
 978:     }
 979: 
 980:     /**
 981:      * Returns the number of rows from last executed select query.
 982:      *
 983:      * @return int The number of rows from last select query result
 984:      * @see cDbDriverHandler::numRows
 985:      */
 986:     public function num_rows() {
 987:         return $this->numRows();
 988:     }
 989: 
 990:     /**
 991:      * Returns number of affected rows from last executed query (update, delete)
 992:      *
 993:      * @return int Number of affected rows
 994:      * @see cDbDriverHandler::affectedRows
 995:      */
 996:     public function affected_rows() {
 997:         return $this->affectedRows();
 998:     }
 999: 
1000:     /**
1001:      * Returns the number of fields (columns) from current record set
1002:      *
1003:      * @return int Number of fields
1004:      * @see cDbDriverHandler::numFields
1005:      */
1006:     public function num_fields() {
1007:         return $this->numFields();
1008:     }
1009: 
1010:     /**
1011:      * Fetches the next record set from result set
1012:      *
1013:      * @return bool
1014:      * @see cDbDriverHandler::nextRecord
1015:      */
1016:     public function next_record() {
1017:         return $this->nextRecord();
1018:     }
1019: }
CMS CONTENIDO 4.9.3 API documentation generated by ApiGen 2.8.0