DBALException.php 8.5 KB

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