1<?php 2 3namespace Doctrine\DBAL; 4 5use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException; 6use Doctrine\DBAL\Driver\ExceptionConverterDriver; 7use Doctrine\DBAL\Exception\DriverException; 8use Doctrine\DBAL\Platforms\AbstractPlatform; 9use Doctrine\DBAL\Types\Type; 10use Throwable; 11 12use function array_map; 13use function bin2hex; 14use function get_class; 15use function gettype; 16use function implode; 17use function is_object; 18use function is_resource; 19use function is_string; 20use function json_encode; 21use function preg_replace; 22use function spl_object_hash; 23use function sprintf; 24 25/** 26 * @deprecated Use {@link Exception} instead 27 * 28 * @psalm-immutable 29 */ 30class DBALException extends \Exception 31{ 32 /** 33 * @param string $method 34 * 35 * @return Exception 36 */ 37 public static function notSupported($method) 38 { 39 return new Exception(sprintf("Operation '%s' is not supported by platform.", $method)); 40 } 41 42 /** 43 * @deprecated Use {@link invalidPlatformType()} instead. 44 */ 45 public static function invalidPlatformSpecified(): self 46 { 47 return new Exception( 48 "Invalid 'platform' option specified, need to give an instance of " . AbstractPlatform::class . '.' 49 ); 50 } 51 52 /** 53 * @param mixed $invalidPlatform 54 */ 55 public static function invalidPlatformType($invalidPlatform): self 56 { 57 if (is_object($invalidPlatform)) { 58 return new Exception( 59 sprintf( 60 "Option 'platform' must be a subtype of '%s', instance of '%s' given", 61 AbstractPlatform::class, 62 get_class($invalidPlatform) 63 ) 64 ); 65 } 66 67 return new Exception( 68 sprintf( 69 "Option 'platform' must be an object and subtype of '%s'. Got '%s'", 70 AbstractPlatform::class, 71 gettype($invalidPlatform) 72 ) 73 ); 74 } 75 76 /** 77 * Returns a new instance for an invalid specified platform version. 78 * 79 * @param string $version The invalid platform version given. 80 * @param string $expectedFormat The expected platform version format. 81 * 82 * @return Exception 83 */ 84 public static function invalidPlatformVersionSpecified($version, $expectedFormat) 85 { 86 return new Exception( 87 sprintf( 88 'Invalid platform version "%s" specified. ' . 89 'The platform version has to be specified in the format: "%s".', 90 $version, 91 $expectedFormat 92 ) 93 ); 94 } 95 96 /** 97 * @deprecated Passing a PDO instance in connection parameters is deprecated. 98 * 99 * @return Exception 100 */ 101 public static function invalidPdoInstance() 102 { 103 return new Exception( 104 "The 'pdo' option was used in DriverManager::getConnection() but no " . 105 'instance of PDO was given.' 106 ); 107 } 108 109 /** 110 * @param string|null $url The URL that was provided in the connection parameters (if any). 111 * 112 * @return Exception 113 */ 114 public static function driverRequired($url = null) 115 { 116 if ($url) { 117 return new Exception( 118 sprintf( 119 "The options 'driver' or 'driverClass' are mandatory if a connection URL without scheme " . 120 'is given to DriverManager::getConnection(). Given URL: %s', 121 $url 122 ) 123 ); 124 } 125 126 return new Exception("The options 'driver' or 'driverClass' are mandatory if no PDO " . 127 'instance is given to DriverManager::getConnection().'); 128 } 129 130 /** 131 * @param string $unknownDriverName 132 * @param string[] $knownDrivers 133 * 134 * @return Exception 135 */ 136 public static function unknownDriver($unknownDriverName, array $knownDrivers) 137 { 138 return new Exception("The given 'driver' " . $unknownDriverName . ' is unknown, ' . 139 'Doctrine currently supports only the following drivers: ' . implode(', ', $knownDrivers)); 140 } 141 142 /** 143 * @deprecated 144 * 145 * @param string $sql 146 * @param mixed[] $params 147 * 148 * @return Exception 149 */ 150 public static function driverExceptionDuringQuery(Driver $driver, Throwable $driverEx, $sql, array $params = []) 151 { 152 $msg = "An exception occurred while executing '" . $sql . "'"; 153 if ($params) { 154 $msg .= ' with params ' . self::formatParameters($params); 155 } 156 157 $msg .= ":\n\n" . $driverEx->getMessage(); 158 159 return self::wrapException($driver, $driverEx, $msg); 160 } 161 162 /** 163 * @deprecated 164 * 165 * @return Exception 166 */ 167 public static function driverException(Driver $driver, Throwable $driverEx) 168 { 169 return self::wrapException($driver, $driverEx, 'An exception occurred in driver: ' . $driverEx->getMessage()); 170 } 171 172 /** 173 * @return Exception 174 */ 175 private static function wrapException(Driver $driver, Throwable $driverEx, string $msg) 176 { 177 if ($driverEx instanceof DriverException) { 178 return $driverEx; 179 } 180 181 if ($driver instanceof ExceptionConverterDriver && $driverEx instanceof DeprecatedDriverException) { 182 return $driver->convertException($msg, $driverEx); 183 } 184 185 return new Exception($msg, 0, $driverEx); 186 } 187 188 /** 189 * Returns a human-readable representation of an array of parameters. 190 * This properly handles binary data by returning a hex representation. 191 * 192 * @param mixed[] $params 193 * 194 * @return string 195 */ 196 private static function formatParameters(array $params) 197 { 198 return '[' . implode(', ', array_map(static function ($param) { 199 if (is_resource($param)) { 200 return (string) $param; 201 } 202 203 $json = @json_encode($param); 204 205 if (! is_string($json) || $json === 'null' && is_string($param)) { 206 // JSON encoding failed, this is not a UTF-8 string. 207 return sprintf('"%s"', preg_replace('/.{2}/', '\\x$0', bin2hex($param))); 208 } 209 210 return $json; 211 }, $params)) . ']'; 212 } 213 214 /** 215 * @param string $wrapperClass 216 * 217 * @return Exception 218 */ 219 public static function invalidWrapperClass($wrapperClass) 220 { 221 return new Exception("The given 'wrapperClass' " . $wrapperClass . ' has to be a ' . 222 'subtype of \Doctrine\DBAL\Connection.'); 223 } 224 225 /** 226 * @param string $driverClass 227 * 228 * @return Exception 229 */ 230 public static function invalidDriverClass($driverClass) 231 { 232 return new Exception( 233 "The given 'driverClass' " . $driverClass . ' has to implement the ' . Driver::class . ' interface.' 234 ); 235 } 236 237 /** 238 * @param string $tableName 239 * 240 * @return Exception 241 */ 242 public static function invalidTableName($tableName) 243 { 244 return new Exception('Invalid table name specified: ' . $tableName); 245 } 246 247 /** 248 * @param string $tableName 249 * 250 * @return Exception 251 */ 252 public static function noColumnsSpecifiedForTable($tableName) 253 { 254 return new Exception('No columns specified for table ' . $tableName); 255 } 256 257 /** 258 * @return Exception 259 */ 260 public static function limitOffsetInvalid() 261 { 262 return new Exception('Invalid Offset in Limit Query, it has to be larger than or equal to 0.'); 263 } 264 265 /** 266 * @param string $name 267 * 268 * @return Exception 269 */ 270 public static function typeExists($name) 271 { 272 return new Exception('Type ' . $name . ' already exists.'); 273 } 274 275 /** 276 * @param string $name 277 * 278 * @return Exception 279 */ 280 public static function unknownColumnType($name) 281 { 282 return new Exception('Unknown column type "' . $name . '" requested. Any Doctrine type that you use has ' . 283 'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' . 284 'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' . 285 'introspection then you might have forgotten to register all database types for a Doctrine Type. Use ' . 286 'AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement ' . 287 'Type#getMappedDatabaseTypes(). If the type name is empty you might ' . 288 'have a problem with the cache or forgot some mapping information.'); 289 } 290 291 /** 292 * @param string $name 293 * 294 * @return Exception 295 */ 296 public static function typeNotFound($name) 297 { 298 return new Exception('Type to be overwritten ' . $name . ' does not exist.'); 299 } 300 301 public static function typeNotRegistered(Type $type): self 302 { 303 return new Exception( 304 sprintf('Type of the class %s@%s is not registered.', get_class($type), spl_object_hash($type)) 305 ); 306 } 307 308 public static function typeAlreadyRegistered(Type $type): self 309 { 310 return new Exception( 311 sprintf('Type of the class %s@%s is already registered.', get_class($type), spl_object_hash($type)) 312 ); 313 } 314} 315