diff --git a/application/MantisBT/Db/DriverAbstract.php b/application/MantisBT/Db/DriverAbstract.php
index 13eea82f87..3e6503b3fe 100644
--- a/application/MantisBT/Db/DriverAbstract.php
+++ b/application/MantisBT/Db/DriverAbstract.php
@@ -19,7 +19,8 @@
namespace MantisBT\Db;
use MantisBT\Db\PDO\Mysql;
-use MantisBT\Exception\Db;
+use MantisBT\Exception\Database\ParameterCountMismatch;
+use MantisBT\Exception\Database\QueryFailed;
use MantisBT\Exception\UnspecifiedException;
/**
@@ -147,16 +148,10 @@ protected function queryStart( $sql, array $params=null ) {
$this->queries++;
}
- /**
- * Called immediately after each db query.
- * @param mixed db specific result
- * @return void
- */
- public function queryEnd( $result ) {
- if ( $result !== false ) {
- return;
- }
- }
+ /**
+ * Called immediately after each db query.
+ */
+ public function queryEnd() {}
/**
* Reset internal column details cache
@@ -202,36 +197,35 @@ public function perfGetQueries() {
}
/**
- * Verify sql parameters
- * @param string $sql query or part of it
- * @param array $params query parameters
- * @return array (sql, params, type of params)
- */
- public function checkSqlParameters($sql, array $params=null) {
- $params = (array)$params; // make null array if needed
-
- // cast booleans to 1/0 int
- foreach ($params as $key => $value) {
- $params[$key] = is_bool($value) ? (int)$value : $value;
- }
+ * Verify parameters to SQL query string
+ * @param string $sql SQL query string (or a portion thereof)
+ * @param array $parameters Query parameters
+ * @return array An array containing: [0] = SQL query string, [1] = array of parameters
+ */
+ public function checkSqlParameters($queryString, array $parameters = null) {
+ $expectedParameterCount = substr_count($queryString, '?');
+ $actualParameterCount = 0;
+ if ($parameters !== null) {
+ $actualParameterCount = count($parameters);
+ } else {
+ $parameters = array();
+ }
- $t_count = substr_count($sql, '?');
+ if ($expectedParameterCount !== $actualParameterCount) {
+ throw new ParameterCountMismatch($queryString, $parameters);
+ }
- if (!$t_count) {
- return array($sql, array() );
- }
+ if ($actualParameterCount === 0) {
+ return array($queryString, array());
+ } else {
+ // cast booleans to 1/0 int
+ foreach ($parameters as $parameterName => $parameterValue) {
+ $parameters[$parameterName] = is_bool($parameterValue) ? (int)$parameterValue : $parameterValue;
+ }
- if ($t_count == count($params)) {
- return array($sql, array_values($params));
+ return array($queryString, array_values($parameters));
}
-
- $a = new stdClass;
- $a->expected = $t_count;
- $a->actual = count($params);
- $a->sql = $sql;
- $a->params = $params;
- throw new Db( ERROR_DB_QUERY_FAILED, $a );
- }
+ }
public function getTableNamePrefix() {
return $this->tableNamePrefix;
diff --git a/application/MantisBT/Db/DriverInterface.php b/application/MantisBT/Db/DriverInterface.php
index 6694ff3ee1..cadbd25c6d 100644
--- a/application/MantisBT/Db/DriverInterface.php
+++ b/application/MantisBT/Db/DriverInterface.php
@@ -89,12 +89,10 @@ public function dispose();
*/
public function queryStart( $sql, array $params=null );
- /**
- * Called immediately after each db query.
- * @param mixed db specific result
- * @return void
- */
- public function queryEnd( $result );
+ /**
+ * Called immediately after each db query.
+ */
+ public function queryEnd();
/**
* Returns database server info array
@@ -102,11 +100,6 @@ public function queryEnd( $result );
*/
public function getServerInfo();
- /**
- * Returns last error reported by database engine.
- * @return string error message
- */
- public function getLastError();
/**
* Return tables in database WITHOUT current prefix
diff --git a/application/MantisBT/Db/PDO/Mysql.php b/application/MantisBT/Db/PDO/Mysql.php
index 3e0e755cca..a3daf01fc3 100644
--- a/application/MantisBT/Db/PDO/Mysql.php
+++ b/application/MantisBT/Db/PDO/Mysql.php
@@ -15,12 +15,14 @@
#
# You should have received a copy of the GNU General Public License
# along with MantisBT. If not, see .
+
namespace MantisBT\Db\PDO;
-use MantisBT\Db\DriverInterface;
-use MantisBT\Db\PDO\PDOAbstract;
-use MantisBT\Exception\Db AS DbException;
+
use \PDO;
use \PDOException;
+use MantisBT\Db\DriverInterface;
+use MantisBT\Db\PDO\PDOAbstract;
+use MantisBT\Exception\Database\QueryFailed;
/**
* MYSQL PDO driver class.
@@ -86,9 +88,8 @@ public function databaseExists( $name ) {
$sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?";
try {
$result = $this->execute( $sql, array( $name ) );
- } catch (PDOException $ex) {
- throw new DbException(ERROR_DB_QUERY_FAILED, $ex->getMessage());
- return false;
+ } catch (PDOException $exception) {
+ throw new QueryFailed($exception->getCode(), $exception->getMessage(), $sql);
}
if ($result) {
$value = $result->fetch();
diff --git a/application/MantisBT/Db/PDO/PDOAbstract.php b/application/MantisBT/Db/PDO/PDOAbstract.php
index 302b912cec..95e223796f 100644
--- a/application/MantisBT/Db/PDO/PDOAbstract.php
+++ b/application/MantisBT/Db/PDO/PDOAbstract.php
@@ -18,12 +18,12 @@
namespace MantisBT\Db\PDO;
+use \PDO;
+use \PDOException;
use MantisBT\Db\DriverAbstract;
use MantisBT\Exception\Database\ConnectionFailed;
use MantisBT\Exception\Database\DatabaseTypeNotSupported;
-use MantisBT\Exception\Db AS DbException;
-use \PDO;
-use \PDOException;
+use MantisBT\Exception\Database\QueryFailed;
/**
* Abstract PDO database driver class.
@@ -32,8 +32,15 @@
*/
abstract class PDOAbstract extends DriverAbstract {
protected $pdb;
- protected $lastError = null;
+ /**
+ * Connect to a database using PDO
+ * @param string $dsn Database Source Name (DSN) for the connection
+ * @param string $dbHost Hostname or IP address of the database server
+ * @param string $dbUser Username
+ * @param string $dbPass Password
+ * @param array $dbOptions Optional configuration to pass to PDO
+ */
public function connect($dsn, $dbHost, $dbUser, $dbPass, $dbName, array $dbOptions = null) {
$driverStatus = $this->driverInstalled();
if ($driverStatus !== true) {
@@ -46,14 +53,13 @@ public function connect($dsn, $dbHost, $dbUser, $dbPass, $dbName, array $dbOptio
$this->dbName = $dbName;
try {
- $this->pdb = new PDO( $this->getDsn(), $this->dbUser, $this->dbPass, $this->getPdoOptions());
+ $this->pdb = new PDO($this->getDsn(), $this->dbUser, $this->dbPass, $this->getPdoOptions());
$this->pdb->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$this->pdb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->postConnect();
} catch (PDOException $exception) {
throw new ConnectionFailed($exception->getCode(), $exception->getMessage());
}
- return true;
}
/**
@@ -121,43 +127,33 @@ public function getInsertId( $table ) {
}
}
- /**
- * Returns last error reported by database engine.
- * @return string error message
- */
- public function getLastError() {
- return $this->lastError;
- }
+ /**
+ * Execute SQL query
+ * @param string $sql Query string
+ * @param array $params Array of parameters to insert into query string
+ * @return PDOStatement Resulting handle for the executed prepared statement
+ */
+ public function execute($queryString, array $parameters = null) {
+ list( $sql, $params ) = $this->checkSqlParameters($queryString, $parameters);
+ $queryString = $this->remapTableNames($queryString);
- /**
- * Execute SQL query.
- * @param string $sql query
- * @param array $params query parameters
- * @return bool success
- */
- public function execute( $sql, array $params=null ) {
- list( $sql, $params ) = $this->checkSqlParameters($sql, $params);
- $sql = $this->remapTableNames($sql);
+ $this->queryStart($queryString, $parameters);
+
+ try {
+ $sth = $this->pdb->prepare($queryString);
+ $sth->execute($parameters);
+ } catch (PDOException $exception) {
+ throw new QueryFailed($exception->getCode(), $exception->getMessage(), $queryString);
+ }
- $result = true;
- $this->queryStart( $sql, $params );
+ $this->queryEnd();
- try {
- $sth = $this->pdb->prepare( $sql );
- $sth->execute( $params );
- } catch ( PDOException $ex ) {
- $this->lastError = $ex->getMessage();
- $result = false;
- }
-
- $this->queryEnd( $result );
- return $result == true ? $sth : false;
- }
+ return $sth;
+ }
/**
*/
public function queryStart( $sql, array $params=null ) {
- $this->lastError = null;
parent::queryStart( $sql, $params );
}
diff --git a/application/MantisBT/Error.php b/application/MantisBT/Error.php
index 84bf265586..fd4848b7c6 100644
--- a/application/MantisBT/Error.php
+++ b/application/MantisBT/Error.php
@@ -82,7 +82,7 @@ public static function error_handler( $type, $error, $file, $line, $context ) {
$errorInfo->file = $file;
$errorInfo->line = $line;
$errorInfo->context = $context;
- $errorInfo->trace = debug_backtrace();
+ $errorInfo->trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
self::$allErrors[] = $errorInfo;
@@ -135,8 +135,8 @@ public static function shutdown_error_handler() {
$errorInfo->message = $error['message'];
$errorInfo->file = $error['file'];
$errorInfo->line = $error['line'];
- $errorInfo->trace = debug_backtrace();
- $errorInfo->context = null;
+ $errorInfo->trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
+ $errorInfo->context = null;
self::$allErrors[] = $errorInfo;
}
@@ -295,7 +295,6 @@ public static function error_print_stack_trace( $stack ) {
# remove the call to the error handler from the stack trace
array_shift( $stack );
-
foreach( $stack as $frame ) {
echo '
';
echo '', ( isset( $frame['file'] ) ? htmlentities( $frame['file'], ENT_COMPAT, 'UTF-8' ) : '-' ), ' | ', ( isset( $frame['line'] ) ? $frame['line'] : '-' ), ' | ', ( isset( $frame['class'] ) ? $frame['class'] : '-' ), ' | ', ( isset( $frame['type'] ) ? $frame['type'] : '-' ), ' | ', ( isset( $frame['function'] ) ? $frame['function'] : '-' ), ' | ';
diff --git a/application/MantisBT/Exception/Database/ParameterCountMismatch.php b/application/MantisBT/Exception/Database/ParameterCountMismatch.php
new file mode 100644
index 0000000000..9a8b0a51d9
--- /dev/null
+++ b/application/MantisBT/Exception/Database/ParameterCountMismatch.php
@@ -0,0 +1,18 @@
+responseCode = 500;
+ }
+}
diff --git a/application/MantisBT/Exception/Database/QueryFailed.php b/application/MantisBT/Exception/Database/QueryFailed.php
new file mode 100644
index 0000000000..3e49df03c7
--- /dev/null
+++ b/application/MantisBT/Exception/Database/QueryFailed.php
@@ -0,0 +1,14 @@
+responseCode = 500;
+ }
+}
diff --git a/application/MantisBT/Exception/Db.php b/application/MantisBT/Exception/Db.php
deleted file mode 100644
index f3d06098ad..0000000000
--- a/application/MantisBT/Exception/Db.php
+++ /dev/null
@@ -1,17 +0,0 @@
-rowCount();
}
/**
- * Retrieve the next row returned from a specific database query
- * @param bool|ADORecordSet $p_result Database Query Record Set to retrieve next result for.
- * @return array Database result
+ * Retrieve the next row returned from a database query.
+ * @param mixed Result of an executed prepared statement
+ * @return array An array of the next row of the query results
*/
-function db_fetch_array( &$result ) {
+function db_fetch_array( $result ) {
return $result->fetch();
}
@@ -382,19 +372,6 @@ function db_field_names( $tableName ) {
return is_array( $columns ) ? $columns : array();
}
-/**
- * send both the error number and error message and query (optional) as paramaters for a triggered error
- * @todo Use/Behaviour of this function should be reviewed before 1.2.0 final
- */
-function db_error( $query = null ) {
- global $g_db;
- if( null !== $query ) {
- error_parameters( /* $g_db->ErrorNo(), */ $g_db->getLastError(), $query );
- } else {
- error_parameters( /* $g_db->ErrorNo(), */ $g_db->getLastError() );
- }
-}
-
/**
* close the connection.
* Not really necessary most of the time since a connection is automatically closed when a page finishes loading.