Skip to content

Commit

Permalink
Fixes for Oracle driver, Oracle query and PDO driver
Browse files Browse the repository at this point in the history
  • Loading branch information
pasamio committed Jun 5, 2012
1 parent 49a4e5b commit 72d1512
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 17 deletions.
116 changes: 113 additions & 3 deletions libraries/joomla/database/driver/oracle.php
Expand Up @@ -27,6 +27,17 @@ class JDatabaseDriverOracle extends JDatabaseDriverPdo
*/
public $name = 'oracle';

/**
* The character(s) used to quote SQL statement names such as table names or field names,
* etc. The child classes should define this as necessary. If a single character string the
* same character is used for both sides of the quoted name, else the first character will be
* used for the opening quote and the second for the closing quote.
*
* @var string
* @since 12.1
*/
protected $nameQuote = '"';

/**
* Returns the current dateformat
*
Expand Down Expand Up @@ -148,6 +159,18 @@ public function getCollation()
return $this->charset;
}

/**
* Get a query to run and verify the database is operational.
*
* @return string The query to check the health of the DB.
*
* @since 12.2
*/
public function getConnectedQuery()
{
return 'SELECT 1 FROM dual';
}

/**
* Returns the current date format
* This method should be useful in the case that
Expand Down Expand Up @@ -231,22 +254,24 @@ public function getTableColumns($table, $typeOnly = true)
$query->from('ALL_TAB_COLUMNS');
$query->where('table_name = :tableName');

$query->bind(':tableName', $table);
$prefixedTable = str_replace('#__', strtoupper($this->tablePrefix), $table);
$query->bind(':tableName', $prefixedTable);
$this->setQuery($query);
$fields = $this->loadObjectList();

if ($typeOnly)
{
foreach ($fields as $field)
{
$columns[$table][$field->COLUMN_NAME] = $field->DATA_TYPE;
$columns[$field->COLUMN_NAME] = $field->DATA_TYPE;
}
}
else
{
foreach ($fields as $field)
{
$columns[$table][$field->COLUMN_NAME] = $field;
$columns[$field->COLUMN_NAME] = $field;
$columns[$field->COLUMN_NAME]->Default = null;
}
}

Expand Down Expand Up @@ -482,4 +507,89 @@ public static function isSupported()
{
return in_array('oci', PDO::getAvailableDrivers());
}

/**
* This function replaces a string identifier <var>$prefix</var> with the string held is the
* <var>tablePrefix</var> class variable.
*
* @param string $sql The SQL statement to prepare.
* @param string $prefix The common table prefix.
*
* @return string The processed SQL statement.
*
* @since 11.1
*/
public function replacePrefix($sql, $prefix = '#__')
{
// Initialize variables.
$escaped = false;
$startPos = 0;
$quoteChar = "'";
$literal = '';

$sql = trim($sql);
$n = strlen($sql);

while ($startPos < $n)
{
$ip = strpos($sql, $prefix, $startPos);
if ($ip === false)
{
break;
}

$j = strpos($sql, "'", $startPos);

if ($j === false)
{
$j = $n;
}

$literal .= str_replace($prefix, $this->tablePrefix, substr($sql, $startPos, $j - $startPos));
$startPos = $j;

$j = $startPos + 1;

if ($j >= $n)
{
break;
}

// Quote comes first, find end of quote
while (true)
{
$k = strpos($sql, $quoteChar, $j);
$escaped = false;
if ($k === false)
{
break;
}
$l = $k - 1;
while ($l >= 0 && $sql{$l} == '\\')
{
$l--;
$escaped = !$escaped;
}
if ($escaped)
{
$j = $k + 1;
continue;
}
break;
}
if ($k === false)
{
// Error in the query - no end quote; ignore it
break;
}
$literal .= substr($sql, $startPos, $k - $startPos + 1);
$startPos = $k + 1;
}
if ($startPos < $n)
{
$literal .= substr($sql, $startPos, $n - $startPos);
}

return $literal;
}
}
44 changes: 38 additions & 6 deletions libraries/joomla/database/driver/pdo.php
Expand Up @@ -343,7 +343,7 @@ public function escape($text, $extra = false)

$text = str_replace("'", "''", $text);

return "'" . addcslashes($text, "\000\n\r\\\032") . "'";
return addcslashes($text, "\000\n\r\\\032");
}

/**
Expand Down Expand Up @@ -407,6 +407,10 @@ public function execute()
// If an error occurred handle it.
if (!$this->executed)
{
// Get the error number and message before we execute any more queries.
$errorNum = (int) $this->connection->errorCode();
$errorMsg = (string) 'SQL: ' . implode(", ", $this->connection->errorInfo());

// Check if the server was disconnected.
if (!$this->connected())
{
Expand Down Expand Up @@ -434,9 +438,9 @@ public function execute()
// The server was not disconnected.
else
{
// Get the error number and message.
$this->errorNum = (int) $this->connection->errorCode();
$this->errorMsg = (string) 'SQL: ' . implode(", ", $this->connection->errorInfo());
// Get the error number and message from before we tried to reconnect.
$this->errorNum = $errorNum;
$this->errorMsg = $errorMsg;

// Throw the normal query exception.
JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'databasequery');
Expand Down Expand Up @@ -466,6 +470,18 @@ public function getOption($key)
return $this->connection->getAttribute($key);
}

/**
* Get a query to run and verify the database is operational.
*
* @return string The query to check the health of the DB.
*
* @since 12.2
*/
public function getConnectedQuery()
{
return 'SELECT 1';
}

/**
* Sets an attribute on the PDO database handle.
* http://www.php.net/manual/en/pdo.setattribute.php
Expand Down Expand Up @@ -510,6 +526,17 @@ public static function isSupported()
*/
public function connected()
{
// Flag to prevent recursion into this function.
static $checkingConnected = false;

if ($checkingConnected)
{
// Reset this flag and throw an exception.
$checkingConnected = true;
die('Recursion trying to check if connected.');
throw new RuntimeException('Not connected to database.');
}

// Backup the query state.
$sql = $this->sql;
$limit = $this->limit;
Expand All @@ -518,8 +545,11 @@ public function connected()

try
{
// Set the checking connection flag.
$checkingConnected = true;

// Run a simple query to check the connection.
$this->setQuery('SELECT 1');
$this->setQuery($this->getConnectedQuery());
$status = (bool) $this->loadResult();
}
// If we catch an exception here, we must not be connected.
Expand All @@ -533,6 +563,7 @@ public function connected()
$this->limit = $limit;
$this->offset = $offset;
$this->prepared = $prepared;
$checkingConnected = false;

return $status;
}
Expand Down Expand Up @@ -597,7 +628,8 @@ public function insertid()
{
$this->connect();

return $this->connection->lastInsertId();
// Error suppress this to prevent PDO warning us that the driver doesn't support this operation.
return @$this->connection->lastInsertId();
}

/**
Expand Down
33 changes: 25 additions & 8 deletions libraries/joomla/database/query/oracle.php
Expand Up @@ -150,14 +150,31 @@ public function clear($clause = null)
*/
public function processLimit($query, $limit, $offset = 0)
{
$query = "SELECT joomla2.*
FROM (
SELECT joomla1.*, ROWNUM AS joomla_db_rownum
FROM (
" . $query . "
) joomla1
) joomla2
WHERE joomla2.joomla_db_rownum BETWEEN " . ($offset + 1) . " AND " . ($offset + $limit);
// Check if we need to mangle the query.
if ($limit || $offset)
{
$query = "SELECT joomla2.*
FROM (
SELECT joomla1.*, ROWNUM AS joomla_db_rownum
FROM (
" . $query . "
) joomla1
) joomla2";

// Check if the limit value is greater than zero.
if ($limit > 0)
{
$query .= ' WHERE joomla2.joomla_db_rownum BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $limit);
}
else
{
// Check if there is an offset and then use this.
if ($offset)
{
$query .= ' WHERE joomla2.joomla_db_rownum > ' . ($offset + 1);
}
}
}

return $query;
}
Expand Down

0 comments on commit 72d1512

Please sign in to comment.