yf_db_utils_driver abstract class

YF db utils driver abstract class.

Fileplugins/db/classes/db/yf_db_utils_driver.class.php
Use_class('db_utils_driver', 'classes/db/')

Public properties

A site sets them in its config with $PROJECT_CONF['db_utils_driver']['NAME'] = ...;

PropertyDefaultDescription
$db null

Public methods 98

add_column

public function add_column($table, $data, $extra = [], &$error = false)
    public function add_column($table, $data, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        $sql = 'ALTER TABLE ' . $this->_escape_table_name($table) . ' ADD COLUMN ' . $this->_ddl_column_line($data);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }
public function add_foreign_key($table, $index_name = '', $fields = [], $ref_table = '', $ref_fields = [], $extra = [], &$error = false)
    public function add_foreign_key($table, $index_name = '', $fields = [], $ref_table = '', $ref_fields = [], $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if (is_array($index_name)) {
            $extra = (array) $extra + $index_name;
            $index_name = '';
        }
        $table = ($extra['table'] ?? null) ?: $table;
        $index_name = ($extra['name'] ?? null) ?: $index_name;
        $fields = ($extra['columns'] ?? null) ?: $fields;
        $ref_table = ($extra['ref_table'] ?? null) ?: $ref_table;
        $ref_fields = ($extra['ref_columns'] ?? null) ?: $ref_fields;
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        if (empty($fields) || ! is_array($fields)) {
            $error = 'fields are empty';
            return false;
        }
        if ( ! strlen($ref_table)) {
            $error = 'referenced table name is empty';
            return false;
        }
        if (empty($ref_fields) || ! is_array($ref_fields)) {
            $error = 'referenced fields are empty';
            return false;
        }
        if (empty($index_name)) {
            $index_name = $ref_table . '_' . implode('_', $ref_fields);
        }
        $on_delete = isset($extra['on_delete']) ? $extra['on_delete'] : '';
        $on_update = isset($extra['on_update']) ? $extra['on_update'] : '';

        $sql = 'ALTER TABLE ' . $this->_escape_table_name($this->db->_fix_table_name($table)) . PHP_EOL
            . ' ADD CONSTRAINT ' . $this->_escape_key($index_name) . PHP_EOL
            . ' FOREIGN KEY (' . implode(',', $this->_escape_fields($fields)) . ')' . PHP_EOL
            . ' REFERENCES ' . $this->_escape_ref_table($this->db->_fix_table_name($ref_table)) . ' (' . implode(',', $this->_escape_fields($ref_fields)) . ')' . PHP_EOL
            . ($on_delete ? ' ON DELETE ' . strtoupper(str_replace('_', ' ', $on_delete)) : '') . PHP_EOL
            . ($on_update ? ' ON UPDATE ' . strtoupper(str_replace('_', ' ', $on_update)) : '');
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

add_index

public function add_index($table, $index_name = '', $fields = [], $extra = [], &$error = false)
    public function add_index($table, $index_name = '', $fields = [], $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if (is_array($index_name)) {
            $extra = (array) $extra + $index_name;
            $index_name = '';
        }
        $table = ($extra['table'] ?? null) ?: $table;
        $index_name = ($extra['name'] ?? null) ?: $index_name;
        $fields = ($extra['columns'] ?? null) ?: $fields;
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        if (empty($fields)) {
            $error = 'fields are empty';
            return false;
        }
        // gemerate index name from columns names
        $index_name = $index_name ?: implode('_', $fields);
        if ( ! strlen($index_name)) {
            $error = 'index name is empty';
            return false;
        }
        $index_type = strtolower(($extra['type'] ?? null) ?: 'index');
        $supported_types = [
            'index' => 'index',
            'primary' => 'primary key',
            'unique' => 'unique key',
            'fulltext' => 'fulltext key',
        ];
        if ( ! isset($supported_types[$index_type])) {
            $error = 'index type is not supported';
            return false;
        }
        $sql = $this->_sql_add_index($table, $index_name, $index_type, $fields, $error);
        if ($sql === false) {
            return false;
        }
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

alter_column

public function alter_column($table, $col_name, $data, $extra = [], &$error = false)
    public function alter_column($table, $col_name, $data, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        $col_info = $this->column_info($table, $col_name);
        if ( ! $col_info) {
            $error = 'column not exists';
            return false;
        }
        foreach ((array) $data as $k => $v) {
            if (isset($col_info[$k])) {
                $col_info[$k] = $v;
            }
        }
        $position_change = '';
        if (isset($data['first'])) {
            $position_change = ' FIRST';
        } elseif ($data['after'] ?? null) {
            $position_change = ' AFTER ' . $this->_escape_key($data['after']);
        }
        $sql = 'ALTER TABLE ' . $this->_escape_table_name($table) . ' MODIFY COLUMN ' . $this->_ddl_column_line($col_info) . $position_change;
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }
public function alter_database($db_name, $extra = [], &$error = false)
    public function alter_database($db_name, $extra = [], &$error = false)
    {
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        $allowed = [
            'charset' => 'CHARACTER SET',
            'collate' => 'COLLATE',
        ];
        $params = [];
        foreach ((array) $extra as $k => $v) {
            $v = preg_replace('~[^a-z0-9_]+~i', '', $v);
            if (isset($allowed[$k])) {
                $params[$k] = $allowed[$k] . ' = ' . $v;
            } elseif (in_array($k, $allowed)) {
                $params[$k] = $k . ' = ' . $v;
            }
        }
        $sql = '';
        if ($params) {
            $sql = 'ALTER DATABASE ' . $this->_escape_database_name($db_name) . ' ' . implode(' ', $params);
        }
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }
public function alter_foreign_key($table, $index_name = '', $fields = [], $ref_table = '', $ref_fields = [], $extra = [], &$error = false)

Alias.

    public function alter_foreign_key($table, $index_name = '', $fields = [], $ref_table = '', $ref_fields = [], $extra = [], &$error = false)
    {
        return $this->update_foreign_key($table, $index_name, $fields, $ref_table, $ref_fields, $extra, $error);
    }

alter_index

public function alter_index($table, $index_name = '', $fields = [], $extra = [], &$error = false)

Alias.

    public function alter_index($table, $index_name = '', $fields = [], $extra = [], &$error = false)
    {
        return $this->update_index($table, $index_name, $fields, $extra, $error);
    }

alter_table

public function alter_table($table, $extra = [], &$error = false)

Here we support only small subset of alter table options, mostly related to basic things like engine or charset.

    public function alter_table($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        $table_options = [];
        foreach ((array) $this->_get_supported_table_options() as $name => $real_name) {
            if (isset($extra[$name]) && strlen($extra[$name])) {
                $table_options[$name] = $real_name . '=' . $extra[$name];
            }
        }
        if (empty($table_options)) {
            $error = 'no supported table options provided';
            return false;
        }
        $sql = 'ALTER TABLE ' . $this->_escape_table_name($table) . PHP_EOL . implode(' ', $table_options);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

column

public function column($db_name, $table, $col)

db()->utils()->database('geonames')->table('geo_city')->column('name')->add(); db()->utils()->database('geonames')->table('geo_city')->column('name')->drop(); db()->utils()->table('geonames', 'geo_city')->column('name')->drop(); db()->utils()->column('geonames', 'geo_city', 'name')->drop();.

    public function column($db_name, $table, $col)
    {
        $obj = clone _class('db_utils_helper_column', 'classes/db/');
        $obj->_setup([
            'utils' => $this,
            'db_name' => $db_name,
            'table' => $table,
            'col' => $col,
        ]);
        return $obj;
    }

column_exists

public function column_exists($table, $col_name, $extra = [], &$error = false)
    public function column_exists($table, $col_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $columns = $this->table_get_columns($table, $extra, $error);
        return isset($columns[$col_name]);
    }

column_info

public function column_info($table, $col_name, $extra = [], &$error = false)
    public function column_info($table, $col_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $columns = $this->table_get_columns($table, $extra, $error);
        return isset($columns[$col_name]) ? $columns[$col_name] : false;
    }
public function column_info_item($table, $col_name, $item_name, $extra = [], &$error = false)
    public function column_info_item($table, $col_name, $item_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $columns = $this->table_get_columns($table, $extra, $error);
        return isset($columns[$col_name][$item_name]) ? $columns[$col_name][$item_name] : false;
    }

columns_names

public function columns_names($table, $extra = [], &$error = false)
    public function columns_names($table, $extra = [], &$error = false)
    {
        $extra['just_names'] = true;
        return $this->table_get_columns($table, $extra, $error);
    }
public function create_database($db_name, $extra = [], &$error = false)
    public function create_database($db_name, $extra = [], &$error = false)
    {
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        if ( ! isset($extra['if_not_exists'])) {
            $extra['if_not_exists'] = true;
        }
        $sql = 'CREATE DATABASE ' . ($extra['if_not_exists'] ? 'IF NOT EXISTS ' : '') . $this->_escape_database_name($db_name);
        return ($extra['sql'] ?? null) ? $sql : (bool) $this->db->query($sql);
    }

create_table

public function create_table($table, $extra = [], &$error = false)
    public function create_table($table, $extra = [], &$error = false)
    {
        // Example callable: create_table($name, function($t) { $t->int('id', 10); });
        if (is_callable($extra)) {
            $db_name = null;
            if (strpos($table, '.') !== false) {
                list($db_name, $table) = explode('.', trim($table));
            }
            if ( ! $table) {
                $error = 'table_name is empty';
                return false;
            }
            if ( ! $db_name) {
                $db_name = $this->db->DB_NAME;
            }
            if ( ! $db_name) {
                $error = 'db_name is empty';
                return false;
            }
            $obj = clone _class('db_utils_helper_create_table', 'classes/db/');
            $extra($obj->_setup([
                'utils' => $this,
                'db_name' => $db_name,
                'table_name' => $table,
                'for_create' => true,
            ]));
            $sql = $obj->render();
            return $this->db->query($sql);
        }
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $table = ($extra['name'] ?? null) ?: $table;
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        if ( ! ($extra['sql'] ?? null) && $this->table_exists($table, $db_name)) {
            $error = 'table_name already exists';
            return false;
        }
        if (empty($extra['fields'])) {
            $data = $this->_get_table_structure_from_db_installer($table, $error);
            if ($data['fields']) {
                foreach (['fields', 'indexes', 'foreign_keys', 'options'] as $k) {
                    $extra[$k] = $data[$k];
                }
            }
        }
        if (empty($extra['fields'])) {
            $error = 'table fields empty';
            return false;
        }
        // Default table options
        $table_options = [
            'engine' => 'InnoDB',
            'charset' => 'utf8',
        ];
        foreach ((array) $this->_get_supported_table_options() as $name => $real_name) {
            if (isset($extra['options'][$name]) && strlen($extra['options'][$name])) {
                $table_options[$name] = $extra['options'][$name];
            }
        }
        $plen = strlen($this->db->DB_PREFIX);
        $need_fix = $db_name == $this->db->DB_NAME;
        if ($need_fix && ($extra['foreign_keys'] ?? null) && $plen) {
            foreach ((array) $extra['foreign_keys'] as $fname => $finfo) {
                $extra['foreign_keys'][$fname]['ref_table'] = $this->db->_fix_table_name($finfo['ref_table']);
            }
        }
        $sql = $this->_ddl_create_sql([
            'name' => $db_name . '.' . ($need_fix ? $this->db->_fix_table_name($table) : $table),
            'fields' => $extra['fields'] ?? null,
            'indexes' => $extra['indexes'] ?? null,
            'foreign_keys' => $extra['foreign_keys'] ?? null,
            'options' => $table_options,
        ], $error);
        if ($sql === false) {
            return false;
        }
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }
public function create_trigger($name, $table, $trigger_time, $trigger_event, $trigger_body, $extra = [], &$error = false)

See http://dev.mysql.com/doc/refman/5.6/en/create-trigger.html.

    public function create_trigger($name, $table, $trigger_time, $trigger_event, $trigger_body, $extra = [], &$error = false)
    {
        $db_name = null;
        if (strpos($name, '.') !== false) {
            list($db_name, $name) = explode('.', trim($name));
        }
        if ( ! $name) {
            $error = 'trigger name is empty';
            return false;
        }
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! $table) {
            $error = 'trigger table is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $supported_trigger_times = [
            'before',
            'after',
        ];
        if ( ! strlen($trigger_time) || ! in_array(strtolower($trigger_time), $supported_trigger_times)) {
            $error = 'trigger time is wrong';
            return false;
        }
        $supported_trigger_events = [
            'insert',
            'update',
            'delete',
        ];
        if ( ! strlen($trigger_event) || ! in_array(strtolower($trigger_event), $supported_trigger_events)) {
            $error = 'trigger event is wrong';
            return false;
        }
        if ( ! strlen($trigger_body)) {
            $error = 'trigger body is empty';
            return false;
        }
        $sql = 'CREATE TRIGGER ' . $this->_escape_table_name($db_name . '.' . $name) . PHP_EOL
            . ' ' . strtoupper($trigger_time) . ' ' . strtoupper($trigger_event) . PHP_EOL
            . ' ON ' . $this->_escape_table_name($db_name . '.' . $table) . ' FOR EACH ROW '
            . $trigger_body;
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

create_view

public function create_view($table, $sql_as, $extra = [], &$error = false)

See https://dev.mysql.com/doc/refman/5.6/en/create-view.html.

    public function create_view($table, $sql_as, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table is empty';
            return false;
        }
        $sql = 'CREATE VIEW ' . $this->_escape_table_name($table) . ' AS ' . $sql_as;
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

database

public function database($db_name)

db()->utils()->database('geonames')->create(); db()->utils()->database('geonames')->drop(); db()->utils()->database('geonames')->alter($params); db()->utils()->database('geonames')->rename($new_name);.

    public function database($db_name)
    {
        $obj = clone _class('db_utils_helper_database', 'classes/db/');
        $obj->_setup([
            'utils' => $this,
            'db_name' => $db_name,
        ]);
        return $obj;
    }
public function database_exists($db_name, $extra = [], &$error = false)
    public function database_exists($db_name, $extra = [], &$error = false)
    {
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        return (bool) in_array($db_name, (array) $this->list_databases());
    }

database_info

public function database_info($db_name = '', $extra = [], &$error = false)
    public function database_info($db_name = '', $extra = [], &$error = false)
    {
        if (is_array($db_name)) {
            $extra = (array) $extra + $db_name;
            $db_name = '';
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        $info = $this->db->get('SELECT * FROM information_schema.SCHEMATA WHERE schema_name = ' . $this->_escape_val($db_name));
        if ( ! $info) {
            $error = 'db_name not exists';
            return false;
        }
        return [
            'name' => $db_name,
            'charset' => $info['DEFAULT_CHARACTER_SET_NAME'],
            'collate' => $info['DEFAULT_COLLATION_NAME'],
        ];
    }

drop_column

public function drop_column($table, $col_name, $extra = [], &$error = false)
    public function drop_column($table, $col_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        $sql = 'ALTER TABLE ' . $this->_escape_table_name($table) . ' DROP COLUMN ' . $this->db->escape_key($col_name);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

drop_database

public function drop_database($db_name, $extra = [], &$error = false)
    public function drop_database($db_name, $extra = [], &$error = false)
    {
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        if ( ! isset($extra['if_exists'])) {
            $extra['if_exists'] = true;
        }
        if ( ! ($extra['sql'] ?? null) && ! $this->database_exists($db_name)) {
            return true;
        }
        foreach ((array) $this->list_tables($db_name) as $table) {
            $table = trim($table);
            if ( ! strlen($table)) {
                continue;
            }
            $sql[] = $this->drop_table($db_name . '.' . $table, $extra);
        }
        $_sql = 'DROP DATABASE ' . ($extra['if_exists'] ? 'IF EXISTS ' : '') . $this->_escape_database_name($db_name);
        $sql[] = ($extra['sql'] ?? null) ? $_sql : $this->db->query($_sql);
        return ($extra['sql'] ?? null) ? implode(PHP_EOL, $sql) : true;
    }
public function drop_foreign_key($table, $index_name, $extra = [], &$error = false)
    public function drop_foreign_key($table, $index_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $table = ($extra['table'] ?? null) ?: $table;
        $index_name = ($extra['name'] ?? null) ?: $index_name;
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        $sql = $this->_sql_drop_foreign_key($table, $index_name);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

drop_index

public function drop_index($table, $index_name, $extra = [], &$error = false)
    public function drop_index($table, $index_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        $index_name = ($extra['name'] ?? null) ?: $index_name;
        if ( ! strlen($index_name)) {
            $error = 'index name is empty';
            return false;
        }
        $sql = $this->_sql_drop_index($table, $index_name);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

drop_table

public function drop_table($table, $extra = [], &$error = false)
    public function drop_table($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        $sql = 'DROP TABLE IF EXISTS ' . $this->_escape_table_name($table);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

drop_trigger

public function drop_trigger($name, $extra = [], &$error = false)
    public function drop_trigger($name, $extra = [], &$error = false)
    {
        if ( ! strlen($name)) {
            $error = 'name is empty';
            return false;
        }
        $sql = 'DROP TRIGGER IF EXISTS ' . $this->_escape_table_name($name);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

drop_view

public function drop_view($table, $extra = [], &$error = false)
    public function drop_view($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'view name is empty';
            return false;
        }
        $sql = 'DROP VIEW IF EXISTS ' . $this->_escape_table_name($table);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

foreign_key

public function foreign_key($db_name, $table, $fk_name)

db()->utils()->database('geonames')->table('geo_city')->foreign_key('geo_city_fk')->create($params); db()->utils()->foreign_key('geonames', 'geo_city', 'geo_city_fk')->create($params);.

    public function foreign_key($db_name, $table, $fk_name)
    {
        $obj = clone _class('db_utils_helper_foreign_key', 'classes/db/');
        $obj->_setup([
            'utils' => $this,
            'db_name' => $db_name,
            'table' => $table,
            'foreign_key' => $fk_name,
        ]);
        return $obj;
    }
public function foreign_key_exists($table, $index_name, &$error = false, $extra = [])
    public function foreign_key_exists($table, $index_name, &$error = false, $extra = [])
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($index_name)) {
            $error = 'index name is empty';
            return false;
        }
        $keys = $this->list_foreign_keys($table);
        return isset($keys[$index_name]);
    }
public function foreign_key_info($table, $index_name, &$error = false, $extra = [])
    public function foreign_key_info($table, $index_name, &$error = false, $extra = [])
    {
        $extra = null;
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($index_name)) {
            $error = 'index name is empty';
            return false;
        }
        $keys = $this->list_foreign_keys($table);
        return isset($keys[$index_name]) ? $keys[$index_name] : false;
    }

index

public function index($db_name, $table, $index)

db()->utils()->database('geonames')->table('geo_city')->index('name', ('id', 'name'))->add(); db()->utils()->database('geonames')->table('geo_city')->index('name')->drop(); db()->utils()->index('geonames', 'geo_city', 'name')->drop();.

    public function index($db_name, $table, $index)
    {
        $obj = clone _class('db_utils_helper_index', 'classes/db/');
        $obj->_setup([
            'utils' => $this,
            'db_name' => $db_name,
            'table' => $table,
            'index' => $index,
        ]);
        return $obj;
    }

index_exists

public function index_exists($table, $index_name, &$error = false, $extra = [])
    public function index_exists($table, $index_name, &$error = false, $extra = [])
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($index_name)) {
            $error = 'index name is empty';
            return false;
        }
        $indexes = $this->list_indexes($table);
        return isset($indexes[$index_name]);
    }

index_info

public function index_info($table, $index_name, &$error = false, $extra = [])
    public function index_info($table, $index_name, &$error = false, $extra = [])
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($index_name)) {
            $error = 'index name is empty';
            return false;
        }
        $indexes = $this->list_indexes($table);
        return isset($indexes[$index_name]) ? $indexes[$index_name] : false;
    }

list_columns

public function list_columns($table, $extra = [], &$error = false)
    public function list_columns($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        return $this->table_get_columns($table, $extra, $error);
    }
public function list_databases($extra = [])
    public function list_databases($extra = [])
    {
        $sql = $this->_sql_list_databases();
        return ($extra['sql'] ?? null) ? $sql : $this->db->get_2d($sql);
    }
public function list_foreign_keys($table, $extra = [], &$error = false)
    public function list_foreign_keys($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $orig_table = $table;
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $keys = [];
        foreach ((array) $this->db->get_all($this->_sql_foreign_keys($db_name, $table)) as $a) {
            $name = $a['CONSTRAINT_NAME'];
            $keys[$name]['name'] = $name;
            $keys[$name]['columns'][$a['COLUMN_NAME']] = $a['COLUMN_NAME'];
            $keys[$name]['ref_table'] = $a['REFERENCED_TABLE_NAME'];
            $keys[$name]['ref_columns'][$a['REFERENCED_COLUMN_NAME']] = $a['REFERENCED_COLUMN_NAME'];
        }
        foreach ((array) $this->db->get_all($this->_sql_foreign_key_rules($db_name, $table)) as $a) {
            $name = $a['CONSTRAINT_NAME'];
            if (isset($keys[$name])) {
                $keys[$name]['on_update'] = $a['UPDATE_RULE'];
                $keys[$name]['on_delete'] = $a['DELETE_RULE'];
            }
        }
        return $keys;
    }

list_indexes

public function list_indexes($table, $extra = [], &$error = false, $db_name = '')
    public function list_indexes($table, $extra = [], &$error = false, $db_name = '')
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        // Possible alternative query: SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'test3' AND TABLE_NAME = 't_user' AND COLUMN_KEY = 'PRI';
        $indexes = [];
        foreach ((array) $this->db->get_all($this->_sql_list_indexes($table, $db_name)) as $row) {
            $type = 'index';
            if ($row['Key_name'] === 'PRIMARY') {
                $type = 'primary';
            } elseif ( ! $row['Non_unique']) {
                $type = 'unique';
            } elseif ($row['Index_type'] == 'FULLTEXT') {
                $type = 'fulltext';
            } elseif ($row['Index_type'] == 'SPATIAL') {
                $type = 'spatial';
            }
            if ( ! isset($indexes[$row['Key_name']])) {
                $indexes[$row['Key_name']] = [
                    'name' => $row['Key_name'],
                    'type' => $type,
                ];
            }
            $indexes[$row['Key_name']]['columns'][$row['Column_name']] = $row['Column_name'];
        }
        return $indexes;
    }

list_tables

public function list_tables($db_name = '', $extra = [], &$error = false)
    public function list_tables($db_name = '', $extra = [], &$error = false)
    {
        if (is_array($db_name)) {
            $extra = (array) $extra + $db_name;
            $db_name = '';
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        $no_views = isset($extra['no_views']) ? (bool) $extra['no_views'] : true;
        $tables = [];
        $sql = $this->_sql_list_tables($db_name, $error);
        if ($sql === false) {
            return false;
        }
        foreach ((array) $this->db->get_all($sql) as $a) {
            if ( ! is_array($a)) {
                continue;
            }
            list($table, $type) = array_values($a);
            if ($no_views && $type === 'VIEW') {
                continue;
            }
            $tables[$table] = $table;
        }
        return $tables;
    }
public function list_tables_details($db_name = '', $extra = [], &$error = false)
    public function list_tables_details($db_name = '', $extra = [], &$error = false)
    {
        if (is_array($db_name)) {
            $extra = (array) $extra + $db_name;
            $db_name = '';
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        $tables = [];
        $sql = $this->_sql_tables_status($db_name, $error);
        if ($sql === false) {
            return false;
        }
        $q = $this->db->query($sql);
        while ($a = $this->db->fetch_assoc($q)) {
            $table = $a['Name'];
            $tables[$table] = [
                'name' => $table,
                'engine' => $a['Engine'],
                'rows' => $a['Rows'],
                'data_size' => $a['Data_length'],
                'collate' => $a['Collation'],
            ];
        }
        return $tables;
    }

list_triggers

public function list_triggers($db_name = '', $extra = [], &$error = false)
    public function list_triggers($db_name = '', $extra = [], &$error = false)
    {
        if (is_array($db_name)) {
            $extra = (array) $extra + $db_name;
            $db_name = '';
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $triggers = [];
        $sql = $this->_sql_list_triggers($db_name, $error);
        if ($sql === false) {
            return false;
        }
        foreach ((array) $this->db->get_all($sql) as $a) {
            $name = $a['Trigger'];
            $triggers[$name] = [
                'name' => $name,
                'table' => $a['Table'],
                'event' => $a['Event'],
                'timing' => $a['Timing'],
                'statement' => $a['Statement'],
                'definer' => $a['definer'] ?? null,
            ];
        }
        return $triggers;
    }

list_views

public function list_views($db_name = '', $extra = [], &$error = false)
    public function list_views($db_name = '', $extra = [], &$error = false)
    {
        if (is_array($db_name)) {
            $extra = (array) $extra + $db_name;
            $db_name = '';
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $sql = $this->_sql_list_views($db_name, $error);
        if ($sql === false) {
            return false;
        }
        $views = [];
        foreach ((array) $this->db->get_all($sql) as $a) {
            // allow to ignore key and directly get value
            $name = array_pop($a);
            $create_view = '';
            if ( ! ($extra['no_details'] ?? null)) {
                $create_view = $this->db->get($this->_sql_view_definition($db_name, $name));
                if (is_array($create_view)) {
                    $create_view = $create_view['Create View'];
                }
            }
            $views[$name] = $create_view;
        }
        return $views;
    }

meta_columns

public function meta_columns($table)
    public function meta_columns($table)
    {
        return $this->list_columns($table);
    }

meta_tables

public function meta_tables($db_prefix = '')
    public function meta_tables($db_prefix = '')
    {
        $tables = $this->list_tables();
        // Skip tables without prefix of current connection
        if (strlen($db_prefix)) {
            $plen = strlen($db_prefix);
            foreach ($tables as $table) {
                if (substr($table, 0, $plen) !== $db_prefix) {
                    unset($tables[$table]);
                }
            }
        }
        return $tables;
    }

rename_column

public function rename_column($table, $col_name, $new_name, $extra = [], &$error = false)
    public function rename_column($table, $col_name, $new_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table name is empty';
            return false;
        }
        $new_data = $this->column_info($table, $col_name);
        $new_data['name'] = $new_name;
        $sql = 'ALTER TABLE ' . $this->_escape_table_name($table) . ' CHANGE COLUMN ' . $this->_escape_key($col_name) . ' ' . $this->_ddl_column_line($new_data);
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }
public function rename_database($db_name, $new_name, $extra = [], &$error = false)
    public function rename_database($db_name, $new_name, $extra = [], &$error = false)
    {
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        if ( ! strlen($new_name)) {
            $error = 'new_name is empty';
            return false;
        }
        if ( ! ($extra['sql'] ?? null) && ! $this->database_exists($db_name)) {
            $error = 'db_name not exists';
            return false;
        }
        if ( ! ($extra['sql'] ?? null) && $this->database_exists($new_name)) {
            $error = 'new database already exists';
            return false;
        }
        $sql[] = $this->create_database($new_name, $extra);
        foreach ((array) $this->list_tables($db_name) as $t) {
            $t = trim($t);
            if ( ! strlen($t)) {
                continue;
            }
            $sql[] = $this->rename_table($db_name . '.' . $t, $new_name . '.' . $t, $extra);
        }
        $sql[] = $this->drop_database($db_name, $extra);
        return ($extra['sql'] ?? null) ? implode(PHP_EOL, $sql) : true;
    }

rename_table

public function rename_table($table, $new_name, $extra = [], &$error = false)
    public function rename_table($table, $new_name, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! $table || ! $new_name) {
            $error = 'table_name is empty';
            return false;
        }
        $sql = $this->_sql_rename_table($table, $new_name);
        if ($sql === false) {
            $error = 'table "' . $table . '" is not in the connected database';
            return false;
        }
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }

split_sql

public function split_sql($sql)

Smart split long SQL into single queries. Usually to be able to execute them with php_mysql API functions.

    public function split_sql($sql)
    {
        $out = [];
        // do not trim
        $sql = rtrim($sql, "\n\r");
        $sql_len = strlen($sql);
        $char = '';
        $string_start = '';
        $in_string = false;
        $nothing = true;
        for ($i = 0; $i < $sql_len; ++$i) {
            $char = $sql[$i];
            // We are in a string, check for not escaped end of strings except for
            // backquotes that can't be escaped
            if ($in_string) {
                for (;;) {
                    $i = strpos($sql, $string_start, $i);
                    // No end of string found -> add the current substring to the
                    // returned array
                    if ( ! $i) {
                        $out[] = $sql;
                        break 2;
                    }
                    // Backquotes or no backslashes before quotes: it's indeed the
                    // end of the string -> exit the loop
                    elseif ($string_start == '`' || $sql[$i - 1] != '\\') {
                        $string_start = '';
                        $in_string = false;
                        break;
                    }
                    // one or more Backslashes before the presumed end of string...

                    // ... first checks for escaped backslashes
                    $j = 2;
                    $escaped_backslash = false;
                    while ($i - $j > 0 && $sql[$i - $j] == '\\') {
                        $escaped_backslash = ! $escaped_backslash;
                        $j++;
                    }
                    // ... if escaped backslashes: it's really the end of the
                    // string -> exit the loop
                    if ($escaped_backslash) {
                        $string_start = '';
                        $in_string = false;
                        break;
                    }
                    // ... else loop

                    $i++;
                }
            }
            // lets skip comments (/*, -- and #)
            elseif (
                ($char == '-' && $sql_len > $i + 2 && $sql[$i + 1] == '-' && $sql[$i + 2] <= ' ')
                 || $char == '#' || ($char == '/' && $sql_len > $i + 1 && $sql[$i + 1] == '*')
            ) {
                $i = strpos($sql, $char == '/' ? '*/' : "\n", $i);
                // didn't we hit end of string?
                if ($i === false) {
                    break;
                }
                if ($char == '/') {
                    $i++;
                }
            }
            // We are not in a string, first check for delimiter...
            elseif ($char == ';') {
                // if delimiter found, add the parsed part to the returned array
                $out[] = substr($sql, 0, $i);
                $nothing = true;
                $sql = ltrim(substr($sql, min($i + 1, $sql_len)));
                $sql_len = strlen($sql);
                if ($sql_len) {
                    $i = -1;
                } else {
                    // The submited statement(s) end(s) here
                    break;
                }
            }
            // ... then check for start of a string,...
            elseif (($char == '"') || ($char == '\'') || ($char == '`')) {
                $in_string = true;
                $nothing = false;
                $string_start = $char;
            } elseif ($nothing) {
                $nothing = false;
            }
        }
        // add any rest to the returned array
        if ( ! empty($sql) && preg_match('@[^[:space:]]+@', $sql)) {
            $out[] = $sql;
        }
        foreach ((array) $out as $k => $v) {
            if ( ! strlen($v)) {
                unset($out[$k]);
            }
        }
        return array_values($out); // array_values needed here to make array indexes flat and properly incremented again
    }

table

public function table($db_name, $table)

db()->utils()->database('geonames')->table('geo_city')->create(); db()->utils()->database('geonames')->table('geo_city')->drop(); db()->utils()->database('geonames')->table('geo_city')->alter($params); db()->utils()->database('geonames')->table('geo_city')->rename($new_name); db()->utils()->table('geonames', 'geo_city')->rename($new_name);.

    public function table($db_name, $table)
    {
        $obj = clone _class('db_utils_helper_table', 'classes/db/');
        $obj->_setup([
            'utils' => $this,
            'db_name' => $db_name,
            'table' => $table,
        ]);
        return $obj;
    }

table_exists

public function table_exists($table, $extra = [], &$error = false)
    public function table_exists($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $db_prefix = $this->db->DB_PREFIX;
        return (bool) in_array($table, (array) $this->list_tables($db_name)) || (strlen($db_prefix) && in_array($db_prefix . $table, (array) $this->list_tables($db_name)));
    }
public function table_get_charset($table, $extra = [], &$error = false)
    public function table_get_charset($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $orig_table = $table;
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! strlen($table)) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        $info = $this->db->get($this->_sql_table_charset($db_name, $table));
        if ( ! $info) {
            $error = 'table_name not exists';
            return false;
        }
        return $info['character_set_name'] ?? null;
    }
public function table_get_columns($table, $extra = [], &$error = false)
    public function table_get_columns($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! strlen($table)) {
            $error = 'table_name is empty';
            return false;
        }
        $cols = [];
        $q = $this->db->query($this->_sql_columns($table));
        if ( ! empty($extra['just_names'])) {
            while ($a = $this->db->fetch_assoc($q)) {
                $name = $a['Field'];
                $cols[$name] = $name;
            }
            return $cols;
        }
        while ($a = $this->db->fetch_assoc($q)) {
            $a = $this->_column_row($a);
            $name = $a['Field'];
            list($type, $length, $unsigned, $decimals, $values) = array_values($this->_parse_column_type($a['Type']));
            $nullable = ($a['Null'] == 'YES');
            $default = null;
            if ($a['Default'] !== null) {
                $default = trim($a['Default']);
                if ($this->_mariadb_literal_defaults()) {
                    $default = $this->_unquote_default_literal($default);
                }
            }
            $extra_lower = strtolower($a['Extra']);
            $cols[$name] = [
                'name' => $name,
                'type' => $type,
                'length' => $length ? (int) $length : null,
                'decimals' => $decimals ?: null,
                'unsigned' => $unsigned ?: null,
                'nullable' => (bool) $nullable,
                'default' => $default,
// TODO: detect charset for column
                'charset' => null,
                'collate' => $a['Collation'] != 'NULL' ? $a['Collation'] : null,
                'auto_inc' => false !== strpos($extra_lower, 'auto_increment') ? true : false,
                'primary' => $a['Key'] == 'PRI',
                'unique' => $a['Key'] == 'UNI',
                'values' => $values ?: null,
            ];
            if (false !== strpos($extra_lower, 'on update') && in_array($type, ['timestamp', 'datetime'])) {
                $cols[$name]['on_update'] = strtoupper($a['Extra']);
            }
            if (false !== strpos($extra_lower, 'virtual') || false !== strpos($extra_lower, 'generated')) {
                $cols[$name]['virtual'] = true;
            }
            $cols[$name]['type_raw'] = $a['Type'];
        }
        // Optionally fill "unique" field from indexes info
        $indexes = $this->list_indexes($table, $extra, $error);
        if ($indexes) {
            foreach ((array) $indexes as $name => $idx) {
                if ($idx['type'] !== 'unique') {
                    continue;
                }
                foreach ($idx['columns'] as $fname) {
                    if ( ! isset($cols[$fname])) {
                        continue;
                    }
                    $cols[$fname]['unique'] = true;
                }
            }
        }
        return $cols;
    }

table_info

public function table_info($table, $extra = [], &$error = false)
    public function table_info($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $orig_table = $table;
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! strlen($table)) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        $info = $this->db->get($this->_sql_table_status($db_name, $table));
        if ( ! $info) {
            $error = 'table_name not exists';
            return false;
        }
        return [
            'name' => $table,
            'db_name' => $db_name,
            'columns' => ! ($extra['just_info'] ?? null) ? $this->table_get_columns($orig_table) : null,
            'row_format' => $info['Row_format'],
            'charset' => ! ($extra['just_info'] ?? null) ? $this->table_get_charset($orig_table) : null,
            'collate' => $info['Collation'],
            'engine' => $info['Engine'],
            'rows' => $info['Rows'],
            'data_size' => $info['Data_length'],
            'auto_inc' => $info['Auto_increment'],
            'comment' => $info['Comment'],
            'create_time' => $info['Create_time'],
            'update_time' => $info['Update_time'],
        ];
    }

table_options

public function table_options($table, $extra = [], &$error = false)
    public function table_options($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $info = $this->table_simple_info($table, $extra, $error);
        return [
            'engine' => $info['engine'],
            'charset' => ! ($extra['just_info'] ?? null) ? $this->table_get_charset($table) : null,
            'collate' => $info['collate'],
            'comment' => $info['comment'],
        ];
    }
public function table_simple_info($table, $extra = [], &$error = false)
    public function table_simple_info($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $extra['just_info'] = true;
        return $this->table_info($table, $extra, $error);
    }
public function trigger_exists($name, $extra = [], &$error = false)
    public function trigger_exists($name, $extra = [], &$error = false)
    {
        $db_name = null;
        if (strpos($name, '.') !== false) {
            list($db_name, $name) = explode('.', trim($name));
        }
        if ( ! $name) {
            $error = 'trigger name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $triggers = $this->list_triggers($db_name, $extra, $error);
        return (bool) isset($triggers[$name]);
    }

trigger_info

public function trigger_info($name, $extra = [], &$error = false)
    public function trigger_info($name, $extra = [], &$error = false)
    {
        $db_name = null;
        if (strpos($name, '.') !== false) {
            list($db_name, $name) = explode('.', trim($name));
        }
        if ( ! $name) {
            $error = 'trigger name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $triggers = $this->list_triggers($db_name, $extra, $error);
        return isset($triggers[$name]) ? $triggers[$name] : false;
    }
public function truncate_database($db_name, $extra = [], &$error = false)
    public function truncate_database($db_name, $extra = [], &$error = false)
    {
        if ( ! strlen($db_name)) {
            $error = 'db_name is empty';
            return false;
        }
        if ( ! isset($extra['if_exists'])) {
            $extra['if_exists'] = true;
        }
        if ( ! ($extra['sql'] ?? null) && ! $this->database_exists($db_name)) {
            return true;
        }
        $sql = [];
        foreach ((array) $this->list_tables($db_name) as $table) {
            $sql[] = $this->drop_table($db_name . '.' . $table, $extra);
        }
        foreach ((array) $this->list_views($db_name) as $name => $tmp) {
            $sql[] = $this->drop_view($db_name . '.' . $name, $extra);
        }
        foreach ((array) $this->list_triggers($db_name) as $name => $tmp) {
            $sql[] = $this->drop_trigger($db_name . '.' . $name, $extra);
        }
        return ($extra['sql'] ?? null) ? implode(PHP_EOL, $sql) : true;
    }
public function truncate_table($table, $extra = [], &$error = false)
    public function truncate_table($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        $sql = $this->_sql_truncate_table($table);
        if ($sql === false) {
            $error = 'table "' . $table . '" is not in the connected database';
            return false;
        }
        return ($extra['sql'] ?? null) ? $sql : $this->db->query($sql);
    }
public function update_foreign_key($table, $index_name = '', $fields = [], $ref_table = '', $ref_fields = [], $extra = [], &$error = false)
    public function update_foreign_key($table, $index_name = '', $fields = [], $ref_table = '', $ref_fields = [], $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if (is_array($index_name)) {
            $extra = (array) $extra + $index_name;
            $index_name = '';
        }
        $table = ($extra['table'] ?? null) ?: $table;
        $index_name = ($extra['name'] ?? null) ?: $index_name;
        if ($this->drop_foreign_key($table, $index_name, $extra, $error)) {
            return $this->add_foreign_key($table, $index_name, $fields, $ref_table, $ref_fields, $extra, $error);
        }
        return false;
    }

update_index

public function update_index($table, $index_name = '', $fields = [], $extra = [], &$error = false)
    public function update_index($table, $index_name = '', $fields = [], $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        if (is_array($index_name)) {
            $extra = (array) $extra + $index_name;
            $index_name = '';
        }
        $table = ($extra['table'] ?? null) ?: $table;
        $index_name = ($extra['name'] ?? null) ?: $index_name;
        if ($this->drop_index($table, $index_name, $extra, $error)) {
            return $this->add_index($table, $index_name, $fields, $extra, $error);
        }
        return false;
    }

view

public function view($db_name, $view)

db()->utils()->database('geonames')->view('geo_city_view')->create('SQL HERE'); db()->utils()->view('geonames', 'geo_city_view')->create('SQL HERE');.

    public function view($db_name, $view)
    {
        $obj = clone _class('db_utils_helper_view', 'classes/db/');
        $obj->_setup([
            'utils' => $this,
            'db_name' => $db_name,
            'view' => $view,
        ]);
        return $obj;
    }

view_exists

public function view_exists($table, $extra = [], &$error = false)
    public function view_exists($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $views = $this->list_views($db_name);
        return (bool) isset($views[$table]);
    }

view_info

public function view_info($table, $extra = [], &$error = false)
    public function view_info($table, $extra = [], &$error = false)
    {
        if (is_array($table)) {
            $extra = (array) $extra + $table;
            $table = '';
        }
        $db_name = null;
        if (strpos($table, '.') !== false) {
            list($db_name, $table) = explode('.', trim($table));
        }
        if ( ! $table) {
            $error = 'table_name is empty';
            return false;
        }
        if ( ! $db_name) {
            $db_name = $this->db->DB_NAME;
        }
        if ( ! $db_name) {
            $error = 'db_name is empty';
            return false;
        }
        $views = $this->list_views($db_name);
        return isset($views[$table]) ? $views[$table] : false;
    }

Methods starting with _ hooks and helpers; not routable as page actions

__call

public function __call($name, $args)

Catch missing method call.

    public function __call($name, $args)
    {
        return main()->extend_call($this, $name, $args);
    }

__clone

public function __clone()

We cleanup object properties when cloning.

    public function __clone()
    {
        foreach ((array) get_object_vars($this) as $k => $v) {
            $this->$k = null;
        }
    }

_column_row

public function _column_row($row)

Lets a driver rewrite a raw column row (type text, default expression) into the MySQL wording the parser knows.

    public function _column_row($row)
    {
        return $row;
    }
public function _ddl_column_line(array $data)

Column definition line (name, type, nullability, default) for "ALTER TABLE ... ADD COLUMN".

  • $data array
    public function _ddl_column_line(array $data)
    {
        return _class('db_ddl_parser_mysql', 'classes/db/')->create_column_line($data);
    }
public function _ddl_create_sql(array $data, &$error = false)

"CREATE TABLE" text for the array shape of the sql_php files (name, fields, indexes, foreign_keys, options).

  • $data array
    public function _ddl_create_sql(array $data, &$error = false)
    {
        return _class('db_ddl_parser_mysql', 'classes/db/')->create($data);
    }

_es

public function _es($val = '')
    public function _es($val = '')
    {
        if ($val === null || $val === 'NULL') {
            return 'NULL';
        }
        $val = trim($val);
        if ( ! strlen($val)) {
            return '';
        }
        // TODO: support for binding params (':field' => $val)
        return is_object($this->db) && method_exists($this->db, '_es') ? $this->db->_es($val) : addslashes($val);
    }
public function _escape_database_name($name = '')
    public function _escape_database_name($name = '')
    {
        $name = str_replace(['\'', '"', '`'], '', trim($name));
        if ( ! strlen($name)) {
            return false;
        }
        return is_object($this->db) ? $this->db->escape_key($name) : '`' . addslashes($name) . '`';
    }
public function _escape_fields(array $fields)
  • $fields array
    public function _escape_fields(array $fields)
    {
        if (empty($fields)) {
            return $fields;
        }
        $self = __FUNCTION__;
        foreach ((array) $fields as $k => $v) {
            if (is_array($v)) {
                $fields[$k] = $this->$self($v);
            } else {
                $fields[$k] = $this->_escape_key($v);
            }
        }
        return $fields;
    }

_escape_key

public function _escape_key($key = '')
    public function _escape_key($key = '')
    {
        $key = trim(trim($key), '`');
        if ( ! strlen($key)) {
            return '';
        }
        $out = '';
        if ($key != '*' && false === strpos($key, '.') && false === strpos($key, '(')) {
            $out = is_object($this->db) ? $this->db->escape_key($key) : '`' . addslashes($key) . '`';
        } else {
            // split by "." and escape each value
            if (false !== strpos($key, '.') && false === strpos($key, '(') && false === strpos($key, ' ')) {
                $tmp = [];
                foreach (explode('.', $key) as $v) {
                    $tmp[] = is_object($this->db) ? $this->db->escape_key($v) : '`' . addslashes($v) . '`';
                }
                $out = implode('.', $tmp);
            } else {
                $out = $key;
            }
        }
        return $out;
    }
public function _escape_ref_table($name)

Referenced table of "REFERENCES", already passed through _fix_table_name().

    public function _escape_ref_table($name)
    {
        return $this->_escape_key($name);
    }
public function _escape_table_name($name = '')
    public function _escape_table_name($name = '')
    {
        $name = str_replace(['\'', '"', '`'], '', trim($name));
        if ( ! strlen($name)) {
            return false;
        }
        $db = '';
        $table = '';
        if (strpos($name, '.') !== false) {
            list($db, $table) = explode('.', $name);
            $db = trim($db);
            $table = trim($table);
        } else {
            $table = $name;
        }
        if ( ! strlen($table)) {
            return false;
        }
        $table = $this->db->_fix_table_name($table);
        return (strlen($db) ? $this->_escape_database_name($db) . '.' : '') . (is_object($this->db) ? $this->db->escape_key($table) : '`' . addslashes($table) . '`');
    }

_escape_val

public function _escape_val($val = '')
    public function _escape_val($val = '')
    {
        if ($val === null || $val === 'NULL') {
            return 'NULL';
        }
        $val = trim(trim($val), '\'');
        if ( ! strlen($val)) {
            return '';
        }
        // TODO: support for binding params (':field' => $val)
        return is_object($this->db) ? $this->db->escape_val($val) : '\'' . addslashes($val) . '\'';
    }
public function _get_supported_field_types()
    public function _get_supported_field_types()
    {
        return ['int', 'float', 'double', 'decimal', 'numeric', 'varchar', 'char', 'text', 'datetime', 'date'];
    }
public function _get_supported_table_options()
    public function _get_supported_table_options()
    {
        return [];
    }
public function _get_table_structure_from_db_installer($table, &$error = false)

Use db installer repository to get table structure.

    public function _get_table_structure_from_db_installer($table, &$error = false)
    {
        // TODO: move this code into db installer class
        if (strlen($this->db->DB_PREFIX) && substr($table, 0, strlen($this->db->DB_PREFIX)) == $this->db->DB_PREFIX) {
            $search_table = substr($table, strlen($this->db->DB_PREFIX));
        } else {
            $search_table = $table;
        }
        $ext = '.sql_php.php';
        $patterns = [
            PROJECT_PATH . 'db/sql_php/' . $search_table . $ext,
            PROJECT_PATH . 'plugins/*/db/sql_php/' . $search_table . $ext,
            PROJECT_PATH . 'share/db/sql_php/' . $search_table . $ext,
            PROJECT_PATH . 'plugins/*/share/db/sql_php/' . $search_table . $ext,
            CONFIG_PATH . 'db/sql_php/' . $search_table . $ext,
            CONFIG_PATH . 'plugins/*/db/sql_php/' . $search_table . $ext,
            CONFIG_PATH . 'share/db/sql_php/' . $search_table . $ext,
            CONFIG_PATH . 'plugins/*/share/db/sql_php/' . $search_table . $ext,
            YF_PATH . 'db/sql_php/' . $search_table . $ext,
            YF_PATH . 'plugins/*/db/sql_php/' . $search_table . $ext,
            YF_PATH . 'share/db/sql_php/' . $search_table . $ext,
            YF_PATH . 'plugins/*/share/db/sql_php/' . $search_table . $ext,
        ];

        $path = '';
        foreach ($patterns as $glob) {
            foreach (glob($glob) as $f) {
                $path = $f;
                break 2;
            }
        }
        if ( ! file_exists($path)) {
            $error = 'file not exists: ' . $path;
            return false;
        }
        $data = include $path;
        return $data;
    }
public function _get_unsigned_field_types()
    public function _get_unsigned_field_types()
    {
        return ['int'];
    }
public function _parse_column_type($str, &$error = false)

See http://dev.mysql.com/doc/refman/5.6/en/create-table.html.

    public function _parse_column_type($str, &$error = false)
    {
        // TODO: use db ddl parser if available for the given db family (mysql currently supported)
        $str = trim($str);
        $type = $length = $decimals = $values = null;
        if (preg_match('~^(?P<type>[a-z]+)[\s\t]*\((?P<length>[^\)]+)\)~i', $str, $m)) {
            $type = $m['type'];
            $length = $m['length'];
        } elseif (preg_match('~^(?P<type>[a-z]+)~i', $str, $m)) {
            $type = $m['type'];
        }
        $types = $this->_get_supported_field_types();
        if ($types) {
            $types = array_combine($types, $types);
        }
        if ($type) {
            $type = strtolower($type);
            foreach ((array) $types as $_type) {
                if (false !== strpos($type, $_type)) {
                    $type = $_type;
                    break;
                }
            }
        }
        if ($length && ! is_numeric($length) && false !== strpos($length, ',')) {
            if (in_array($type, ['real', 'double', 'float', 'decimal', 'numeric'])) {
                list($length, $decimals) = explode(',', $length);
                $length = (int) trim($length);
                $decimals = (int) trim($decimals);
            } elseif (in_array($type, ['enum', 'set'])) {
                $values = [];
                foreach (explode(',', $length) as $v) {
                    $v = trim(trim(trim($v), '\'"'));
                    if (strlen($v)) {
                        $values[$v] = $v;
                    }
                }
                $length = '';
            }
        }
        return [
            'type' => $type,
            'length' => $length,
            'unsigned' => false !== strpos(strtolower($str), 'unsigned') && in_array($type, $this->_get_unsigned_field_types()) ? true : false,
            'decimals' => $decimals,
            'values' => $values,
        ];
    }
public function _sql_add_index($table, $index_name, $index_type, array $fields, &$error = false)

False with $error set when the server cannot create such an index.

  • $fields array
    public function _sql_add_index($table, $index_name, $index_type, array $fields, &$error = false)
    {
        $supported_types = [
            'index' => 'index',
            'primary' => 'primary key',
            'unique' => 'unique key',
            'fulltext' => 'fulltext key',
        ];
        if ($index_name == 'PRIMARY' || $index_type == 'primary') {
            return 'ALTER TABLE ' . $this->_escape_table_name($table) . ' ADD PRIMARY KEY (' . implode(',', $this->_escape_fields($fields)) . ')';
        }
        return 'ALTER TABLE ' . $this->_escape_table_name($table) . ' ADD ' . strtoupper($supported_types[$index_type]) . ' ' . $this->_escape_val($index_name) . ' (' . implode(',', $this->_escape_fields($fields)) . ')';
    }

_sql_columns

public function _sql_columns($table)

Columns Field, Type, Null, Default, Extra, Key, Collation.

    public function _sql_columns($table)
    {
        return 'SHOW FULL COLUMNS FROM ' . $this->_escape_table_name($table);
    }
public function _sql_drop_foreign_key($table, $index_name)
    public function _sql_drop_foreign_key($table, $index_name)
    {
        return 'ALTER TABLE ' . $this->_escape_table_name($table) . ' DROP FOREIGN KEY ' . $this->_escape_key($index_name);
    }
public function _sql_drop_index($table, $index_name)
    public function _sql_drop_index($table, $index_name)
    {
        if ($index_name == 'PRIMARY') {
            return 'ALTER TABLE ' . $this->_escape_table_name($table) . ' DROP PRIMARY KEY';
        }
        return 'ALTER TABLE ' . $this->_escape_table_name($table) . ' DROP INDEX ' . $this->_escape_key($index_name);
    }
public function _sql_foreign_key_rules($db_name, $table)

One row per constraint: CONSTRAINT_NAME, UPDATE_RULE, DELETE_RULE.

    public function _sql_foreign_key_rules($db_name, $table)
    {
        return 'SELECT CONSTRAINT_NAME, UPDATE_RULE, DELETE_RULE
			FROM information_schema.REFERENTIAL_CONSTRAINTS
			WHERE CONSTRAINT_SCHEMA = ' . $this->_escape_val($db_name) . '
				AND TABLE_NAME = ' . $this->_escape_val($this->db->_fix_table_name($table));
    }
public function _sql_foreign_keys($db_name, $table)

One row per column: CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME.

    public function _sql_foreign_keys($db_name, $table)
    {
        return 'SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
			FROM information_schema.KEY_COLUMN_USAGE
			WHERE TABLE_SCHEMA = ' . $this->_escape_val($db_name) . '
				AND REFERENCED_TABLE_NAME IS NOT NULL
				AND TABLE_NAME = ' . $this->_escape_val($this->db->_fix_table_name($table));
    }
public function _sql_list_databases()

Vendor SQL hooks: the defaults are MySQL, a driver subclass overrides them to answer the same result columns.

    public function _sql_list_databases()
    {
        return 'SHOW DATABASES';
    }
public function _sql_list_indexes($table, $db_name = '')

One row per index column: Key_name ('PRIMARY' for the primary key), Non_unique, Index_type, Column_name.

    public function _sql_list_indexes($table, $db_name = '')
    {
        return 'SHOW INDEX FROM ' . $this->_escape_table_name($table);
    }
public function _sql_list_tables($db_name, &$error = false)

Two columns: table name and type ('VIEW' for views). False when the server cannot answer for $db_name.

    public function _sql_list_tables($db_name, &$error = false)
    {
        return 'SHOW FULL TABLES' . (strlen($db_name) ? ' FROM ' . $this->_escape_database_name($db_name) : '');
    }
public function _sql_list_triggers($db_name, &$error = false)

Columns Trigger, Table, Event, Timing, Statement. False when the server cannot answer for $db_name.

    public function _sql_list_triggers($db_name, &$error = false)
    {
        return 'SHOW TRIGGERS FROM ' . $this->_escape_database_name($db_name);
    }
public function _sql_list_views($db_name, &$error = false)

One column with the view name. False when the server cannot answer for $db_name.

    public function _sql_list_views($db_name, &$error = false)
    {
        return 'SELECT table_name FROM information_schema.tables WHERE table_schema = ' . $this->_escape_val($db_name) . ' AND table_type = "VIEW"';
    }
public function _sql_rename_table($table, $new_name)
    public function _sql_rename_table($table, $new_name)
    {
        return 'RENAME TABLE ' . $this->_escape_table_name($table) . ' TO ' . $this->_escape_table_name($new_name);
    }
public function _sql_table_charset($db_name, $table)

One row with the column character_set_name.

    public function _sql_table_charset($db_name, $table)
    {
        return 'SELECT CCSA.character_set_name
			FROM information_schema.`TABLES` T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
			WHERE CCSA.collation_name = T.table_collation
				AND T.table_schema = "' . $db_name . '"
				AND T.table_name = "' . $this->db->_fix_table_name($table) . '"';
    }
public function _sql_table_status($db_name, $table)

One row with Row_format, Collation, Engine, Rows, Data_length, Auto_increment, Comment, Create_time, Update_time.

    public function _sql_table_status($db_name, $table)
    {
        return 'SHOW TABLE STATUS' . (strlen($db_name) ? ' FROM ' . $this->_escape_database_name($db_name) . ' LIKE "' . $this->db->_fix_table_name($table) . '"' : '');
    }
public function _sql_tables_status($db_name, &$error = false)

Columns Name, Engine, Rows, Data_length, Collation.

    public function _sql_tables_status($db_name, &$error = false)
    {
        return 'SHOW TABLE STATUS' . (strlen($db_name) ? ' FROM ' . $this->_escape_database_name($db_name) : '');
    }
public function _sql_truncate_table($table)
    public function _sql_truncate_table($table)
    {
        return 'TRUNCATE TABLE ' . $this->_escape_table_name($table);
    }
public function _sql_view_definition($db_name, $name)

One row with the column "Create View" (the text of the CREATE VIEW statement).

    public function _sql_view_definition($db_name, $name)
    {
        return 'SHOW CREATE VIEW ' . $this->_escape_table_name($db_name . '.' . $name);
    }
public function _unquote_default_literal($default)
    public function _unquote_default_literal($default)
    {
        if ($default === 'NULL') {
            return null;
        }
        if (strlen($default) >= 2 && $default[0] === "'" && substr($default, -1) === "'") {
            return str_replace(["''", "\\'"], "'", substr($default, 1, -1));
        }
        return $default;
    }