Ejemplo n.º 1
0
 /**
  * Collects the foreign key column details for the given table.
  *
  * @param TableSchema $table the table metadata
  */
 protected function findConstraints($table)
 {
     $keys = [];
     /** @type TableNameSchema $each */
     foreach ($this->getTableNames() as $each) {
         $sql = "PRAGMA foreign_key_list({$each->name})";
         $fks = $this->connection->createCommand($sql)->queryAll();
         if ($each->name === $table->name) {
             foreach ($fks as $key) {
                 $column = $table->columns[strtolower($key['from'])];
                 $column->isForeignKey = true;
                 $column->refTable = $key['table'];
                 $column->refFields = $key['to'];
                 if (ColumnSchema::TYPE_INTEGER === $column->type) {
                     $column->type = ColumnSchema::TYPE_REF;
                 }
                 $table->foreignKeys[$key['from']] = [$key['table'], $key['to']];
                 // Add it to our foreign references as well
                 $relation = new RelationSchema(RelationSchema::BELONGS_TO, ['ref_table' => $key['table'], 'ref_fields' => $key['to'], 'field' => $key['from']]);
                 $table->addRelation($relation);
             }
         } else {
             $keys[$each->name] = $fks;
             foreach ($fks as $key => $fk) {
                 if ($fk['table'] === $table->name) {
                     $relation = new RelationSchema(RelationSchema::HAS_MANY, ['ref_table' => $each->name, 'ref_fields' => $fk['from'], 'field' => $fk['to']]);
                     $table->addRelation($relation);
                     $fks2 = $fks;
                     // if other has foreign keys to other tables, we can say these are related as well
                     foreach ($fks2 as $key2 => $fk2) {
                         if ($key !== $key2 && $fk2['table'] !== $table->name) {
                             // not same as parent, i.e. via reference back to self
                             // not the same key
                             $relation = new RelationSchema(RelationSchema::MANY_MANY, ['ref_table' => $fk2['table'], 'ref_fields' => $fk['to'], 'field' => $fk2['to'], 'junction_table' => $each->name, 'junction_field' => $fk['from'], 'junction_ref_field' => $fk2['from']]);
                             $table->addRelation($relation);
                         }
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 2
0
 protected function buildTableRelations(TableSchema $table, $constraints)
 {
     $schema = !empty($table->schemaName) ? $table->schemaName : $this->getDefaultSchema();
     $defaultSchema = $this->getDefaultSchema();
     $constraints2 = $constraints;
     foreach ($constraints as $key => $constraint) {
         $constraint = array_change_key_case($constraint, CASE_LOWER);
         $ts = $constraint['table_schema'];
         $tn = $constraint['table_name'];
         $cn = $constraint['column_name'];
         $rts = $constraint['referenced_table_schema'];
         $rtn = $constraint['referenced_table_name'];
         $rcn = $constraint['referenced_column_name'];
         if (0 == strcasecmp($tn, $table->tableName) && 0 == strcasecmp($ts, $schema)) {
             $name = $rts == $defaultSchema ? $rtn : $rts . '.' . $rtn;
             $cnk = strtolower($cn);
             $table->foreignKeys[$cnk] = [$name, $rcn];
             if (isset($table->columns[$cnk])) {
                 $table->columns[$cnk]->isForeignKey = true;
                 $table->columns[$cnk]->refTable = $name;
                 $table->columns[$cnk]->refFields = $rcn;
                 if (ColumnSchema::TYPE_INTEGER === $table->columns[$cnk]->type) {
                     $table->columns[$cnk]->type = ColumnSchema::TYPE_REF;
                 }
             }
             // Add it to our foreign references as well
             $relation = new RelationSchema(['type' => RelationSchema::BELONGS_TO, 'ref_table' => $name, 'ref_fields' => $rcn, 'field' => $cn]);
             $table->addRelation($relation);
         } elseif (0 == strcasecmp($rtn, $table->tableName) && 0 == strcasecmp($rts, $schema)) {
             $name = $ts == $defaultSchema ? $tn : $ts . '.' . $tn;
             $relation = new RelationSchema(['type' => RelationSchema::HAS_MANY, 'ref_table' => $name, 'ref_fields' => $cn, 'field' => $rcn]);
             $table->addRelation($relation);
             // if other has foreign keys to other tables, we can say these are related as well
             foreach ($constraints2 as $key2 => $constraint2) {
                 if (0 != strcasecmp($key, $key2)) {
                     $constraint2 = array_change_key_case($constraint2, CASE_LOWER);
                     $ts2 = $constraint2['table_schema'];
                     $tn2 = $constraint2['table_name'];
                     $cn2 = $constraint2['column_name'];
                     if (0 == strcasecmp($ts2, $ts) && 0 == strcasecmp($tn2, $tn)) {
                         $rts2 = $constraint2['referenced_table_schema'];
                         $rtn2 = $constraint2['referenced_table_name'];
                         $rcn2 = $constraint2['referenced_column_name'];
                         if (0 != strcasecmp($rts2, $schema) || 0 != strcasecmp($rtn2, $table->tableName)) {
                             $name2 = $rts2 == $schema ? $rtn2 : $rts2 . '.' . $rtn2;
                             // not same as parent, i.e. via reference back to self
                             // not the same key
                             $relation = new RelationSchema(['type' => RelationSchema::MANY_MANY, 'ref_table' => $name2, 'ref_fields' => $rcn2, 'field' => $rcn, 'junction_table' => $name, 'junction_field' => $cn, 'junction_ref_field' => $cn2]);
                             $table->addRelation($relation);
                         }
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 3
0
    /**
     * Collects the foreign key column details for the given table.
     * Also, collects the foreign tables and columns that reference the given table.
     *
     * @param TableSchema $table the table metadata
     */
    protected function findConstraints($table)
    {
        $schema = !empty($table->schemaName) ? $table->schemaName : $this->getDefaultSchema();
        $defaultSchema = $this->getDefaultSchema();
        $sql = <<<EOD
SELECT indextype,colnames FROM SYS.SYSINDEXES WHERE creator = :schema AND tname = :table
EOD;
        $params = [':schema' => $schema, ':table' => $table->name];
        $columns = $this->connection->createCommand($sql)->queryAll(true, $params);
        foreach ($columns as $key => $column) {
            $type = $column['indextype'];
            $colnames = $column['colnames'];
            switch ($type) {
                case 'Primary Key':
                    $colnames = explode(',', $colnames);
                    switch (count($colnames)) {
                        case 0:
                            // No primary key on table
                            $table->primaryKey = null;
                            break;
                        case 1:
                            // Only 1 primary key
                            $primary = strstr($colnames[0], ' ', true);
                            $key = strtolower($primary);
                            if (isset($table->columns[$key])) {
                                $table->columns[$key]->isPrimaryKey = true;
                                if ('integer' === $table->columns[$key]->type && $table->columns[$key]->autoIncrement) {
                                    $table->columns[$key]->type = 'id';
                                }
                            }
                            $table->primaryKey = $primary;
                            break;
                        default:
                            if (is_array($colnames)) {
                                $primary = '';
                                foreach ($colnames as $key) {
                                    $key = strstr($key, ' ', true);
                                    $primary = empty($key) ? $key : ',' . $key;
                                }
                                $table->primaryKey = $primary;
                            }
                            break;
                    }
                    break;
                case 'Unique Constraint':
                    $field = strtolower(strstr($colnames, ' ', true));
                    if (isset($table->columns[$field])) {
                        $table->columns[$field]->IsUnique = true;
                    }
                    break;
                case 'Non-unique':
                    $colnames = explode(',', $colnames);
                    switch (count($colnames)) {
                        case 1:
                            // Only 1 key
                            $field = strtolower(strstr($colnames[0], ' ', true));
                            if (isset($table->columns[$field])) {
                                $table->columns[$field]->isIndex = true;
                            }
                            break;
                        default:
                            if (is_array($colnames)) {
                                foreach ($colnames as $key) {
                                    $field = strtolower(strstr($key, ' ', true));
                                    if (isset($table->columns[$field])) {
                                        $table->columns[$field]->isIndex = true;
                                    }
                                }
                            }
                            break;
                    }
                    break;
            }
        }
        $sql = <<<EOD
SELECT * FROM SYS.SYSFOREIGNKEYS WHERE foreign_creator NOT IN ('SYS','dbo')
EOD;
        $columns = $columns2 = $this->connection->createCommand($sql)->queryAll();
        foreach ($columns as $key => $column) {
            list($cn, $rcn) = explode(' IS ', $column['columns']);
            $ts = $column['foreign_creator'];
            $tn = $column['foreign_tname'];
            $rts = $column['primary_creator'];
            $rtn = $column['primary_tname'];
            if (0 == strcasecmp($tn, $table->name) && 0 == strcasecmp($ts, $schema)) {
                $name = $rts == $defaultSchema ? $rtn : $rts . '.' . $rtn;
                $cnk = strtolower($cn);
                $table->foreignKeys[$cnk] = [$name, $rcn];
                if (isset($table->columns[$cnk])) {
                    $table->columns[$cnk]->isForeignKey = true;
                    $table->columns[$cnk]->refTable = $name;
                    $table->columns[$cnk]->refFields = $rcn;
                    if ('integer' === $table->columns[$cnk]->type) {
                        $table->columns[$cnk]->type = 'reference';
                    }
                }
                // Add it to our foreign references as well
                $table->addRelation('belongs_to', $name, $rcn, $cn);
            } elseif (0 == strcasecmp($rtn, $table->name) && 0 == strcasecmp($rts, $schema)) {
                $name = $ts == $defaultSchema ? $tn : $ts . '.' . $tn;
                $table->addRelation('has_many', $name, $cn, $rcn);
                // if other has foreign keys to other tables, we can say these are related as well
                foreach ($columns2 as $key2 => $column2) {
                    if (0 != strcasecmp($key, $key2)) {
                        $ts2 = $column2['foreign_creator'];
                        $tn2 = $column2['foreign_tname'];
                        list($cn2, $rcn2) = explode(' IS ', $column2['columns']);
                        if (0 == strcasecmp($ts2, $ts) && 0 == strcasecmp($tn2, $tn)) {
                            $rts2 = $column2['primary_creator'];
                            $rtn2 = $column2['primary_tname'];
                            if (0 != strcasecmp($rts2, $schema) || 0 != strcasecmp($rtn2, $table->name)) {
                                $name2 = $rts2 == $defaultSchema ? $rtn2 : $rts2 . '.' . $rtn2;
                                // not same as parent, i.e. via reference back to self
                                // not the same key
                                $table->addRelation('many_many', $name2, $rcn2, $rcn, "{$name}({$cn},{$cn2})");
                            }
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 4
0
    /**
     * Collects the primary and foreign key column details for the given table.
     *
     * @param TableSchema $table the table metadata
     */
    protected function findConstraints($table)
    {
        $defaultSchema = static::getDefaultSchema();
        $schema = !empty($table->schemaName) ? $table->schemaName : $defaultSchema;
        $sql = <<<EOD
\t\tSELECT D.constraint_type, C.position, D.r_constraint_name,
            C.owner as table_schema,
            C.table_name as table_name,
\t\t    C.column_name as column_name,
            E.owner as referenced_table_schema,
            E.table_name as referenced_table_name,
            F.column_name as referenced_column_name
        FROM ALL_CONS_COLUMNS C
        inner join ALL_constraints D on D.OWNER = C.OWNER and D.constraint_name = C.constraint_name
        left join ALL_constraints E on E.OWNER = D.r_OWNER and E.constraint_name = D.r_constraint_name
        left join ALL_cons_columns F on F.OWNER = E.OWNER and F.constraint_name = E.constraint_name and F.position = C.position
        WHERE D.constraint_type = 'R'
        ORDER BY D.constraint_name, C.position
EOD;
        $columns = $columns2 = $command = $this->connection->createCommand($sql)->queryAll();
        foreach ($columns as $key => $column) {
            $ts = $column['TABLE_SCHEMA'];
            $tn = $column['TABLE_NAME'];
            $cn = $column['COLUMN_NAME'];
            $rts = $column['REFERENCED_TABLE_SCHEMA'];
            $rtn = $column['REFERENCED_TABLE_NAME'];
            $rcn = $column['REFERENCED_COLUMN_NAME'];
            if (0 == strcasecmp($tn, $table->name) && 0 == strcasecmp($ts, $schema)) {
                $name = $rts == $defaultSchema ? $rtn : $rts . '.' . $rtn;
                $table->foreignKeys[$cn] = [$name, $rcn];
                if (isset($table->columns[$cn])) {
                    $table->columns[$cn]->isForeignKey = true;
                    $table->columns[$cn]->refTable = $name;
                    $table->columns[$cn]->refFields = $rcn;
                    if ('integer' === $table->columns[$cn]->type) {
                        $table->columns[$cn]->type = 'reference';
                    }
                }
                // Add it to our foreign references as well
                $table->addRelation('belongs_to', $name, $rcn, $cn);
            } elseif (0 == strcasecmp($rtn, $table->name) && 0 == strcasecmp($rts, $schema)) {
                $name = $ts == $defaultSchema ? $tn : $ts . '.' . $tn;
                $table->addRelation('has_many', $name, $cn, $rcn);
                // if other has foreign keys to other tables, we can say these are related as well
                foreach ($columns2 as $key2 => $column2) {
                    if (0 != strcasecmp($key, $key2)) {
                        $ts2 = $column2['TABLE_SCHEMA'];
                        $tn2 = $column2['TABLE_NAME'];
                        $cn2 = $column2['COLUMN_NAME'];
                        if (0 == strcasecmp($ts2, $ts) && 0 == strcasecmp($tn2, $tn)) {
                            $rts2 = $column2['REFERENCED_TABLE_SCHEMA'];
                            $rtn2 = $column2['REFERENCED_TABLE_NAME'];
                            $rcn2 = $column2['REFERENCED_COLUMN_NAME'];
                            if (0 != strcasecmp($rts2, $schema) || 0 != strcasecmp($rtn2, $table->name)) {
                                $name2 = $rts2 == $defaultSchema ? $rtn2 : $rts2 . '.' . $rtn2;
                                // not same as parent, i.e. via reference back to self
                                // not the same key
                                $table->addRelation('many_many', $name2, $rcn2, $rcn, "{$name}({$cn},{$cn2})");
                            }
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 5
0
    /**
     * Collects the foreign key column details for the given table.
     * Also, collects the foreign tables and columns that reference the given table.
     *
     * @param TableSchema $table the table metadata
     */
    protected function findConstraints($table)
    {
        $defaultSchema = $this->getDefaultSchema();
        $tableSchema = !empty($table->schemaName) ? $table->schemaName : $this->getDefaultSchema();
        $columns = [];
        foreach ($this->getSchemaNames() as $schema) {
            $sql = <<<MYSQL
SELECT table_schema, table_name, column_name, referenced_table_schema, referenced_table_name, referenced_column_name
FROM information_schema.KEY_COLUMN_USAGE WHERE referenced_table_name IS NOT NULL AND table_schema = '{$schema}';
MYSQL;
            $columns = array_merge($columns, $this->connection->createCommand($sql)->queryAll());
        }
        $columns2 = $columns;
        foreach ($columns as $key => $column) {
            $ts = $column['table_schema'];
            $tn = $column['table_name'];
            $cn = $column['column_name'];
            $rts = $column['referenced_table_schema'];
            $rtn = $column['referenced_table_name'];
            $rcn = $column['referenced_column_name'];
            if (0 == strcasecmp($tn, $table->name) && 0 == strcasecmp($ts, $tableSchema)) {
                $name = $rts == $defaultSchema ? $rtn : $rts . '.' . $rtn;
                $table->foreignKeys[$cn] = [$name, $rcn];
                $cnk = strtolower($cn);
                if (isset($table->columns[$cnk])) {
                    $table->columns[$cnk]->isForeignKey = true;
                    $table->columns[$cnk]->refTable = $name;
                    $table->columns[$cnk]->refFields = $rcn;
                    if ('integer' === $table->columns[$cnk]->type) {
                        $table->columns[$cnk]->type = 'reference';
                    }
                }
                // Add it to our foreign references as well
                $table->addRelation('belongs_to', $name, $rcn, $cn);
            } elseif (0 == strcasecmp($rtn, $table->name) && 0 == strcasecmp($rts, $tableSchema)) {
                $name = $ts == $defaultSchema ? $tn : $ts . '.' . $tn;
                $table->addRelation('has_many', $name, $cn, $rcn);
                // if other has foreign keys to other tables, we can say these are related as well
                foreach ($columns2 as $key2 => $column2) {
                    if (0 != strcasecmp($key, $key2)) {
                        $ts2 = $column2['table_schema'];
                        $tn2 = $column2['table_name'];
                        $cn2 = $column2['column_name'];
                        if (0 == strcasecmp($ts2, $ts) && 0 == strcasecmp($tn2, $tn)) {
                            $rts2 = $column2['referenced_table_schema'];
                            $rtn2 = $column2['referenced_table_name'];
                            $rcn2 = $column2['referenced_column_name'];
                            if (0 != strcasecmp($rts2, $tableSchema) || 0 != strcasecmp($rtn2, $table->name)) {
                                $name2 = $rts2 == $defaultSchema ? $rtn2 : $rts2 . '.' . $rtn2;
                                // not same as parent, i.e. via reference back to self
                                // not the same key
                                $table->addRelation('many_many', $name2, $rcn2, $rcn, "{$name}({$cn},{$cn2})");
                            }
                        }
                    }
                }
            }
        }
    }
Ejemplo n.º 6
0
 /**
  * Collects the foreign key column details for the given table.
  *
  * @param TableSchema $table the table metadata
  */
 protected function findConstraints($table)
 {
     $keys = [];
     /** @type TableNameSchema $each */
     foreach ($this->getTableNames() as $each) {
         $sql = "PRAGMA foreign_key_list({$each->name})";
         $fks = $this->connection->createCommand($sql)->queryAll();
         if ($each->name === $table->name) {
             foreach ($fks as $key) {
                 $column = $table->columns[$key['from']];
                 $column->isForeignKey = true;
                 $column->refTable = $key['table'];
                 $column->refFields = $key['to'];
                 if ('integer' === $column->type) {
                     $column->type = 'reference';
                 }
                 $table->foreignKeys[$key['from']] = [$key['table'], $key['to']];
                 // Add it to our foreign references as well
                 $table->addRelation('belongs_to', $key['table'], $key['to'], $key['from']);
             }
         } else {
             $keys[$each->name] = $fks;
             foreach ($fks as $key => $fk) {
                 if ($fk['table'] === $table->name) {
                     $table->addRelation('has_many', $each->name, $fk['from'], $fk['to']);
                     $fks2 = $fks;
                     // if other has foreign keys to other tables, we can say these are related as well
                     foreach ($fks2 as $key2 => $fk2) {
                         if ($key !== $key2 && $fk2['table'] !== $table->name) {
                             // not same as parent, i.e. via reference back to self
                             // not the same key
                             $table->addRelation('many_many', $fk2['table'], $fk['to'], $fk2['to'], "{$each->name}({$fk['from']},{$fk2['from']})");
                         }
                     }
                 }
             }
         }
     }
 }