php-yaoi/php-yaoi

View on GitHub
src/Database/Mysql/SchemaReader.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php

namespace Yaoi\Database\Mysql;

use Yaoi\Database;
use Yaoi\Database\Definition\Column;
use Yaoi\Database\Definition\Index;
use Yaoi\Database\Definition\Table;
use Yaoi\Sql\Symbol;

class SchemaReader
{
    const _PRIMARY = 'PRIMARY';

    /**
     * @var Database
     */
    protected $database;

    /**
     * @var Database\Utility
     */
    protected $utility;

    public function __construct(Database\Contract $database) {
        $this->database = $database;
        $this->utility = $database->getUtility();
    }

    public function getTableDefinition($tableName) {
        $tableSymbol = new Symbol($tableName);
        $res = $this->database->query("DESC ?", $tableSymbol);
        $columns = new \stdClass();
        while ($row = $res->fetchRow()) {
            $type = $row['Type'];
            $field = $row['Field'];

            $phpType = $this->getTypeByString($type);

            if ('auto_increment' === $row['Extra']) {
                $phpType += Column::AUTO_ID;
            }

            $column = new Column($phpType);
            $columns->$field = $column;
            $column->schemaName = $field;
            $notNull = $row['Null'] === 'NO';
            if ($row['Default'] !== null || !$notNull) {
                $column->setDefault($row['Default']);
            }
            $column->setFlag(Column::NOT_NULL, $notNull);
        }

        $definition = new Table($columns, $this->database, $tableName);

        $res = $this->database->query("SHOW INDEX FROM ?", $tableSymbol);
        $indexes = array();
        $uniqueIndex = array();
        foreach ($res as $row) {
            $indexes [$row['Key_name']][$row['Seq_in_index']] = $columns->{$row['Column_name']};
            $uniqueIndex [$row['Key_name']] = !$row['Non_unique'];
        }

        foreach ($indexes as $indexName => $indexData) {
            ksort($indexData);
            $index = new Index(array_values($indexData));
            $index->setName($indexName);
            $index->setType($uniqueIndex[$indexName] ? Index::TYPE_UNIQUE : Index::TYPE_KEY);
            if ($indexName === self::_PRIMARY) {
                $definition->setPrimaryKey($index->columns);
            }
            else {
                $definition->addIndex($index);
            }
        }

        return $definition;

    }


    public function getTypeByString($type) {
        $phpType = Column::STRING;
        switch (true) {
            case 'bigint' === substr($type, 0, 6):
            case 'int' === substr($type, 0, 3):
            case 'mediumint' === substr($type, 0, 9):
            case 'smallint' === substr($type, 0, 8):
            case 'tinyint' === substr($type, 0, 7):
                $phpType = Column::INTEGER;
                break;

            case 'decimal' === substr($type, 0, 7):
            case 'double' === $type:
            case 'float' === $type:
                $phpType = Column::FLOAT;
                break;

            case 'date' === $type:
            case 'datetime' === $type:
            case 'timestamp' === $type:
                $phpType = Column::TIMESTAMP;
                break;

        }
        return $phpType;
    }

}