Class: ActiveRecord::ConnectionAdapters::OracleAdapter

Inherits:
AbstractAdapter show all
Defined in:
lib/connection_adapters/oracle_adapter.rb

Instance Method Summary collapse

Instance Method Details

#constraints(table_name, name = nil) ⇒ Object

:nodoc:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/connection_adapters/oracle_adapter.rb', line 62

def constraints(table_name, name = nil)#:nodoc:
  constraints = []    
  upcase_table_name = table_name.upcase   
    	sql = %Q{
 select UC.constraint_name, UC.constraint_type, UC.table_name, COL.column_name, 
   REF.r_constraint_name as referenced_constraint_name, REF.constraint_name as foreign_constraint_name, 
   REF.delete_rule as foreign_delete_rule, 
   COLREF.table_name as foreign_table_name, 
   COLREF.column_name as foreign_column_name 
 from	(select owner, constraint_name, constraint_type, table_name, r_owner, r_constraint_name 
   from all_constraints 
   where table_name='#{upcase_table_name}') UC 
 inner join (select constraint_name, table_name, column_name from all_cons_columns where table_name='#{upcase_table_name}') COL 
   on (COL.constraint_name = UC.constraint_name) 
 left join all_constraints REF 
   on (UC.constraint_name=REF.constraint_name OR UC.constraint_name=REF.r_constraint_name) 
 left join all_cons_columns COLREF 
   on (not COLREF.table_name='#{upcase_table_name}' 
   AND (REF.constraint_name=COLREF.constraint_name OR REF.r_constraint_name=COLREF.constraint_name)) 
    	}
    
  results = select_all(sql, name)     
  constraint_name_hash = {}
  results.each do |row| 
    # The author(s) of the Oracle adapter chose to selectively downcase column names for
    # "cleanliness" within our Rails code. I had to follow suit with constraint column & table names
    # so that model objects could look up their data values using the generated column accessor methods 
    unless row['column_name'].nil? then row['column_name'] = oracle_downcase(row['column_name']) end
    unless row['foreign_column_name'].nil? then row['foreign_column_name'] = oracle_downcase(row['foreign_column_name']) end
    unless row['table_name'].nil? then row['table_name'] = oracle_downcase(row['table_name']) end
    unless row['foreign_table_name'].nil? then row['foreign_table_name'] = oracle_downcase(row['foreign_table_name']) end
    constraint_name = row['constraint_name']
    foreign_constraint_name = row['foreign_constraint_name']
    column_name = row['column_name']
    
    # Process constraints local to this table
    if !(current_constraint = constraint_name_hash[constraint_name])
      current_constraint = OracleConstraint.new(constraint_name, row['constraint_type'], row['table_name'], 
      column_name, row['referenced_constraint_name'], row['foreign_table_name'], 
      row['foreign_column_name'], row['foreign_delete_rule'])
      constraints << current_constraint
      constraint_name_hash[constraint_name] = current_constraint
    # This key is a composite
    else 
      current_constraint.column_names << column_name unless current_constraint.column_names.include?(column_name)
      referenced_column_name = row['foreign_column_name']
      if referenced_column_name
        current_constraint.referenced_column_names << referenced_column_name unless current_constraint.referenced_column_names.include?(referenced_column_name)
      end
    end
    
    # Process constraints that reference this table's local constraints
    if foreign_constraint_name && foreign_constraint_name != constraint_name
   if !(current_foreign_constraint = constraint_name_hash[foreign_constraint_name])
        current_foreign_constraint = OracleConstraint.new(foreign_constraint_name, OracleConstraint::FOREIGN_KEY_TYPE,
          row['foreign_table_name'], row['foreign_column_name'], constraint_name,  
          row['table_name'], row['column_name'], row['foreign_delete_rule'])
        constraints << current_foreign_constraint
        constraint_name_hash[foreign_constraint_name] = current_foreign_constraint
      # This key is a composite
      else 
        referenced_column_name = row['foreign_column_name']
        if referenced_column_name
          current_foreign_constraint.column_names << referenced_column_name unless current_foreign_constraint.column_names.include?(referenced_column_name)
        end
        current_foreign_constraint.referenced_column_names << column_name unless current_foreign_constraint.referenced_column_names.include?(column_name)
      end
    end   
  end
  constraints       
end