AbstractPostgreSQLDriver.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\DBAL\Driver;
  20. use Doctrine\DBAL\DBALException;
  21. use Doctrine\DBAL\Driver;
  22. use Doctrine\DBAL\Exception;
  23. use Doctrine\DBAL\Platforms\PostgreSQL91Platform;
  24. use Doctrine\DBAL\Platforms\PostgreSQL92Platform;
  25. use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
  26. use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;
  27. use Doctrine\DBAL\VersionAwarePlatformDriver;
  28. /**
  29. * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for PostgreSQL based drivers.
  30. *
  31. * @author Steve Müller <st.mueller@dzh-online.de>
  32. * @link www.doctrine-project.org
  33. * @since 2.5
  34. */
  35. abstract class AbstractPostgreSQLDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
  36. {
  37. /**
  38. * {@inheritdoc}
  39. *
  40. * @link http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
  41. */
  42. public function convertException($message, DriverException $exception)
  43. {
  44. switch ($exception->getSQLState()) {
  45. case '0A000':
  46. // Foreign key constraint violations during a TRUNCATE operation
  47. // are considered "feature not supported" in PostgreSQL.
  48. if (strpos($exception->getMessage(), 'truncate') !== false) {
  49. return new Exception\ForeignKeyConstraintViolationException($message, $exception);
  50. }
  51. break;
  52. case '23502':
  53. return new Exception\NotNullConstraintViolationException($message, $exception);
  54. case '23503':
  55. return new Exception\ForeignKeyConstraintViolationException($message, $exception);
  56. case '23505':
  57. return new Exception\UniqueConstraintViolationException($message, $exception);
  58. case '42601':
  59. return new Exception\SyntaxErrorException($message, $exception);
  60. case '42702':
  61. return new Exception\NonUniqueFieldNameException($message, $exception);
  62. case '42703':
  63. return new Exception\InvalidFieldNameException($message, $exception);
  64. case '42P01':
  65. return new Exception\TableNotFoundException($message, $exception);
  66. case '42P07':
  67. return new Exception\TableExistsException($message, $exception);
  68. case '7':
  69. // In some case (mainly connection errors) the PDO exception does not provide a SQLSTATE via its code.
  70. // The exception code is always set to 7 here.
  71. // We have to match against the SQLSTATE in the error message in these cases.
  72. if (strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) {
  73. return new Exception\ConnectionException($message, $exception);
  74. }
  75. break;
  76. }
  77. return new Exception\DriverException($message, $exception);
  78. }
  79. /**
  80. * {@inheritdoc}
  81. */
  82. public function createDatabasePlatformForVersion($version)
  83. {
  84. if ( ! preg_match('/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?)?/', $version, $versionParts)) {
  85. throw DBALException::invalidPlatformVersionSpecified(
  86. $version,
  87. '<major_version>.<minor_version>.<patch_version>'
  88. );
  89. }
  90. $majorVersion = $versionParts['major'];
  91. $minorVersion = isset($versionParts['minor']) ? $versionParts['minor'] : 0;
  92. $patchVersion = isset($versionParts['patch']) ? $versionParts['patch'] : 0;
  93. $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
  94. switch(true) {
  95. case version_compare($version, '9.2', '>='):
  96. return new PostgreSQL92Platform();
  97. case version_compare($version, '9.1', '>='):
  98. return new PostgreSQL91Platform();
  99. default:
  100. return new PostgreSqlPlatform();
  101. }
  102. }
  103. /**
  104. * {@inheritdoc}
  105. */
  106. public function getDatabase(\Doctrine\DBAL\Connection $conn)
  107. {
  108. $params = $conn->getParams();
  109. return (isset($params['dbname']))
  110. ? $params['dbname']
  111. : $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn();
  112. }
  113. /**
  114. * {@inheritdoc}
  115. */
  116. public function getDatabasePlatform()
  117. {
  118. return new PostgreSqlPlatform();
  119. }
  120. /**
  121. * {@inheritdoc}
  122. */
  123. public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
  124. {
  125. return new PostgreSqlSchemaManager($conn);
  126. }
  127. }