コード例 #1
0
 /**
  * Attepts to find a column on a foreign table.
  * Walks up table inheritance chains.
  * If the foreign column is itself a foreign key, resolves the type of that column before returning.
  */
 private static function resolve_foreign_column($db_doc, $local_schema, $local_table, $local_colname, $foreign_schema, $foreign_table, $foreign_colname, $visited = array())
 {
     // walk up the foreign table inheritance chain to find the foreign column definition
     $fschema = $foreign_schema;
     $ftable = $foreign_table;
     do {
         $foreign_column = dbx::get_table_column($ftable, $foreign_colname);
         if ($ftable['inheritsSchema']) {
             $fschema = dbx::get_schema($db_doc, (string) $ftable['inheritsSchema']);
         }
         if ($ftable['inheritsTable']) {
             $ftable = dbx::get_table($fschema, (string) $ftable['inheritsTable']);
         } else {
             $ftable = null;
         }
     } while (!$foreign_column && !!$fschema && !!$ftable);
     if (!$foreign_column) {
         // column wasn't found in any referenced tables
         throw new Exception("Local column {$local_schema['name']}.{$local_table['name']}.{$local_colname} references unknown column {$foreign_schema['name']}.{$foreign_table['name']}.{$foreign_colname}");
     }
     // column type is missing, and resolved foreign is also a foreign key?
     // recurse and find the cascading foreign key
     if (empty($foreign_column['type']) && !empty($foreign_column['foreignTable'])) {
         // make sure we don't visit the same column twice
         $foreign_col = format::get_fully_qualified_column_name($foreign_schema['name'], $foreign_table['name'], $foreign_column['name']);
         if (in_array($foreign_col, $visited)) {
             $local = format::get_fully_qualified_column_name($local_schema['name'], $local_table['name'], $local_colname);
             throw new Exception("Foreign key cyclic dependency detected! Local column {$local} pointing to foreign column {$foreign_col}");
         }
         $visited[] = $foreign_col;
         $nested_fkey = self::foreign_key_lookup($db_doc, $foreign_schema, $foreign_table, $foreign_column, $visited);
         // make a separate clone of the column element because we are specifying the type only for foreign key type referencing
         $foreign_column = new SimpleXMLElement($foreign_column->asXML());
         $foreign_column['type'] = (string) $nested_fkey['column']['type'];
     }
     return $foreign_column;
 }