Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • 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
  • Smarty
    • Cacher
    • Compiler
    • Config
    • Debug
    • PluginsBlock
    • PluginsFilter
    • PluginsFunction
    • PluginsInternal
    • PluginsModifier
    • PluginsModifierCompiler
    • PluginsShared
    • Security
    • Template
    • TemplateResources
  • Swift
    • ByteStream
    • CharacterStream
    • Encoder
    • Events
    • KeyCache
    • Mailer
    • Mime
    • Plugins
    • Transport

Classes

  • Swift_FailoverTransport
  • Swift_LoadBalancedTransport
  • Swift_MailTransport
  • Swift_Plugins_Loggers_ArrayLogger
  • Swift_Plugins_Loggers_EchoLogger
  • Swift_SendmailTransport
  • Swift_SmtpTransport
  • Swift_Transport_AbstractSmtpTransport
  • Swift_Transport_Esmtp_Auth_CramMd5Authenticator
  • Swift_Transport_Esmtp_Auth_LoginAuthenticator
  • Swift_Transport_Esmtp_Auth_PlainAuthenticator
  • Swift_Transport_Esmtp_AuthHandler
  • Swift_Transport_EsmtpTransport
  • Swift_Transport_FailoverTransport
  • Swift_Transport_LoadBalancedTransport
  • Swift_Transport_MailTransport
  • Swift_Transport_SendmailTransport
  • Swift_Transport_SimpleMailInvoker
  • Swift_Transport_StreamBuffer

Interfaces

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