2017-10-26 01:56:09 -05:00
< ? php
/**
* Database . php
*
* Checks the database for errors
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2021-02-09 00:29:04 +01:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2017-10-26 01:56:09 -05:00
*
2021-02-09 00:29:04 +01:00
* @ link https :// www . librenms . org
2017-10-26 01:56:09 -05:00
* @ copyright 2017 Tony Murray
* @ author Tony Murray < murraytony @ gmail . com >
*/
namespace LibreNMS\Validations ;
2018-10-23 15:56:09 -05:00
use Carbon\Carbon ;
use Carbon\CarbonInterval ;
2017-10-26 01:56:09 -05:00
use LibreNMS\Config ;
2018-10-23 15:56:09 -05:00
use LibreNMS\DB\Eloquent ;
2019-02-05 16:50:51 -06:00
use LibreNMS\DB\Schema ;
2017-10-26 01:56:09 -05:00
use LibreNMS\ValidationResult ;
use LibreNMS\Validator ;
use Symfony\Component\Yaml\Yaml ;
2018-02-27 09:57:20 -06:00
class Database extends BaseValidation
2017-10-26 01:56:09 -05:00
{
2021-03-11 11:41:44 +01:00
const MYSQL_MIN_VERSION = '5.7.7' ;
const MYSQL_MIN_VERSION_DATE = 'March, 2021' ;
2021-03-04 19:01:57 +01:00
const MYSQL_RECOMMENDED_VERSION = '8.0' ;
2021-03-11 11:41:44 +01:00
const MARIADB_MIN_VERSION = '10.2.2' ;
const MARIADB_MIN_VERSION_DATE = 'March, 2021' ;
2021-03-04 19:01:57 +01:00
const MARIADB_RECOMMENDED_VERSION = '10.5' ;
2017-10-26 01:56:09 -05:00
public function validate ( Validator $validator )
{
2021-05-13 07:18:54 -05:00
if ( ! Eloquent :: isConnected ()) {
2017-10-26 01:56:09 -05:00
return ;
}
2021-05-13 13:02:43 -05:00
$this -> validateSystem ( $validator );
if ( $this -> checkSchemaVersion ( $validator )) {
$this -> checkSchema ( $validator );
$this -> checkCollation ( $validator );
}
}
public function validateSystem ( Validator $validator )
{
2021-03-04 19:01:57 +01:00
$this -> checkVersion ( $validator );
2017-10-26 01:56:09 -05:00
$this -> checkMode ( $validator );
2018-10-23 15:56:09 -05:00
$this -> checkTime ( $validator );
2019-03-18 21:26:49 -05:00
$this -> checkMysqlEngine ( $validator );
2021-05-13 13:02:43 -05:00
}
2017-10-26 01:56:09 -05:00
2021-05-13 13:02:43 -05:00
private function checkSchemaVersion ( Validator $validator ) : bool
{
2021-05-13 07:18:54 -05:00
$current = \LibreNMS\DB\Schema :: getLegacySchema ();
2019-01-14 07:44:23 -05:00
$latest = 1000 ;
2017-10-26 01:56:09 -05:00
2019-01-14 07:44:23 -05:00
if ( $current === 0 || $current === $latest ) {
2019-02-06 10:53:25 -06:00
// Using Laravel migrations
2020-09-21 14:54:51 +02:00
if ( ! Schema :: isCurrent ()) {
2020-09-21 15:59:34 +02:00
$validator -> fail ( 'Your database is out of date!' , './lnms migrate' );
2020-09-21 14:54:51 +02:00
2021-05-13 13:02:43 -05:00
return false ;
2019-01-14 07:44:23 -05:00
}
2019-02-05 16:50:51 -06:00
2019-02-06 10:53:25 -06:00
$migrations = Schema :: getUnexpectedMigrations ();
if ( $migrations -> isNotEmpty ()) {
2020-09-21 15:59:34 +02:00
$validator -> warn ( 'Your database schema has extra migrations (' . $migrations -> implode ( ', ' ) .
2021-05-13 13:02:43 -05:00
'). If you just switched to the stable release from the daily release, your database is in between releases and this will be resolved with the next release.' );
2019-02-05 16:50:51 -06:00
}
2019-01-14 07:44:23 -05:00
} elseif ( $current < $latest ) {
2017-10-26 01:56:09 -05:00
$validator -> fail (
" Your database schema ( $current ) is older than the latest ( $latest ). " ,
2020-09-21 15:59:34 +02:00
'Manually run ./daily.sh, and check for any errors.'
2017-10-26 01:56:09 -05:00
);
2020-09-21 14:54:51 +02:00
2021-05-13 13:02:43 -05:00
return false ;
2017-10-26 01:56:09 -05:00
} elseif ( $current > $latest ) {
2018-12-13 14:16:08 +01:00
$validator -> warn ( " Your database schema ( $current ) is newer than expected ( $latest ). If you just switched to the stable release from the daily release, your database is in between releases and this will be resolved with the next release. " );
2017-10-26 01:56:09 -05:00
}
2021-05-13 13:02:43 -05:00
return true ;
2017-10-26 01:56:09 -05:00
}
2021-03-04 19:01:57 +01:00
private function checkVersion ( Validator $validator )
{
2021-08-09 18:33:31 -05:00
$version = Eloquent :: version ();
2021-03-04 19:01:57 +01:00
$version = explode ( '-' , $version );
if ( isset ( $version [ 1 ]) && $version [ 1 ] == 'MariaDB' ) {
if ( version_compare ( $version [ 0 ], self :: MARIADB_MIN_VERSION , '<=' )) {
$validator -> fail (
'MariaDB version ' . self :: MARIADB_MIN_VERSION . ' is the minimum supported version as of ' .
2021-06-14 13:33:59 -05:00
self :: MARIADB_MIN_VERSION_DATE . '.' ,
'Update MariaDB to a supported version, ' . self :: MARIADB_RECOMMENDED_VERSION . ' suggested.'
2021-03-04 19:01:57 +01:00
);
}
} else {
if ( version_compare ( $version [ 0 ], self :: MYSQL_MIN_VERSION , '<=' )) {
$validator -> fail (
'MySQL version ' . self :: MYSQL_MIN_VERSION . ' is the minimum supported version as of ' .
2021-06-14 13:33:59 -05:00
self :: MYSQL_MIN_VERSION_DATE . '.' ,
'Update MySQL to a supported version, ' . self :: MYSQL_RECOMMENDED_VERSION . ' suggested.'
2021-03-04 19:01:57 +01:00
);
}
}
}
2018-10-23 15:56:09 -05:00
private function checkTime ( Validator $validator )
{
2021-05-14 12:38:00 -05:00
$raw_time = Eloquent :: DB () -> selectOne ( 'SELECT NOW() as time' ) -> time ;
2018-10-23 15:56:09 -05:00
$db_time = new Carbon ( $raw_time );
$php_time = Carbon :: now ();
$diff = $db_time -> diffAsCarbonInterval ( $php_time );
if ( $diff -> compare ( CarbonInterval :: minute ( 1 )) > 0 ) {
$message = " Time between this server and the mysql database is off \n " ;
2020-09-21 15:59:34 +02:00
$message .= ' Mysql time ' . $db_time -> toDateTimeString () . PHP_EOL ;
$message .= ' PHP time ' . $php_time -> toDateTimeString () . PHP_EOL ;
2018-10-23 15:56:09 -05:00
$validator -> fail ( $message );
}
}
2017-10-26 01:56:09 -05:00
private function checkMode ( Validator $validator )
{
// Test for lower case table name support
2021-05-13 07:18:54 -05:00
$lc_mode = Eloquent :: DB () -> selectOne ( 'SELECT @@global.lower_case_table_names as mode' ) -> mode ;
2017-10-26 01:56:09 -05:00
if ( $lc_mode != 0 ) {
$validator -> fail (
'You have lower_case_table_names set to 1 or true in mysql config.' ,
'Set lower_case_table_names=0 in your mysql config file in the [mysqld] section.'
);
}
}
2019-02-12 17:55:52 -06:00
private function checkMysqlEngine ( Validator $validator )
{
2020-09-21 14:54:51 +02:00
$db = \config ( 'database.connections.' . \config ( 'database.default' ) . '.database' );
2019-02-12 17:55:52 -06:00
$query = " SELECT `TABLE_NAME` FROM information_schema.tables WHERE `TABLE_SCHEMA` = ' $db ' && `ENGINE` != 'InnoDB' " ;
2021-05-13 07:18:54 -05:00
$tables = Eloquent :: DB () -> select ( $query );
2020-09-21 14:54:51 +02:00
if ( ! empty ( $tables )) {
2019-02-12 17:55:52 -06:00
$validator -> result (
2020-09-21 15:59:34 +02:00
ValidationResult :: warn ( 'Some tables are not using the recommended InnoDB engine, this may cause you issues.' )
2021-05-14 12:38:00 -05:00
-> setList ( 'Tables' , array_column ( $tables , 'TABLE_NAME' ))
2019-02-12 17:55:52 -06:00
);
}
}
2017-10-26 01:56:09 -05:00
private function checkCollation ( Validator $validator )
{
2021-05-13 07:18:54 -05:00
$db_name = Eloquent :: DB () -> selectOne ( 'SELECT DATABASE() as name' ) -> name ;
2018-04-11 10:15:13 -05:00
2017-10-26 01:56:09 -05:00
// Test for correct character set and collation
2020-11-05 18:19:15 -06:00
$db_collation_sql = " SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema . SCHEMATA S
WHERE schema_name = '$db_name' AND
2021-03-28 16:23:08 +02:00
( DEFAULT_CHARACTER_SET_NAME != 'utf8mb4' OR DEFAULT_COLLATION_NAME != 'utf8mb4_unicode_ci' ) " ;
2021-05-14 12:38:00 -05:00
$collation = Eloquent :: DB () -> selectOne ( $db_collation_sql );
2017-10-26 01:56:09 -05:00
if ( empty ( $collation ) !== true ) {
$validator -> fail (
2021-05-14 12:38:00 -05:00
" MySQL Database collation is wrong: $collation->DEFAULT_CHARACTER_SET_NAME $collation->DEFAULT_COLLATION_NAME " ,
2021-03-28 16:23:08 +02:00
'Check https://community.librenms.org/t/new-default-database-charset-collation/14956 for info on how to fix.'
2017-10-26 01:56:09 -05:00
);
}
2020-11-05 18:19:15 -06:00
$table_collation_sql = " SELECT T.TABLE_NAME, C.CHARACTER_SET_NAME, C.COLLATION_NAME
FROM information_schema . TABLES AS T , information_schema . COLLATION_CHARACTER_SET_APPLICABILITY AS C
2018-04-11 10:15:13 -05:00
WHERE C . collation_name = T . table_collation AND T . table_schema = '$db_name' AND
2021-03-28 16:23:08 +02:00
( C . CHARACTER_SET_NAME != 'utf8mb4' OR C . COLLATION_NAME != 'utf8mb4_unicode_ci' ); " ;
2021-05-13 07:18:54 -05:00
$collation_tables = Eloquent :: DB () -> select ( $table_collation_sql );
2017-10-26 01:56:09 -05:00
if ( empty ( $collation_tables ) !== true ) {
$result = ValidationResult :: fail ( 'MySQL tables collation is wrong: ' )
2021-03-28 16:23:08 +02:00
-> setFix ( 'Check https://community.librenms.org/t/new-default-database-charset-collation/14956 for info on how to fix.' )
2021-05-14 12:38:00 -05:00
-> setList ( 'Tables' , array_map ( function ( $row ) {
return " $row->TABLE_NAME $row->CHARACTER_SET_NAME $row->COLLATION_NAME " ;
}, $collation_tables ));
2017-10-26 01:56:09 -05:00
$validator -> result ( $result );
}
2020-11-05 18:19:15 -06:00
$column_collation_sql = " SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
2018-04-11 10:15:13 -05:00
FROM information_schema . COLUMNS WHERE TABLE_SCHEMA = '$db_name' AND
2021-03-28 16:23:08 +02:00
( CHARACTER_SET_NAME != 'utf8mb4' OR COLLATION_NAME != 'utf8mb4_unicode_ci' ); " ;
2021-05-13 07:18:54 -05:00
$collation_columns = Eloquent :: DB () -> select ( $column_collation_sql );
2017-10-26 01:56:09 -05:00
if ( empty ( $collation_columns ) !== true ) {
$result = ValidationResult :: fail ( 'MySQL column collation is wrong: ' )
2021-03-28 16:23:08 +02:00
-> setFix ( 'Check https://community.librenms.org/t/new-default-database-charset-collation/14956 for info on how to fix.' )
2021-05-14 12:38:00 -05:00
-> setList ( 'Columns' , array_map ( function ( $row ) {
return " $row->TABLE_NAME : $row->COLUMN_NAME $row->CHARACTER_SET_NAME $row->COLLATION_NAME " ;
}, $collation_columns ));
2017-10-26 01:56:09 -05:00
$validator -> result ( $result );
}
}
private function checkSchema ( Validator $validator )
{
$schema_file = Config :: get ( 'install_dir' ) . '/misc/db_schema.yaml' ;
2020-09-21 14:54:51 +02:00
if ( ! is_file ( $schema_file )) {
2017-10-26 01:56:09 -05:00
$validator -> warn ( " We haven't detected the db_schema.yaml file " );
2020-09-21 14:54:51 +02:00
2017-10-26 01:56:09 -05:00
return ;
}
$master_schema = Yaml :: parse ( file_get_contents ( $schema_file ));
2020-11-05 18:19:15 -06:00
$current_schema = Schema :: dump ();
2020-09-21 14:54:51 +02:00
$schema_update = [];
2017-10-26 01:56:09 -05:00
2020-09-21 14:54:51 +02:00
foreach (( array ) $master_schema as $table => $data ) {
2017-10-26 01:56:09 -05:00
if ( empty ( $current_schema [ $table ])) {
$validator -> fail ( " Database: missing table ( $table ) " );
$schema_update [] = $this -> addTableSql ( $table , $data );
} else {
$current_columns = array_reduce ( $current_schema [ $table ][ 'Columns' ], function ( $array , $item ) {
$array [ $item [ 'Field' ]] = $item ;
2020-09-21 14:54:51 +02:00
2017-10-26 01:56:09 -05:00
return $array ;
2020-09-21 14:54:51 +02:00
}, []);
2017-10-26 01:56:09 -05:00
foreach ( $data [ 'Columns' ] as $index => $cdata ) {
$column = $cdata [ 'Field' ];
2019-03-09 21:15:03 +01:00
// MySQL 8 fix, remove DEFAULT_GENERATED from timestamp extra columns
if ( $cdata [ 'Type' ] == 'timestamp' ) {
2020-09-21 15:59:34 +02:00
$current_columns [ $column ][ 'Extra' ] = preg_replace ( '/DEFAULT_GENERATED[ ]*/' , '' , $current_columns [ $column ][ 'Extra' ]);
2019-03-09 21:15:03 +01:00
}
2017-10-26 01:56:09 -05:00
if ( empty ( $current_columns [ $column ])) {
$validator -> fail ( " Database: missing column ( $table / $column ) " );
2018-03-23 02:51:34 -05:00
$primary = false ;
if ( $data [ 'Indexes' ][ 'PRIMARY' ][ 'Columns' ] == [ $column ]) {
// include the primary index with the add statement
unset ( $data [ 'Indexes' ][ 'PRIMARY' ]);
$primary = true ;
}
2019-01-17 08:58:26 -06:00
$schema_update [] = $this -> addColumnSql ( $table , $cdata , isset ( $data [ 'Columns' ][ $index - 1 ]) ? $data [ 'Columns' ][ $index - 1 ][ 'Field' ] : null , $primary );
2017-10-26 01:56:09 -05:00
} elseif ( $cdata !== $current_columns [ $column ]) {
$validator -> fail ( " Database: incorrect column ( $table / $column ) " );
$schema_update [] = $this -> updateTableSql ( $table , $column , $cdata );
}
unset ( $current_columns [ $column ]); // remove checked columns
}
foreach ( $current_columns as $column => $_unused ) {
$validator -> fail ( " Database: extra column ( $table / $column ) " );
$schema_update [] = $this -> dropColumnSql ( $table , $column );
}
2019-01-17 08:59:42 -06:00
$index_changes = [];
2017-10-26 01:56:09 -05:00
if ( isset ( $data [ 'Indexes' ])) {
foreach ( $data [ 'Indexes' ] as $name => $index ) {
if ( empty ( $current_schema [ $table ][ 'Indexes' ][ $name ])) {
$validator -> fail ( " Database: missing index ( $table / $name ) " );
2019-01-17 08:59:42 -06:00
$index_changes [] = $this -> addIndexSql ( $table , $index );
2017-10-26 01:56:09 -05:00
} elseif ( $index != $current_schema [ $table ][ 'Indexes' ][ $name ]) {
$validator -> fail ( " Database: incorrect index ( $table / $name ) " );
2019-01-17 08:59:42 -06:00
$index_changes [] = $this -> updateIndexSql ( $table , $name , $index );
2017-10-26 01:56:09 -05:00
}
unset ( $current_schema [ $table ][ 'Indexes' ][ $name ]);
}
}
if ( isset ( $current_schema [ $table ][ 'Indexes' ])) {
foreach ( $current_schema [ $table ][ 'Indexes' ] as $name => $_unused ) {
$validator -> fail ( " Database: extra index ( $table / $name ) " );
$schema_update [] = $this -> dropIndexSql ( $table , $name );
}
}
2019-01-17 08:59:42 -06:00
$schema_update = array_merge ( $schema_update , $index_changes ); // drop before create/update
$constraint_changes = [];
if ( isset ( $data [ 'Constraints' ])) {
foreach ( $data [ 'Constraints' ] as $name => $constraint ) {
if ( empty ( $current_schema [ $table ][ 'Constraints' ][ $name ])) {
$validator -> fail ( " Database: missing constraint ( $table / $name ) " );
$constraint_changes [] = $this -> addConstraintSql ( $table , $constraint );
} elseif ( $constraint != $current_schema [ $table ][ 'Constraints' ][ $name ]) {
$validator -> fail ( " Database: incorrect constraint ( $table / $name ) " );
$constraint_changes [] = $this -> dropConstraintSql ( $table , $name );
$constraint_changes [] = $this -> addConstraintSql ( $table , $constraint );
}
unset ( $current_schema [ $table ][ 'Constraints' ][ $name ]);
}
}
if ( isset ( $current_schema [ $table ][ 'Constraints' ])) {
foreach ( $current_schema [ $table ][ 'Constraints' ] as $name => $_unused ) {
$validator -> fail ( " Database: extra constraint ( $table / $name ) " );
$schema_update [] = $this -> dropConstraintSql ( $table , $name );
}
}
$schema_update = array_merge ( $schema_update , $constraint_changes ); // drop before create/update
2017-10-26 01:56:09 -05:00
}
unset ( $current_schema [ $table ]); // remove checked tables
}
foreach ( $current_schema as $table => $data ) {
$validator -> fail ( " Database: extra table ( $table ) " );
$schema_update [] = $this -> dropTableSql ( $table );
}
2021-08-30 11:02:48 -05:00
// set utc timezone if timestamp issues
if ( preg_grep ( '/\d{4}-\d\d-\d\d \d\d:\d\d:\d\d/' , $schema_update )) {
array_unshift ( $schema_update , " SET TIME_ZONE='+00:00'; " );
}
2017-10-26 01:56:09 -05:00
if ( empty ( $schema_update )) {
$validator -> ok ( 'Database schema correct' );
} else {
2020-09-21 15:59:34 +02:00
$result = ValidationResult :: fail ( 'We have detected that your database schema may be wrong, please report the following to us on Discord (https://t.libren.ms/discord) or the community site (https://t.libren.ms/5gscd):' )
2017-10-26 01:56:09 -05:00
-> setFix ( 'Run the following SQL statements to fix.' )
-> setList ( 'SQL Statements' , $schema_update );
$validator -> result ( $result );
}
}
private function addTableSql ( $table , $table_schema )
{
2020-09-21 14:54:51 +02:00
$columns = array_map ([ $this , 'columnToSql' ], $table_schema [ 'Columns' ]);
$indexes = array_map ([ $this , 'indexToSql' ], isset ( $table_schema [ 'Indexes' ]) ? $table_schema [ 'Indexes' ] : []);
2017-10-26 01:56:09 -05:00
2020-09-21 14:54:51 +02:00
$def = implode ( ', ' , array_merge ( array_values (( array ) $columns ), array_values (( array ) $indexes )));
2017-10-26 01:56:09 -05:00
return " CREATE TABLE ` $table ` ( $def ); " ;
}
2018-03-23 02:51:34 -05:00
private function addColumnSql ( $table , $schema , $previous_column , $primary = false )
2017-10-26 01:56:09 -05:00
{
$sql = " ALTER TABLE ` $table ` ADD " . $this -> columnToSql ( $schema );
2018-03-23 02:51:34 -05:00
if ( $primary ) {
$sql .= ' PRIMARY KEY' ;
}
if ( empty ( $previous_column )) {
$sql .= ' FIRST' ;
} else {
2017-10-26 01:56:09 -05:00
$sql .= " AFTER ` $previous_column ` " ;
}
2020-09-21 14:54:51 +02:00
2017-10-26 01:56:09 -05:00
return $sql . ';' ;
}
private function updateTableSql ( $table , $column , $column_schema )
{
return " ALTER TABLE ` $table ` CHANGE ` $column ` " . $this -> columnToSql ( $column_schema ) . ';' ;
}
private function dropColumnSql ( $table , $column )
{
return " ALTER TABLE ` $table ` DROP ` $column `; " ;
}
private function addIndexSql ( $table , $index_schema )
{
return " ALTER TABLE ` $table ` ADD " . $this -> indexToSql ( $index_schema ) . ';' ;
}
private function updateIndexSql ( $table , $name , $index_schema )
{
return " ALTER TABLE ` $table ` DROP INDEX ` $name `, " . $this -> indexToSql ( $index_schema ) . ';' ;
}
private function dropIndexSql ( $table , $name )
{
return " ALTER TABLE ` $table ` DROP INDEX ` $name `; " ;
}
private function dropTableSql ( $table )
{
return " DROP TABLE ` $table `; " ;
}
/**
2020-11-05 18:19:15 -06:00
* Generate an SQL segment to create the column based on data from Schema :: dump ()
2017-10-26 01:56:09 -05:00
*
2021-09-08 23:35:56 +02:00
* @ param array $column_data The array of data for the column
2017-10-26 01:56:09 -05:00
* @ return string sql fragment , for example : " `ix_id` int(10) unsigned NOT NULL "
*/
private function columnToSql ( $column_data )
{
2018-03-23 02:51:34 -05:00
$segments = [ " ` ${ column_data['Field'] } ` " , $column_data [ 'Type' ]];
2017-10-26 01:56:09 -05:00
2018-03-23 02:51:34 -05:00
$segments [] = $column_data [ 'Null' ] ? 'NULL' : 'NOT NULL' ;
2017-10-26 01:56:09 -05:00
2018-03-23 02:51:34 -05:00
if ( isset ( $column_data [ 'Default' ])) {
if ( $column_data [ 'Default' ] === 'CURRENT_TIMESTAMP' ) {
$segments [] = 'DEFAULT CURRENT_TIMESTAMP' ;
} elseif ( $column_data [ 'Default' ] == 'NULL' ) {
$segments [] = 'DEFAULT NULL' ;
} else {
$segments [] = " DEFAULT ' ${ column_data['Default'] } ' " ;
}
}
if ( $column_data [ 'Extra' ] == 'on update current_timestamp()' ) {
$segments [] = 'on update CURRENT_TIMESTAMP' ;
2017-10-26 01:56:09 -05:00
} else {
2018-03-23 02:51:34 -05:00
$segments [] = $column_data [ 'Extra' ];
2017-10-26 01:56:09 -05:00
}
2018-03-23 02:51:34 -05:00
return implode ( ' ' , $segments );
2017-10-26 01:56:09 -05:00
}
/**
2020-11-05 18:19:15 -06:00
* Generate an SQL segment to create the index based on data from Schema :: dump ()
2017-10-26 01:56:09 -05:00
*
2021-09-08 23:35:56 +02:00
* @ param array $index_data The array of data for the index
2017-10-26 01:56:09 -05:00
* @ return string sql fragment , for example : " PRIMARY KEY (`device_id`) "
*/
private function indexToSql ( $index_data )
{
if ( $index_data [ 'Name' ] == 'PRIMARY' ) {
$index = 'PRIMARY KEY (%s)' ;
} elseif ( $index_data [ 'Unique' ]) {
$index = " UNIQUE ` { $index_data [ 'Name' ] } ` (%s) " ;
} else {
$index = " INDEX ` { $index_data [ 'Name' ] } ` (%s) " ;
}
$columns = implode ( ',' , array_map ( function ( $col ) {
return " ` $col ` " ;
}, $index_data [ 'Columns' ]));
return sprintf ( $index , $columns );
}
2019-01-17 08:59:42 -06:00
private function addConstraintSql ( $table , $constraint )
{
$sql = " ALTER TABLE ` $table ` ADD CONSTRAINT ` { $constraint [ 'name' ] } ` FOREIGN KEY (` { $constraint [ 'foreign_key' ] } `) " ;
$sql .= " REFERENCES ` { $constraint [ 'table' ] } ` (` { $constraint [ 'key' ] } `) " ;
2020-09-21 14:54:51 +02:00
if ( ! empty ( $constraint [ 'extra' ])) {
2019-01-17 08:59:42 -06:00
$sql .= ' ' . $constraint [ 'extra' ];
}
$sql .= ';' ;
return $sql ;
}
private function dropConstraintSql ( $table , $name )
{
return " ALTER TABLE ` $table ` DROP FOREIGN KEY ` $name `; " ;
}
2017-10-26 01:56:09 -05:00
}