Passed
Push — fix-8379 ( 67d6d1...73dd0e )
by Sam
07:16
created

DB::replace_parameter()   B

Complexity

Conditions 11
Paths 2

Size

Total Lines 50
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 30
nc 2
nop 4
dl 0
loc 50
rs 7.3166
c 0
b 0
f 0

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 SilverStripe\ORM;
4
5
use BadMethodCallException;
6
use InvalidArgumentException;
7
use SilverStripe\Control\Director;
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Core\Convert;
11
use SilverStripe\Core\Environment;
12
use SilverStripe\Core\Injector\Injector;
13
use SilverStripe\Dev\Deprecation;
14
use SilverStripe\ORM\Connect\Database;
15
use SilverStripe\ORM\Connect\DBConnector;
16
use SilverStripe\ORM\Connect\DBSchemaManager;
17
use SilverStripe\ORM\Connect\Query;
18
use SilverStripe\ORM\Queries\SQLExpression;
19
20
/**
21
 * Global database interface, complete with static methods.
22
 * Use this class for interacting with the database.
23
 */
24
class DB
25
{
26
27
    /**
28
     * This constant was added in SilverStripe 2.4 to indicate that SQL-queries
29
     * should now use ANSI-compatible syntax.  The most notable affect of this
30
     * change is that table and field names should be escaped with double quotes
31
     * and not backticks
32
     */
33
    const USE_ANSI_SQL = true;
34
35
    /**
36
     * Session key for alternative database name
37
     */
38
    const ALT_DB_KEY = 'alternativeDatabaseName';
39
40
    /**
41
     * Allow alternative DB to be disabled.
42
     * Necessary for DB backed session store to work.
43
     *
44
     * @config
45
     * @var bool
46
     */
47
    private static $alternative_database_enabled = true;
0 ignored issues
show
introduced by
The private property $alternative_database_enabled is not used, and could be removed.
Loading history...
48
49
    /**
50
     * The global database connection.
51
     *
52
     * @var Database
53
     */
54
    protected static $connections = [];
55
56
    /**
57
     * List of configurations for each connection
58
     *
59
     * @var array List of configs each in the $databaseConfig format
60
     */
61
    protected static $configs = [];
62
63
64
65
    /**
66
     * The last SQL query run.
67
     * @var string
68
     */
69
    public static $lastQuery;
70
71
    /**
72
     * Internal flag to keep track of when db connection was attempted.
73
     */
74
    private static $connection_attempted = false;
75
76
    /**
77
     * Set the global database connection.
78
     * Pass an object that's a subclass of SS_Database.  This object will be used when {@link DB::query()}
79
     * is called.
80
     *
81
     * @param Database $connection The connecton object to set as the connection.
82
     * @param string $name The name to give to this connection.  If you omit this argument, the connection
83
     * will be the default one used by the ORM.  However, you can store other named connections to
84
     * be accessed through DB::get_conn($name).  This is useful when you have an application that
85
     * needs to connect to more than one database.
86
     */
87
    public static function set_conn(Database $connection, $name = 'default')
88
    {
89
        self::$connections[$name] = $connection;
90
    }
91
92
    /**
93
     * Get the global database connection.
94
     *
95
     * @param string $name An optional name given to a connection in the DB::setConn() call.  If omitted,
96
     * the default connection is returned.
97
     * @return Database
98
     */
99
    public static function get_conn($name = 'default')
100
    {
101
        if (isset(self::$connections[$name])) {
102
            return self::$connections[$name];
103
        }
104
105
        // lazy connect
106
        $config = static::getConfig($name);
107
        if ($config) {
108
            return static::connect($config, $name);
109
        }
110
111
        return null;
112
    }
113
114
    /**
115
     * @deprecated since version 4.0 Use DB::get_conn instead
116
     * @todo PSR-2 standardisation will probably un-deprecate this
117
     */
118
    public static function getConn($name = 'default')
119
    {
120
        Deprecation::notice('4.0', 'Use DB::get_conn instead');
121
        return self::get_conn($name);
122
    }
123
124
    /**
125
     * Retrieves the schema manager for the current database
126
     *
127
     * @param string $name An optional name given to a connection in the DB::setConn() call.  If omitted,
128
     * the default connection is returned.
129
     * @return DBSchemaManager
130
     */
131
    public static function get_schema($name = 'default')
132
    {
133
        $connection = self::get_conn($name);
134
        if ($connection) {
0 ignored issues
show
introduced by
$connection is of type SilverStripe\ORM\Connect\Database, thus it always evaluated to true.
Loading history...
135
            return $connection->getSchemaManager();
136
        }
137
        return null;
138
    }
139
140
    /**
141
     * Builds a sql query with the specified connection
142
     *
143
     * @param SQLExpression $expression The expression object to build from
144
     * @param array $parameters Out parameter for the resulting query parameters
145
     * @param string $name An optional name given to a connection in the DB::setConn() call.  If omitted,
146
     * the default connection is returned.
147
     * @return string The resulting SQL as a string
148
     */
149
    public static function build_sql(SQLExpression $expression, &$parameters, $name = 'default')
150
    {
151
        $connection = self::get_conn($name);
152
        if ($connection) {
0 ignored issues
show
introduced by
$connection is of type SilverStripe\ORM\Connect\Database, thus it always evaluated to true.
Loading history...
153
            return $connection->getQueryBuilder()->buildSQL($expression, $parameters);
154
        } else {
155
            $parameters = array();
156
            return null;
157
        }
158
    }
159
160
    /**
161
     * Retrieves the connector object for the current database
162
     *
163
     * @param string $name An optional name given to a connection in the DB::setConn() call.  If omitted,
164
     * the default connection is returned.
165
     * @return DBConnector
166
     */
167
    public static function get_connector($name = 'default')
168
    {
169
        $connection = self::get_conn($name);
170
        if ($connection) {
0 ignored issues
show
introduced by
$connection is of type SilverStripe\ORM\Connect\Database, thus it always evaluated to true.
Loading history...
171
            return $connection->getConnector();
172
        }
173
        return null;
174
    }
175
176
    /**
177
     * Set an alternative database in a browser cookie,
178
     * with the cookie lifetime set to the browser session.
179
     * This is useful for integration testing on temporary databases.
180
     *
181
     * There is a strict naming convention for temporary databases to avoid abuse:
182
     * <prefix> (default: 'ss_') + tmpdb + <7 digits>
183
     * As an additional security measure, temporary databases will
184
     * be ignored in "live" mode.
185
     *
186
     * Note that the database will be set on the next request.
187
     * Set it to null to revert to the main database.
188
     *
189
     * @param string $name
190
     */
191
    public static function set_alternative_database_name($name = null)
192
    {
193
        // Ignore if disabled
194
        if (!Config::inst()->get(static::class, 'alternative_database_enabled')) {
195
            return;
196
        }
197
        // Skip if CLI
198
        if (Director::is_cli()) {
199
            return;
200
        }
201
        // Validate name
202
        if ($name && !self::valid_alternative_database_name($name)) {
203
            throw new InvalidArgumentException(sprintf(
204
                'Invalid alternative database name: "%s"',
205
                $name
206
            ));
207
        }
208
209
        // Set against session
210
        if (!Injector::inst()->has(HTTPRequest::class)) {
211
            return;
212
        }
213
        /** @var HTTPRequest $request */
214
        $request = Injector::inst()->get(HTTPRequest::class);
215
        if ($name) {
216
            $request->getSession()->set(self::ALT_DB_KEY, $name);
217
        } else {
218
            $request->getSession()->clear(self::ALT_DB_KEY);
219
        }
220
    }
221
222
    /**
223
     * Get the name of the database in use
224
     *
225
     * @return string|false Name of temp database, or false if not set
226
     */
227
    public static function get_alternative_database_name()
228
    {
229
        // Ignore if disabled
230
        if (!Config::inst()->get(static::class, 'alternative_database_enabled')) {
231
            return false;
232
        }
233
        // Skip if CLI
234
        if (Director::is_cli()) {
235
            return false;
236
        }
237
        // Skip if there's no request object yet
238
        if (!Injector::inst()->has(HTTPRequest::class)) {
239
            return null;
240
        }
241
        /** @var HTTPRequest $request */
242
        $request = Injector::inst()->get(HTTPRequest::class);
243
        // Skip if the session hasn't been started
244
        if (!$request->getSession()->isStarted()) {
245
            return null;
246
        }
247
248
        $name = $request->getSession()->get(self::ALT_DB_KEY);
249
        if (self::valid_alternative_database_name($name)) {
250
            return $name;
251
        }
252
253
        return false;
254
    }
255
256
    /**
257
     * Determines if the name is valid, as a security
258
     * measure against setting arbitrary databases.
259
     *
260
     * @param string $name
261
     * @return bool
262
     */
263
    public static function valid_alternative_database_name($name)
264
    {
265
        if (Director::isLive() || empty($name)) {
266
            return false;
267
        }
268
269
        $prefix = Environment::getEnv('SS_DATABASE_PREFIX') ?: 'ss_';
270
        $pattern = strtolower(sprintf('/^%stmpdb\d{7}$/', $prefix));
271
        return (bool)preg_match($pattern, $name);
272
    }
273
274
    /**
275
     * Specify connection to a database
276
     *
277
     * Given the database configuration, this method will create the correct
278
     * subclass of {@link SS_Database}.
279
     *
280
     * @param array $databaseConfig A map of options. The 'type' is the name of the
281
     * subclass of SS_Database to use. For the rest of the options, see the specific class.
282
     * @param string $label identifier for the connection
283
     * @return Database
284
     */
285
    public static function connect($databaseConfig, $label = 'default')
286
    {
287
        // This is used by the "testsession" module to test up a test session using an alternative name
288
        if ($name = self::get_alternative_database_name()) {
289
            $databaseConfig['database'] = $name;
290
        }
291
292
        if (!isset($databaseConfig['type']) || empty($databaseConfig['type'])) {
293
            throw new InvalidArgumentException("DB::connect: Not passed a valid database config");
294
        }
295
296
        self::$connection_attempted = true;
297
298
        $dbClass = $databaseConfig['type'];
299
300
        // Using Injector->create allows us to use registered configurations
301
        // which may or may not map to explicit objects
302
        $conn = Injector::inst()->create($dbClass);
303
        self::set_conn($conn, $label);
304
        $conn->connect($databaseConfig);
305
306
        return $conn;
307
    }
308
309
    /**
310
     * Set config for a lazy-connected database
311
     *
312
     * @param array $databaseConfig
313
     * @param string $name
314
     */
315
    public static function setConfig($databaseConfig, $name = 'default')
316
    {
317
        static::$configs[$name] = $databaseConfig;
318
    }
319
320
    /**
321
     * Get the named connection config
322
     *
323
     * @param string $name
324
     * @return mixed
325
     */
326
    public static function getConfig($name = 'default')
327
    {
328
        if (isset(static::$configs[$name])) {
329
            return static::$configs[$name];
330
        }
331
    }
332
333
    /**
334
     * Returns true if a database connection has been attempted.
335
     * In particular, it lets the caller know if we're still so early in the execution pipeline that
336
     * we haven't even tried to connect to the database yet.
337
     */
338
    public static function connection_attempted()
339
    {
340
        return self::$connection_attempted;
341
    }
342
343
    /**
344
     * Execute the given SQL query.
345
     * @param string $sql The SQL query to execute
346
     * @param int $errorLevel The level of error reporting to enable for the query
347
     * @return Query
348
     */
349
    public static function query($sql, $errorLevel = E_USER_ERROR)
350
    {
351
        self::$lastQuery = $sql;
352
353
        return self::get_conn()->query($sql, $errorLevel);
354
    }
355
356
    /**
357
     * Helper function for generating a list of parameter placeholders for the
358
     * given argument(s)
359
     *
360
     * @param array|integer $input An array of items needing placeholders, or a
361
     * number to specify the number of placeholders
362
     * @param string $join The string to join each placeholder together with
363
     * @return string|null Either a list of placeholders, or null
364
     */
365
    public static function placeholders($input, $join = ', ')
366
    {
367
        if (is_array($input)) {
368
            $number = count($input);
369
        } elseif (is_numeric($input)) {
0 ignored issues
show
introduced by
The condition is_numeric($input) is always true.
Loading history...
370
            $number = intval($input);
371
        } else {
372
            return null;
373
        }
374
        if ($number === 0) {
375
            return null;
376
        }
377
        return implode($join, array_fill(0, $number, '?'));
378
    }
379
380
    /**
381
     * @param string $sql The parameterised query
382
     * @param array $parameters The parameters to inject into the query
383
     *
384
     * @return string
385
     */
386
    public static function inline_parameters($sql, $parameters)
387
    {
388
        $segments = preg_split('/\?/', $sql);
389
        $joined = '';
390
        $inString = false;
391
        $numSegments = count($segments);
0 ignored issues
show
Bug introduced by
It seems like $segments can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

391
        $numSegments = count(/** @scrutinizer ignore-type */ $segments);
Loading history...
392
        for ($i = 0; $i < $numSegments; $i++) {
393
            $input = $segments[$i];
394
            // Append next segment
395
            $joined .= $segments[$i];
396
            // Don't add placeholder after last segment
397
            if ($i === $numSegments - 1) {
398
                break;
399
            }
400
            // check string escape on previous fragment
401
            // Remove escaped backslashes, count them!
402
            $input = preg_replace('/\\\\\\\\/', '', $input);
403
            // Count quotes
404
            $totalQuotes = substr_count($input, "'"); // Includes double quote escaped quotes
405
            $escapedQuotes = substr_count($input, "\\'");
406
            if ((($totalQuotes - $escapedQuotes) % 2) !== 0) {
407
                $inString = !$inString;
0 ignored issues
show
introduced by
The condition $inString is always false.
Loading history...
408
            }
409
            // Append placeholder replacement
410
            if ($inString) {
411
                // Literal question mark
412
                $joined .= '?';
413
                continue;
414
            }
415
416
            // Encode and insert next parameter
417
            $next = array_shift($parameters);
418
            if (is_array($next) && isset($next['value'])) {
419
                $next = $next['value'];
420
            }
421
            if (is_bool($next)) {
422
                $value = $next ? '1' : '0';
423
            } elseif (is_int($next)) {
424
                $value = $next;
425
            } else {
426
                $value = (DB::get_conn() !== null) ? Convert::raw2sql($next, true) : $next;
427
            }
428
            $joined .= $value;
429
        }
430
        return $joined;
431
    }
432
433
434
    /**
435
     * Replace 1 parameter with the given value
436
     * For example, you can use this to replace a parameter with a column name instead of a literal
437
     * @param string $sql The parameterised query
438
     * @param int $paramIdx The 0-based position of the parameter
439
     * @param array $replacement The value to insert into the queyr
440
     * @param bool $skipEscaping Set to true to insert the value as-is, with no escaping. Use with caution!
441
     *
442
     * @return string
443
     */
444
    public static function replace_parameter($sql, $paramIdx, $replacement, $skipEscaping = false)
445
    {
446
        $segments = preg_split('/\?/', $sql);
447
        $joined = '';
448
        $inString = false;
449
        $numSegments = count($segments);
0 ignored issues
show
Bug introduced by
It seems like $segments can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

449
        $numSegments = count(/** @scrutinizer ignore-type */ $segments);
Loading history...
450
        $currentParamIdx = 0;
451
452
        for ($i = 0; $i < $numSegments; $i++) {
453
            $input = $segments[$i];
454
            // Append next segment
455
            $joined .= $segments[$i];
456
            // Don't add placeholder after last segment
457
            if ($i === $numSegments - 1) {
458
                break;
459
            }
460
            // check string escape on previous fragment
461
            // Remove escaped backslashes, count them!
462
            $input = preg_replace('/\\\\\\\\/', '', $input);
463
            // Count quotes
464
            $totalQuotes = substr_count($input, "'"); // Includes double quote escaped quotes
465
            $escapedQuotes = substr_count($input, "\\'");
466
            if ((($totalQuotes - $escapedQuotes) % 2) !== 0) {
467
                $inString = !$inString;
0 ignored issues
show
introduced by
The condition $inString is always false.
Loading history...
468
            }
469
470
            // Append placeholder replacement
471
            if ($inString) {
472
                // Literal question mark
473
                $joined .= '?';
474
                continue;
475
            }
476
477
            // If we've found the right parameter, replace it
478
            if ($currentParamIdx == $paramIdx) {
479
                if ($skipEscaping) {
480
                    $value = $replacement;
481
                } elseif (is_bool($replacement)) {
482
                    $value = $replacement ? '1' : '0';
483
                } elseif (is_int($replacement)) {
484
                    $value = $replacement;
485
                } else {
486
                    $value = (DB::get_conn() !== null) ? Convert::raw2sql($replacement, true) : $replacement;
487
                }
488
                $joined .= $value;
489
            }
490
491
            $currentParamIdx++;
492
        }
493
        return $joined;
494
    }
495
496
    /**
497
     * Execute the given SQL parameterised query with the specified arguments
498
     *
499
     * @param string $sql The SQL query to execute. The ? character will denote parameters.
500
     * @param array $parameters An ordered list of arguments.
501
     * @param int $errorLevel The level of error reporting to enable for the query
502
     * @return Query
503
     */
504
    public static function prepared_query($sql, $parameters, $errorLevel = E_USER_ERROR)
505
    {
506
        self::$lastQuery = $sql;
507
508
        return self::get_conn()->preparedQuery($sql, $parameters, $errorLevel);
509
    }
510
511
    /**
512
     * Execute a complex manipulation on the database.
513
     * A manipulation is an array of insert / or update sequences.  The keys of the array are table names,
514
     * and the values are map containing 'command' and 'fields'.  Command should be 'insert' or 'update',
515
     * and fields should be a map of field names to field values, including quotes.  The field value can
516
     * also be a SQL function or similar.
517
     *
518
     * Example:
519
     * <code>
520
     * array(
521
     *   // Command: insert
522
     *   "table name" => array(
523
     *      "command" => "insert",
524
     *      "fields" => array(
525
     *         "ClassName" => "'MyClass'", // if you're setting a literal, you need to escape and provide quotes
526
     *         "Created" => "now()", // alternatively, you can call DB functions
527
     *         "ID" => 234,
528
     *       ),
529
     *      "id" => 234 // an alternative to providing ID in the fields list
530
     *    ),
531
     *
532
     *   // Command: update
533
     *   "other table" => array(
534
     *      "command" => "update",
535
     *      "fields" => array(
536
     *         "ClassName" => "'MyClass'",
537
     *         "LastEdited" => "now()",
538
     *       ),
539
     *      "where" => "ID = 234",
540
     *      "id" => 234 // an alternative to providing a where clause
541
     *    ),
542
     * )
543
     * </code>
544
     *
545
     * You'll note that only one command on a given table can be called.
546
     * That's a limitation of the system that's due to it being written for {@link DataObject::write()},
547
     * which needs to do a single write on a number of different tables.
548
     *
549
     * @todo Update this to support paramaterised queries
550
     *
551
     * @param array $manipulation
552
     */
553
    public static function manipulate($manipulation)
554
    {
555
        self::$lastQuery = $manipulation;
0 ignored issues
show
Documentation Bug introduced by
It seems like $manipulation of type array is incompatible with the declared type string of property $lastQuery.

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...
556
        self::get_conn()->manipulate($manipulation);
557
    }
558
559
    /**
560
     * Get the autogenerated ID from the previous INSERT query.
561
     *
562
     * @param string $table
563
     * @return int
564
     */
565
    public static function get_generated_id($table)
566
    {
567
        return self::get_conn()->getGeneratedID($table);
568
    }
569
570
    /**
571
     * Check if the connection to the database is active.
572
     *
573
     * @return boolean
574
     */
575
    public static function is_active()
576
    {
577
        return ($conn = self::get_conn()) && $conn->isActive();
578
    }
579
580
    /**
581
     * Create the database and connect to it. This can be called if the
582
     * initial database connection is not successful because the database
583
     * does not exist.
584
     *
585
     * @param string $database Name of database to create
586
     * @return boolean Returns true if successful
587
     */
588
    public static function create_database($database)
589
    {
590
        return self::get_conn()->selectDatabase($database, true);
591
    }
592
593
    /**
594
     * Create a new table.
595
     * @param string $table The name of the table
596
     * @param array$fields A map of field names to field types
597
     * @param array $indexes A map of indexes
598
     * @param array $options An map of additional options.  The available keys are as follows:
599
     *   - 'MSSQLDatabase'/'MySQLDatabase'/'PostgreSQLDatabase' - database-specific options such as "engine"
600
     *     for MySQL.
601
     *   - 'temporary' - If true, then a temporary table will be created
602
     * @param array $advancedOptions Advanced creation options
603
     * @return string The table name generated.  This may be different from the table name, for example with
604
     * temporary tables.
605
     */
606
    public static function create_table(
607
        $table,
608
        $fields = null,
609
        $indexes = null,
610
        $options = null,
611
        $advancedOptions = null
612
    ) {
613
        return self::get_schema()->createTable($table, $fields, $indexes, $options, $advancedOptions);
614
    }
615
616
    /**
617
     * Create a new field on a table.
618
     * @param string $table Name of the table.
619
     * @param string $field Name of the field to add.
620
     * @param string $spec The field specification, eg 'INTEGER NOT NULL'
621
     */
622
    public static function create_field($table, $field, $spec)
623
    {
624
        return self::get_schema()->createField($table, $field, $spec);
625
    }
626
627
    /**
628
     * Generate the following table in the database, modifying whatever already exists
629
     * as necessary.
630
     *
631
     * @param string $table The name of the table
632
     * @param string $fieldSchema A list of the fields to create, in the same form as DataObject::$db
633
     * @param string $indexSchema A list of indexes to create.  The keys of the array are the names of the index.
634
     * The values of the array can be one of:
635
     *   - true: Create a single column index on the field named the same as the index.
636
     *   - array('fields' => array('A','B','C'), 'type' => 'index/unique/fulltext'): This gives you full
637
     *     control over the index.
638
     * @param boolean $hasAutoIncPK A flag indicating that the primary key on this table is an autoincrement type
639
     * @param string $options SQL statement to append to the CREATE TABLE call.
640
     * @param array $extensions List of extensions
641
     */
642
    public static function require_table(
643
        $table,
644
        $fieldSchema = null,
645
        $indexSchema = null,
646
        $hasAutoIncPK = true,
647
        $options = null,
648
        $extensions = null
649
    ) {
650
        self::get_schema()->requireTable($table, $fieldSchema, $indexSchema, $hasAutoIncPK, $options, $extensions);
0 ignored issues
show
Bug introduced by
It seems like $fieldSchema can also be of type string; however, parameter $fieldSchema of SilverStripe\ORM\Connect...Manager::requireTable() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

650
        self::get_schema()->requireTable($table, /** @scrutinizer ignore-type */ $fieldSchema, $indexSchema, $hasAutoIncPK, $options, $extensions);
Loading history...
Bug introduced by
It seems like $options can also be of type string; however, parameter $options of SilverStripe\ORM\Connect...Manager::requireTable() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

650
        self::get_schema()->requireTable($table, $fieldSchema, $indexSchema, $hasAutoIncPK, /** @scrutinizer ignore-type */ $options, $extensions);
Loading history...
Bug introduced by
It seems like $indexSchema can also be of type string; however, parameter $indexSchema of SilverStripe\ORM\Connect...Manager::requireTable() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

650
        self::get_schema()->requireTable($table, $fieldSchema, /** @scrutinizer ignore-type */ $indexSchema, $hasAutoIncPK, $options, $extensions);
Loading history...
651
    }
652
653
    /**
654
     * Generate the given field on the table, modifying whatever already exists as necessary.
655
     *
656
     * @param string $table The table name.
657
     * @param string $field The field name.
658
     * @param string $spec The field specification.
659
     */
660
    public static function require_field($table, $field, $spec)
661
    {
662
        self::get_schema()->requireField($table, $field, $spec);
663
    }
664
665
    /**
666
     * Generate the given index in the database, modifying whatever already exists as necessary.
667
     *
668
     * @param string $table The table name.
669
     * @param string $index The index name.
670
     * @param string|boolean $spec The specification of the index. See requireTable() for more information.
671
     */
672
    public static function require_index($table, $index, $spec)
673
    {
674
        self::get_schema()->requireIndex($table, $index, $spec);
675
    }
676
677
    /**
678
     * If the given table exists, move it out of the way by renaming it to _obsolete_(tablename).
679
     *
680
     * @param string $table The table name.
681
     */
682
    public static function dont_require_table($table)
683
    {
684
        self::get_schema()->dontRequireTable($table);
685
    }
686
687
    /**
688
     * See {@link SS_Database->dontRequireField()}.
689
     *
690
     * @param string $table The table name.
691
     * @param string $fieldName The field name not to require
692
     */
693
    public static function dont_require_field($table, $fieldName)
694
    {
695
        self::get_schema()->dontRequireField($table, $fieldName);
696
    }
697
698
    /**
699
     * Checks a table's integrity and repairs it if necessary.
700
     *
701
     * @param string $table The name of the table.
702
     * @return boolean Return true if the table has integrity after the method is complete.
703
     */
704
    public static function check_and_repair_table($table)
705
    {
706
        return self::get_schema()->checkAndRepairTable($table);
707
    }
708
709
    /**
710
     * Return the number of rows affected by the previous operation.
711
     *
712
     * @return integer The number of affected rows
713
     */
714
    public static function affected_rows()
715
    {
716
        return self::get_conn()->affectedRows();
717
    }
718
719
    /**
720
     * Returns a list of all tables in the database.
721
     * The table names will be in lower case.
722
     *
723
     * @return array The list of tables
724
     */
725
    public static function table_list()
726
    {
727
        return self::get_schema()->tableList();
728
    }
729
730
    /**
731
     * Get a list of all the fields for the given table.
732
     * Returns a map of field name => field spec.
733
     *
734
     * @param string $table The table name.
735
     * @return array The list of fields
736
     */
737
    public static function field_list($table)
738
    {
739
        return self::get_schema()->fieldList($table);
740
    }
741
742
    /**
743
     * Enable supression of database messages.
744
     *
745
     * @param bool $quiet
746
     */
747
    public static function quiet($quiet = true)
748
    {
749
        self::get_schema()->quiet($quiet);
750
    }
751
752
    /**
753
     * Show a message about database alteration
754
     *
755
     * @param string $message to display
756
     * @param string $type one of [created|changed|repaired|obsolete|deleted|error]
757
     */
758
    public static function alteration_message($message, $type = "")
759
    {
760
        self::get_schema()->alterationMessage($message, $type);
761
    }
762
}
763