Failed Conditions
Pull Request — develop (#3367)
by Benjamin
13:43
created

SQLAnywhereConnection::__construct()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 21
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 21
ccs 0
cts 14
cp 0
rs 9.2222
c 0
b 0
f 0
cc 6
nc 10
nop 2
crap 42
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 Doctrine\DBAL\ParameterType;
11
use function assert;
12
use function is_float;
13
use function is_int;
14
use function is_resource;
15
use function is_string;
16
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...
17
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...
18
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...
19
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...
20
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...
21
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...
22
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...
23
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...
24
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...
25
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...
26
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...
27
28
/**
29
 * SAP Sybase SQL Anywhere implementation of the Connection interface.
30
 */
31
class SQLAnywhereConnection implements Connection, ServerInfoAwareConnection
32
{
33
    /** @var resource The SQL Anywhere connection resource. */
34
    private $connection;
35
36
    /**
37
     * Connects to database with given connection string.
38
     *
39
     * @param string $dsn        The connection string.
40
     * @param bool   $persistent Whether or not to establish a persistent connection.
41
     *
42
     * @throws DriverException
43
     */
44
    public function __construct($dsn, $persistent = false)
45
    {
46
        $this->connection = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn);
0 ignored issues
show
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

46
        $this->connection = $persistent ? @/** @scrutinizer ignore-call */ sasql_pconnect($dsn) : @sasql_connect($dsn);
Loading history...
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

46
        $this->connection = $persistent ? @sasql_pconnect($dsn) : @/** @scrutinizer ignore-call */ sasql_connect($dsn);
Loading history...
47
48
        if (! is_resource($this->connection)) {
49
            throw self::exceptionFromSQLAnywhereError();
50
        }
51
52
        // Disable PHP warnings on error.
53
        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

53
        if (! /** @scrutinizer ignore-call */ sasql_set_option($this->connection, 'verbose_errors', false)) {
Loading history...
54
            throw self::exceptionFromSQLAnywhereError($this->connection);
55
        }
56
57
        // Enable auto committing by default.
58
        if (! sasql_set_option($this->connection, 'auto_commit', 'on')) {
59
            throw self::exceptionFromSQLAnywhereError($this->connection);
60
        }
61
62
        // Enable exact, non-approximated row count retrieval.
63
        if (! sasql_set_option($this->connection, 'row_counts', true)) {
64
            throw self::exceptionFromSQLAnywhereError($this->connection);
65
        }
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function beginTransaction()
72
    {
73
        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

73
        if (! /** @scrutinizer ignore-call */ sasql_set_option($this->connection, 'auto_commit', 'off')) {
Loading history...
74
            throw self::exceptionFromSQLAnywhereError($this->connection);
75
        }
76
77
        return true;
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function commit()
84
    {
85
        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

85
        if (! /** @scrutinizer ignore-call */ sasql_commit($this->connection)) {
Loading history...
86
            throw self::exceptionFromSQLAnywhereError($this->connection);
87
        }
88
89
        $this->endTransaction();
90
91
        return true;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function errorCode()
98
    {
99
        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

99
        return /** @scrutinizer ignore-call */ sasql_errorcode($this->connection);
Loading history...
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function errorInfo()
106
    {
107
        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

107
        return /** @scrutinizer ignore-call */ sasql_error($this->connection);
Loading history...
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function exec(string $statement) : int
114
    {
115
        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

115
        if (/** @scrutinizer ignore-call */ sasql_real_query($this->connection, $statement) === false) {
Loading history...
116
            throw self::exceptionFromSQLAnywhereError($this->connection);
117
        }
118
119
        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

119
        return /** @scrutinizer ignore-call */ sasql_affected_rows($this->connection);
Loading history...
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function getServerVersion()
126
    {
127
        $version = $this->query("SELECT PROPERTY('ProductVersion')")->fetchColumn();
128
129
        assert(is_string($version));
130
131
        return $version;
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137
    public function lastInsertId($name = null)
138
    {
139
        if ($name === null) {
140
            return 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

140
            return /** @scrutinizer ignore-call */ sasql_insert_id($this->connection);
Loading history...
141
        }
142
143
        return $this->query('SELECT ' . $name . '.CURRVAL')->fetchColumn();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->query('SEL...URRVAL')->fetchColumn() also could return the type false which is incompatible with the return type mandated by Doctrine\DBAL\Driver\Connection::lastInsertId() of string.
Loading history...
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149
    public function prepare(string $sql) : DriverStatement
150
    {
151
        return new SQLAnywhereStatement($this->connection, $sql);
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157
    public function query(string $sql) : ResultStatement
158
    {
159
        $stmt = $this->prepare($sql);
160
        $stmt->execute();
161
162
        return $stmt;
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168
    public function quote($input, $type = ParameterType::STRING)
169
    {
170
        if (is_int($input) || is_float($input)) {
171
            return $input;
172
        }
173
174
        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

174
        return "'" . /** @scrutinizer ignore-call */ sasql_escape_string($this->connection, $input) . "'";
Loading history...
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function requiresQueryForServerVersion()
181
    {
182
        return true;
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188
    public function rollBack()
189
    {
190
        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

190
        if (! /** @scrutinizer ignore-call */ sasql_rollback($this->connection)) {
Loading history...
191
            throw self::exceptionFromSQLAnywhereError($this->connection);
192
        }
193
194
        $this->endTransaction();
195
196
        return true;
197
    }
198
199
    /**
200
     * Ends transactional mode and enables auto commit again.
201
     *
202
     * @return bool Whether or not ending transactional mode succeeded.
203
     *
204
     * @throws DriverException
205
     */
206
    private function endTransaction()
207
    {
208
        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

208
        if (! /** @scrutinizer ignore-call */ sasql_set_option($this->connection, 'auto_commit', 'on')) {
Loading history...
209
            throw self::exceptionFromSQLAnywhereError($this->connection);
210
        }
211
212
        return true;
213
    }
214
215
    /**
216
     * Helper method to turn SQL Anywhere error into exception.
217
     *
218
     * @param resource|null $conn The SQL Anywhere connection resource to retrieve the last error from.
219
     * @param resource|null $stmt The SQL Anywhere statement resource to retrieve the last error from.
220
     *
221
     * @throws InvalidArgumentException
222
     */
223
    public static function exceptionFromSQLAnywhereError($conn = null, $stmt = null) : DriverException
224
    {
225
        if ($conn !== null && ! is_resource($conn)) {
226
            throw new InvalidArgumentException('Invalid SQL Anywhere connection resource given: ' . $conn);
0 ignored issues
show
Bug introduced by
The type Doctrine\DBAL\Driver\SQL...nvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
227
        }
228
229
        if ($stmt !== null && ! is_resource($stmt)) {
230
            throw new InvalidArgumentException('Invalid SQL Anywhere statement resource given: ' . $stmt);
231
        }
232
233
        $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

233
        $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...
234
        $code    = null;
235
        $message = null;
236
237
        /**
238
         * Try retrieving the last error from statement resource if given
239
         */
240
        if ($stmt) {
0 ignored issues
show
introduced by
$stmt is of type null|resource, thus it always evaluated to false.
Loading history...
241
            $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

241
            $code    = /** @scrutinizer ignore-call */ sasql_stmt_errno($stmt);
Loading history...
242
            $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

242
            $message = /** @scrutinizer ignore-call */ sasql_stmt_error($stmt);
Loading history...
243
        }
244
245
        /**
246
         * Try retrieving the last error from the connection resource
247
         * if either the statement resource is not given or the statement
248
         * resource is given but the last error could not be retrieved from it (fallback).
249
         * Depending on the type of error, it is sometimes necessary to retrieve
250
         * it from the connection resource even though it occurred during
251
         * a prepared statement.
252
         */
253
        if ($conn && ! $code) {
0 ignored issues
show
introduced by
$conn is of type null|resource, thus it always evaluated to false.
Loading history...
254
            $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

254
            $code    = /** @scrutinizer ignore-call */ sasql_errorcode($conn);
Loading history...
255
            $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

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