| Current File : //opt/RZphp82/includes/XML/Query2XML/Driver/DB.php |
<?php
/**
* This file contains the class XML_Query2XML_Driver_DB.
*
* PHP version 5
*
* @category XML
* @package XML_Query2XML
* @author Lukas Feiler <lukas.feiler@lukasfeiler.com>
* @copyright 2006 Lukas Feiler
* @license http://www.gnu.org/copyleft/lesser.html LGPL Version 2.1
* @version CVS: $Id: DB.php 276639 2009-03-01 13:17:08Z lukasfeiler $
* @link http://pear.php.net/package/XML_Query2XML
*/
/**
* XML_Query2XML_Driver_DB extends XML_Query2XML_Driver.
*/
require_once 'XML/Query2XML.php';
/**
* As the method PEAR::isError() is used within XML_Query2XML_Driver_DB
* we require PEAR.php.
*/
require_once 'PEAR.php';
/**
* Driver for the database abstraction layer PEAR DB.
*
* usage:
* <code>
* $driver = XML_Query2XML_Driver::factory(DB::connect(...));
* </code>
*
* @category XML
* @package XML_Query2XML
* @author Lukas Feiler <lukas.feiler@lukasfeiler.com>
* @copyright 2006 Lukas Feiler
* @license http://www.gnu.org/copyleft/lesser.html LGPL Version 2.1
* @version Release: 1.7.2
* @link http://pear.php.net/package/XML_Query2XML
* @since Release 1.5.0RC1
*/
class XML_Query2XML_Driver_DB extends XML_Query2XML_Driver
{
/**
* In instance of a class that extends DB_common.
* @var DB_common
*/
private $_db = null;
/**
* Constructor
*
* @param DB_Common $db An instance of a class that extends DB_Common.
*
* @throws XML_Query2XML_DBException If the fetch mode cannot be set to
* DB_FETCHMODE_ASSOC.
*/
public function __construct(DB_common $db)
{
$fetchModeError = $db->setFetchMode(DB_FETCHMODE_ASSOC);
if (PEAR::isError($fetchModeError)) {
// no unit tests for this one
throw new XML_Query2XML_DBException(
'Could not set fetch mode to DB_FETCHMODE_ASSOC: '
. $fetchModeError->toString()
);
}
$this->_db = $db;
}
/**
* Pre-processes a query specification and returns a string representation
* of the query.
* This method will call parent::preprocessQuery(). Additionally it will
* verify $query['limit'] and $query['offset'].
*
* @param mixed &$query A string or an array containing the element 'query'.
* @param string $configPath The config path; used for exception messages.
*
* @return string The query statement as a string.
* @throws XML_Query2XML_ConfigException If $query['limit'] or $query['offset']
* is set but not numeric. This exception
* might also bubble up from
* parent::preprocessQuery().
*/
public function preprocessQuery(&$query, $configPath)
{
/*
* This will make $query an array if it is not already.
* We'll ignore preprocessQuery()'s return value here.
*/
parent::preprocessQuery($query, $configPath);
foreach (array('limit', 'offset') as $sqlOption) {
if (isset($query[$sqlOption])) {
if (!is_numeric($query[$sqlOption])) {
/*
* unit test: getXML/
* offsetlimit_throwConfigException_limit_not_numeric.phpt
* offsetlimit_throwConfigException_offset_not_numeric.phpt
*/
throw new XML_Query2XML_ConfigException(
$configPath . '[' . $sqlOption
. ']: integer expected, '
. gettype($query[$sqlOption]) . ' given.'
);
}
}
}
$queryString = $query['query'];
if (isset($query['limit'])) {
if ($query['limit'] == 0) {
// setting limit to 0 is like not setting it at all
unset($query['limit']);
} else {
if (!isset($query['offset'])) {
// offset defaults to 0
$query['offset'] = 0;
}
$queryString .= '; LIMIT:' . $query['limit'];
$queryString .= '; OFFSET:' . $query['offset'];
$query['query'] = $this->_db->modifyLimitQuery(
$query['query'],
$query['offset'],
$query['limit']
);
}
}
return $queryString;
}
/**
* Execute a SQL SELECT stement and fetch all records from the result set.
*
* @param mixed $sql The SQL query as an array containing the
* element 'query'.
* @param string $configPath The config path; used for exception messages.
*
* @return array An array of records.
* @throws XML_Query2XML_DBException If a database related error occures.
* @see XML_Query2XML_Driver::getAllRecords()
*/
public function getAllRecords($sql, $configPath)
{
if (isset($sql['limit']) && $sql['limit'] < 0) {
return array();
}
$result =& $this->_prepareAndExecute($sql, $configPath);
$records = array();
while ($record = $result->fetchRow()) {
if (PEAR::isError($record)) {
// no unit test for this exception as it cannot be produced easily
throw new XML_Query2XML_DBException(
$configPath . ': Could not fetch rows for the following '
. 'SQL query: ' . $sql['query'] . '; '
. $record->toString()
);
}
$records[] = $record;
}
$result->free();
return $records;
}
/**
* Private method that will use DB_Common::prepare() & DB_Common::execute()
* to run an SQL query.
*
* @param mixed $sql An associative array with a 'query' element.
* @param string $configPath The config path used for exception messages.
*
* @return DB_result
* @throws XML_Query2XML_DBException If a database related error occures.
*/
private function _prepareAndExecute($sql, $configPath)
{
$query = $sql['query'];
if (isset($this->_preparedQueries[$query])) {
$queryHandle = $this->_preparedQueries[$query];
} else {
// PREPARE
$queryHandle = $this->_db->prepare($query);
if (PEAR::isError($queryHandle)) {
/*
* No unit test for this exception as DB's mysql and pgsql
* drivers never return a PEAR error from prepare().
*/
throw new XML_Query2XML_DBException(
$configPath . ': Could not prepare the following SQL query: '
. $query . '; ' . $queryHandle->toString()
);
}
$this->_preparedQueries[$query] =& $queryHandle;
}
// EXECUTE
if (isset($sql['data'])) {
$result = $this->_db->execute($queryHandle, $sql['data']);
} else {
$result = $this->_db->execute($queryHandle);
}
if (PEAR::isError($result)) {
/*
* unit test: DB/_prepareAndExecute/
* throwDBException_complexQuery.phpt
*/
throw new XML_Query2XML_DBException(
$configPath . ': Could not execute the following SQL query: '
. $query . '; ' . $result->toString()
);
}
if (!($result instanceof DB_result)) {
/*
* unit tests: DB/getXML/
* throwDBException_nullResultSet_complexQuery_multipleRecords.phpt
* throwDBException_nullResultSet_complexQuery_singleRecord.phpt
*/
throw new XML_Query2XML_DBException(
$configPath . ': the following SQL query returned no '
. 'result set: ' . $query
);
}
return $result;
}
}
?>