Class: DataMiner::Schema
- Inherits:
-
Object
- Object
- DataMiner::Schema
- Includes:
- Blockenspiel::DSL
- Defined in:
- lib/data_miner/schema.rb
Constant Summary collapse
- MAX_INDEX_NAME_LENGTH =
50
- INDEX_PROPERTIES =
%w{ name columns }
- EXTRA_COLUMNS =
{ :updated_at => :datetime, :created_at => :datetime }
Instance Attribute Summary collapse
-
#base ⇒ Object
readonly
Returns the value of attribute base.
-
#create_table_options ⇒ Object
readonly
Returns the value of attribute create_table_options.
-
#position_in_run ⇒ Object
readonly
Returns the value of attribute position_in_run.
Instance Method Summary collapse
- #_add_columns ⇒ Object
- #_add_extra_columns ⇒ Object
- #_add_indexes ⇒ Object
- #_create_table ⇒ Object
- #_remove_columns ⇒ Object
- #_remove_indexes ⇒ Object
-
#_set_primary_key ⇒ Object
FIXME mysql only.
- #actual_column(name) ⇒ Object
- #actual_index(name) ⇒ Object
- #actual_indexes ⇒ Object
- #actual_primary_key_name ⇒ Object
- #column(*args) ⇒ Object
-
#column_equivalent?(a, b) ⇒ Boolean
FIXME mysql only (assume integer primary keys).
- #connection ⇒ Object
- #description ⇒ Object
- #ideal_column(name) ⇒ Object
- #ideal_index(name) ⇒ Object
- #ideal_indexes ⇒ Object
- #ideal_primary_key_name ⇒ Object
- #ideal_table ⇒ Object
- #index(columns, options = {}) ⇒ Object
- #index_equivalent?(a, b) ⇒ Boolean
-
#initialize(base, position_in_run, create_table_options) ⇒ Schema
constructor
A new instance of Schema.
- #inspect ⇒ Object
- #place_column(name) ⇒ Object
- #place_index(name) ⇒ Object
- #remove_column(name) ⇒ Object
- #remove_index(name) ⇒ Object
- #run(run) ⇒ Object
- #table_name ⇒ Object
Constructor Details
#initialize(base, position_in_run, create_table_options) ⇒ Schema
Returns a new instance of Schema.
10 11 12 13 14 15 16 17 18 |
# File 'lib/data_miner/schema.rb', line 10 def initialize(base, position_in_run, ) @base = base @position_in_run = position_in_run @create_table_options = @create_table_options.symbolize_keys! DataMiner.log_or_raise ":id => true is not allowed in create_table_options." if @create_table_options[:id] === true DataMiner.log_or_raise ":primary_key is not allowed in create_table_options. Use set_primary_key instead." if @create_table_options.has_key?(:primary_key) @create_table_options[:id] = false # always end |
Instance Attribute Details
#base ⇒ Object (readonly)
Returns the value of attribute base.
5 6 7 |
# File 'lib/data_miner/schema.rb', line 5 def base @base end |
#create_table_options ⇒ Object (readonly)
Returns the value of attribute create_table_options.
7 8 9 |
# File 'lib/data_miner/schema.rb', line 7 def @create_table_options end |
#position_in_run ⇒ Object (readonly)
Returns the value of attribute position_in_run.
6 7 8 |
# File 'lib/data_miner/schema.rb', line 6 def position_in_run @position_in_run end |
Instance Method Details
#_add_columns ⇒ Object
225 226 227 228 229 |
# File 'lib/data_miner/schema.rb', line 225 def _add_columns ideal_table.columns.each do |ideal| place_column ideal.name if column_needs_to_be_placed? ideal.name end end |
#_add_extra_columns ⇒ Object
174 175 176 177 178 |
# File 'lib/data_miner/schema.rb', line 174 def _add_extra_columns EXTRA_COLUMNS.each do |extra_name, extra_type| send extra_type, extra_name unless ideal_column extra_name end end |
#_add_indexes ⇒ Object
237 238 239 240 241 242 |
# File 'lib/data_miner/schema.rb', line 237 def _add_indexes ideal_indexes.each do |ideal| next if ideal.name == ideal_primary_key_name # this should already have been taken care of place_index ideal.name if index_needs_to_be_placed? ideal.name end end |
#_create_table ⇒ Object
180 181 182 183 184 185 186 187 188 |
# File 'lib/data_miner/schema.rb', line 180 def _create_table if not resource.table_exists? DataMiner.log_debug "CREATING TABLE #{table_name} with #{.inspect}" connection.create_table table_name, do |t| t.integer :data_miner_placeholder end resource.reset_column_information end end |
#_remove_columns ⇒ Object
219 220 221 222 223 |
# File 'lib/data_miner/schema.rb', line 219 def _remove_columns resource.columns_hash.values.each do |actual| remove_column actual.name if column_needs_to_be_removed? actual.name end end |
#_remove_indexes ⇒ Object
231 232 233 234 235 |
# File 'lib/data_miner/schema.rb', line 231 def _remove_indexes actual_indexes.each do |actual| remove_index actual.name if index_needs_to_be_removed? actual.name end end |
#_set_primary_key ⇒ Object
FIXME mysql only
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/data_miner/schema.rb', line 191 def _set_primary_key if ideal_primary_key_name == 'id' and not ideal_column('id') DataMiner.log_debug "no special primary key set on #{table_name}, so using 'id'" column 'id', :primary_key end actual = actual_column actual_primary_key_name ideal = ideal_column ideal_primary_key_name if not column_equivalent? actual, ideal DataMiner.log_debug "looks like #{table_name} has a bad (or missing) primary key" if actual DataMiner.log_debug "looks like primary key needs to change from #{actual_primary_key_name} to #{ideal_primary_key_name}, re-creating #{table_name} from scratch" connection.drop_table table_name resource.reset_column_information _create_table end place_column ideal_primary_key_name unless ideal.type.to_s == 'primary_key' DataMiner.log_debug "SETTING #{ideal_primary_key_name} AS PRIMARY KEY" if ActiveRecord::Base.connection.adapter_name.downcase == 'sqlite' connection.execute "CREATE UNIQUE INDEX IDX_#{table_name}_#{ideal_primary_key_name} ON #{table_name} (#{ideal_primary_key_name} ASC)" else connection.execute "ALTER TABLE `#{table_name}` ADD PRIMARY KEY (`#{ideal_primary_key_name}`)" end end end resource.reset_column_information end |
#actual_column(name) ⇒ Object
119 120 121 |
# File 'lib/data_miner/schema.rb', line 119 def actual_column(name) resource.columns_hash[name.to_s] end |
#actual_index(name) ⇒ Object
127 128 129 |
# File 'lib/data_miner/schema.rb', line 127 def actual_index(name) actual_indexes.detect { |actual| actual.name == name.to_s } end |
#actual_indexes ⇒ Object
36 37 38 |
# File 'lib/data_miner/schema.rb', line 36 def actual_indexes connection.indexes table_name end |
#actual_primary_key_name ⇒ Object
79 80 81 |
# File 'lib/data_miner/schema.rb', line 79 def actual_primary_key_name connection.primary_key(table_name).to_s end |
#column(*args) ⇒ Object
59 60 61 |
# File 'lib/data_miner/schema.rb', line 59 def column(*args) ideal_table.column(*args) end |
#column_equivalent?(a, b) ⇒ Boolean
FIXME mysql only (assume integer primary keys)
93 94 95 96 97 98 |
# File 'lib/data_miner/schema.rb', line 93 def column_equivalent?(a, b) return false unless a and b a_type = a.type.to_s == 'primary_key' ? 'integer' : a.type.to_s b_type = b.type.to_s == 'primary_key' ? 'integer' : b.type.to_s a_type == b_type and a.name.to_s == b.name.to_s end |
#connection ⇒ Object
20 21 22 |
# File 'lib/data_miner/schema.rb', line 20 def connection ActiveRecord::Base.connection end |
#description ⇒ Object
40 41 42 |
# File 'lib/data_miner/schema.rb', line 40 def description "Define a table called #{table_name} with primary key #{ideal_primary_key_name}" end |
#ideal_column(name) ⇒ Object
115 116 117 |
# File 'lib/data_miner/schema.rb', line 115 def ideal_column(name) ideal_table[name.to_s] end |
#ideal_index(name) ⇒ Object
123 124 125 |
# File 'lib/data_miner/schema.rb', line 123 def ideal_index(name) ideal_indexes.detect { |ideal| ideal.name == name.to_s } end |
#ideal_indexes ⇒ Object
32 33 34 |
# File 'lib/data_miner/schema.rb', line 32 def ideal_indexes @ideal_indexes ||= Array.new end |
#ideal_primary_key_name ⇒ Object
75 76 77 |
# File 'lib/data_miner/schema.rb', line 75 def ideal_primary_key_name resource.primary_key.to_s end |
#ideal_table ⇒ Object
28 29 30 |
# File 'lib/data_miner/schema.rb', line 28 def ideal_table @ideal_table ||= ActiveRecord::ConnectionAdapters::TableDefinition.new(connection) end |
#index(columns, options = {}) ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/data_miner/schema.rb', line 64 def index(columns, = {}) .symbolize_keys! columns = Array.wrap columns unless name = [:name] default_name = connection.index_name(table_name, .merge(:column => columns)) name = default_name.length < MAX_INDEX_NAME_LENGTH ? default_name : default_name[0..MAX_INDEX_NAME_LENGTH-11] + Zlib.crc32(default_name).to_s end index_unique = .has_key?(:unique) ? [:unique] : true ideal_indexes.push ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, name, index_unique, columns) end |
#index_equivalent?(a, b) ⇒ Boolean
84 85 86 87 88 89 90 |
# File 'lib/data_miner/schema.rb', line 84 def index_equivalent?(a, b) return false unless a and b INDEX_PROPERTIES.all? do |property| DataMiner.log_debug "...comparing #{a.send(property).inspect}.to_s <-> #{b.send(property).inspect}.to_s" a.send(property).to_s == b.send(property).to_s end end |
#inspect ⇒ Object
44 45 46 |
# File 'lib/data_miner/schema.rb', line 44 def inspect "Schema(#{resource}): #{description}" end |
#place_column(name) ⇒ Object
131 132 133 134 135 136 137 |
# File 'lib/data_miner/schema.rb', line 131 def place_column(name) remove_column name if actual_column name ideal = ideal_column name DataMiner.log_debug "ADDING COLUMN #{name}" connection.add_column table_name, name, ideal.type.to_sym # symbol type! resource.reset_column_information end |
#place_index(name) ⇒ Object
145 146 147 148 149 150 151 |
# File 'lib/data_miner/schema.rb', line 145 def place_index(name) remove_index name if actual_index name ideal = ideal_index name DataMiner.log_debug "ADDING INDEX #{name}" connection.add_index table_name, ideal.columns, :name => ideal.name resource.reset_column_information end |
#remove_column(name) ⇒ Object
139 140 141 142 143 |
# File 'lib/data_miner/schema.rb', line 139 def remove_column(name) DataMiner.log_debug "REMOVING COLUMN #{name}" connection.remove_column table_name, name resource.reset_column_information end |
#remove_index(name) ⇒ Object
153 154 155 156 157 |
# File 'lib/data_miner/schema.rb', line 153 def remove_index(name) DataMiner.log_debug "REMOVING INDEX #{name}" connection.remove_index table_name, :name => name resource.reset_column_information end |
#run(run) ⇒ Object
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/data_miner/schema.rb', line 159 def run(run) _add_extra_columns _create_table _set_primary_key _remove_columns _add_columns _remove_indexes _add_indexes DataMiner.log_debug "ran #{inspect}" end |
#table_name ⇒ Object
24 25 26 |
# File 'lib/data_miner/schema.rb', line 24 def table_name resource.table_name end |