Unverified Commit 5193c972 authored by Sergei Morozov's avatar Sergei Morozov

Merge pull request #3536 from jwage/improve-exception-messages

Improve consistency of exception message formatting.
parents d95ce266 e1accb21
......@@ -15,6 +15,7 @@ use function array_merge;
use function array_values;
use function count;
use function reset;
use function sprintf;
class ArrayStatement implements IteratorAggregate, ResultStatement
{
......@@ -48,7 +49,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
*/
public function closeCursor() : void
{
unset($this->data);
$this->data = null;
}
/**
......@@ -77,7 +78,7 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
public function setFetchMode($fetchMode, ...$args) : void
{
if (count($args) > 0) {
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode()');
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode().');
}
$this->defaultFetchMode = $fetchMode;
......@@ -121,7 +122,9 @@ class ArrayStatement implements IteratorAggregate, ResultStatement
return reset($row);
}
throw new InvalidArgumentException('Invalid fetch-style given for fetching result.');
throw new InvalidArgumentException(
sprintf('Invalid fetch mode given for fetching result, %d given.', $fetchMode)
);
}
/**
......
......@@ -28,13 +28,20 @@ class DBALException extends Exception
*/
public static function driverExceptionDuringQuery(Driver $driver, Throwable $driverEx, $sql, array $params = [])
{
$msg = "An exception occurred while executing '" . $sql . "'";
if ($params) {
$msg .= ' with params ' . self::formatParameters($params);
}
$msg .= ":\n\n" . $driverEx->getMessage();
$messageFormat = <<<'MESSAGE'
An exception occurred while executing "%s"%s:
%s
MESSAGE;
$message = sprintf(
$messageFormat,
$sql,
$params !== [] ? sprintf(' with params %s', self::formatParameters($params)) : '',
$driverEx->getMessage()
);
return static::wrapException($driver, $driverEx, $msg);
return static::wrapException($driver, $driverEx, $message);
}
/**
......@@ -42,7 +49,7 @@ class DBALException extends Exception
*/
public static function driverException(Driver $driver, Throwable $driverEx)
{
return static::wrapException($driver, $driverEx, 'An exception occurred in driver: ' . $driverEx->getMessage());
return static::wrapException($driver, $driverEx, sprintf('An exception occurred in driver with message: %s', $driverEx->getMessage()));
}
/**
......@@ -64,11 +71,9 @@ class DBALException extends Exception
* Returns a human-readable representation of an array of parameters.
* This properly handles binary data by returning a hex representation.
*
* @param mixed[] $params
*
* @return string
* @param array<mixed, mixed> $params
*/
private static function formatParameters(array $params)
private static function formatParameters(array $params) : string
{
return '[' . implode(', ', array_map(static function ($param) {
if (is_resource($param)) {
......
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use mysqli;
final class ConnectionError extends MysqliException
{
public static function new(mysqli $connection) : self
{
return new self($connection->error, $connection->sqlstate ?: null, $connection->errno);
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use function sprintf;
final class FailedReadingStreamOffset extends MysqliException
{
public static function new(int $offset) : self
{
return new self(sprintf('Failed reading the stream resource for parameter offset %d.', $offset));
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use mysqli_stmt;
final class StatementError extends MysqliException
{
public static function new(mysqli_stmt $statement) : self
{
return new self($statement->error, $statement->sqlstate ?: null, $statement->errno);
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use function sprintf;
final class UnknownFetchMode extends MysqliException
{
/**
* @param mixed $fetchMode
*/
public static function new($fetchMode) : self
{
return new self(sprintf('Unknown fetch mode %d.', $fetchMode));
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use function sprintf;
final class UnknownType extends MysqliException
{
/**
* @param mixed $type
*/
public static function new($type) : self
{
return new self(sprintf('Unknown type, %d given.', $type));
}
}
......@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
......@@ -73,7 +74,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
});
try {
if (! $this->conn->real_connect($host, $username, $password, $dbname, $port, $socket, $flags)) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
} finally {
restore_error_handler();
......@@ -161,7 +162,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
public function exec(string $statement) : int
{
if ($this->conn->query($statement) === false) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
return $this->conn->affected_rows;
......@@ -189,7 +190,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
public function commit() : void
{
if (! $this->conn->commit()) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
}
......@@ -199,7 +200,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
public function rollBack() : void
{
if (! $this->conn->rollback()) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
}
......@@ -242,7 +243,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
continue;
}
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
}
......
......@@ -5,21 +5,10 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\AbstractDriverException;
use mysqli;
use mysqli_stmt;
/**
* Exception thrown in case the mysqli driver errors.
*/
class MysqliException extends AbstractDriverException
{
public static function fromConnectionError(mysqli $connection) : self
{
return new self($connection->error, $connection->sqlstate ?: null, $connection->errno);
}
public static function fromStatementError(mysqli_stmt $statement) : self
{
return new self($statement->error, $statement->sqlstate ?: null, $statement->errno);
}
}
......@@ -5,6 +5,11 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownFetchMode;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidArgumentException;
......@@ -25,7 +30,6 @@ use function get_resource_type;
use function is_array;
use function is_int;
use function is_resource;
use function sprintf;
use function str_repeat;
class MysqliStatement implements IteratorAggregate, Statement
......@@ -87,7 +91,7 @@ class MysqliStatement implements IteratorAggregate, Statement
$stmt = $conn->prepare($prepareString);
if ($stmt === false) {
throw MysqliException::fromConnectionError($this->_conn);
throw ConnectionError::new($this->_conn);
}
$this->_stmt = $stmt;
......@@ -109,7 +113,7 @@ class MysqliStatement implements IteratorAggregate, Statement
assert(is_int($column));
if (! isset(self::$_paramTypeMap[$type])) {
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
throw UnknownType::new($type);
}
$this->_bindedValues[$column] =& $variable;
......@@ -124,7 +128,7 @@ class MysqliStatement implements IteratorAggregate, Statement
assert(is_int($param));
if (! isset(self::$_paramTypeMap[$type])) {
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
throw UnknownType::new($type);
}
$this->_values[$param] = $value;
......@@ -139,14 +143,14 @@ class MysqliStatement implements IteratorAggregate, Statement
{
if ($params !== null && count($params) > 0) {
if (! $this->bindUntypedValues($params)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
} else {
$this->bindTypedParameters();
}
if (! $this->_stmt->execute()) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
if ($this->_columnNames === null) {
......@@ -193,7 +197,7 @@ class MysqliStatement implements IteratorAggregate, Statement
}
if (! $this->_stmt->bind_result(...$refs)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
}
......@@ -232,7 +236,7 @@ class MysqliStatement implements IteratorAggregate, Statement
}
if (count($values) > 0 && ! $this->_stmt->bind_param($types, ...$values)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
$this->sendLongData($streams);
......@@ -250,11 +254,11 @@ class MysqliStatement implements IteratorAggregate, Statement
$chunk = fread($stream, 8192);
if ($chunk === false) {
throw new MysqliException("Failed reading the stream resource for parameter offset ${paramNr}.");
throw FailedReadingStreamOffset::new($paramNr);
}
if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
}
}
......@@ -322,7 +326,7 @@ class MysqliStatement implements IteratorAggregate, Statement
}
if ($values === false) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
if ($fetchMode === FetchMode::NUMERIC) {
......@@ -344,7 +348,7 @@ class MysqliStatement implements IteratorAggregate, Statement
return (object) $assoc;
default:
throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode));
throw UnknownFetchMode::new($fetchMode);
}
}
......
......@@ -160,7 +160,7 @@ class OCI8Statement implements IteratorAggregate, Statement
if ($currentLiteralDelimiter) {
throw new OCI8Exception(sprintf(
'The statement contains non-terminated string literal starting at offset %d',
'The statement contains non-terminated string literal starting at offset %d.',
$tokenOffset - 1
));
}
......@@ -411,7 +411,7 @@ class OCI8Statement implements IteratorAggregate, Statement
}
if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode);
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
}
return oci_fetch_array(
......@@ -438,7 +438,7 @@ class OCI8Statement implements IteratorAggregate, Statement
}
if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode);
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
}
if (self::$fetchModeMap[$fetchMode] === OCI_BOTH) {
......
......@@ -206,7 +206,7 @@ class PDOStatement implements IteratorAggregate, Statement
if (! isset(self::PARAM_TYPE_MAP[$type])) {
// TODO: next major: throw an exception
@trigger_error(sprintf(
'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0',
'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0.',
$type
), E_USER_DEPRECATED);
......@@ -227,7 +227,7 @@ class PDOStatement implements IteratorAggregate, Statement
// TODO: next major: throw an exception
@trigger_error(sprintf(
'Using a PDO fetch mode or their combination (%d given)' .
' is deprecated and will cause an error in Doctrine 3.0',
' is deprecated and will cause an error in Doctrine 3.0.',
$fetchMode
), E_USER_DEPRECATED);
......
......@@ -6,6 +6,7 @@ namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\GetVariableType;
use Doctrine\DBAL\Exception\InvalidColumnIndex;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
......@@ -17,7 +18,6 @@ use const SASQL_BOTH;
use function array_key_exists;
use function count;
use function func_get_args;
use function gettype;
use function is_array;
use function is_int;
use function is_object;
......@@ -73,7 +73,10 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
public function __construct($conn, $sql)
{
if (! is_resource($conn)) {
throw new SQLAnywhereException('Invalid SQL Anywhere connection resource: ' . $conn);
throw new SQLAnywhereException(sprintf(
'Invalid SQL Anywhere connection resource, %s given.',
(new GetVariableType())->__invoke($conn)
));
}
$this->conn = $conn;
......@@ -108,7 +111,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
break;
default:
throw new SQLAnywhereException('Unknown type: ' . $type);
throw new SQLAnywhereException(sprintf('Unknown type %d.', $type));
}
$this->boundValues[$column] =& $variable;
......@@ -215,7 +218,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
return sasql_fetch_object($this->result);
default:
throw new SQLAnywhereException('Fetch mode is not supported: ' . $fetchMode);
throw new SQLAnywhereException(sprintf('Fetch mode is not supported %d.', $fetchMode));
}
}
......@@ -314,8 +317,8 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
if (! is_string($destinationClass)) {
if (! is_object($destinationClass)) {
throw new SQLAnywhereException(sprintf(
'Destination class has to be of type string or object, %s given.',
gettype($destinationClass)
'Destination class has to be of type string or object, "%s" given.',
(new GetVariableType())->__invoke($destinationClass)
));
}
} else {
......
......@@ -17,7 +17,7 @@ class Driver extends AbstractSQLServerDriver
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
{
if (! isset($params['host'])) {
throw new SQLSrvException("Missing 'host' in configuration for sqlsrv driver.");
throw new SQLSrvException('Missing "host" in configuration for sqlsrv driver.');
}
$serverName = $params['host'];
......
......@@ -347,7 +347,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
return sqlsrv_fetch_object($this->stmt, $className, $ctorArgs) ?: false;
}
throw new SQLSrvException('Fetch mode is not supported!');
throw new SQLSrvException('Fetch mode is not supported.');
}
/**
......
......@@ -17,15 +17,15 @@ final class DriverRequired extends DBALException
if ($url !== null) {
return new self(
sprintf(
"The options 'driver' or 'driverClass' are mandatory if a connection URL without scheme "
. 'is given to DriverManager::getConnection(). Given URL: %s',
'The options "driver" or "driverClass" are mandatory if a connection URL without scheme '
. 'is given to DriverManager::getConnection(). Given URL "%s".',
$url
)
);
}
return new self(
"The options 'driver' or 'driverClass' are mandatory if no PDO "
'The options "driver" or "driverClass" are mandatory if no PDO '
. 'instance is given to DriverManager::getConnection().'
);
}
......
......@@ -8,6 +8,6 @@ final class EmptyCriteriaNotAllowed extends InvalidArgumentException
{
public static function new() : self
{
return new self('Empty criteria was used, expected non-empty criteria');
return new self('Empty criteria was used, expected non-empty criteria.');
}
}
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Exception;
use function get_class;
use function get_resource_type;
use function gettype;
use function is_bool;
use function is_object;
use function is_resource;
final class GetVariableType
{
/**
* @param mixed $value
*/
public function __invoke($value) : string
{
if (is_object($value)) {
return get_class($value);
}
if (is_resource($value)) {
return get_resource_type($value);
}
if (is_bool($value)) {
return $value === true ? 'true' : 'false';
}
return gettype($value);
}
}
......@@ -14,7 +14,7 @@ final class InvalidDriverClass extends DBALException
{
return new self(
sprintf(
"The given 'driverClass' %s has to implement the %s interface.",
'The given "driverClass" %s has to implement the %s interface.',
$driverClass,
Driver::class
)
......
......@@ -10,6 +10,6 @@ final class InvalidPdoInstance extends DBALException
{
public static function new() : self
{
return new self("The 'pdo' option was used in DriverManager::getConnection() but no instance of PDO was given.");
return new self('The "pdo" option was used in DriverManager::getConnection() but no instance of PDO was given.');
}
}
......@@ -7,7 +7,6 @@ namespace Doctrine\DBAL\Exception;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use function get_class;
use function gettype;
use function is_object;
use function sprintf;
......@@ -21,7 +20,7 @@ final class InvalidPlatformType extends DBALException
if (is_object($invalidPlatform)) {
return new self(
sprintf(
"Option 'platform' must be a subtype of '%s', instance of '%s' given",
'Option "platform" must be a subtype of %s, instance of %s given.',
AbstractPlatform::class,
get_class($invalidPlatform)
)
......@@ -30,9 +29,9 @@ final class InvalidPlatformType extends DBALException
return new self(
sprintf(
"Option 'platform' must be an object and subtype of '%s'. Got '%s'",
'Option "platform" must be an object and subtype of %s. Got %s.',
AbstractPlatform::class,
gettype($invalidPlatform)
(new GetVariableType())->__invoke($invalidPlatform)
)
);
}
......
......@@ -14,7 +14,7 @@ final class InvalidWrapperClass extends DBALException
{
return new self(
sprintf(
"The given 'wrapperClass' %s has to be a subtype of %s.",
'The given "wrapperClass" %s has to be a subtype of %s.',
$wrapperClass,
Connection::class
)
......
......@@ -7,12 +7,10 @@ namespace Doctrine\DBAL\Exception;
use Doctrine\DBAL\SQLParserUtilsException;
use function sprintf;
final class MissingSQLParam extends SQLParserUtilsException
final class MissingArrayParameter extends SQLParserUtilsException
{
public static function new(string $paramName) : self
{
return new self(
sprintf('Value for :%1$s not found in params array. Params array key should be "%1$s"', $paramName)
);
return new self(sprintf('Parameter "%s" is missing.', $paramName));
}
}
......@@ -7,12 +7,10 @@ namespace Doctrine\DBAL\Exception;
use Doctrine\DBAL\SQLParserUtilsException;
use function sprintf;
final class MissingSQLType extends SQLParserUtilsException
final class MissingArrayParameterType extends SQLParserUtilsException
{
public static function new(string $typeName) : self
public static function new(string $paramName) : self
{
return new self(
sprintf('Value for :%1$s not found in types array. Types array key should be "%1$s"', $typeName)
);
return new self(sprintf('Type of array parameter "%s" is missing.', $paramName));
}
}
......@@ -17,7 +17,7 @@ final class UnknownDriver extends DBALException
{
return new self(
sprintf(
"The given 'driver' %s is unknown, Doctrine currently supports only the following drivers: %s",
'The given "driver" "%s" is unknown, Doctrine currently supports only the following drivers: %s',
$unknownDriverName,
implode(', ', $knownDrivers)
)
......
......@@ -12,6 +12,7 @@ use Doctrine\DBAL\LockMode;
use Throwable;
use const CASE_LOWER;
use function array_change_key_case;
use function sprintf;
/**
* Table ID Generator for those poor languages that are missing sequences.
......@@ -126,7 +127,7 @@ class TableGenerator
$rows = $this->conn->executeUpdate($sql, [$sequenceName, $row['sequence_value']]);
if ($rows !== 1) {
throw new DBALException('Race-condition detected while updating sequence. Aborting generation');
throw new DBALException('Race condition detected while updating sequence. Aborting generation.');
}
} else {
$this->conn->insert(
......@@ -139,7 +140,7 @@ class TableGenerator
$this->conn->commit();
} catch (Throwable $e) {
$this->conn->rollBack();
throw new DBALException('Error occurred while generating ID with TableGenerator, aborted generation: ' . $e->getMessage(), 0, $e);
throw new DBALException(sprintf('Error occurred while generating ID with TableGenerator, aborted generation with error: %s', $e->getMessage()), 0, $e);
}
return $value;
......
......@@ -420,7 +420,11 @@ abstract class AbstractPlatform
$dbType = strtolower($dbType);
if (! isset($this->doctrineTypeMapping[$dbType])) {
throw new DBALException('Unknown database type ' . $dbType . ' requested, ' . static::class . ' may not support it.');
throw new DBALException(sprintf(
'Unknown database type "%s" requested, %s may not support it.',
$dbType,
static::class
));
}
return $this->doctrineTypeMapping[$dbType];
......@@ -762,7 +766,7 @@ abstract class AbstractPlatform
default:
throw new InvalidArgumentException(
sprintf(
'The value of $mode is expected to be one of the TrimMode constants, %d given',
'The value of $mode is expected to be one of the TrimMode constants, %d given.',
$mode
)
);
......@@ -1323,7 +1327,7 @@ abstract class AbstractPlatform
$sql = $eventArgs->getSql();
if ($sql === null) {
throw new UnexpectedValueException('Default implementation of DROP TABLE was overridden with NULL');
throw new UnexpectedValueException('Default implementation of DROP TABLE was overridden with NULL.');
}
return $sql;
......@@ -1428,7 +1432,7 @@ abstract class AbstractPlatform
public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
{
if (! is_int($createFlags)) {
throw new InvalidArgumentException('Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.');
throw new InvalidArgumentException('Second argument of AbstractPlatform::getCreateTableSQL() has to be an integer.');
}
if (count($table->getColumns()) === 0) {
......@@ -1715,7 +1719,7 @@ abstract class AbstractPlatform
$columns = $index->getColumns();
if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
throw new InvalidArgumentException('Incomplete definition. "columns" required.');
}
if ($index->isPrimary()) {
......@@ -2278,7 +2282,7 @@ abstract class AbstractPlatform
$name = new Identifier($name);
if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
throw new InvalidArgumentException('Incomplete definition. "columns" required.');
}
$flags = ['UNIQUE'];
......@@ -2311,7 +2315,7 @@ abstract class AbstractPlatform
$name = new Identifier($name);
if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
throw new InvalidArgumentException('Incomplete definition. "columns" required.');
}
return $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name->getQuotedName($this) . ' ('
......@@ -2449,7 +2453,7 @@ abstract class AbstractPlatform
case 'SET DEFAULT':
return $upper;
default:
throw new InvalidArgumentException('Invalid foreign key action: ' . $upper);
throw new InvalidArgumentException(sprintf('Invalid foreign key action "%s".', $upper));
}
}
......@@ -2470,13 +2474,13 @@ abstract class AbstractPlatform
$sql .= 'FOREIGN KEY (';
if (count($foreignKey->getLocalColumns()) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'local' required.");
throw new InvalidArgumentException('Incomplete definition. "local" required.');
}
if (count($foreignKey->getForeignColumns()) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'foreign' required.");
throw new InvalidArgumentException('Incomplete definition. "foreign" required.');
}
if (strlen($foreignKey->getForeignTableName()) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
throw new InvalidArgumentException('Incomplete definition. "foreignTable" required.');
}
return $sql . implode(', ', $foreignKey->getQuotedLocalColumns($this))
......@@ -2658,7 +2662,7 @@ abstract class AbstractPlatform
case TransactionIsolationLevel::SERIALIZABLE:
return 'SERIALIZABLE';
default:
throw new InvalidArgumentException('Invalid isolation level:' . $level);
throw new InvalidArgumentException(sprintf('Invalid isolation level "%s".', $level));
}
}
......@@ -3302,14 +3306,14 @@ abstract class AbstractPlatform
{
if ($offset < 0) {
throw new DBALException(sprintf(
'Offset must be a positive integer or zero, %d given',
'Offset must be a positive integer or zero, %d given.',
$offset
));
}
if ($offset > 0 && ! $this->supportsLimitOffset()) {
throw new DBALException(sprintf(
'Platform %s does not support offset values in limit queries.',
'Platform "%s" does not support offset values in limit queries.',
$this->getName()
));
}
......
......@@ -11,6 +11,6 @@ final class NoColumnsSpecifiedForTable extends DBALException implements Platform
{
public static function new(string $tableName) : self
{
return new self(sprintf('No columns specified for table %s', $tableName));
return new self(sprintf('No columns specified for table "%s".', $tableName));
}
}
......@@ -11,6 +11,6 @@ final class NotSupported extends DBALException implements PlatformException
{
public static function new(string $method) : self
{
return new self(sprintf('Operation \'%s\' is not supported by platform.', $method));
return new self(sprintf('Operation "%s" is not supported by platform.', $method));
}
}
......@@ -42,7 +42,7 @@ class OraclePlatform extends AbstractPlatform
public static function assertValidIdentifier($identifier)
{
if (! preg_match('(^(([a-zA-Z]{1}[a-zA-Z0-9_$#]{0,})|("[^"]+"))$)', $identifier)) {
throw new DBALException('Invalid Oracle identifier');
throw new DBALException('Invalid Oracle identifier.');
}
}
......@@ -740,7 +740,7 @@ SQL
default:
// SET DEFAULT is not supported, throw exception instead.
throw new InvalidArgumentException('Invalid foreign key action: ' . $action);
throw new InvalidArgumentException(sprintf('Invalid foreign key action "%s".', $action));
}
}
......
......@@ -828,7 +828,10 @@ SQL
return $callback(true);
}
throw new UnexpectedValueException("Unrecognized boolean literal '${value}'");
throw new UnexpectedValueException(sprintf(
'Unrecognized boolean literal, %s given.',
$value
));
}
/**
......
......@@ -551,7 +551,7 @@ class SQLAnywherePlatform extends AbstractPlatform
if (! is_string($index)) {
throw new InvalidArgumentException(
'SQLAnywherePlatform::getDropIndexSQL() expects $index parameter to be string or ' . Index::class . '.'
sprintf('SQLAnywherePlatform::getDropIndexSQL() expects $index parameter to be a string or an instance of %s.', Index::class)
);
}
......@@ -565,7 +565,7 @@ class SQLAnywherePlatform extends AbstractPlatform
if (! is_string($table)) {
throw new InvalidArgumentException(
'SQLAnywherePlatform::getDropIndexSQL() expects $table parameter to be string or ' . Index::class . '.'
sprintf('SQLAnywherePlatform::getDropIndexSQL() expects $table parameter to be a string or an instance of %s.', Index::class)
);
}
......@@ -596,15 +596,15 @@ class SQLAnywherePlatform extends AbstractPlatform
}
if (empty($localColumns)) {
throw new InvalidArgumentException("Incomplete definition. 'local' required.");
throw new InvalidArgumentException('Incomplete definition. "local" required.');
}
if (empty($foreignColumns)) {
throw new InvalidArgumentException("Incomplete definition. 'foreign' required.");
throw new InvalidArgumentException('Incomplete definition. "foreign" required.');
}
if (empty($foreignTableName)) {
throw new InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
throw new InvalidArgumentException('Incomplete definition. "foreignTable" required.');
}
if ($foreignKey->hasOption('notnull') && (bool) $foreignKey->getOption('notnull')) {
......@@ -644,7 +644,7 @@ class SQLAnywherePlatform extends AbstractPlatform
case self::FOREIGN_KEY_MATCH_FULL_UNIQUE:
return 'UNIQUE FULL';
default:
throw new InvalidArgumentException('Invalid foreign key match type: ' . $type);
throw new InvalidArgumentException(sprintf('Invalid foreign key match type "%s".', $type));
}
}
......@@ -1355,7 +1355,7 @@ SQL
case TransactionIsolationLevel::SERIALIZABLE:
return 3;
default:
throw new InvalidArgumentException('Invalid isolation level:' . $level);
throw new InvalidArgumentException(sprintf('Invalid isolation level %d.', $level));
}
}
......@@ -1446,7 +1446,7 @@ SQL
}
if (! $constraint instanceof Index) {
throw new InvalidArgumentException('Unsupported constraint type: ' . get_class($constraint));
throw new InvalidArgumentException(sprintf('Unsupported constraint type %s.', get_class($constraint)));
}
if (! $constraint->isPrimary() && ! $constraint->isUnique()) {
......@@ -1459,7 +1459,7 @@ SQL
$constraintColumns = $constraint->getQuotedColumns($this);
if (empty($constraintColumns)) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
throw new InvalidArgumentException('Incomplete definition. "columns" required.');
}
$sql = '';
......
......@@ -214,7 +214,10 @@ class SQLServerPlatform extends AbstractPlatform
if ($index instanceof Index) {
$index = $index->getQuotedName($this);
} elseif (! is_string($index)) {
throw new InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
throw new InvalidArgumentException(sprintf(
'AbstractPlatform::getDropIndexSQL() expects $index parameter to be a string or an instanceof %s.',
Index::class
));
}
if (! isset($table)) {
......@@ -388,7 +391,7 @@ SQL
public function getDefaultConstraintDeclarationSQL($table, array $column)
{
if (! isset($column['default'])) {
throw new InvalidArgumentException("Incomplete column definition. 'default' required.");
throw new InvalidArgumentException('Incomplete column definition. "default" required.');
}
$columnName = new Identifier($column['name']);
......
......@@ -81,7 +81,7 @@ class SqlitePlatform extends AbstractPlatform
default:
throw new InvalidArgumentException(
sprintf(
'The value of $mode is expected to be one of the TrimMode constants, %d given',
'The value of $mode is expected to be one of the TrimMode constants, %d given.',
$mode
)
);
......@@ -668,7 +668,7 @@ class SqlitePlatform extends AbstractPlatform
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{
if (! $diff->fromTable instanceof Table) {
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema.');
}
$sql = [];
......@@ -689,7 +689,7 @@ class SqlitePlatform extends AbstractPlatform
protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
{
if (! $diff->fromTable instanceof Table) {
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema.');
}
$sql = [];
......@@ -826,7 +826,7 @@ class SqlitePlatform extends AbstractPlatform
$fromTable = $diff->fromTable;
if (! $fromTable instanceof Table) {
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema.');
}
$table = clone $fromTable;
......
......@@ -17,7 +17,7 @@ final class NonUniqueAlias extends QueryException
{
return new self(
sprintf(
"The given alias '%s' is not unique in FROM and JOIN clause table. "
'The given alias "%s" is not unique in FROM and JOIN clause table. '
. 'The currently registered aliases are: %s.',
$alias,
implode(', ', $registeredAliases)
......
......@@ -17,7 +17,7 @@ final class UnknownAlias extends QueryException
{
return new self(
sprintf(
"The given alias '%s' is not part of any FROM or JOIN clause table. "
'The given alias "%s" is not part of any FROM or JOIN clause table. '
. 'The currently registered aliases are: %s.',
$alias,
implode(', ', $registeredAliases)
......
......@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Doctrine\DBAL;
use Doctrine\DBAL\Exception\MissingSQLParam;
use Doctrine\DBAL\Exception\MissingSQLType;
use Doctrine\DBAL\Exception\MissingArrayParameter;
use Doctrine\DBAL\Exception\MissingArrayParameterType;
use const PREG_OFFSET_CAPTURE;
use function array_fill;
use function array_key_exists;
......@@ -287,9 +287,9 @@ class SQLParserUtils
}
if ($isParam) {
throw MissingSQLParam::new($paramName);
throw MissingArrayParameter::new($paramName);
}
throw MissingSQLType::new($paramName);
throw MissingArrayParameterType::new($paramName);
}
}
......@@ -12,7 +12,7 @@ final class ColumnAlreadyExists extends SchemaException
public static function new(string $tableName, string $columnName) : self
{
return new self(
sprintf("The column '%s' on table '%s' already exists.", $columnName, $tableName),
sprintf('The column "%s" on table "%s" already exists.', $columnName, $tableName),
self::COLUMN_ALREADY_EXISTS
);
}
......
......@@ -12,7 +12,7 @@ final class ColumnDoesNotExist extends SchemaException
public static function new(string $columnName, string $table) : self
{
return new self(
sprintf("There is no column with name '%s' on table '%s'.", $columnName, $table),
sprintf('There is no column with name "%s" on table "%s".', $columnName, $table),
self::COLUMN_DOESNT_EXIST
);
}
......
......@@ -12,7 +12,7 @@ final class ForeignKeyDoesNotExist extends SchemaException
public static function new(string $foreignKeyName, string $table) : self
{
return new self(
sprintf("There exists no foreign key with the name '%s' on table '%s'.", $foreignKeyName, $table),
sprintf('There exists no foreign key with the name "%s" on table "%s".', $foreignKeyName, $table),
self::FOREIGNKEY_DOESNT_EXIST
);
}
......
......@@ -12,7 +12,7 @@ final class IndexAlreadyExists extends SchemaException
public static function new(string $indexName, string $table) : self
{
return new self(
sprintf("An index with name '%s' was already defined on table '%s'.", $indexName, $table),
sprintf('An index with name "%s" was already defined on table "%s".', $indexName, $table),
self::INDEX_ALREADY_EXISTS
);
}
......
......@@ -12,7 +12,7 @@ final class IndexDoesNotExist extends SchemaException
public static function new(string $indexName, string $table) : self
{
return new self(
sprintf("Index '%s' does not exist on table '%s'.", $indexName, $table),
sprintf('Index "%s" does not exist on table "%s".', $indexName, $table),
self::INDEX_DOESNT_EXIST
);
}
......
......@@ -12,7 +12,7 @@ final class IndexNameInvalid extends SchemaException
public static function new(string $indexName) : self
{
return new self(
sprintf('Invalid index-name %s given, has to be [a-zA-Z0-9_]', $indexName),
sprintf('Invalid index name "%s" given, has to be [a-zA-Z0-9_].', $indexName),
self::INDEX_INVALID_NAME
);
}
......
......@@ -11,6 +11,6 @@ final class InvalidTableName extends SchemaException
{
public static function new(string $tableName) : self
{
return new self(sprintf('Invalid table name specified: %s', $tableName));
return new self(sprintf('Invalid table name specified "%s".', $tableName));
}
}
......@@ -16,8 +16,8 @@ final class NamedForeignKeyRequired extends SchemaException
{
return new self(
sprintf(
'The performed schema operation on %s requires a named foreign key, ' .
"but the given foreign key from (%s) onto foreign table '%s' (%s) is currently unnamed.",
'The performed schema operation on "%s" requires a named foreign key, ' .
'but the given foreign key from (%s) onto foreign table "%s" (%s) is currently unnamed.',
$localTable->getName(),
implode(', ', $foreignKey->getColumns()),
$foreignKey->getForeignTableName(),
......
......@@ -12,7 +12,7 @@ final class NamespaceAlreadyExists extends SchemaException
public static function new(string $namespaceName) : self
{
return new self(
sprintf("The namespace with name '%s' already exists.", $namespaceName),
sprintf('The namespace with name "%s" already exists.', $namespaceName),
self::NAMESPACE_ALREADY_EXISTS
);
}
......
......@@ -12,7 +12,7 @@ final class SequenceAlreadyExists extends SchemaException
public static function new(string $sequenceName) : self
{
return new self(
sprintf("The sequence '%s' already exists.", $sequenceName),
sprintf('The sequence "%s" already exists.', $sequenceName),
self::SEQUENCE_ALREADY_EXISTS
);
}
......
......@@ -12,7 +12,7 @@ final class SequenceDoesNotExist extends SchemaException
public static function new(string $sequenceName) : self
{
return new self(
sprintf("There exists no sequence with the name '%s'.", $sequenceName),
sprintf('There exists no sequence with the name "%s".', $sequenceName),
self::SEQUENCE_DOENST_EXIST
);
}
......
......@@ -12,7 +12,7 @@ final class TableAlreadyExists extends SchemaException
public static function new(string $tableName) : self
{
return new self(
sprintf("The table with name '%s' already exists.", $tableName),
sprintf('The table with name "%s" already exists.', $tableName),
self::TABLE_ALREADY_EXISTS
);
}
......
......@@ -12,7 +12,7 @@ final class TableDoesNotExist extends SchemaException
public static function new(string $tableName) : self
{
return new self(
sprintf("There is no table with name '%s' in the schema.", $tableName),
sprintf('There is no table with name "%s" in the schema.', $tableName),
self::TABLE_DOESNT_EXIST
);
}
......
......@@ -12,7 +12,7 @@ final class UniqueConstraintDoesNotExist extends SchemaException
public static function new(string $constraintName, string $table) : self
{
return new self(
sprintf("There exists no unique constraint with the name '%s' on table '%s'.", $constraintName, $table),
sprintf('There exists no unique constraint with the name "%s" on table "%s".', $constraintName, $table),
self::CONSTRAINT_DOESNT_EXIST
);
}
......
......@@ -22,6 +22,7 @@ use function array_unique;
use function in_array;
use function is_string;
use function preg_match;
use function sprintf;
use function strlen;
use function strtolower;
use function uksort;
......@@ -651,7 +652,7 @@ class Table extends AbstractAsset
$primaryKey = $this->getPrimaryKey();
if ($primaryKey === null) {
throw new DBALException('Table ' . $this->getName() . ' has no primary key.');
throw new DBALException(sprintf('Table "%s" has no primary key.', $this->getName()));
}
return $primaryKey->getColumns();
......
......@@ -5,10 +5,8 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use InvalidArgumentException;
use function array_keys;
use function array_map;
use function is_string;
use function strtolower;
/**
......@@ -168,19 +166,8 @@ class UniqueConstraint extends AbstractAsset implements Constraint
return $this->options;
}
/**
* @param string $column
*
* @return void
*
* @throws InvalidArgumentException
*/
protected function _addColumn($column)
protected function _addColumn(string $column) : void
{
if (! is_string($column)) {
throw new InvalidArgumentException('Expecting a string as Index Column');
}
$this->columns[$column] = new Identifier($column);
}
}
......@@ -10,6 +10,6 @@ final class MissingDistributionType extends ShardingException
{
public static function new() : self
{
return new self("You have to specify a sharding distribution type such as 'integer', 'string', 'guid'.");
return new self('You have to specify a sharding distribution type such as "integer", "string", "guid".');
}
}
......@@ -16,6 +16,7 @@ use InvalidArgumentException;
use function array_merge;
use function is_numeric;
use function is_string;
use function sprintf;
/**
* Sharding implementation that pools many different connections
......@@ -69,11 +70,11 @@ class PoolingShardConnection extends Connection
public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null)
{
if (! isset($params['global'], $params['shards'])) {
throw new InvalidArgumentException("Connection Parameters require 'global' and 'shards' configurations.");
throw new InvalidArgumentException('Connection Parameters require "global" and "shards" configurations.');
}
if (! isset($params['shardChoser'])) {
throw new InvalidArgumentException("Missing Shard Choser configuration 'shardChoser'");
throw new InvalidArgumentException('Missing Shard Choser configuration "shardChoser".');
}
if (is_string($params['shardChoser'])) {
......@@ -81,14 +82,14 @@ class PoolingShardConnection extends Connection
}
if (! ($params['shardChoser'] instanceof ShardChoser)) {
throw new InvalidArgumentException("The 'shardChoser' configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser");
throw new InvalidArgumentException('The "shardChoser" configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser');
}
$this->connectionParameters[0] = array_merge($params, $params['global']);
foreach ($params['shards'] as $shard) {
if (! isset($shard['id'])) {
throw new InvalidArgumentException("Missing 'id' for one configured shard. Please specify a unique shard-id.");
throw new InvalidArgumentException('Missing "id" for one configured shard. Please specify a unique shard-id.');
}
if (! is_numeric($shard['id']) || $shard['id'] < 1) {
......@@ -96,7 +97,7 @@ class PoolingShardConnection extends Connection
}
if (isset($this->connectionParameters[$shard['id']])) {
throw new InvalidArgumentException('Shard ' . $shard['id'] . ' is duplicated in the configuration.');
throw new InvalidArgumentException(sprintf('Shard "%s" is duplicated in the configuration.', $shard['id']));
}
$this->connectionParameters[$shard['id']] = array_merge($params, $shard);
......
......@@ -173,7 +173,7 @@ class SQLAzureShardManager implements ShardManager
{
$shards = $this->getShards();
if (! $shards) {
throw new RuntimeException('No shards found for ' . $this->federationName);
throw new RuntimeException(sprintf('No shards found for "%s".', $this->federationName));
}
$result = [];
......
......@@ -13,6 +13,7 @@ use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Visitor\Visitor;
use RuntimeException;
use function in_array;
use function sprintf;
/**
* Converts a single tenant schema into a multi-tenant schema for SQL Azure
......@@ -110,7 +111,7 @@ class MultiTenantVisitor implements Visitor
return $index;
}
}
throw new RuntimeException('No clustered index found on table ' . $table->getName());
throw new RuntimeException(sprintf('No clustered index found on table "%s".', $table->getName()));
}
/**
......
......@@ -26,6 +26,7 @@ use Symfony\Component\Console\Output\OutputInterface;
use function array_keys;
use function count;
use function implode;
use function sprintf;
class ReservedWordsCommand extends Command
{
......@@ -121,10 +122,11 @@ EOT
$keywords = [];
foreach ($keywordLists as $keywordList) {
if (! isset($this->keywordListClasses[$keywordList])) {
throw new InvalidArgumentException(
"There exists no keyword list with name '" . $keywordList . "'. " .
'Known lists: ' . implode(', ', array_keys($this->keywordListClasses))
);
throw new InvalidArgumentException(sprintf(
'There exists no keyword list with name "%s". Known lists: %s',
$keywordList,
implode(', ', array_keys($this->keywordListClasses))
));
}
$class = $this->keywordListClasses[$keywordList];
$keywords[] = new $class();
......
......@@ -52,7 +52,7 @@ EOT
$sql = $input->getArgument('sql');
if ($sql === null) {
throw new RuntimeException("Argument 'SQL' is required in order to execute this command correctly.");
throw new RuntimeException('Argument "sql" is required in order to execute this command correctly.');
}
assert(is_string($sql));
......@@ -60,7 +60,7 @@ EOT
$depth = $input->getOption('depth');
if (! is_numeric($depth)) {
throw new LogicException("Option 'depth' must contains an integer value");
throw new LogicException('Option "depth" must contains an integer value.');
}
if (stripos($sql, 'select') === 0 || $input->getOption('force-fetch')) {
......
......@@ -24,7 +24,7 @@ final class InvalidFormat extends ConversionException implements TypesException
) : self {
return new self(
sprintf(
'Could not convert database value "%s" to Doctrine Type %s. Expected format: %s',
'Could not convert database value "%s" to Doctrine Type %s. Expected format "%s".',
strlen($value) > 32 ? substr($value, 0, 20) . '...' : $value,
$toType,
$expectedFormat ?? ''
......
......@@ -31,7 +31,7 @@ final class InvalidType extends ConversionException implements TypesException
if (is_scalar($value)) {
return new self(
sprintf(
"Could not convert PHP value '%s' of type '%s' to type '%s'. Expected one of the following types: %s",
'Could not convert PHP value "%s" of type "%s" to type "%s". Expected one of the following types: %s.',
$value,
$actualType,
$toType,
......@@ -42,7 +42,7 @@ final class InvalidType extends ConversionException implements TypesException
return new self(
sprintf(
"Could not convert PHP value of type '%s' to type '%s'. Expected one of the following types: %s",
'Could not convert PHP value of type "%s" to type "%s". Expected one of the following types: %s.',
$actualType,
$toType,
implode(', ', $possibleTypes)
......
......@@ -21,7 +21,7 @@ final class SerializationFailed extends ConversionException implements TypesExce
return new self(
sprintf(
"Could not convert PHP type '%s' to '%s', as an '%s' error was triggered by the serialization",
'Could not convert PHP type "%s" to "%s". An error was triggered by the serialization: %s',
$actualType,
$format,
$error
......
......@@ -11,6 +11,6 @@ final class TypeNotFound extends DBALException implements TypesException
{
public static function new(string $name) : self
{
return new self(sprintf('Type to be overwritten %s does not exist.', $name));
return new self(sprintf('Type to be overwritten "%s" does not exist.', $name));
}
}
......@@ -11,6 +11,6 @@ final class TypesAlreadyExists extends DBALException implements TypesException
{
public static function new(string $name) : self
{
return new self(sprintf('Type %s already exists.', $name));
return new self(sprintf('Type "%s" already exists.', $name));
}
}
......@@ -20,7 +20,7 @@ final class ValueNotConvertible extends ConversionException implements TypesExce
if ($message !== null) {
return new self(
sprintf(
"Could not convert database value to '%s' as an error was triggered by the unserialization: '%s'",
'Could not convert database value to "%s" as an error was triggered by the unserialization: %s',
$toType,
$message
)
......@@ -29,7 +29,7 @@ final class ValueNotConvertible extends ConversionException implements TypesExce
return new self(
sprintf(
'Could not convert database value "%s" to Doctrine Type %s',
'Could not convert database value "%s" to Doctrine Type "%s".',
is_string($value) && strlen($value) > 32 ? substr($value, 0, 20) . '...' : $value,
$toType
)
......
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Cache;
use Doctrine\DBAL\Cache\ArrayStatement;
use Doctrine\DBAL\FetchMode;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use function array_values;
use function iterator_to_array;
class ArrayStatementTest extends TestCase
{
/** @var array<int, array<string, mixed>> */
private $users = [
[
'username' => 'jwage',
'active' => true,
],
[
'username' => 'romanb',
'active' => false,
],
];
public function testCloseCursor() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame(2, $statement->rowCount());
$statement->closeCursor();
self::assertSame(0, $statement->rowCount());
}
public function testColumnCount() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame(2, $statement->columnCount());
}
public function testRowCount() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame(2, $statement->rowCount());
}
public function testSetFetchMode() : void
{
$statement = $this->createTestArrayStatement();
$statement->setFetchMode(FetchMode::ASSOCIATIVE);
self::assertSame($this->users[0], $statement->fetch());
}
public function testSetFetchModeThrowsInvalidArgumentException() : void
{
$statement = $this->createTestArrayStatement();
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('Caching layer does not support 2nd/3rd argument to setFetchMode().');
$statement->setFetchMode(FetchMode::ASSOCIATIVE, 'arg1', 'arg2');
}
public function testGetIterator() : void
{
$statement = $this->createTestArrayStatement();
$statement->setFetchMode(FetchMode::ASSOCIATIVE);
self::assertSame($this->users, iterator_to_array($statement->getIterator()));
}
public function testFetchModeAssociative() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame($this->users[0], $statement->fetch(FetchMode::ASSOCIATIVE));
}
public function testFetchModeNumeric() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame(array_values($this->users[0]), $statement->fetch(FetchMode::NUMERIC));
}
public function testFetchModeMixed() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame([
'username' => 'jwage',
'active' => true,
0 => 'jwage',
1 => true,
], $statement->fetch(FetchMode::MIXED));
}
public function testFetchModeColumn() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame('jwage', $statement->fetch(FetchMode::COLUMN));
}
public function testFetchThrowsInvalidArgumentException() : void
{
$statement = $this->createTestArrayStatement();
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('Invalid fetch mode given for fetching result, 9999 given.');
$statement->fetch(9999);
}
public function testFetchAll() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame($this->users, $statement->fetchAll(FetchMode::ASSOCIATIVE));
}
public function testFetchColumn() : void
{
$statement = $this->createTestArrayStatement();
self::assertSame('jwage', $statement->fetchColumn(0));
self::assertSame('romanb', $statement->fetchColumn(0));
$statement = $this->createTestArrayStatement();
self::assertSame(true, $statement->fetchColumn(1));
self::assertSame(false, $statement->fetchColumn(1));
}
private function createTestArrayStatement() : ArrayStatement
{
return new ArrayStatement($this->users);
}
}
......@@ -190,7 +190,7 @@ class ConnectionTest extends DbalTestCase
public function testDriverExceptionIsWrapped(string $method) : void
{
$this->expectException(DBALException::class);
$this->expectExceptionMessage("An exception occurred while executing 'MUUHAAAAHAAAA':\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
$this->expectExceptionMessage("An exception occurred while executing \"MUUHAAAAHAAAA\":\n\nSQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
$connection = DriverManager::getConnection([
'driver' => 'pdo_sqlite',
......
......@@ -56,8 +56,8 @@ class DBALExceptionTest extends DbalTestCase
self::assertInstanceOf(DBALException::class, $exception);
self::assertSame(
sprintf(
"The options 'driver' or 'driverClass' are mandatory if a connection URL without scheme " .
'is given to DriverManager::getConnection(). Given URL: %s',
'The options "driver" or "driverClass" are mandatory if a connection URL without scheme ' .
'is given to DriverManager::getConnection(). Given URL "%s".',
$url
),
$exception->getMessage()
......@@ -72,7 +72,7 @@ class DBALExceptionTest extends DbalTestCase
$exception = InvalidPlatformType::new(new stdClass());
self::assertSame(
"Option 'platform' must be a subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform', instance of 'stdClass' given",
'Option "platform" must be a subtype of Doctrine\DBAL\Platforms\AbstractPlatform, instance of stdClass given.',
$exception->getMessage()
);
}
......@@ -85,7 +85,7 @@ class DBALExceptionTest extends DbalTestCase
$exception = InvalidPlatformType::new('some string');
self::assertSame(
"Option 'platform' must be an object and subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform'. Got 'string'",
'Option "platform" must be an object and subtype of Doctrine\DBAL\Platforms\AbstractPlatform. Got string.',
$exception->getMessage()
);
}
......
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Driver\Mysqli\Exception;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType;
use PHPUnit\Framework\TestCase;
final class UnknownTypeTest extends TestCase
{
public function testNew() : void
{
$exception = UnknownType::new('9999');
self::assertSame('Unknown type, 9999 given.', $exception->getMessage());
}
}
......@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\MysqliConnection;
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\Tests\DbalFunctionalTestCase;
use PHPUnit\Framework\MockObject\MockObject;
......@@ -54,7 +54,7 @@ class MysqliConnectionTest extends DbalFunctionalTestCase
try {
new MysqliConnection(['host' => '255.255.255.255'], 'user', 'pass');
self::fail('An exception was supposed to be raised');
} catch (MysqliException $e) {
} catch (ConnectionError $e) {
// Do nothing
}
......
......@@ -110,15 +110,15 @@ class OCI8StatementTest extends DbalTestCase
return [
'no-matching-quote' => [
"SELECT 'literal FROM DUAL",
'/offset 7/',
'/offset 7./',
],
'no-matching-double-quote' => [
'SELECT 1 "COL1 FROM DUAL',
'/offset 9/',
'/offset 9./',
],
'incorrect-escaping-syntax' => [
"SELECT 'quoted \\'string' FROM DUAL",
'/offset 23/',
'/offset 23./',
],
];
}
......
......@@ -19,8 +19,8 @@ class DriverRequiredTest extends TestCase
self::assertInstanceOf(DBALException::class, $exception);
self::assertSame(
sprintf(
"The options 'driver' or 'driverClass' are mandatory if a connection URL without scheme " .
'is given to DriverManager::getConnection(). Given URL: %s',
'The options "driver" or "driverClass" are mandatory if a connection URL without scheme ' .
'is given to DriverManager::getConnection(). Given URL "%s".',
$url
),
$exception->getMessage()
......
......@@ -15,6 +15,6 @@ class EmptyCriteriaNotAllowedTest extends TestCase
$exception = EmptyCriteriaNotAllowed::new();
self::assertInstanceOf(InvalidArgumentException::class, $exception);
self::assertSame('Empty criteria was used, expected non-empty criteria', $exception->getMessage());
self::assertSame('Empty criteria was used, expected non-empty criteria.', $exception->getMessage());
}
}
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Exception;
use Doctrine\DBAL\Exception\GetVariableType;
use PHPUnit\Framework\TestCase;
use stdClass;
use function tmpfile;
class GetVariableTypeTest extends TestCase
{
/**
* @param mixed $value
*
* @dataProvider provideDataForFormatVariable
*/
public function testFormatVariable(string $expected, $value) : void
{
self::assertSame($expected, (new GetVariableType())->__invoke($value));
}
/**
* @return array<int, array<int, mixed>>
*/
public function provideDataForFormatVariable() : array
{
return [
['string', ''],
['string', 'test'],
['double', 1.0],
['integer', 1],
['NULL', null],
['stdClass', new stdClass()],
['stream', tmpfile()],
['true', true],
['false', false],
['array', [true, 1, 2, 3, 'test']],
];
}
}
......@@ -18,7 +18,7 @@ class InvalidPlatformTypeTest extends TestCase
$exception = InvalidPlatformType::new(new stdClass());
self::assertSame(
"Option 'platform' must be a subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform', instance of 'stdClass' given",
'Option "platform" must be a subtype of Doctrine\DBAL\Platforms\AbstractPlatform, instance of stdClass given.',
$exception->getMessage()
);
}
......@@ -31,7 +31,7 @@ class InvalidPlatformTypeTest extends TestCase
$exception = InvalidPlatformType::new('some string');
self::assertSame(
"Option 'platform' must be an object and subtype of 'Doctrine\DBAL\Platforms\AbstractPlatform'. Got 'string'",
'Option "platform" must be an object and subtype of Doctrine\DBAL\Platforms\AbstractPlatform. Got string.',
$exception->getMessage()
);
}
......
......@@ -330,7 +330,7 @@ class ExceptionTest extends DbalFunctionalTestCase
$this->expectException(Exception\ReadOnlyException::class);
$this->expectExceptionMessage(
<<<EOT
An exception occurred while executing 'CREATE TABLE no_connection (id INTEGER NOT NULL)':
An exception occurred while executing "CREATE TABLE no_connection (id INTEGER NOT NULL)":
SQLSTATE[HY000]: General error: 8 attempt to write a readonly database
EOT
......
......@@ -32,7 +32,7 @@ class PDOStatementTest extends DbalFunctionalTestCase
/**
* @group legacy
* @expectedDeprecation Using a PDO fetch mode or their combination (%d given) is deprecated and will cause an error in Doctrine 3.0
* @expectedDeprecation Using a PDO fetch mode or their combination (%d given) is deprecated and will cause an error in Doctrine 3.0.
*/
public function testPDOSpecificModeIsAccepted() : void
{
......
......@@ -1297,7 +1297,7 @@ abstract class AbstractPlatformTestCase extends DbalTestCase
}
$this->expectException(DBALException::class);
$this->expectExceptionMessage("Operation 'Doctrine\\DBAL\\Platforms\\AbstractPlatform::getInlineColumnCommentSQL' is not supported by platform.");
$this->expectExceptionMessage('Operation "Doctrine\\DBAL\\Platforms\\AbstractPlatform::getInlineColumnCommentSQL" is not supported by platform.');
$this->expectExceptionCode(0);
$this->platform->getInlineColumnCommentSQL('unsupported');
......
......@@ -503,7 +503,7 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
$platform = $this->createPlatform();
$this->expectException(UnexpectedValueException::class);
$this->expectExceptionMessage("Unrecognized boolean literal 'my-bool'");
$this->expectExceptionMessage('Unrecognized boolean literal, my-bool given.');
$platform->convertBooleansToDatabaseValue('my-bool');
}
......
......@@ -684,7 +684,7 @@ class QueryBuilderTest extends DbalTestCase
->where('nt.lang = :lang AND n.deleted != 1');
$this->expectException(QueryException::class);
$this->expectExceptionMessage("The given alias 'invalid' is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.");
$this->expectExceptionMessage('The given alias "invalid" is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.');
self::assertEquals('', $qb->getSQL());
}
......@@ -937,7 +937,7 @@ class QueryBuilderTest extends DbalTestCase
->join('a', 'table_b', 'a', 'a.fk_b = a.id');
$this->expectException(QueryException::class);
$this->expectExceptionMessage("The given alias 'a' is not unique in FROM and JOIN clause table. The currently registered aliases are: a.");
$this->expectExceptionMessage('The given alias "a" is not unique in FROM and JOIN clause table. The currently registered aliases are: a.');
$qb->getSQL();
}
......
......@@ -70,7 +70,7 @@ class SQLParserUtilsTest extends DbalTestCase
['SELECT table.field1, ARRAY[:foo]::integer[] FROM schema.table table WHERE table.f1 = :bar AND ARRAY[\'3\']::integer[]', false, [27 => 'foo', 85 => 'bar']],
[
<<<'SQLDATA'
SELECT * FROM foo WHERE
SELECT * FROM foo WHERE
bar = ':not_a_param1 ''":not_a_param2"'''
OR bar=:a_param1
OR bar=:a_param2||':not_a_param3'
......@@ -81,9 +81,9 @@ SQLDATA
,
false,
[
74 => 'a_param1',
91 => 'a_param2',
190 => 'a_param3',
73 => 'a_param1',
90 => 'a_param2',
189 => 'a_param3',
],
],
["SELECT data.age AS age, data.id AS id, data.name AS name, data.id AS id FROM test_data data WHERE (data.description LIKE :condition_0 ESCAPE '\\\\') AND (data.description LIKE :condition_1 ESCAPE '\\\\') ORDER BY id ASC", false, [121 => 'condition_0', 174 => 'condition_1']],
......@@ -493,7 +493,7 @@ SQLDATA
public function testExceptionIsThrownForMissingParam(string $query, array $params, array $types = []) : void
{
$this->expectException(SQLParserUtilsException::class);
$this->expectExceptionMessage('Value for :param not found in params array. Params array key should be "param"');
$this->expectExceptionMessage('Parameter "param" is missing.');
SQLParserUtils::expandListParameters($query, $params, $types);
}
......
......@@ -8,6 +8,7 @@ use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Sharding\PoolingShardConnection;
use Doctrine\DBAL\Sharding\ShardChoser\MultiTenantShardChoser;
use Doctrine\DBAL\Sharding\ShardingException;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use stdClass;
......@@ -52,8 +53,8 @@ class PoolingShardConnectionTest extends TestCase
public function testNoGlobalServerException() : void
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("Connection Parameters require 'global' and 'shards' configurations.");
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Connection Parameters require "global" and "shards" configurations.');
DriverManager::getConnection([
'wrapperClass' => PoolingShardConnection::class,
......@@ -68,8 +69,8 @@ class PoolingShardConnectionTest extends TestCase
public function testNoShardsServersException() : void
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("Connection Parameters require 'global' and 'shards' configurations.");
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Connection Parameters require "global" and "shards" configurations.');
DriverManager::getConnection([
'wrapperClass' => PoolingShardConnection::class,
......@@ -81,8 +82,8 @@ class PoolingShardConnectionTest extends TestCase
public function testNoShardsChoserException() : void
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("Missing Shard Choser configuration 'shardChoser'");
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Missing Shard Choser configuration "shardChoser".');
DriverManager::getConnection([
'wrapperClass' => PoolingShardConnection::class,
......@@ -97,8 +98,8 @@ class PoolingShardConnectionTest extends TestCase
public function testShardChoserWrongInstance() : void
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("The 'shardChoser' configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser");
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The "shardChoser" configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser');
DriverManager::getConnection([
'wrapperClass' => PoolingShardConnection::class,
......@@ -130,8 +131,8 @@ class PoolingShardConnectionTest extends TestCase
public function testShardMissingId() : void
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage("Missing 'id' for one configured shard. Please specify a unique shard-id.");
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Missing "id" for one configured shard. Please specify a unique shard-id.');
DriverManager::getConnection([
'wrapperClass' => PoolingShardConnection::class,
......@@ -146,8 +147,8 @@ class PoolingShardConnectionTest extends TestCase
public function testDuplicateShardId() : void
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('Shard 1 is duplicated in the configuration.');
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Shard "1" is duplicated in the configuration.');
DriverManager::getConnection([
'wrapperClass' => PoolingShardConnection::class,
......
......@@ -43,29 +43,25 @@ class RunSqlCommandTest extends TestCase
public function testMissingSqlArgument() : void
{
try {
$this->commandTester->execute([
'command' => $this->command->getName(),
'sql' => null,
]);
$this->fail('Expected a runtime exception when omitting sql argument');
} catch (RuntimeException $e) {
self::assertStringContainsString("Argument 'SQL", $e->getMessage());
}
self::expectException(RuntimeException::class);
self::expectExceptionMessage('Argument "sql" is required in order to execute this command correctly.');
$this->commandTester->execute([
'command' => $this->command->getName(),
'sql' => null,
]);
}
public function testIncorrectDepthOption() : void
{
try {
$this->commandTester->execute([
'command' => $this->command->getName(),
'sql' => 'SELECT 1',
'--depth' => 'string',
]);
$this->fail('Expected a logic exception when executing with a stringy depth');
} catch (LogicException $e) {
self::assertStringContainsString("Option 'depth'", $e->getMessage());
}
self::expectException(LogicException::class);
self::expectExceptionMessage('Option "depth" must contains an integer value.');
$this->commandTester->execute([
'command' => $this->command->getName(),
'sql' => 'SELECT 1',
'--depth' => 'string',
]);
}
public function testSelectStatementsPrintsResult() : void
......
......@@ -39,7 +39,7 @@ class ArrayTest extends DbalTestCase
public function testConversionFailure() : void
{
$this->expectException(ConversionException::class);
$this->expectExceptionMessage("Could not convert database value to 'array' as an error was triggered by the unserialization: 'unserialize(): Error at offset 0 of 7 bytes'");
$this->expectExceptionMessage('Could not convert database value to "array" as an error was triggered by the unserialization: unserialize(): Error at offset 0 of 7 bytes');
$this->type->convertToPHPValue('abcdefg', $this->platform);
}
......
......@@ -10,6 +10,10 @@ use Doctrine\DBAL\Types\Exception\InvalidType;
use Exception;
use PHPUnit\Framework\TestCase;
use stdClass;
use function get_class;
use function gettype;
use function is_object;
use function sprintf;
use function tmpfile;
class ConversionExceptionTest extends TestCase
......@@ -23,10 +27,15 @@ class ConversionExceptionTest extends TestCase
{
$exception = InvalidType::new($scalarValue, 'foo', ['bar', 'baz']);
$type = is_object($scalarValue) ? get_class($scalarValue) : gettype($scalarValue);
self::assertInstanceOf(ConversionException::class, $exception);
self::assertRegExp(
'/^Could not convert PHP value \'.*\' of type \'(string|boolean|float|double|integer)\' to type \'foo\'. '
. 'Expected one of the following types: bar, baz$/',
self::assertSame(
sprintf(
'Could not convert PHP value "%s" of type "%s" to type "foo". Expected one of the following types: bar, baz.',
$scalarValue,
$type
),
$exception->getMessage()
);
}
......@@ -40,10 +49,11 @@ class ConversionExceptionTest extends TestCase
{
$exception = InvalidType::new($nonScalar, 'foo', ['bar', 'baz']);
$type = is_object($nonScalar) ? get_class($nonScalar) : gettype($nonScalar);
self::assertInstanceOf(ConversionException::class, $exception);
self::assertRegExp(
'/^Could not convert PHP value of type \'(.*)\' to type \'foo\'. '
. 'Expected one of the following types: bar, baz$/',
self::assertSame(
sprintf('Could not convert PHP value of type "%s" to type "foo". Expected one of the following types: bar, baz.', $type),
$exception->getMessage()
);
}
......
<?php
declare(strict_types=1);
namespace Doctrine\Tests\DBAL\Types\Exception;
use Doctrine\DBAL\Types\Exception\SerializationFailed;
use PHPUnit\Framework\TestCase;
use const NAN;
use function json_encode;
use function json_last_error_msg;
class SerializationFailedTest extends TestCase
{
public function testNew() : void
{
$value = NAN;
$encoded = json_encode($value);
$exception = SerializationFailed::new($value, 'json', json_last_error_msg());
self::assertSame(
'Could not convert PHP type "double" to "json". An error was triggered by the serialization: Inf and NaN cannot be JSON encoded',
$exception->getMessage()
);
}
}
......@@ -40,7 +40,7 @@ class ObjectTest extends DbalTestCase
public function testConversionFailure() : void
{
$this->expectException(ConversionException::class);
$this->expectExceptionMessage("Could not convert database value to 'object' as an error was triggered by the unserialization: 'unserialize(): Error at offset 0 of 7 bytes'");
$this->expectExceptionMessage('Could not convert database value to "object" as an error was triggered by the unserialization: unserialize(): Error at offset 0 of 7 bytes');
$this->type->convertToPHPValue('abcdefg', $this->platform);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment