1<?php
2
3namespace Doctrine\DBAL\Driver;
4
5use Doctrine\DBAL\Connection;
6use Doctrine\DBAL\Driver;
7use Doctrine\DBAL\Driver\DriverException as DeprecatedDriverException;
8use Doctrine\DBAL\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\DeadlockException;
11use Doctrine\DBAL\Exception\DriverException;
12use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
13use Doctrine\DBAL\Exception\InvalidFieldNameException;
14use Doctrine\DBAL\Exception\LockWaitTimeoutException;
15use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
16use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
17use Doctrine\DBAL\Exception\SyntaxErrorException;
18use Doctrine\DBAL\Exception\TableExistsException;
19use Doctrine\DBAL\Exception\TableNotFoundException;
20use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
21use Doctrine\DBAL\Platforms\SQLAnywhere11Platform;
22use Doctrine\DBAL\Platforms\SQLAnywhere12Platform;
23use Doctrine\DBAL\Platforms\SQLAnywhere16Platform;
24use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
25use Doctrine\DBAL\Schema\SQLAnywhereSchemaManager;
26use Doctrine\DBAL\VersionAwarePlatformDriver;
27
28use function assert;
29use function preg_match;
30use function version_compare;
31
32/**
33 * Abstract base implementation of the {@link Driver} interface for SAP Sybase SQL Anywhere based drivers.
34 *
35 * @deprecated Support for SQLAnywhere will be removed in 3.0.
36 */
37abstract class AbstractSQLAnywhereDriver implements Driver, ExceptionConverterDriver, VersionAwarePlatformDriver
38{
39    /**
40     * {@inheritdoc}
41     *
42     * @deprecated
43     *
44     * @link http://dcx.sybase.com/index.html#sa160/en/saerrors/sqlerror.html
45     */
46    public function convertException($message, DeprecatedDriverException $exception)
47    {
48        switch ($exception->getErrorCode()) {
49            case '-306':
50            case '-307':
51            case '-684':
52                return new DeadlockException($message, $exception);
53
54            case '-210':
55            case '-1175':
56            case '-1281':
57                return new LockWaitTimeoutException($message, $exception);
58
59            case '-100':
60            case '-103':
61            case '-832':
62                return new ConnectionException($message, $exception);
63
64            case '-143':
65                return new InvalidFieldNameException($message, $exception);
66
67            case '-193':
68            case '-196':
69                return new UniqueConstraintViolationException($message, $exception);
70
71            case '-194':
72            case '-198':
73                return new ForeignKeyConstraintViolationException($message, $exception);
74
75            case '-144':
76                return new NonUniqueFieldNameException($message, $exception);
77
78            case '-184':
79            case '-195':
80                return new NotNullConstraintViolationException($message, $exception);
81
82            case '-131':
83                return new SyntaxErrorException($message, $exception);
84
85            case '-110':
86                return new TableExistsException($message, $exception);
87
88            case '-141':
89            case '-1041':
90                return new TableNotFoundException($message, $exception);
91        }
92
93        return new DriverException($message, $exception);
94    }
95
96    /**
97     * {@inheritdoc}
98     */
99    public function createDatabasePlatformForVersion($version)
100    {
101        if (
102            ! preg_match(
103                '/^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<patch>\d+)(?:\.(?P<build>\d+))?)?)?/',
104                $version,
105                $versionParts
106            )
107        ) {
108            throw Exception::invalidPlatformVersionSpecified(
109                $version,
110                '<major_version>.<minor_version>.<patch_version>.<build_version>'
111            );
112        }
113
114        $majorVersion = $versionParts['major'];
115        $minorVersion = $versionParts['minor'] ?? 0;
116        $patchVersion = $versionParts['patch'] ?? 0;
117        $buildVersion = $versionParts['build'] ?? 0;
118        $version      = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . '.' . $buildVersion;
119
120        switch (true) {
121            case version_compare($version, '16', '>='):
122                return new SQLAnywhere16Platform();
123
124            case version_compare($version, '12', '>='):
125                return new SQLAnywhere12Platform();
126
127            case version_compare($version, '11', '>='):
128                return new SQLAnywhere11Platform();
129
130            default:
131                return new SQLAnywherePlatform();
132        }
133    }
134
135    /**
136     * {@inheritdoc}
137     *
138     * @deprecated Use Connection::getDatabase() instead.
139     */
140    public function getDatabase(Connection $conn)
141    {
142        $params = $conn->getParams();
143
144        if (isset($params['dbname'])) {
145            return $params['dbname'];
146        }
147
148        $database = $conn->query('SELECT DB_NAME()')->fetchColumn();
149
150        assert($database !== false);
151
152        return $database;
153    }
154
155    /**
156     * {@inheritdoc}
157     */
158    public function getDatabasePlatform()
159    {
160        return new SQLAnywhere12Platform();
161    }
162
163    /**
164     * {@inheritdoc}
165     */
166    public function getSchemaManager(Connection $conn)
167    {
168        return new SQLAnywhereSchemaManager($conn);
169    }
170}
171