Failed Conditions
Pull Request — develop (#3368)
by Benjamin
13:33
created

exceptionFromSQLAnywhereError()   C

Complexity

Conditions 12
Paths 34

Size

Total Lines 50
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 50
ccs 0
cts 27
cp 0
rs 6.9666
c 0
b 0
f 0
cc 12
nc 34
nop 2
crap 156

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Doctrine\DBAL\Driver\SQLAnywhere;
4
5
use Doctrine\DBAL\Driver\Connection;
6
use Doctrine\DBAL\Driver\DriverException;
7
use Doctrine\DBAL\Driver\ResultStatement;
8
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
9
use Doctrine\DBAL\Driver\Statement as DriverStatement;
10
use InvalidArgumentException;
11
use function assert;
12
use function is_resource;
13
use function is_string;
14
use function sasql_affected_rows;
0 ignored issues
show
introduced by
The function sasql_affected_rows was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
15
use function sasql_commit;
0 ignored issues
show
introduced by
The function sasql_commit was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
16
use function sasql_connect;
0 ignored issues
show
introduced by
The function sasql_connect was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
17
use function sasql_error;
0 ignored issues
show
introduced by
The function sasql_error was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
18
use function sasql_errorcode;
0 ignored issues
show
introduced by
The function sasql_errorcode was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
19
use function sasql_escape_string;
0 ignored issues
show
introduced by
The function sasql_escape_string was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
20
use function sasql_insert_id;
0 ignored issues
show
introduced by
The function sasql_insert_id was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
21
use function sasql_pconnect;
0 ignored issues
show
introduced by
The function sasql_pconnect was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
22
use function sasql_real_query;
0 ignored issues
show
introduced by
The function sasql_real_query was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
23
use function sasql_rollback;
0 ignored issues
show
introduced by
The function sasql_rollback was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
24
use function sasql_set_option;
0 ignored issues
show
introduced by
The function sasql_set_option was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
25
26
/**
27
 * SAP Sybase SQL Anywhere implementation of the Connection interface.
28
 */
29
class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
30
{
31
    /** @var resource The SQL Anywhere connection resource. */
32
    private $connection;
33
34
    /**
35
     * Connects to database with given connection string.
36
     *
37
     * @param string $dsn        The connection string.
38
     * @param bool   $persistent Whether or not to establish a persistent connection.
39
     *
40
     * @throws DriverException
41
     */
42
    public function __construct($dsn, $persistent = false)
43
    {
44
        $this->connection = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn);
0 ignored issues
show
Bug introduced by
The function sasql_connect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
        $this->connection = $persistent ? @sasql_pconnect($dsn) : @/** @scrutinizer ignore-call */ sasql_connect($dsn);
Loading history...
Bug introduced by
The function sasql_pconnect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
        $this->connection = $persistent ? @/** @scrutinizer ignore-call */ sasql_pconnect($dsn) : @sasql_connect($dsn);
Loading history...
45
46
        if (! is_resource($this->connection)) {
47
            throw self::exceptionFromSQLAnywhereError();
48
        }
49
50
        // Disable PHP warnings on error.
51
        if (! sasql_set_option($this->connection, 'verbose_errors', false)) {
0 ignored issues
show
Bug introduced by
The function sasql_set_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        if (! /** @scrutinizer ignore-call */ sasql_set_option($this->connection, 'verbose_errors', false)) {
Loading history...
52
            throw self::exceptionFromSQLAnywhereError($this->connection);
53
        }
54
55
        // Enable auto committing by default.
56
        if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
57
            throw self::exceptionFromSQLAnywhereError($this->connection);
58
        }
59
60
        // Enable exact, non-approximated row count retrieval.
61
        if (! sasql_set_option($this->connection, 'row_counts', true)) {
62
            throw self::exceptionFromSQLAnywhereError($this->connection);
63
        }
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function beginTransaction() : void
70
    {
71
        if (! sasql_set_option($this->connection, 'auto_commit', 'off')) {
0 ignored issues
show
Bug introduced by
The function sasql_set_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

71
        if (! /** @scrutinizer ignore-call */ sasql_set_option($this->connection, 'auto_commit', 'off')) {
Loading history...
72
            throw self::exceptionFromSQLAnywhereError($this->connection);
73
        }
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79
    public function commit() : void
80
    {
81
        if (! sasql_commit($this->connection)) {
0 ignored issues
show
Bug introduced by
The function sasql_commit was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
        if (! /** @scrutinizer ignore-call */ sasql_commit($this->connection)) {
Loading history...
82
            throw self::exceptionFromSQLAnywhereError($this->connection);
83
        }
84
85
        $this->endTransaction();
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function errorCode()
92
    {
93
        return sasql_errorcode($this->connection);
0 ignored issues
show
Bug introduced by
The function sasql_errorcode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

93
        return /** @scrutinizer ignore-call */ sasql_errorcode($this->connection);
Loading history...
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function errorInfo()
100
    {
101
        return sasql_error($this->connection);
0 ignored issues
show
Bug introduced by
The function sasql_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
        return /** @scrutinizer ignore-call */ sasql_error($this->connection);
Loading history...
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function exec(string $statement) : int
108
    {
109
        if (sasql_real_query($this->connection, $statement) === false) {
0 ignored issues
show
Bug introduced by
The function sasql_real_query was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

109
        if (/** @scrutinizer ignore-call */ sasql_real_query($this->connection, $statement) === false) {
Loading history...
110
            throw self::exceptionFromSQLAnywhereError($this->connection);
111
        }
112
113
        return sasql_affected_rows($this->connection);
0 ignored issues
show
Bug introduced by
The function sasql_affected_rows was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

113
        return /** @scrutinizer ignore-call */ sasql_affected_rows($this->connection);
Loading history...
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function getServerVersion()
120
    {
121
        $version = $this->query("SELECT PROPERTY('ProductVersion')")->fetchColumn();
122
123
        assert(is_string($version));
124
125
        return $version;
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function lastInsertId() : string
132
    {
133
        $result = sasql_insert_id($this->connection);
0 ignored issues
show
Bug introduced by
The function sasql_insert_id was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

133
        $result = /** @scrutinizer ignore-call */ sasql_insert_id($this->connection);
Loading history...
134
135
        if ($result === false) {
136
            throw self::exceptionFromSQLAnywhereError($this->connection);
137
        }
138
139
        if ($result === 0) {
140
            throw DriverException::noInsertId();
141
        }
142
143
        return (string) $result;
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149
    public function getSequenceNumber(string $name) : string
150
    {
151
        $result = $this->query('SELECT ' . $name . '.CURRVAL')->fetchColumn();
152
153
        if ($result === false) {
154
            throw DriverException::noSuchSequence($name);
155
        }
156
157
        return (string) $result;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    public function prepare(string $sql) : DriverStatement
164
    {
165
        return new SQLAnywhereStatement($this->connection, $sql);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function query(string $sql) : ResultStatement
172
    {
173
        $stmt = $this->prepare($sql);
174
        $stmt->execute();
175
176
        return $stmt;
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function quote(string $input) : string
183
    {
184
        return "'" . sasql_escape_string($this->connection, $input) . "'";
0 ignored issues
show
Bug introduced by
The function sasql_escape_string was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

184
        return "'" . /** @scrutinizer ignore-call */ sasql_escape_string($this->connection, $input) . "'";
Loading history...
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190
    public function requiresQueryForServerVersion()
191
    {
192
        return true;
193
    }
194
195
    /**
196
     * {@inheritdoc}
197
     */
198
    public function rollBack() : void
199
    {
200
        if (! sasql_rollback($this->connection)) {
0 ignored issues
show
Bug introduced by
The function sasql_rollback was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

200
        if (! /** @scrutinizer ignore-call */ sasql_rollback($this->connection)) {
Loading history...
201
            throw self::exceptionFromSQLAnywhereError($this->connection);
202
        }
203
204
        $this->endTransaction();
205
    }
206
207
    /**
208
     * Ends transactional mode and enables auto commit again.
209
     *
210
     * @return bool Whether or not ending transactional mode succeeded.
211
     *
212
     * @throws DriverException
213
     */
214
    private function endTransaction()
215
    {
216
        if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
0 ignored issues
show
Bug introduced by
The function sasql_set_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

216
        if (! /** @scrutinizer ignore-call */ sasql_set_option($this->connection, 'auto_commit', 'on')) {
Loading history...
217
            throw self::exceptionFromSQLAnywhereError($this->connection);
218
        }
219
220
        return true;
221
    }
222
223
    /**
224
     * Helper method to turn SQL Anywhere error into exception.
225
     *
226
     * @param resource|null $conn The SQL Anywhere connection resource to retrieve the last error from.
227
     * @param resource|null $stmt The SQL Anywhere statement resource to retrieve the last error from.
228
     *
229
     * @throws InvalidArgumentException
230
     */
231
    public static function exceptionFromSQLAnywhereError($conn = null, $stmt = null) : DriverException
232
    {
233
        if ($conn !== null && ! is_resource($conn)) {
234
            throw new InvalidArgumentException('Invalid SQL Anywhere connection resource given: ' . $conn);
235
        }
236
237
        if ($stmt !== null && ! is_resource($stmt)) {
238
            throw new InvalidArgumentException('Invalid SQL Anywhere statement resource given: ' . $stmt);
239
        }
240
241
        $state   = $conn ? sasql_sqlstate($conn) : sasql_sqlstate();
0 ignored issues
show
Bug introduced by
The function sasql_sqlstate was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
        $state   = $conn ? /** @scrutinizer ignore-call */ sasql_sqlstate($conn) : sasql_sqlstate();
Loading history...
introduced by
$conn is of type null|resource, thus it always evaluated to false.
Loading history...
242
        $code    = null;
243
        $message = null;
244
245
        /**
246
         * Try retrieving the last error from statement resource if given
247
         */
248
        if ($stmt) {
0 ignored issues
show
introduced by
$stmt is of type null|resource, thus it always evaluated to false.
Loading history...
249
            $code    = sasql_stmt_errno($stmt);
0 ignored issues
show
Bug introduced by
The function sasql_stmt_errno was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

249
            $code    = /** @scrutinizer ignore-call */ sasql_stmt_errno($stmt);
Loading history...
250
            $message = sasql_stmt_error($stmt);
0 ignored issues
show
Bug introduced by
The function sasql_stmt_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

250
            $message = /** @scrutinizer ignore-call */ sasql_stmt_error($stmt);
Loading history...
251
        }
252
253
        /**
254
         * Try retrieving the last error from the connection resource
255
         * if either the statement resource is not given or the statement
256
         * resource is given but the last error could not be retrieved from it (fallback).
257
         * Depending on the type of error, it is sometimes necessary to retrieve
258
         * it from the connection resource even though it occurred during
259
         * a prepared statement.
260
         */
261
        if ($conn && ! $code) {
0 ignored issues
show
introduced by
$conn is of type null|resource, thus it always evaluated to false.
Loading history...
262
            $code    = sasql_errorcode($conn);
0 ignored issues
show
Bug introduced by
The function sasql_errorcode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

262
            $code    = /** @scrutinizer ignore-call */ sasql_errorcode($conn);
Loading history...
263
            $message = sasql_error($conn);
0 ignored issues
show
Bug introduced by
The function sasql_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

263
            $message = /** @scrutinizer ignore-call */ sasql_error($conn);
Loading history...
264
        }
265
266
        /**
267
         * Fallback mode if either no connection resource is given
268
         * or the last error could not be retrieved from the given
269
         * connection / statement resource.
270
         */
271
        if (! $conn || ! $code) {
0 ignored issues
show
introduced by
$conn is of type null|resource, thus it always evaluated to false.
Loading history...
272
            $code    = sasql_errorcode();
273
            $message = sasql_error();
274
        }
275
276
        if ($message) {
277
            return new DriverException('SQLSTATE [' . $state . '] [' . $code . '] ' . $message, $state, $code);
278
        }
279
280
        return new DriverException('SQL Anywhere error occurred but no error message was retrieved from driver.', $state, $code);
281
    }
282
}
283