LazyRecord\TableParser\MysqlTableParser::reverseTableSchema PHP Method

reverseTableSchema() public method

public reverseTableSchema ( $table, $referenceSchema = null )
    public function reverseTableSchema($table, $referenceSchema = null)
    {
        $stm = $this->connection->query("SHOW COLUMNS FROM {$table}");
        $schema = new DeclareSchema();
        $schema->columnNames = $schema->columns = array();
        $schema->table($table);
        $rows = $stm->fetchAll();
        foreach ($rows as $row) {
            $type = $row['Type'];
            $typeInfo = TypeInfoParser::parseTypeInfo($type, $this->driver);
            $isa = $typeInfo->isa;
            $column = $schema->column($row['Field']);
            $column->type($typeInfo->type);
            if ($typeInfo->length) {
                $column->length($typeInfo->length);
            }
            if ($typeInfo->precision) {
                $column->decimals($typeInfo->precision);
            }
            if ($typeInfo->isa) {
                $column->isa($typeInfo->isa);
            }
            if ($typeInfo->unsigned) {
                $column->unsigned();
            }
            if ($typeInfo->enum) {
                $column->enum($typeInfo->enum);
            } elseif ($typeInfo->set) {
                $column->set($typeInfo->set);
            }
            switch ($row['Null']) {
                case 'NO':
                    // timestamp is set to Null=No by default.
                    // However, it's possible that user didn't set notNull in the schema,
                    // we should skip the check in comparator.
                    if ($referenceSchema && isset($row['Field']) && $referenceSchema->getColumn($row['Field']) && !$referenceSchema->getColumn($row['Field'])->notNull && (strtolower($typeInfo->type) === 'timestamp' || isset($row['Key']) && $row['Key'] === 'PRI')) {
                    } else {
                        $column->notNull(true);
                    }
                    break;
                case 'YES':
                    $column->null();
                    break;
            }
            switch ($row['Key']) {
                case 'PRI':
                    $column->primary(true);
                    $schema->primaryKey = $row['Field'];
                    break;
                    // If Key is MUL, multiple occurrences of a given value are
                    // permitted within the column. The column is the first
                    // column of a nonunique index or a unique-valued index
                    // that can contain NULL values.
                // If Key is MUL, multiple occurrences of a given value are
                // permitted within the column. The column is the first
                // column of a nonunique index or a unique-valued index
                // that can contain NULL values.
                case 'MUL':
                    break;
                case 'UNI':
                    $column->unique(true);
                    break;
            }
            // Parse information from the Extra field
            // @see https://dev.mysql.com/doc/refman/5.7/en/show-columns.html
            $extraAttributes = [];
            if (strtolower($row['Extra']) == 'auto_increment') {
                $column->autoIncrement();
            } elseif (preg_match('/ON UPDATE (\\w+)/i', $row['Extra'], $matches)) {
                /*
                To specify automatic properties, use the DEFAULT
                CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses
                in column definitions. The order of the clauses does not
                matter. If both are present in a column definition, either
                can occur first. Any of the synonyms for CURRENT_TIMESTAMP
                have the same meaning as CURRENT_TIMESTAMP. These are
                CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(),
                LOCALTIMESTAMP, and LOCALTIMESTAMP().
                */
                $extraAttributes['OnUpdate' . Inflector::getInstance()->camelize(strtolower($matches[1]))] = true;
            } elseif (preg_match('/VIRTUAL GENERATED/i', $row['Extra'])) {
                $extraAttributes['VirtualGenerated'] = true;
            } elseif (preg_match('/VIRTUAL STORED/i', $row['Extra'])) {
                $extraAttributes['VirtualStored'] = true;
            }
            // The default value returned from MySQL is string, we need the
            // type information to cast them to PHP Scalar or other
            // corresponding type
            if (null !== $row['Default']) {
                $default = $row['Default'];
                if ($typeInfo->type == 'boolean') {
                    if ($default == '1') {
                        $column->default(true);
                    } elseif ($default == '0') {
                        $column->default(false);
                    }
                } elseif ($typeInfo->isa == 'int') {
                    $column->default(intval($default));
                } elseif ($typeInfo->isa == 'double') {
                    $column->default(doubleval($default));
                } elseif ($typeInfo->isa == 'float') {
                    $column->default(floatval($default));
                } elseif ($typeInfo->isa == 'str') {
                    $column->default($default);
                } elseif ($typeInfo->type == 'timestamp') {
                    // for mysql, timestamp fields' default value is
                    // 'current_timestamp' and 'on update current_timestamp'
                    // when the two conditions are matched, we need to elimante
                    // the default value just as what we've defined in schema.
                    if (isset($extraAttributes['OnUpdateCurrentTimestamp']) && strtolower($default) == 'current_timestamp') {
                        // Don't set default value
                    } elseif (strtolower($default) == 'current_timestamp') {
                        $column->default(new Raw($default));
                    } elseif (is_numeric($default)) {
                        $column->default(intval($default));
                    }
                } elseif ($typeInfo->type == 'datetime') {
                    // basically, CURRENT_TIMESTAMP, transaction_timestamp()
                    // and now() do exactly the same. CURRENT_TIMESTAMP is a
                    // syntactical oddity for a function, having no trailing
                    // pair of parentheses. That's according to the SQL
                    // standard.
                    //
                    // @see http://dba.stackexchange.com/questions/63548/difference-between-now-and-current-timestamp
                    if (strtolower($default) == 'current_timestamp') {
                        // XXX: NOW() will be converted into current_timestamp
                        $column->default(new Raw($default));
                    }
                }
            }
        }
        return $schema;
    }

Usage Example

Esempio n. 1
0
 public function testGetTables()
 {
     $manager = ConnectionManager::getInstance();
     $conn = $manager->getConnection('mysql');
     $driver = $manager->getQueryDriver('mysql');
     $conn->query("DROP TABLE IF EXISTS t1");
     $conn->query("CREATE TABLE t1 (val enum('a','b','c') );");
     $parser = new MysqlTableParser($driver, $conn);
     $tables = $parser->getTables();
     $this->assertNotEmpty($tables);
     $schema = $parser->reverseTableSchema('t1');
     $this->assertNotNull($schema);
     /*
             $sql = $parser->getTableSql('foo');
             ok($sql);
     
             $columns = $parser->parseTableSql('foo');
             $this->assertNotEmpty($columns);
     
             $columns = $parser->parseTableSql('bar');
             $this->assertNotEmpty($columns);
     
             $schema = $parser->reverseTableSchema('bar');
             $this->assertNotNull($schema);
     
             $id = $schema->getColumn('id');
             $this->assertNotNull($id);
             $this->assertTrue($id->autoIncrement);
             $this->assertEquals('INTEGER',$id->type);
             $this->assertEquals('int',$id->isa);
             $this->assertTrue($id->primary);
     */
 }
All Usage Examples Of LazyRecord\TableParser\MysqlTableParser::reverseTableSchema