data_miner 0.4.31 → 0.4.32

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.31
1
+ 0.4.32
data/data_miner.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{data_miner}
8
- s.version = "0.4.31"
8
+ s.version = "0.4.32"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Seamus Abshere", "Andy Rossmeissl"]
@@ -11,6 +11,10 @@ module DataMiner
11
11
  @configuration = configuration
12
12
  @position_in_run = position_in_run
13
13
  @create_table_options = create_table_options
14
+ @create_table_options.symbolize_keys!
15
+ DataMiner.log_or_raise ":id => true is not allowed in create_table_options." if @create_table_options[:id] === true
16
+ 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)
17
+ @create_table_options[:id] = false # always
14
18
  end
15
19
 
16
20
  def connection
@@ -34,11 +38,11 @@ module DataMiner
34
38
  end
35
39
 
36
40
  def description
37
- "Define a table called #{table_name} with primary key #{primary_key}"
41
+ "Define a table called #{table_name} with primary key #{ideal_primary_key_name}"
38
42
  end
39
43
 
40
44
  def inspect
41
- "Block(#{resource}): #{description}"
45
+ "Schema(#{resource}): #{description}"
42
46
  end
43
47
 
44
48
  # lifted straight from activerecord-3.0.0.beta3/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -55,31 +59,46 @@ module DataMiner
55
59
  def column(*args)
56
60
  ideal_table.column(*args)
57
61
  end
58
- # class IndexDefinition < Struct.new(:table, :name, :unique, :columns)
59
62
  def index(columns, options = {})
60
63
  options.symbolize_keys!
61
64
  columns = Array.wrap columns
62
- name = connection.index_name table_name, options.merge(:columns => columns)
65
+ name = options[:name] || connection.index_name(table_name, options.merge(:column => columns))
63
66
  index_unique = options.has_key?(:unique) ? options[:unique] : true
64
67
  ideal_indexes.push ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, name, index_unique, columns)
65
68
  end
66
-
67
- def primary_key
69
+
70
+ def ideal_primary_key_name
68
71
  resource.primary_key.to_s
69
72
  end
70
73
 
74
+ def actual_primary_key_name
75
+ connection.primary_key(table_name).to_s
76
+ end
77
+
71
78
  INDEX_PROPERTIES = %w{ name columns }
72
- COLUMN_PROPERTIES = %w{ name type }
79
+ def index_equivalent?(a, b)
80
+ return false unless a and b
81
+ INDEX_PROPERTIES.all? do |property|
82
+ DataMiner.log_debug "...comparing #{a.send(property).inspect}.to_s <-> #{b.send(property).inspect}.to_s"
83
+ a.send(property).to_s == b.send(property).to_s
84
+ end
85
+ end
86
+
87
+ # FIXME mysql only (assume integer primary keys)
88
+ def column_equivalent?(a, b)
89
+ return false unless a and b
90
+ a_type = a.type.to_s == 'primary_key' ? 'integer' : a.type.to_s
91
+ b_type = b.type.to_s == 'primary_key' ? 'integer' : b.type.to_s
92
+ a_type == b_type and a.name.to_s == b.name.to_s
93
+ end
94
+
73
95
  %w{ column index }.each do |i|
74
96
  eval %{
75
97
  def #{i}_needs_to_be_placed?(name)
76
98
  actual = actual_#{i} name
77
99
  return true unless actual
78
100
  ideal = ideal_#{i} name
79
- #{i.upcase}_PROPERTIES.any? do |property|
80
- DataMiner.log_debug "...comparing \#{actual.send(property).inspect}.to_s <-> \#{ideal.send(property).inspect}.to_s"
81
- actual.send(property).to_s != ideal.send(property).to_s
82
- end
101
+ not #{i}_equivalent? actual, ideal
83
102
  end
84
103
 
85
104
  def #{i}_needs_to_be_removed?(name)
@@ -107,13 +126,13 @@ module DataMiner
107
126
  def place_column(name)
108
127
  remove_column name if actual_column name
109
128
  ideal = ideal_column name
110
- DataMiner.log_info "adding column #{name}"
129
+ DataMiner.log_debug "ADDING COLUMN #{name}"
111
130
  connection.add_column table_name, name, ideal.type.to_sym # symbol type!
112
131
  resource.reset_column_information
113
132
  end
114
133
 
115
134
  def remove_column(name)
116
- DataMiner.log_info "removing column #{name}"
135
+ DataMiner.log_debug "REMOVING COLUMN #{name}"
117
136
  connection.remove_column table_name, name
118
137
  resource.reset_column_information
119
138
  end
@@ -121,17 +140,17 @@ module DataMiner
121
140
  def place_index(name)
122
141
  remove_index name if actual_index name
123
142
  ideal = ideal_index name
124
- DataMiner.log_info "adding index #{name}"
143
+ DataMiner.log_debug "ADDING INDEX #{name}"
125
144
  connection.add_index table_name, ideal.columns, :name => ideal.name
126
145
  resource.reset_column_information
127
146
  end
128
147
 
129
148
  def remove_index(name)
130
- DataMiner.log_info "removing index #{name}"
149
+ DataMiner.log_debug "REMOVING INDEX #{name}"
131
150
  connection.remove_index table_name, :name => name
132
151
  resource.reset_column_information
133
152
  end
134
-
153
+
135
154
  def run(run)
136
155
  _add_extra_columns
137
156
  _create_table
@@ -140,7 +159,7 @@ module DataMiner
140
159
  _add_columns
141
160
  _remove_indexes
142
161
  _add_indexes
143
- DataMiner.log_info "ran #{inspect}"
162
+ DataMiner.log_debug "ran #{inspect}"
144
163
  end
145
164
 
146
165
  EXTRA_COLUMNS = {
@@ -157,7 +176,7 @@ module DataMiner
157
176
 
158
177
  def _create_table
159
178
  if not resource.table_exists?
160
- DataMiner.log_info "creating table #{table_name} with #{create_table_options.inspect}"
179
+ DataMiner.log_debug "CREATING TABLE #{table_name} with #{create_table_options.inspect}"
161
180
  connection.create_table table_name, create_table_options do |t|
162
181
  t.integer :data_miner_placeholder
163
182
  end
@@ -167,26 +186,25 @@ module DataMiner
167
186
 
168
187
  # FIXME mysql only
169
188
  def _set_primary_key
170
- if column_needs_to_be_placed?(primary_key)
171
- retries_allowed = 1
172
- begin
173
- place_column primary_key
174
- DataMiner.log_info "adding primary key #{primary_key}"
175
- connection.execute "ALTER TABLE `#{table_name}` ADD PRIMARY KEY (`#{primary_key}`)"
176
- rescue
177
- if retries_allowed > 0 and $!.message =~ /primary/i
178
- DataMiner.log_info "looks like primary key changed, re-creating table from scratch"
179
- connection.drop_table table_name
180
- resource.reset_column_information
181
- _create_table
182
- retries_allowed -= 1
183
- retry
184
- else
185
- raise $!
186
- end
189
+ if ideal_primary_key_name == 'id' and not ideal_column('id')
190
+ DataMiner.log_debug "no special primary key set on #{table_name}, so using 'id'"
191
+ column 'id', :primary_key
192
+ end
193
+ actual = actual_column actual_primary_key_name
194
+ ideal = ideal_column ideal_primary_key_name
195
+ if not column_equivalent? actual, ideal
196
+ DataMiner.log_debug "looks like #{table_name} has a bad (or missing) primary key"
197
+ if actual
198
+ 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"
199
+ connection.drop_table table_name
200
+ resource.reset_column_information
201
+ _create_table
187
202
  end
188
- resource.reset_column_information
203
+ place_column ideal_primary_key_name
204
+ DataMiner.log_debug "ADDING PRIMARY KEY #{ideal_primary_key_name}"
205
+ connection.execute "ALTER TABLE `#{table_name}` ADD PRIMARY KEY (`#{ideal_primary_key_name}`)"
189
206
  end
207
+ resource.reset_column_information
190
208
  end
191
209
 
192
210
  def _remove_columns
@@ -209,7 +227,7 @@ module DataMiner
209
227
 
210
228
  def _add_indexes
211
229
  ideal_indexes.each do |ideal|
212
- next if ideal.name == primary_key # this should already have been taken care of
230
+ next if ideal.name == ideal_primary_key_name # this should already have been taken care of
213
231
  place_index ideal.name if index_needs_to_be_placed? ideal.name
214
232
  end
215
233
  end
@@ -1123,7 +1123,19 @@ end
1123
1123
  class CensusDivisionTrois < ActiveRecord::Base
1124
1124
  set_primary_key :number_code
1125
1125
  data_miner do
1126
- schema :options => 'ENGINE=InnoDB default charset=utf8', :id => false do
1126
+ schema :options => 'ENGINE=InnoDB default charset=utf8' do
1127
+ string 'number_code'
1128
+ string 'name'
1129
+ string 'census_region_name'
1130
+ integer 'census_region_number'
1131
+ index 'census_region_name', :name => 'homefry'
1132
+ end
1133
+ end
1134
+ end
1135
+
1136
+ class CensusDivisionFour < ActiveRecord::Base
1137
+ data_miner do
1138
+ schema do
1127
1139
  string 'number_code'
1128
1140
  string 'name'
1129
1141
  string 'census_region_name'
@@ -1169,6 +1181,36 @@ class DataMinerTest < Test::Unit::TestCase
1169
1181
  end
1170
1182
  end
1171
1183
 
1184
+ should "let schemas work with default id primary keys" do
1185
+ ActiveRecord::Base.connection.create_table 'census_division_fours', :id => true, :force => true, :options => 'ENGINE=InnoDB default charset=utf8' do |t|
1186
+ t.string 'name'
1187
+ # t.datetime 'updated_at'
1188
+ # t.datetime 'created_at'
1189
+ t.string 'census_region_name'
1190
+ # t.integer 'census_region_number'
1191
+ # t.integer 'data_miner_touch_count'
1192
+ # t.integer 'data_miner_last_run_id'
1193
+ end
1194
+ ActiveRecord::Base.connection.execute 'ALTER TABLE census_division_fours ADD INDEX (census_region_name)'
1195
+ CensusDivisionFour.reset_column_information
1196
+ missing_columns = %w{ updated_at created_at census_region_number data_miner_last_run_id data_miner_touch_count }
1197
+
1198
+ # sanity check
1199
+ missing_columns.each do |column|
1200
+ assert_equal false, CensusDivisionFour.column_names.include?(column)
1201
+ end
1202
+ assert_equal false, ActiveRecord::Base.connection.indexes(CensusDivisionFour.table_name).any? { |index| index.name == 'homefry' }
1203
+
1204
+ 3.times do
1205
+ CensusDivisionFour.run_data_miner!
1206
+ missing_columns.each do |column|
1207
+ assert_equal true, CensusDivisionFour.column_names.include?(column)
1208
+ end
1209
+ assert_equal true, ActiveRecord::Base.connection.indexes(CensusDivisionFour.table_name).any? { |index| index.name == 'homefry' }
1210
+ assert_equal :integer, CensusDivisionFour.columns_hash[CensusDivisionFour.primary_key].type
1211
+ end
1212
+ end
1213
+
1172
1214
  should "allow specifying dictionaries explicitly" do
1173
1215
  CensusDivisionDeux.run_data_miner!
1174
1216
  assert_equal 'South Region', CensusDivisionDeux.find(5).census_region_name
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 4
8
- - 31
9
- version: 0.4.31
8
+ - 32
9
+ version: 0.4.32
10
10
  platform: ruby
11
11
  authors:
12
12
  - Seamus Abshere