Completed
Pull Request — master (#47)
by Robbie
01:29
created

DatabaseProxy::getConnector()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace LeKoala\DebugBar\Proxy;
4
5
6
use LeKoala\DebugBar\DebugBar;
7
use SqlFormatter;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\Control\Director;
10
use SilverStripe\Dev\Debug;
11
use SilverStripe\ORM\Connect\Database;
12
use SilverStripe\ORM\Connect\DBConnector;
13
use SilverStripe\ORM\Connect\DBSchemaManager;
14
use SilverStripe\ORM\Connect\DBQueryBuilder;
15
use SilverStripe\ORM\DataList;
16
use SilverStripe\ORM\DataObject;
17
use SilverStripe\ORM\DataQuery;
18
use SilverStripe\ORM\DB;
19
use SilverStripe\ORM\ListDecorator;
20
use SilverStripe\ORM\Map;
21
use SilverStripe\ORM\Queries\SQLExpression;
22
use SilverStripe\ORM\Queries\SQLSelect;
23
use SilverStripe\View\SSViewer;
24
use SilverStripe\View\SSViewer_DataPresenter;
25
use SilverStripe\View\SSViewer_Scope;
26
use SilverStripe\View\ViewableData;
27
28
/**
29
 * A proxy database to log queries
30
 *
31
 * @author Koala
32
 */
33
class DatabaseProxy extends Database
34
{
35
    /** @var MySQLDatabase */
36
    protected $realConn;
37
    protected $findSource;
38
39
    /** @var array */
40
    protected $queries;
41
    protected $connector;
42
    protected $schemaManager;
43
    protected $queryBuilder;
44
    protected $showQueries = false;
45
46
    /**
47
     * @param Database|array $realConn
48
     */
49
    public function __construct($realConn)
50
    {
51
        // Some service hooks pass $databaseConfig to constructor
52
        if (is_array($realConn)) {
53
            $realConn = DB::connect($realConn);
54
        }
55
        $this->realConn      = $realConn;
0 ignored issues
show
Documentation Bug introduced by
It seems like $realConn of type object<SilverStripe\ORM\Connect\Database> is incompatible with the declared type object<LeKoala\DebugBar\Proxy\MySQLDatabase> of property $realConn.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
56
        $this->connector     = $realConn->getConnector();
57
        $this->schemaManager = $realConn->getSchemaManager();
58
        $this->queryBuilder  = $realConn->getQueryBuilder();
59
        $this->queries       = array();
60
        $this->findSource    = DebugBar::config()->find_source;
61
    }
62
63
    public function getShowQueries()
64
    {
65
        return $this->showQueries;
66
    }
67
68
    public function setShowQueries($showQueries)
69
    {
70
        $this->showQueries = $showQueries;
71
        return $this;
72
    }
73
74
    /**
75
     * Get the current connector
76
     *
77
     * @return DBConnector
78
     */
79
    public function getConnector()
80
    {
81
        return $this->realConn->getConnector();
82
    }
83
84
    /**
85
     * Injector injection point for connector dependency
86
     *
87
     * @param DBConnector $connector
88
     */
89
    public function setConnector(DBConnector $connector)
90
    {
91
        parent::setConnector($connector);
92
        $this->realConn->setConnector($connector);
93
    }
94
95
    /**
96
     * Returns the current schema manager
97
     *
98
     * @return DBSchemaManager
99
     */
100
    public function getSchemaManager()
101
    {
102
        return $this->realConn->getSchemaManager();
103
    }
104
105
    /**
106
     * Injector injection point for schema manager
107
     *
108
     * @param DBSchemaManager $schemaManager
109
     */
110
    public function setSchemaManager(DBSchemaManager $schemaManager)
111
    {
112
        parent::setSchemaManager($schemaManager);
113
        $this->realConn->setSchemaManager($schemaManager);
114
    }
115
116
    /**
117
     * Returns the current query builder
118
     *
119
     * @return DBQueryBuilder
120
     */
121
    public function getQueryBuilder()
122
    {
123
        return $this->realConn->getQueryBuilder();
124
    }
125
126
    /**
127
     * Injector injection point for schema manager
128
     *
129
     * @param DBQueryBuilder $queryBuilder
130
     */
131
    public function setQueryBuilder(DBQueryBuilder $queryBuilder)
132
    {
133
        parent::setQueryBuilder($queryBuilder);
134
        $this->realConn->setQueryBuilder($queryBuilder);
135
    }
136
137
    /**
138
     * Determines if the query should be previewed, and thus interrupted silently.
139
     * If so, this function also displays the query via the debuging system.
140
     * Subclasess should respect the results of this call for each query, and not
141
     * execute any queries that generate a true response.
142
     *
143
     * @param string $sql The query to be executed
144
     * @return boolean Flag indicating that the query was previewed
145
     */
146
    protected function previewWrite($sql)
0 ignored issues
show
Coding Style introduced by
previewWrite uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
147
    {
148
        // Only preview if previewWrite is set, we are in dev mode, and
149
        // the query is mutable
150
        if (isset($_REQUEST['previewwrite']) && Director::isDev() && $this->connector->isQueryMutable($sql)
151
        ) {
152
            // output preview message
153
            Debug::message("Will execute: $sql");
154
            return true;
155
        } else {
156
            return false;
157
        }
158
    }
159
160
    /**
161
     * Allows the display and benchmarking of queries as they are being run
162
     *
163
     * @param string $sql Query to run, and single parameter to callback
164
     * @param callable $callback Callback to execute code
165
     * @param array $parameters
166
     * @return mixed Result of query
167
     */
168
    protected function benchmarkQuery($sql, $callback, $parameters = array())
169
    {
170
        $starttime   = microtime(true);
171
        $startmemory = memory_get_usage(true);
172
173
        if (is_array($sql)) {
174
            $parameters = $sql[1];
175
            $sql        = $sql[0];
176
        }
177
178
        if ($this->showQueries && Director::isDev()) {
179
            $starttime = microtime(true);
180
            $result    = $callback($sql);
181
            $endtime   = round(microtime(true) - $starttime, 4);
182
183
            $formattedSql = SqlFormatter::format($sql);
184
            $rows         = $result->numRecords();
185
            echo '<pre>The following query took <b>'.$endtime.'</b>s an returned <b>'.$rows."</b> row(s) \n";
186
            echo 'Triggered by: <i>'.$this->findSource().'</i></pre>';
187
            echo $formattedSql;
188
189
            $results = iterator_to_array($result);
190
            if ($rows > 0) {
191
                if ($rows == 1) {
192
                    dump($results[0]);
193
                } else {
194
                    $linearValues = count($results[0]);
195
                    if ($linearValues) {
196
                        dump(implode(
197
                            ',',
198
                            array_map(
199
                                function ($item) {
200
                                    return $item[key($item)];
201
                                },
202
                                $results
203
                            )
204
                        ));
205
                    } else {
206
                        if ($rows < 20) {
207
                            dump($results);
208
                        } else {
209
                            dump("Too many results to display");
210
                        }
211
                    }
212
                }
213
            }
214
            echo '<hr/>';
215
216
            $handle = $result;
217
            $handle->rewind(); // Rewind the results
218
        } else {
219
            /* @var $handle PDOQuery */
220
            $handle = $callback($sql);
221
        }
222
        $endtime   = microtime(true);
223
        $endmemory = memory_get_usage(true);
224
225
        $rawsql = $sql;
226
227
        // Prepared query are not so readable
228
        if (!empty($parameters)) {
229
            foreach ($parameters as $param) {
230
                $pos = strpos($sql, '?');
231
                if ($pos !== false) {
232
                    $param = '"'.$param.'"';
233
                    $sql   = substr_replace($sql, $param, $pos, 1);
234
                }
235
            }
236
        }
237
238
239
        // Sometimes, ugly spaces are there
240
        $sql = preg_replace('/[[:blank:]]+/', ' ', trim($sql));
241
242
        $shortsql = $sql;
243
244
        // Sometimes, the select statement can be very long and unreadable
245
        $matches = null;
246
        preg_match_all('/SELECT(.+?) FROM/is', $sql, $matches);
247
        $select  = empty($matches[1]) ? null : trim($matches[1][0]);
248
        if (strlen($select) > 100) {
249
            $shortsql = str_replace($select, '"ClickToShowFields"', $sql);
250
        } else {
251
            $select = null;
252
        }
253
254
        $this->queries[] = array(
255
            'raw_query' => $rawsql,
256
            'short_query' => $shortsql,
257
            'select' => $select,
258
            'query' => $sql,
259
            'start_time' => $starttime,
260
            'end_time' => $endtime,
261
            'duration' => $endtime - $starttime,
262
            'memory' => $endmemory - $startmemory,
263
            'rows' => $handle ? $handle->numRecords() : null,
264
            'success' => $handle ? true : false,
265
            'database' => $this->getSelectedDatabase(),
266
            'source' => $this->findSource ? $this->findSource() : null
267
        );
268
        return $handle;
269
    }
270
271
    protected function findSource()
272
    {
273
        $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
274
275
        // Not relevant to determine source
276
        $internalClasses = array(
277
            DB::class, SQLExpression::class, DataList::class, DataObject::class,
278
            DataQuery::class, SQLSelect::class, 'SQLQuery', Map::class, ListDecorator::class, 'Object'
279
        );
280
281
        $viewerClasses = array(
282
            SSViewer_DataPresenter::class, SSViewer_Scope::class, SSViewer::class,
283
            ViewableData::class
284
        );
285
286
        $sources = array();
287
        foreach ($traces as $trace) {
288
            $class    = isset($trace['class']) ? $trace['class'] : null;
289
            $line     = isset($trace['line']) ? $trace['line'] : null;
290
            $function = isset($trace['function']) ? $trace['function'] : null;
291
            $type     = isset($trace['type']) ? $trace['type'] : '::';
292
293
            /* @var $object SSViewer */
294
            $object = isset($trace['object']) ? $trace['object'] : null;
295
296
            if (!$class) {
297
                continue;
298
            }
299
            if ($function && $function == '{closure}') {
300
                continue;
301
            }
302
            if (strpos($class, DebugBar::class) === 0) {
303
                continue;
304
            }
305
            if (in_array($class, $internalClasses)) {
306
                continue;
307
            }
308
            if (in_array($class, $viewerClasses)) {
309
                if ($function == 'includeGeneratedTemplate') {
310
                    $templates = $object->templates();
311
312
                    $template = null;
313
                    if (isset($templates['main'])) {
314
                        $template = basename($templates['main']);
315
                    } else {
316
                        $keys = array_keys($templates);
317
                        $key  = reset($keys);
318
                        if (isset($templates[$key])) {
319
                            $template = $key.':'.basename($templates[$key]);
320
                        }
321
                    }
322
                    if (!empty($template)) {
323
                        $sources[] = $template;
324
                    }
325
                }
326
                continue;
327
            }
328
329
            $name = $class;
330
            if ($function) {
331
                $name .= $type.$function;
332
            }
333
            if ($line) {
334
                $name .= ':'.$line;
335
            }
336
337
            $sources[] = $name;
338
339
            if (count($sources) > 3) {
340
                break;
341
            }
342
343
344
            // We reached a Controller, exit loop
345
            if ($object && $object instanceof Controller) {
346
                break;
347
            }
348
        }
349
350
        if (empty($sources)) {
351
            return 'Undefined source';
352
        }
353
        return implode(' > ', $sources);
354
    }
355
356
    /**
357
     * Execute the given SQL query.
358
     *
359
     * @param string $sql The SQL query to execute
360
     * @param int $errorLevel The level of error reporting to enable for the query
361
     * @return SS_Query
362
     */
363
    public function query($sql, $errorLevel = E_USER_ERROR)
364
    {
365
        // Check if we should only preview this query
366
        if ($this->previewWrite($sql)) {
367
            return;
368
        }
369
370
        if (!$this->connector) {
371
            $self = $this;
372
            return $this->benchmarkQuery(
373
                $sql,
374
                function ($sql) use ($self, $errorLevel) {
375
                    return $self->oldQuery($sql, $errorLevel);
376
                }
377
            );
378
        }
379
380
        // Benchmark query
381
        $connector = $this->connector;
382
        return $this->benchmarkQuery(
383
            $sql,
384
            function ($sql) use ($connector, $errorLevel) {
385
                return $connector->query($sql, $errorLevel);
386
            }
387
        );
388
    }
389
390
    public function oldQuery($sql, $errorLevel = E_USER_ERROR)
391
    {
392
        return $this->realConn->query($sql, $errorLevel);
393
    }
394
395
    /**
396
     * Execute the given SQL parameterised query with the specified arguments
397
     *
398
     * @param string $sql The SQL query to execute. The ? character will denote parameters.
399
     * @param array $parameters An ordered list of arguments.
400
     * @param int $errorLevel The level of error reporting to enable for the query
401
     * @return SS_Query
402
     */
403
    public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR)
404
    {
405
        // Check if we should only preview this query
406
        if ($this->previewWrite($sql)) {
407
            return;
408
        }
409
410
        // Benchmark query
411
        $connector = $this->connector;
412
        return $this->benchmarkQuery(
413
            array($sql, $parameters),
0 ignored issues
show
Documentation introduced by
array($sql, $parameters) is of type array<integer,string|arr...:"string","1":"array"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
414
            function ($sql) use ($connector, $parameters, $errorLevel) {
415
                return $connector->preparedQuery($sql, $parameters, $errorLevel);
416
            }
417
        );
418
    }
419
420
    /**
421
     * @return array
422
     */
423
    public function getQueries()
424
    {
425
        return $this->queries;
426
    }
427
428
    /**
429
     * @param string $name
430
     * @param array $arguments
431
     * @return mixed
432
     */
433
    public function __call($name, $arguments)
434
    {
435
        return call_user_func_array(array($this->realConn, $name), $arguments);
436
    }
437
438
    public function addslashes($val)
0 ignored issues
show
Unused Code introduced by
The parameter $val is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
439
    {
440
        return call_user_func_array(
441
            array($this->realConn, __FUNCTION__),
442
            func_get_args()
443
        );
444
    }
445
446 View Code Duplication
    public function alterTable(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
447
        $table,
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
448
        $newFields = null,
0 ignored issues
show
Unused Code introduced by
The parameter $newFields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
449
        $newIndexes = null,
0 ignored issues
show
Unused Code introduced by
The parameter $newIndexes is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
450
        $alteredFields = null,
0 ignored issues
show
Unused Code introduced by
The parameter $alteredFields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
451
        $alteredIndexes = null,
0 ignored issues
show
Unused Code introduced by
The parameter $alteredIndexes is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
452
        $alteredOptions = null,
0 ignored issues
show
Unused Code introduced by
The parameter $alteredOptions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
453
        $advancedOptions = null
0 ignored issues
show
Unused Code introduced by
The parameter $advancedOptions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
454
    ) {
455
        return call_user_func_array(
456
            array($this->realConn, __FUNCTION__),
457
            func_get_args()
458
        );
459
    }
460
461 View Code Duplication
    public function comparisonClause(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
462
        $field,
463
        $value,
464
        $exact = false,
465
        $negate = false,
466
        $caseSensitive = false,
467
        $parameterised = false
468
    ) {
469
        return call_user_func_array(
470
            array($this->realConn, __FUNCTION__),
471
            func_get_args()
472
        );
473
    }
474
475
    public function createDatabase()
476
    {
477
        return call_user_func_array(
478
            array($this->realConn, __FUNCTION__),
479
            func_get_args()
480
        );
481
    }
482
483
    public function createField($table, $field, $spec)
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $spec is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
484
    {
485
        return call_user_func_array(
486
            array($this->realConn, __FUNCTION__),
487
            func_get_args()
488
        );
489
    }
490
491 View Code Duplication
    public function createTable(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
492
        $table,
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
493
        $fields = null,
0 ignored issues
show
Unused Code introduced by
The parameter $fields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
494
        $indexes = null,
0 ignored issues
show
Unused Code introduced by
The parameter $indexes is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
495
        $options = null,
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
496
        $advancedOptions = null
0 ignored issues
show
Unused Code introduced by
The parameter $advancedOptions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
497
    ) {
498
        return call_user_func_array(
499
            array($this->realConn, __FUNCTION__),
500
            func_get_args()
501
        );
502
    }
503
504
    public function datetimeDifferenceClause($date1, $date2)
505
    {
506
        return call_user_func_array(
507
            array($this->realConn, __FUNCTION__),
508
            func_get_args()
509
        );
510
    }
511
512
    public function datetimeIntervalClause($date, $interval)
513
    {
514
        return call_user_func_array(
515
            array($this->realConn, __FUNCTION__),
516
            func_get_args()
517
        );
518
    }
519
520
    public function enumValuesForField($tableName, $fieldName)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fieldName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
521
    {
522
        return call_user_func_array(
523
            array($this->realConn, __FUNCTION__),
524
            func_get_args()
525
        );
526
    }
527
528
    public function fieldList($table)
0 ignored issues
show
Unused Code introduced by
The parameter $table is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
529
    {
530
        return call_user_func_array(
531
            array($this->realConn, __FUNCTION__),
532
            func_get_args()
533
        );
534
    }
535
536
    public function formattedDatetimeClause($date, $format)
537
    {
538
        return call_user_func_array(
539
            array($this->realConn, __FUNCTION__),
540
            func_get_args()
541
        );
542
    }
543
544
    public function getConnect($parameters)
0 ignored issues
show
Unused Code introduced by
The parameter $parameters is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
545
    {
546
        return call_user_func_array(
547
            array($this->realConn, __FUNCTION__),
548
            func_get_args()
549
        );
550
    }
551
552
    public function getGeneratedID($table)
553
    {
554
        return call_user_func_array(
555
            array($this->realConn, __FUNCTION__),
556
            func_get_args()
557
        );
558
    }
559
560
    public function hasTable($tableName)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
561
    {
562
        return call_user_func_array(
563
            array($this->realConn, __FUNCTION__),
564
            func_get_args()
565
        );
566
    }
567
568
    public function isActive()
569
    {
570
        return call_user_func_array(
571
            array($this->realConn, __FUNCTION__),
572
            func_get_args()
573
        );
574
    }
575
576
    public function renameField($tableName, $oldName, $newName)
0 ignored issues
show
Unused Code introduced by
The parameter $tableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $oldName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $newName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
577
    {
578
        return call_user_func_array(
579
            array($this->realConn, __FUNCTION__),
580
            func_get_args()
581
        );
582
    }
583
584
    public function renameTable($oldTableName, $newTableName)
0 ignored issues
show
Unused Code introduced by
The parameter $oldTableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $newTableName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
585
    {
586
        return call_user_func_array(
587
            array($this->realConn, __FUNCTION__),
588
            func_get_args()
589
        );
590
    }
591
592
    public function supportsTimezoneOverride()
593
    {
594
        return call_user_func_array(
595
            array($this->realConn, __FUNCTION__),
596
            func_get_args()
597
        );
598
    }
599
600
    public function supportsTransactions()
601
    {
602
        return call_user_func_array(
603
            array($this->realConn, __FUNCTION__),
604
            func_get_args()
605
        );
606
    }
607
608
    public function tableList()
609
    {
610
        return call_user_func_array(
611
            array($this->realConn, __FUNCTION__),
612
            func_get_args()
613
        );
614
    }
615
616
    public function transactionEnd($chain = false)
617
    {
618
        return call_user_func_array(
619
            array($this->realConn, __FUNCTION__),
620
            func_get_args()
621
        );
622
    }
623
624
    public function transactionRollback($savepoint = false)
625
    {
626
        return call_user_func_array(
627
            array($this->realConn, __FUNCTION__),
628
            func_get_args()
629
        );
630
    }
631
632
    public function transactionSavepoint($savepoint)
633
    {
634
        return call_user_func_array(
635
            array($this->realConn, __FUNCTION__),
636
            func_get_args()
637
        );
638
    }
639
640
    public function transactionStart($transaction_mode = false, $session_characteristics = false)
641
    {
642
        return call_user_func_array(
643
            array($this->realConn, __FUNCTION__),
644
            func_get_args()
645
        );
646
    }
647
648
    public function clearTable($table)
649
    {
650
        return call_user_func_array(
651
            array($this->realConn, __FUNCTION__),
652
            func_get_args()
653
        );
654
    }
655
656
    public function getDatabaseServer()
657
    {
658
        return call_user_func_array(
659
            array($this->realConn, __FUNCTION__),
660
            func_get_args()
661
        );
662
    }
663
664
    public function now()
665
    {
666
        return call_user_func_array(
667
            array($this->realConn, __FUNCTION__),
668
            func_get_args()
669
        );
670
    }
671
672
    public function random()
673
    {
674
        return call_user_func_array(
675
            array($this->realConn, __FUNCTION__),
676
            func_get_args()
677
        );
678
    }
679
680
    public function searchEngine(
681
        $classesToSearch,
682
        $keywords,
683
        $start,
684
        $pageLength,
685
        $sortBy = "Relevance DESC",
686
        $extraFilter = "",
687
        $booleanSearch = false,
688
        $alternativeFileFilter = "",
689
        $invertedMatch = false
690
    ) {
691
        return call_user_func_array(
692
            array($this->realConn, __FUNCTION__),
693
            func_get_args()
694
        );
695
    }
696
697
    public function supportsCollations()
698
    {
699
        return call_user_func_array(
700
            array($this->realConn, __FUNCTION__),
701
            func_get_args()
702
        );
703
    }
704
}
705