Models/DBOperator.php
public function getTableStructure($tableName, $forceReload = false) {

        if (empty($this->_tables[$tableName]) || $forceReload) {
            try {
                $res = QC::executeSQL('SHOW CREATE TABLE `'.$tableName.'`');
            } catch (\Exception $e) {
                return null;
            }
        } else {
            return $this->_tables[$tableName];
        }

        $this->_tables[$tableName] = array();
        if ($res->rowCount()) {
            $res = $res->fetchAll(\PDO::FETCH_NUM);
            foreach($res as $row) {

                $this->_tables[$tableName] = array(
                    'table'			=>$tableName,
                    'columns'		=>array(),
                    'indexes'		=>array(),
                    'constraints'	=>array(),
                    'character_set'	=>'utf8',
                    'collation'		=>'utf8_unicode_ci'
                );

                $structure = $row[1];
                $info = explode("\n", $structure);
                array_shift($info);

                while($row = trim(array_shift($info))) {
                    if ($row[strlen($row)-1] == ',') $row = substr($row, 0, -1);

                    if ($row[0] == '`') {
                        $column = array();
                        $pos = strpos($row, '`', 1);
                        $column['name'] = substr($row, 1, $pos-1);
                        $row = trim(substr($row, $pos+1));

                        $pos = strpos($row, ' ');
                        if ($pos === false) $pos = strlen($row);
                        $column['type'] = substr($row, 0, $pos);
                        if (strpos($row, 'unsigned') !== false) {
                            $column['type'] .= ' unsigned';
                        }
                        $row = trim(substr($row, $pos + (isset($column['unsigned']) ? 9 : 0)));

                        $column['not_null'] = false;

                        if (strpos(strtolower($row), 'auto_increment')) {
                            $column['auto_increment'] = true;
                            $column['not_null'] = true;
                        } else {
                            if (($pos = strpos(strtolower($row), 'zerofill')) !== false) {
                                $column['zerofill'] = true;
                                $row = trim(substr($row, $pos + 8));
                            }

                            if (($pos = strpos($row, 'NULL')) !== false) {
                                $null = substr($row, 0, $pos + 4);
                                $row = trim(substr($row, $pos + 4));
                                if (strpos(strtolower($null), 'not') !== false) {
                                    $column['not_null'] = true;
                                }
                            }
                            if (strpos(strtolower($row), 'default') !== false) {
                                $row = trim(substr($row, 8));
                                $row = str_replace(array('"', '\''), '', $row);
                                $pos = strpos($row, ' ');
                                if ($pos === false) $pos = strlen($row);
                                $column['default'] = substr($row, $pos+1);
                                if ($column['default'] === false) $column['default'] = '';
                            }
                        }
                        $this->_tables[$tableName]['columns'][$column['name']] = $column;
                    } else if (($pos = strpos($row, 'KEY')) !== false) {
                        $key_start = strpos($row, '`')+1;

                        if (strpos($row, 'CONSTRAINT') !== false) {
                            $name = substr($row, $key_start, strpos($row, '`', $key_start+1)-$key_start);
                            $con = array('name' => $name);

                            $pos = strpos($row, 'FOREIGN KEY')+14;
                            $con['foreign_key'] = substr($row, $pos, strpos($row, '`', $pos) - $pos);

                            $pos = strpos($row, 'REFERENCES')+12;
                            $con['references'] = substr($row, $pos, strpos($row, '`', $pos) - $pos);

                            $pos = strpos($row, '(', $pos) + 2;
                            $con['local_key'] = substr($row, $pos, strpos($row, '`', $pos) - $pos);

                            if (($pos = strpos($row, 'ON DELETE'))) {
                                $pos += 10;
                                $con['on_delete'] = strtolower(substr($row, $pos, strpos($row, ' ON', $pos) - $pos));
                            } else {
                                $con['on_delete'] = 'restrict';
                            }

                            if (($pos = strpos($row, 'ON UPDATE'))) {
                                $pos += 10;
                                $con['on_update'] = strtolower(substr($row, $pos));
                            } else {
                                $con['on_update'] = 'restrict';
                            }

//							vd('constraint', $row, '!@#');

                            $this->_tables[$tableName]['constraints'][$name] = $con;
                        } elseif (strpos($row, 'PRIMARY') !== false) {
                            $key = substr($row, $key_start, strpos($row, '`', $key_start+1)-$key_start);
                            $this->_tables[$tableName]['indexes']['primary'] = array('columns'=>explode(',', $key), 'type'=>'primary');
                        } else {
                            $name = substr($row, $key_start, strpos($row, '`', $key_start+1)-$key_start);
                            $pos = strpos($row, '(')+1;
                            $key = str_replace('`', '', substr($row, $pos, strpos($row, ')') - $pos));
                            $key = explode(',', $key);
                            $item = array('type' => (strpos($row, 'UNIQUE') !== false) ? 'unique' : 'simple', 'columns'=>$key);
                            $this->_tables[$tableName]['indexes'][$name] = $item;
                        }
                    }
                }
                return $this->_tables[$tableName];
            }
        }
        return array();
    }
public function getTableStructure($tableName, $forceReload = false) {

        if (empty($this->_tables[$tableName]) || $forceReload) {
            try {
                $res = QC::executeSQL('SHOW CREATE TABLE `'.$tableName.'`');
            } catch (\Exception $e) {
                return null;
            }
        } else {
            return $this->_tables[$tableName];
        }

        $this->_tables[$tableName] = array();
        if ($res->rowCount()) {
            $res = $res->fetchAll(\PDO::FETCH_NUM);
            foreach($res as $row) {

                $this->_tables[$tableName] = array(
                    'table'			=>$tableName,
                    'columns'		=>array(),
                    'indexes'		=>array(),
                    'constraints'	=>array(),
                    'character_set'	=>'utf8',
                    'collation'		=>'utf8_unicode_ci'
                );

                $structure = $row[1];
                $info = explode("\n", $structure);
                array_shift($info);

                while($row = trim(array_shift($info))) {
                    if ($row[strlen($row)-1] == ',') $row = substr($row, 0, -1);

                    if ($row[0] == '`') {
                        $column = array();
                        $pos = strpos($row, '`', 1);
                        $column['name'] = substr($row, 1, $pos-1);
                        $row = trim(substr($row, $pos+1));

                        $pos = strpos($row, ' ');
                        if ($pos === false) $pos = strlen($row);
                        $column['type'] = substr($row, 0, $pos);
                        if (strpos($row, 'unsigned') !== false) {
                            $column['type'] .= ' unsigned';
                        }
                        $row = trim(substr($row, $pos + (isset($column['unsigned']) ? 9 : 0)));

                        $column['not_null'] = false;

                        if (strpos(strtolower($row), 'auto_increment')) {
                            $column['auto_increment'] = true;
                            $column['not_null'] = true;
                        } else {
                            if (($pos = strpos(strtolower($row), 'zerofill')) !== false) {
                                $column['zerofill'] = true;
                                $row = trim(substr($row, $pos + 8));
                            }

                            if (($pos = strpos($row, 'NULL')) !== false) {
                                $null = substr($row, 0, $pos + 4);
                                $row = trim(substr($row, $pos + 4));
                                if (strpos(strtolower($null), 'not') !== false) {
                                    $column['not_null'] = true;
                                }
                            }
                            if (strpos(strtolower($row), 'default') !== false) {
                                $row = trim(substr($row, 8));
                                $row = str_replace(array('"', '\''), '', $row);
                                $pos = strpos($row, ' ');
                                if ($pos === false) $pos = strlen($row);
                                $column['default'] = substr($row, $pos+1);
                                if ($column['default'] === false) $column['default'] = '';
                            }
                        }
                        $this->_tables[$tableName]['columns'][$column['name']] = $column;
                    } else if (($pos = strpos($row, 'KEY')) !== false) {
                        $key_start = strpos($row, '`')+1;

                        if (strpos($row, 'CONSTRAINT') !== false) {
                            $name = substr($row, $key_start, strpos($row, '`', $key_start+1)-$key_start);
                            $con = array('name' => $name);

                            $pos = strpos($row, 'FOREIGN KEY')+14;
                            $con['foreign_key'] = substr($row, $pos, strpos($row, '`', $pos) - $pos);

                            $pos = strpos($row, 'REFERENCES')+12;
                            $con['references'] = substr($row, $pos, strpos($row, '`', $pos) - $pos);

                            $pos = strpos($row, '(', $pos) + 2;
                            $con['local_key'] = substr($row, $pos, strpos($row, '`', $pos) - $pos);

                            if (($pos = strpos($row, 'ON DELETE'))) {
                                $pos += 10;
                                $con['on_delete'] = strtolower(substr($row, $pos, strpos($row, ' ON', $pos) - $pos));
                            } else {
                                $con['on_delete'] = 'restrict';
                            }

                            if (($pos = strpos($row, 'ON UPDATE'))) {
                                $pos += 10;
                                $con['on_update'] = strtolower(substr($row, $pos));
                            } else {
                                $con['on_update'] = 'restrict';
                            }

//							vd('constraint', $row, '!@#');

                            $this->_tables[$tableName]['constraints'][$name] = $con;
                        } elseif (strpos($row, 'PRIMARY') !== false) {
                            $key = substr($row, $key_start, strpos($row, '`', $key_start+1)-$key_start);
                            $this->_tables[$tableName]['indexes']['primary'] = array('columns'=>explode(',', $key), 'type'=>'primary');
                        } else {
                            $name = substr($row, $key_start, strpos($row, '`', $key_start+1)-$key_start);
                            $pos = strpos($row, '(')+1;
                            $key = str_replace('`', '', substr($row, $pos, strpos($row, ')') - $pos));
                            $key = explode(',', $key);
                            $item = array('type' => (strpos($row, 'UNIQUE') !== false) ? 'unique' : 'simple', 'columns'=>$key);
                            $this->_tables[$tableName]['indexes'][$name] = $item;
                        }
                    }
                }
                return $this->_tables[$tableName];
            }
        }
        return array();
    }
Get Full information about table structure and return it as array with keys
@param string $tableName
@param bool $forceReload
@return array structure