Class: LegacyData::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/legacy_data/schema.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table_name) ⇒ Schema

Returns a new instance of Schema.



60
61
62
# File 'lib/legacy_data/schema.rb', line 60

def initialize(table_name)
  @table_name = table_name
end

Instance Attribute Details

#table_nameObject (readonly)

Returns the value of attribute table_name.



3
4
5
# File 'lib/legacy_data/schema.rb', line 3

def table_name
  @table_name
end

Class Method Details

.add_pending_table(table_name) ⇒ Object



32
33
34
# File 'lib/legacy_data/schema.rb', line 32

def self.add_pending_table table_name
  table_definitions[table_name] = :pending if table_definitions[table_name].nil?
end

.analyze(options = {}) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/legacy_data/schema.rb', line 5

def self.analyze(options={})
  initialize_tables(options[:table_name])

  while table_name = next_table_to_process
    table_definitions[table_name] = analyze_table(table_name)

    [:has_some, :belongs_to].each do |relation_type| 
      associated_tables = table_definitions[table_name][:relations][relation_type].keys.map(&:to_s) 
      associated_tables.each {|associated_table| add_pending_table(associated_table) }
    end
  end

  remove_join_tables
end

.analyze_table(table_name) ⇒ Object



19
20
21
# File 'lib/legacy_data/schema.rb', line 19

def self.analyze_table table_name
  new(table_name).analyze_table
end

.clear_table_definitionsObject



38
39
40
# File 'lib/legacy_data/schema.rb', line 38

def self.clear_table_definitions
  @tables = {}
end

.convert_to_habtm(join_table) ⇒ Object



54
55
56
57
58
# File 'lib/legacy_data/schema.rb', line 54

def self.convert_to_habtm join_table
  join_table.belongs_to_tables.each do |table|
    table_definitions[table].convert_has_many_to_habtm(join_table)
  end
end

.initialize_tables(table_name) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/legacy_data/schema.rb', line 24

def self.initialize_tables(table_name)
  clear_table_definitions
  if table_name
    add_pending_table(table_name)
  else
    LegacyData::Schema.tables.each {|table| add_pending_table(table) }
  end
end

.next_join_tableObject



44
45
46
# File 'lib/legacy_data/schema.rb', line 44

def self.next_join_table
  table_definitions.keys.detect {|table_name| table_definitions[table_name].join_table? }
end

.next_table_to_processObject



35
36
37
# File 'lib/legacy_data/schema.rb', line 35

def self.next_table_to_process
  table_definitions.keys.detect {|table_name| table_definitions[table_name] == :pending }
end

.remove_join_tablesObject



47
48
49
50
51
52
53
# File 'lib/legacy_data/schema.rb', line 47

def self.remove_join_tables
  join_tables, other_tables = table_definitions.values.partition &:join_table?

  join_tables.each { |join_table| convert_to_habtm(join_table) }

  other_tables
end

.table_definitionsObject



41
42
43
# File 'lib/legacy_data/schema.rb', line 41

def self.table_definitions
  @tables ||= {}
end

.tablesObject



74
75
76
# File 'lib/legacy_data/schema.rb', line 74

def self.tables 
  connection.tables.sort
end

Instance Method Details

#analyze_tableObject



64
65
66
67
68
69
70
71
72
# File 'lib/legacy_data/schema.rb', line 64

def analyze_table
  puts "analyzing #{table_name} => #{class_name}"
  TableDefinition.new(:table_name   => table_name,
                      :columns      => column_names,
                      :primary_key  => primary_key,
                      :relations    => relations,
                      :constraints  => constraints
                      )
end

#belongs_to_relationsObject



94
95
96
97
98
99
100
101
102
# File 'lib/legacy_data/schema.rb', line 94

def belongs_to_relations
  return [] unless connection.respond_to? :foreign_keys_for
  
  belongs_to = {}
  connection.foreign_keys_for(table_name).each do |relation|
    belongs_to[relation.first.downcase] = relation.second.downcase.to_sym
  end
  belongs_to
end

#class_nameObject



78
79
80
# File 'lib/legacy_data/schema.rb', line 78

def class_name
  TableClassNameMapper.class_name_for(self.table_name)
end

#column_namesObject



125
126
127
# File 'lib/legacy_data/schema.rb', line 125

def column_names
  columns.map(&:name)
end

#columnsObject



122
123
124
# File 'lib/legacy_data/schema.rb', line 122

def columns
  @columns ||= connection.columns(table_name, "#{table_name} Columns")
end

#constraintsObject



113
114
115
116
117
118
119
120
# File 'lib/legacy_data/schema.rb', line 113

def constraints
  unique, multi_column_unique = unique_constraints.partition {|columns| columns.size == 1}
  { :unique              => unique,
    :multi_column_unique => multi_column_unique,
    :non_nullable        => non_nullable_constraints,
    :custom              => custom_constraints
  }
end

#custom_constraintsObject



137
138
139
140
141
142
143
144
# File 'lib/legacy_data/schema.rb', line 137

def custom_constraints
  return [] unless connection.respond_to? :constraints
  user_constraints = {}
  connection.constraints(table_name).each do |constraint|
    user_constraints[constraint.first.underscore.to_sym] = constraint.second
  end
  user_constraints
end

#has_some_relationsObject



103
104
105
106
107
108
109
110
111
# File 'lib/legacy_data/schema.rb', line 103

def has_some_relations
  return [] unless connection.respond_to? :foreign_keys_of

  has_some = {}
  connection.foreign_keys_of(table_name).each do |relation|
    has_some[relation.delete(:to_table).downcase] = relation
  end
  has_some
end

#non_nullable_constraintsObject



128
129
130
131
# File 'lib/legacy_data/schema.rb', line 128

def non_nullable_constraints
  non_nullable_constraints = columns.reject(&:null).map(&:name)
  non_nullable_constraints.reject {|col| col == primary_key}
end

#primary_keyObject



82
83
84
85
# File 'lib/legacy_data/schema.rb', line 82

def primary_key
  pk_and_sequence_for = connection.pk_and_sequence_for(table_name)
  pk_and_sequence_for.first if pk_and_sequence_for.respond_to? :first
end

#relationsObject



87
88
89
90
91
92
# File 'lib/legacy_data/schema.rb', line 87

def relations
  { :belongs_to               => belongs_to_relations,
    :has_some                 => has_some_relations,
    :has_and_belongs_to_many  => {}
  }
end

#unique_constraintsObject



133
134
135
# File 'lib/legacy_data/schema.rb', line 133

def unique_constraints
  connection.indexes(table_name).select(&:unique).map(&:columns)
end