Classes

File io/db/dbms/MySQLDBMSUtils.class.php

File io/db/dbms/MySQLDBMSUtils.class.php

  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 
<?php
/**
 * @package     IO
 * @subpackage  DB\dbms
 * @copyright   &copy; 2005-2019 PHPBoost
 * @license     https://www.gnu.org/licenses/gpl-3.0.html GNU/GPL-3.0
 * @author      Loic ROUCHON <horn@phpboost.com>
 * @version     PHPBoost 5.2 - last update: 2017 04 12
 * @since       PHPBoost 3.0 - 2009 11 03
 * @contributor Julien BRISWALTER <j1.seth@phpboost.com>
 * @contributor Arnaud GENET <elenwii@phpboost.com>
*/

class MySQLDBMSUtils implements DBMSUtils
{
    /**
     * @var SQLQuerier
     */
    private $querier;

    /**
     * @var MySqlPlatform
     */
    private $platform;

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

    public function get_dbms_version()
    {
        $result = $this->select('SELECT VERSION();')->fetch();
        return 'MySQL ' . $result['VERSION()'];
    }

    public function list_databases()
    {
        $databases = array();
        $results = $this->select('SHOW DATABASES;', array(), SelectQueryResult::FETCH_NUM);
        foreach ($results as $result)
        {
            $databases[] = $result[0];
        }
        return $databases;
    }

    function create_database($database_name)
    {
        $database_name = str_replace(array('/', '\\', '.', ' ', '"', '\''), '_', $database_name);
        $this->inject('CREATE DATABASE `' . $database_name . '`;');
        return $database_name;
    }

    public function get_database_name()
    {
        $result = $this->select('SELECT DATABASE();')->fetch();
        return $result['DATABASE()'];
    }

    public function list_tables($with_prefix = false)
    {
        $tables = array();
        $like_prefix = $with_prefix ? ' LIKE \'' . PREFIX . '%\'' : '';
        $results = $this->select('SHOW TABLES ' . $like_prefix . ';', array(), SelectQueryResult::FETCH_NUM);
        foreach ($results as $result)
        {
            $tables[] = $result[0];
        }
        return $tables;
    }

    public function list_and_desc_tables($with_prefix = false)
    {
        $tables = array();
        $like_prefix = $with_prefix ? ' LIKE \'' . PREFIX . '%\'' : '';
        $results = $this->select('SHOW TABLE STATUS FROM `' . $this->get_database_name() . '`' .
            $like_prefix . ';');
        foreach ($results as $table)
        {
            $tables[$table['Name']] = array(
              'name' => $table['Name'],
              'engine' => $table['Engine'],
              'row_format' => $table['Row_format'],
              'rows' => $table['Rows'],
              'data_length' => $table['Data_length'],
              'index_length' => $table['Index_length'],
              'data_free' => $table['Data_free'],
              'auto_increment' => $table['Auto_increment'],
              'create_time' => $table['Create_time'],
              'update_time' => $table['Update_time'],
              'collation' => $table['Collation'],
            );

        }
        return $tables;
    }

    public function desc_table($table)
    {
        $fields = array();
        $results = $this->select('DESC ' . $table . ';');
        foreach ($results as $result)
        {
            $fields[$result['Field']] = array(
                'name' => $result['Field'],
                'type' => $result['Type'],
                'null' => $result['Null'],
                'key' => $result['Key'],
                'default' => $result['Default'],
                'extra' => $result['Extra'],
            );
        }
        return $fields;
    }

    public function create_table($table_name, array $fields, array $options = array())
    {
        // Force charset to utf8 if not set
        if (!isset($options['charset']) || empty($options['charset']))
            $options['charset'] = 'UTF8';

        // Force collate to utf8_general_ci if not set
        if ((!isset($options['collate']) || empty($options['collate'])) && strtolower($options['charset']) == 'utf8')
            $options['collate'] = 'utf8_general_ci';

        foreach ($this->get_platform()->getCreateTableSql($table_name, $fields, $options) as $query)
        {
            $this->inject($query);
        }
    }

    public function drop($tables)
    {
        $this->inject($this->get_drop_table_query($tables));
    }

    public function truncate($tables)
    {
        if (!is_array($tables))
        {
            $tables = array($tables);
        }
        foreach ($tables as $table)
        {
            $this->inject('TRUNCATE TABLE `' . $table . '`;');
        }
    }

    public function optimize($tables)
    {
        if (is_array($tables))
        {
            $tables = implode('`, `', $tables);
        }
        $this->inject('OPTIMIZE TABLE`' . $tables . '`;');
    }

    public function repair($tables)
    {
        if (is_array($tables))
        {
            $tables = implode('`, `', $tables);
        }
        $this->inject('REPAIR TABLE `' . $tables . '`;');
    }

    public function add_column($table_name, $column_name, array $column_description)
    {
        $changes = array('add' => array($column_name => $column_description));
        $alter_query = $this->get_platform()->getAlterTableSql($table_name, $changes);
        $this->inject($alter_query);
    }


    public function drop_column($table_name, $column_name)
    {
        $result = $this->select('SELECT column_name  FROM `information_schema`.`COLUMNS` C WHERE TABLE_SCHEMA=:schema
            AND TABLE_NAME=:table_name AND COLUMN_NAME=:column_name',
            array(
                'schema' => $this->get_database_name(),
                'table_name' => $table_name,
                'column_name' => $column_name
        ));
        if ($result->get_rows_count() > 0)
        {
            $this->inject('ALTER TABLE `' . $table_name . '` DROP `' . $column_name . '`');
        }
    }

    public function dump_phpboost(FileWriter $file, $what = self::DUMP_STRUCTURE_AND_DATA)
    {
        $this->dump_tables($file, $this->list_tables(), $what);
    }

    public function dump_tables(FileWriter $file, array $tables, $what = self::DUMP_STRUCTURE_AND_DATA)
    {
        $tables = array_intersect($tables, $this->list_tables());
        foreach ($tables as $table)
        {
            $this->dump_table($file, $table, $what);
        }
        $file->flush();
    }

    public function dump_table(FileWriter $file, $table, $what = self::DUMP_STRUCTURE_AND_DATA)
    {
        if ($what == self::DUMP_STRUCTURE || $what == self::DUMP_STRUCTURE_AND_DATA)
        {
            $this->write($this->get_drop_table_query($table), $file);
            $this->write($this->get_create_table_query($table), $file);
        }

        if ($what == self::DUMP_DATA || $what == self::DUMP_STRUCTURE_AND_DATA)
        {
            $this->dump_table_rows($table, $file);
        }
    }

    public function dump_table_rows($table, $file = null)
    {
        $results = $this->select('SELECT * FROM `' . $table . '`');
        $field_names = array_keys($this->desc_table($table));
        $query = 'INSERT INTO `' . $table . '` (`' .
        implode('`, `', $field_names) . '`) VALUES ';
        foreach ($results as $result)
        {
            $fields = array();
            foreach ($field_names as $field)
            {
                $fields[] = $this->export_field($result[$field]);
            }
            $this->write($query . '(' . implode(',', $fields) . ');', $file);
        }
    }

    private function export_field($field)
    {
        if (is_numeric($field))
        {
            return $field;
        }
        else if (is_string($field))
        {
            return '\'' .
            str_replace(chr(13), '\r',
            str_replace(chr(10), '\n',
            str_replace('\\', '\\\\',
            str_replace("'", "''", $field)))) . '\'';
        }
        else
        {
            return 'NULL';
        }
    }

    private function write($string, FileWriter $file)
    {
        $file->append($string .  "\n");
    }

    private function get_drop_table_query($tables)
    {
        if (is_array($tables))
        {
            $tables = implode('`, `', $tables);
        }
        return 'DROP TABLE IF EXISTS `' . $tables . '`;';
    }

    private function get_create_table_query($table)
    {
        $result = $this->select('SHOW CREATE TABLE ' . $table)->fetch();
        return $result['Create Table'] . ';';
    }

    private function select($query, $parameters = array(), $fetch_mode = SelectQueryResult::FETCH_ASSOC)
    {
        $this->querier->disable_query_translator();
        $result = $this->querier->select($query, $parameters, $fetch_mode);
        $this->querier->enable_query_translator();
        return $result;
    }

    private function inject($query, $parameters = array())
    {
        $this->querier->disable_query_translator();
        $result = $this->querier->inject($query, $parameters);
        $this->querier->enable_query_translator();
        return $result;
    }

    public function parse_file(File $file, $prefix = '')
    {
        $reader = new BufferedFileReader($file);
        $query = '';
        while (($line = $reader->read_line()) !== null)
        {
            if (!empty($line) && TextHelper::substr($line, 0, 2) !== '--')
            {
                if (TextHelper::substr($line, -1) == ';')
                {
                    if (empty($query))
                    {
                        $query = $line;
                    }
                    else
                    {
                        $query .= ' ' . $line;
                    }

                    if (!empty($tableprefix))
                    {
                        $query = str_replace('phpboost_', $tableprefix, $query);
                    }

                    $this->querier->inject($query);
                    $query = '';
                }
                else
                {
                    $query .= ' ' . $line;
                }
            }
        }
    }

    /**
     * @return MySqlPlatform
     */
    private function get_platform()
    {
        if ($this->platform === null)
        {
            $this->platform = new  MySqlPlatform();
        }
        return $this->platform;
    }
}
?>