Passed
Pull Request — 4 (#10016)
by Ingo
10:13
created

NullDatabase::searchEngine()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 9
dl 0
loc 11
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace SilverStripe\ORM\Connect;
4
5
use BadMethodCallException;
6
use Exception;
7
8
/**
9
 * Utility class required due to bad coupling in framework.
10
 * Not every framework execution should require a working database connection.
11
 * For example, when generating class and config manifests for deployment bundles,
12
 * or when generating code in a silverstripe/graphql schema build.
13
 *
14
 * This class creates the required no-ops to
15
 *
16
 * @internal
17
 */
18
class NullDatabase extends Database
19
{
20
21
    public function __construct()
22
    {
23
        $this->connector = new NullConnector();
24
        $this->schemaManager = new MySQLSchemaManager();
25
        $this->schemaManager->setDatabase($this);
26
        $this->queryBuilder = new MySQLQueryBuilder();
27
    }
28
29
    public function query($sql, $errorLevel = E_USER_ERROR)
30
    {
31
        throw new \Exception('cannot query');
32
    }
33
34
    public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR)
35
    {
36
        throw new \Exception('cannot query');
37
    }
38
39
    /**
40
     * Get the autogenerated ID from the previous INSERT query.
41
     *
42
     * @param string $table The name of the table to get the generated ID for
43
     * @return integer the most recently generated ID for the specified table
44
     */
45
    public function getGeneratedID($table)
46
    {
47
        return $this->connector->getGeneratedID($table);
48
    }
49
50
    /**
51
     * Determines if we are connected to a server AND have a valid database
52
     * selected.
53
     *
54
     * @return boolean Flag indicating that a valid database is connected
55
     */
56
    public function isActive()
57
    {
58
        return true;
59
    }
60
61
    /**
62
     * Returns an escaped string. This string won't be quoted, so would be suitable
63
     * for appending to other quoted strings.
64
     *
65
     * @param mixed $value Value to be prepared for database query
66
     * @return string Prepared string
67
     */
68
    public function escapeString($value)
69
    {
70
        return $value;
71
    }
72
73
    /**
74
     * Wrap a string into DB-specific quotes.
75
     *
76
     * @param mixed $value Value to be prepared for database query
77
     * @return string Prepared string
78
     */
79
    public function quoteString($value)
80
    {
81
        return $value;
82
    }
83
84
    public function escapeIdentifier($value, $separator = '.')
85
    {
86
        return $value;
87
    }
88
89
    protected function escapeColumnKeys($fieldValues)
90
    {
91
        return $fieldValues;
92
    }
93
94
    public function manipulate($manipulation)
95
    {
96
        throw new \Exception('cannot query');
97
    }
98
99
    /**
100
     * Clear all data out of the database
101
     */
102
    public function clearAllData()
103
    {
104
        throw new \Exception('cannot query');
105
    }
106
107
    /**
108
     * Clear all data in a given table
109
     *
110
     * @param string $table Name of table
111
     */
112
    public function clearTable($table)
113
    {
114
        throw new \Exception('cannot query');
115
    }
116
117
    /**
118
     * Generates a WHERE clause for null comparison check
119
     *
120
     * @param string $field Quoted field name
121
     * @param bool $isNull Whether to check for NULL or NOT NULL
122
     * @return string Non-parameterised null comparison clause
123
     */
124
    public function nullCheckClause($field, $isNull)
125
    {
126
        $clause = $isNull
127
            ? "%s IS NULL"
128
            : "%s IS NOT NULL";
129
        return sprintf($clause, $field);
130
    }
131
132
    public function comparisonClause(
133
        $field,
134
        $value,
135
        $exact = false,
136
        $negate = false,
137
        $caseSensitive = null,
138
        $parameterised = false
139
    ) {
140
        // no-op
141
    }
142
143
    public function formattedDatetimeClause($date, $format)
144
    {
145
        // no-op
146
    }
147
148
    public function datetimeIntervalClause($date, $interval)
149
    {
150
        // no-op
151
    }
152
153
    public function datetimeDifferenceClause($date1, $date2)
154
    {
155
        // no-op
156
    }
157
158
    public function concatOperator()
159
    {
160
        // no-op
161
    }
162
163
    public function supportsCollations()
164
    {
165
        // no-op
166
    }
167
168
    public function supportsTimezoneOverride()
169
    {
170
        // no-op
171
    }
172
173
    public function getVersion()
174
    {
175
        // no-op
176
    }
177
178
    public function getDatabaseServer()
179
    {
180
        // no-op
181
    }
182
183
    public function affectedRows()
184
    {
185
        // no-op
186
    }
187
188
    public function searchEngine(
189
        $classesToSearch,
190
        $keywords,
191
        $start,
192
        $pageLength,
193
        $sortBy = "Relevance DESC",
194
        $extraFilter = "",
195
        $booleanSearch = false,
196
        $alternativeFileFilter = "",
197
        $invertedMatch = false
198
    ) {
199
        // no-op
200
    }
201
202
    public function supportsTransactions()
203
    {
204
        // no-op
205
    }
206
207
    public function supportsSavepoints()
208
    {
209
        // no-op
210
    }
211
212
213
    public function supportsTransactionMode(string $mode): bool
214
    {
215
        // no-op
216
    }
217
218
    /**
219
     * Invoke $callback within a transaction
220
     *
221
     * @param callable $callback Callback to run
222
     * @param callable $errorCallback Optional callback to run after rolling back transaction.
223
     * @param bool|string $transactionMode Optional transaction mode to use
224
     * @param bool $errorIfTransactionsUnsupported If true, this method will fail if transactions are unsupported.
225
     * Otherwise, the $callback will potentially be invoked outside of a transaction.
226
     * @throws Exception
227
     */
228
    public function withTransaction(
229
        $callback,
230
        $errorCallback = null,
231
        $transactionMode = false,
232
        $errorIfTransactionsUnsupported = false
233
    ) {
234
        $supported = $this->supportsTransactions();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $supported is correct as $this->supportsTransactions() targeting SilverStripe\ORM\Connect...:supportsTransactions() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
235
        if (!$supported && $errorIfTransactionsUnsupported) {
0 ignored issues
show
introduced by
$supported is defined implicitly as null, thus it is always evaluated to false.
Loading history...
236
            throw new BadMethodCallException("Transactions not supported by this database.");
237
        }
238
        if ($supported) {
0 ignored issues
show
introduced by
$supported is defined implicitly as null, thus it is always evaluated to false.
Loading history...
239
            $this->transactionStart($transactionMode);
240
        }
241
        try {
242
            call_user_func($callback);
243
        } catch (Exception $ex) {
244
            if ($supported) {
0 ignored issues
show
introduced by
$supported is defined implicitly as null, thus it is always evaluated to false.
Loading history...
245
                $this->transactionRollback();
246
            }
247
            if ($errorCallback) {
248
                call_user_func($errorCallback);
249
            }
250
            throw $ex;
251
        }
252
        if ($supported) {
0 ignored issues
show
introduced by
$supported is defined implicitly as null, thus it is always evaluated to false.
Loading history...
253
            $this->transactionEnd();
254
        }
255
    }
256
257
    /*
258
     * Determines if the current database connection supports a given list of extensions
259
     *
260
     * @param array $extensions List of extensions to check for support of. The key of this array
261
     * will be an extension name, and the value the configuration for that extension. This
262
     * could be one of partitions, tablespaces, or clustering
263
     * @return boolean Flag indicating support for all of the above
264
     * @todo Write test cases
265
     */
266
    public function supportsExtensions($extensions)
267
    {
268
        return false;
269
    }
270
271
    /**
272
     * Start a prepared transaction
273
     * See http://developer.postgresql.org/pgdocs/postgres/sql-set-transaction.html for details on
274
     * transaction isolation options
275
     *
276
     * @param string|boolean $transactionMode Transaction mode, or false to ignore
277
     * @param string|boolean $sessionCharacteristics Session characteristics, or false to ignore
278
     */
279
    public function transactionStart($transactionMode = false, $sessionCharacteristics = false)
280
    {
281
        // no-op
282
    }
283
284
    /**
285
     * Create a savepoint that you can jump back to if you encounter problems
286
     *
287
     * @param string $savepoint Name of savepoint
288
     */
289
    public function transactionSavepoint($savepoint)
290
    {
291
        // no-op
292
    }
293
294
    /**
295
     * Rollback or revert to a savepoint if your queries encounter problems
296
     * If you encounter a problem at any point during a transaction, you may
297
     * need to rollback that particular query, or return to a savepoint
298
     *
299
     * @param string|boolean $savepoint Name of savepoint, or leave empty to rollback
300
     * to last savepoint
301
     * @return bool|null Boolean is returned if success state is known, or null if
302
     * unknown. Note: For error checking purposes null should not be treated as error.
303
     */
304
    public function transactionRollback($savepoint = false)
305
    {
306
        // no-op
307
    }
308
309
    /**
310
     * Commit everything inside this transaction so far
311
     *
312
     * @param bool $chain
313
     * @return bool|null Boolean is returned if success state is known, or null if
314
     * unknown. Note: For error checking purposes null should not be treated as error.
315
     */
316
    public function transactionEnd($chain = false)
317
    {
318
        // no-op
319
    }
320
321
    /**
322
     * Return depth of current transaction
323
     *
324
     * @return int Nesting level, or 0 if not in a transaction
325
     */
326
    public function transactionDepth()
327
    {
328
        // Placeholder error for transactional DBs that don't expose depth
329
        if ($this->supportsTransactions()) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->supportsTransactions() targeting SilverStripe\ORM\Connect...:supportsTransactions() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
330
            user_error(get_class($this) . " does not support transactionDepth", E_USER_WARNING);
331
        }
332
        return 0;
333
    }
334
335
    /**
336
     * Determines if the used database supports application-level locks,
337
     * which is different from table- or row-level locking.
338
     * See {@link getLock()} for details.
339
     *
340
     * @return bool Flag indicating that locking is available
341
     */
342
    public function supportsLocks()
343
    {
344
        return false;
345
    }
346
347
    /**
348
     * Returns if the lock is available.
349
     * See {@link supportsLocks()} to check if locking is generally supported.
350
     *
351
     * @param string $name Name of the lock
352
     * @return bool
353
     */
354
    public function canLock($name)
355
    {
356
        return false;
357
    }
358
359
    /**
360
     * Sets an application-level lock so that no two processes can run at the same time,
361
     * also called a "cooperative advisory lock".
362
     *
363
     * Return FALSE if acquiring the lock fails; otherwise return TRUE, if lock was acquired successfully.
364
     * Lock is automatically released if connection to the database is broken (either normally or abnormally),
365
     * making it less prone to deadlocks than session- or file-based locks.
366
     * Should be accompanied by a {@link releaseLock()} call after the logic requiring the lock has completed.
367
     * Can be called multiple times, in which case locks "stack" (PostgreSQL, SQL Server),
368
     * or auto-releases the previous lock (MySQL).
369
     *
370
     * Note that this might trigger the database to wait for the lock to be released, delaying further execution.
371
     *
372
     * @param string $name Name of lock
373
     * @param integer $timeout Timeout in seconds
374
     * @return bool
375
     */
376
    public function getLock($name, $timeout = 5)
377
    {
378
        return false;
379
    }
380
381
    /**
382
     * Remove an application-level lock file to allow another process to run
383
     * (if the execution aborts (e.g. due to an error) all locks are automatically released).
384
     *
385
     * @param string $name Name of the lock
386
     * @return bool Flag indicating whether the lock was successfully released
387
     */
388
    public function releaseLock($name)
389
    {
390
        return false;
391
    }
392
393
    /**
394
     * Instruct the database to generate a live connection
395
     *
396
     * @param array $parameters An map of parameters, which should include:
397
     *  - server: The server, eg, localhost
398
     *  - username: The username to log on with
399
     *  - password: The password to log on with
400
     *  - database: The database to connect to
401
     *  - charset: The character set to use. Defaults to utf8
402
     *  - timezone: (optional) The timezone offset. For example: +12:00, "Pacific/Auckland", or "SYSTEM"
403
     *  - driver: (optional) Driver name
404
     */
405
    public function connect($parameters)
406
    {
407
        // Ensure that driver is available (required by PDO)
408
        if (empty($parameters['driver'])) {
409
            $parameters['driver'] = $this->getDatabaseServer();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $parameters['driver'] is correct as $this->getDatabaseServer() targeting SilverStripe\ORM\Connect...se::getDatabaseServer() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
410
        }
411
412
        // Notify connector of parameters
413
        $this->connector->connect($parameters);
414
415
        // SS_Database subclass maintains responsibility for selecting database
416
        // once connected in order to correctly handle schema queries about
417
        // existence of database, error handling at the correct level, etc
418
        if (!empty($parameters['database'])) {
419
            $this->selectDatabase($parameters['database'], false, false);
420
        }
421
    }
422
423
    /**
424
     * Determine if the database with the specified name exists
425
     *
426
     * @param string $name Name of the database to check for
427
     * @return bool Flag indicating whether this database exists
428
     */
429
    public function databaseExists($name)
430
    {
431
        return $this->schemaManager->databaseExists($name);
432
    }
433
434
    /**
435
     * Retrieves the list of all databases the user has access to
436
     *
437
     * @return array List of database names
438
     */
439
    public function databaseList()
440
    {
441
        return $this->schemaManager->databaseList();
442
    }
443
444
    public function selectDatabase($name, $create = false, $errorLevel = E_USER_ERROR)
445
    {
446
        // no-op
447
    }
448
449
    public function dropSelectedDatabase()
450
    {
451
        // no-op
452
    }
453
454
    public function getSelectedDatabase()
455
    {
456
        // no-op
457
    }
458
459
    public function now()
460
    {
461
        // no-op
462
    }
463
464
    public function random()
465
    {
466
        // no-op
467
    }
468
}
469