data_miner 3.0.0.alpha → 3.0.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/CHANGELOG +12 -0
- data/data_miner.gemspec +3 -1
- data/lib/data_miner.rb +1 -0
- data/lib/data_miner/active_record_class_methods.rb +1 -0
- data/lib/data_miner/script.rb +35 -0
- data/lib/data_miner/step.rb +16 -0
- data/lib/data_miner/step/import.rb +30 -0
- data/lib/data_miner/step/test.rb +77 -0
- data/lib/data_miner/version.rb +1 -1
- data/spec/spec_helper.rb +25 -0
- data/spec/test_step_spec.rb +134 -0
- data/test/helper.rb +1 -49
- data/test/support/database.rb +50 -0
- data/test/support/pet.rb +7 -0
- metadata +42 -2
data/.rspec
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
3.0.0.beta / 2013-07-26
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
|
5
|
+
* test steps with after: and every: options, referring to row counts in the previous step
|
6
|
+
* :limit option for import steps - oh yeah
|
7
|
+
* :random_skip option - goes nicely with :limit if you're debugging
|
8
|
+
|
9
|
+
* Bug fixes
|
10
|
+
|
11
|
+
* Make sure to stringify data_miner(:append) option
|
12
|
+
|
1
13
|
3.0.0.alpha / 2013-07-24
|
2
14
|
|
3
15
|
* breaking changes
|
data/data_miner.gemspec
CHANGED
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_runtime_dependency 'posix-spawn'
|
26
26
|
s.add_runtime_dependency 'unix_utils'
|
27
27
|
s.add_runtime_dependency 'roo', '>=1.10.3'
|
28
|
-
|
28
|
+
s.add_runtime_dependency 'rspec-expectations'
|
29
|
+
|
30
|
+
s.add_development_dependency 'rspec'
|
29
31
|
s.add_development_dependency 'pry'
|
30
32
|
s.add_development_dependency 'active_record_inline_schema'
|
31
33
|
s.add_development_dependency 'fuzzy_match'
|
data/lib/data_miner.rb
CHANGED
data/lib/data_miner/script.rb
CHANGED
@@ -92,6 +92,36 @@ class DataMiner
|
|
92
92
|
append(:process, method_id_or_description, &blk)
|
93
93
|
end
|
94
94
|
|
95
|
+
# A step that runs tests and stops the data miner on failures.
|
96
|
+
#
|
97
|
+
# rspec-expectations are automatically included.
|
98
|
+
#
|
99
|
+
# @see DataMiner::ActiveRecordClassMethods#data_miner Overview of how to define data miner scripts inside of ActiveRecord models.
|
100
|
+
# @see DataMiner::Step::Test The actual Test class.
|
101
|
+
#
|
102
|
+
# @param [String] description A description of what the block does.
|
103
|
+
# @param [Hash] settings Settings
|
104
|
+
# @option settings [String] :after After how many rows of the previous step to run the tests.
|
105
|
+
# @yield [] Tests to be run
|
106
|
+
#
|
107
|
+
# @example Tests
|
108
|
+
# data_miner do
|
109
|
+
# [...]
|
110
|
+
# test "make sure something works" do
|
111
|
+
# expect(Pet.count).to be > 10
|
112
|
+
# end
|
113
|
+
# [...]
|
114
|
+
# test "make sure something works", after: 20 do
|
115
|
+
# [...]
|
116
|
+
# end
|
117
|
+
# [...]
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# @return [nil]
|
121
|
+
def test(description, settings = {}, &blk)
|
122
|
+
append(:test, description, settings, &blk)
|
123
|
+
end
|
124
|
+
|
95
125
|
# Import rows into your model.
|
96
126
|
#
|
97
127
|
# As long as...
|
@@ -217,6 +247,11 @@ class DataMiner
|
|
217
247
|
Script.current_stack.clear
|
218
248
|
end
|
219
249
|
Script.current_stack << model_name
|
250
|
+
steps.each do |step|
|
251
|
+
steps.each do |other|
|
252
|
+
other.register step
|
253
|
+
end
|
254
|
+
end
|
220
255
|
steps.each do |step|
|
221
256
|
step.start
|
222
257
|
model.reset_column_information
|
data/lib/data_miner/step.rb
CHANGED
@@ -12,5 +12,21 @@ class DataMiner
|
|
12
12
|
def model
|
13
13
|
script.model
|
14
14
|
end
|
15
|
+
|
16
|
+
def pos
|
17
|
+
script.steps.index self
|
18
|
+
end
|
19
|
+
|
20
|
+
def register(step)
|
21
|
+
# noop
|
22
|
+
end
|
23
|
+
|
24
|
+
def notify(*args)
|
25
|
+
# noop
|
26
|
+
end
|
27
|
+
|
28
|
+
def target?(*args)
|
29
|
+
false
|
30
|
+
end
|
15
31
|
end
|
16
32
|
end
|
@@ -20,6 +20,17 @@ class DataMiner
|
|
20
20
|
# @return [String]
|
21
21
|
attr_reader :description
|
22
22
|
|
23
|
+
# Max number of rows to import.
|
24
|
+
# @return [Numeric]
|
25
|
+
attr_reader :limit
|
26
|
+
|
27
|
+
# Number from zero to one representing what percentage of rows to skip. Defaults to 0, of course :)
|
28
|
+
# @return [Numeric]
|
29
|
+
attr_reader :random_skip
|
30
|
+
|
31
|
+
# @private
|
32
|
+
attr_reader :listeners
|
33
|
+
|
23
34
|
# @private
|
24
35
|
def initialize(script, description, settings, &blk)
|
25
36
|
settings = settings.stringify_keys
|
@@ -41,6 +52,9 @@ class DataMiner
|
|
41
52
|
@table_settings = settings.dup
|
42
53
|
@table_settings['streaming'] = true
|
43
54
|
@table_mutex = ::Mutex.new
|
55
|
+
@limit = settings.fetch 'limit', (1.0/0)
|
56
|
+
@random_skip = settings['random_skip']
|
57
|
+
@listeners = []
|
44
58
|
instance_eval(&blk)
|
45
59
|
end
|
46
60
|
|
@@ -94,6 +108,12 @@ class DataMiner
|
|
94
108
|
@validate_query == true
|
95
109
|
end
|
96
110
|
|
111
|
+
def register(step)
|
112
|
+
if step.target?(self)
|
113
|
+
listeners << step
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
97
117
|
private
|
98
118
|
|
99
119
|
def upsert_enabled?
|
@@ -110,7 +130,9 @@ class DataMiner
|
|
110
130
|
count = 0
|
111
131
|
Upsert.stream(c, model.table_name) do |upsert|
|
112
132
|
table.each do |row|
|
133
|
+
next if random_skip and random_skip > Kernel.rand
|
113
134
|
$stderr.puts "#{count}..." if count_every > 0 and count % count_every == 0
|
135
|
+
break if count > limit
|
114
136
|
count += 1
|
115
137
|
selector = @key ? { @key => attributes[@key].read(row) } : { model.primary_key => nil }
|
116
138
|
document = attrs_except_key.inject({}) do |memo, attr|
|
@@ -125,6 +147,9 @@ class DataMiner
|
|
125
147
|
memo
|
126
148
|
end
|
127
149
|
upsert.row selector, document
|
150
|
+
listeners.select! do |listener|
|
151
|
+
listener.notify self, count
|
152
|
+
end
|
128
153
|
end
|
129
154
|
end
|
130
155
|
model.connection_pool.checkin c
|
@@ -133,11 +158,16 @@ class DataMiner
|
|
133
158
|
def save_with_find_or_initialize
|
134
159
|
count = 0
|
135
160
|
table.each do |row|
|
161
|
+
next if random_skip and random_skip > Kernel.rand
|
136
162
|
$stderr.puts "#{count}..." if count_every > 0 and count % count_every == 0
|
163
|
+
break if count > limit
|
137
164
|
count += 1
|
138
165
|
record = @key ? model.send("find_or_initialize_by_#{@key}", attributes[@key].read(row)) : model.new
|
139
166
|
attributes.each { |_, attr| attr.set_from_row record, row }
|
140
167
|
record.save!
|
168
|
+
listeners.select! do |listener|
|
169
|
+
listener.notify self, count
|
170
|
+
end
|
141
171
|
end
|
142
172
|
end
|
143
173
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rspec-expectations'
|
2
|
+
|
3
|
+
class DataMiner
|
4
|
+
class Step
|
5
|
+
# A step that runs tests and stops the data miner on failures.
|
6
|
+
#
|
7
|
+
# Create these by calling +test+ inside a +data_miner+ block.
|
8
|
+
#
|
9
|
+
# @see DataMiner::ActiveRecordClassMethods#data_miner Overview of how to define data miner scripts inside of ActiveRecord models.
|
10
|
+
# @see DataMiner::Script#test Creating a test step by calling DataMiner::Script#test from inside a data miner script
|
11
|
+
class Test < Step
|
12
|
+
include ::RSpec::Expectations
|
13
|
+
include ::RSpec::Matchers
|
14
|
+
|
15
|
+
# A description of what the block does. Doesn't exist when a single class method is specified using a Symbol.
|
16
|
+
# @return [String]
|
17
|
+
attr_reader :description
|
18
|
+
|
19
|
+
# The block of arbitrary code to be run.
|
20
|
+
# @return [Proc]
|
21
|
+
attr_reader :blk
|
22
|
+
|
23
|
+
# After how many rows of the previous step to run the tests.
|
24
|
+
# @return [Numeric]
|
25
|
+
attr_reader :after
|
26
|
+
|
27
|
+
# Every how many rows to run tests
|
28
|
+
# @return [Numeric]
|
29
|
+
attr_reader :every
|
30
|
+
|
31
|
+
alias :block_description :description
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def initialize(script, description, settings, &blk)
|
35
|
+
@script = script
|
36
|
+
@description = description
|
37
|
+
@blk = blk
|
38
|
+
@after = settings[:after]
|
39
|
+
@every = settings[:every]
|
40
|
+
raise "can't do both after and every" if after and every
|
41
|
+
end
|
42
|
+
|
43
|
+
# @private
|
44
|
+
def start
|
45
|
+
if inline?
|
46
|
+
eval_catching_errors
|
47
|
+
end
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def target?(step)
|
52
|
+
!inline? and (step.pos == pos - 1)
|
53
|
+
end
|
54
|
+
|
55
|
+
def notify(step, count)
|
56
|
+
if count % (after || every) == 0
|
57
|
+
eval_catching_errors
|
58
|
+
!after # if it's an after, return false, so that we stop getting informed
|
59
|
+
else
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def inline?
|
67
|
+
not (after or every)
|
68
|
+
end
|
69
|
+
|
70
|
+
def eval_catching_errors
|
71
|
+
DataMiner::Script.uniq { instance_eval(&blk) }
|
72
|
+
rescue ::RSpec::Expectations::ExpectationNotMetError
|
73
|
+
raise RuntimeError, "FAILED: #{description} (#{$!.inspect})"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/data_miner/version.rb
CHANGED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
4
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
5
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
6
|
+
# loaded once.
|
7
|
+
#
|
8
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
config.filter_run :focus
|
13
|
+
|
14
|
+
# Run specs in random order to surface order dependencies. If you find an
|
15
|
+
# order dependency and want to debug it, you can fix the order by providing
|
16
|
+
# the seed, which is printed after each run.
|
17
|
+
# --seed 1234
|
18
|
+
config.order = 'random'
|
19
|
+
end
|
20
|
+
|
21
|
+
require_relative '../test/support/database'
|
22
|
+
init_database
|
23
|
+
init_models
|
24
|
+
|
25
|
+
require 'data_miner'
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class PetTest1 < ActiveRecord::Base
|
4
|
+
self.primary_key = "name"
|
5
|
+
col :name
|
6
|
+
col :favorite_food
|
7
|
+
data_miner do
|
8
|
+
process :auto_upgrade!
|
9
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
10
|
+
key :name
|
11
|
+
store :favorite_food
|
12
|
+
end
|
13
|
+
test "Jerry likes cheese" do
|
14
|
+
expect(PetTest1.find('Jerry').favorite_food).to eq 'cheese'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class PetTest2 < ActiveRecord::Base
|
20
|
+
self.primary_key = "name"
|
21
|
+
col :name
|
22
|
+
col :favorite_food
|
23
|
+
data_miner do
|
24
|
+
process :auto_upgrade!
|
25
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
26
|
+
key :name
|
27
|
+
store :favorite_food
|
28
|
+
end
|
29
|
+
test "Jerry likes veggies" do
|
30
|
+
expect(PetTest2.find('Jerry').favorite_food).to eq 'veggies'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class PetTest3 < ActiveRecord::Base
|
36
|
+
self.primary_key = "name"
|
37
|
+
col :name
|
38
|
+
col :favorite_food
|
39
|
+
data_miner do
|
40
|
+
process :auto_upgrade!
|
41
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
42
|
+
key :name
|
43
|
+
store :favorite_food
|
44
|
+
end
|
45
|
+
test "First few have somebody named Pierre", after: 2 do
|
46
|
+
expect(PetTest3.count).to eq 2
|
47
|
+
expect(PetTest3.where(name: 'Pierre').count).to be > 0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class PetTest4 < ActiveRecord::Base
|
53
|
+
self.primary_key = "name"
|
54
|
+
col :name
|
55
|
+
col :favorite_food
|
56
|
+
data_miner do
|
57
|
+
process :auto_upgrade!
|
58
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
59
|
+
key :name
|
60
|
+
store :favorite_food
|
61
|
+
end
|
62
|
+
test "First few have somebody named Johnny", after: 2 do
|
63
|
+
expect(PetTest4.count).to eq 2 # that's where we are
|
64
|
+
expect(PetTest4.where(name: 'Johnny').count).to be > 0
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
$pet_test_5_i = 0
|
70
|
+
class PetTest5 < ActiveRecord::Base
|
71
|
+
self.primary_key = "name"
|
72
|
+
col :name
|
73
|
+
col :favorite_food
|
74
|
+
data_miner do
|
75
|
+
process :auto_upgrade!
|
76
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
77
|
+
key :name
|
78
|
+
store :favorite_food
|
79
|
+
end
|
80
|
+
test "Everybody has a name", every: 2 do
|
81
|
+
$pet_test_5_i += 1
|
82
|
+
expect(PetTest5.count).to eq $pet_test_5_i*2
|
83
|
+
expect(PetTest5.where(name: nil).count).to be 0
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
$pet_test_6_i = 0
|
89
|
+
class PetTest6 < ActiveRecord::Base
|
90
|
+
self.primary_key = "name"
|
91
|
+
col :name
|
92
|
+
col :favorite_food
|
93
|
+
data_miner do
|
94
|
+
process :auto_upgrade!
|
95
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
96
|
+
key :name
|
97
|
+
store :favorite_food
|
98
|
+
end
|
99
|
+
test "Everybody has a favorite food", every: 2 do
|
100
|
+
$pet_test_6_i += 1
|
101
|
+
expect(PetTest6.count).to eq $pet_test_6_i*2
|
102
|
+
expect(PetTest6.where(favorite_food: nil).count).to be 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe DataMiner::Step::Test do
|
108
|
+
it "keeps going if it passes" do
|
109
|
+
PetTest1.run_data_miner!
|
110
|
+
expect(PetTest1.count).to be > 0
|
111
|
+
end
|
112
|
+
it "stops on failure" do
|
113
|
+
expect { PetTest2.run_data_miner! }.to raise_error(/Jerry.*veggies/)
|
114
|
+
expect(PetTest2.count).to be > 0 # still populated tho
|
115
|
+
end
|
116
|
+
it "can be run in the middle of the previous step" do
|
117
|
+
PetTest3.run_data_miner!
|
118
|
+
expect(PetTest3.count).to be > 0
|
119
|
+
end
|
120
|
+
it "can be run in the middle of the previous step - failing" do
|
121
|
+
expect { PetTest4.run_data_miner! }.to raise_error(/First few.*Johnny/)
|
122
|
+
expect(PetTest4.count).to be 2 # stopped after 2
|
123
|
+
end
|
124
|
+
it "can be run every 2" do
|
125
|
+
PetTest5.run_data_miner!
|
126
|
+
expect($pet_test_5_i).to eq 2
|
127
|
+
expect(PetTest5.count).to be 5
|
128
|
+
end
|
129
|
+
it "can be run every 2 - failing" do
|
130
|
+
expect { PetTest6.run_data_miner! }.to raise_error(/Everybody has a favorite food/)
|
131
|
+
expect($pet_test_6_i).to eq 2
|
132
|
+
expect(PetTest6.count).to be $pet_test_6_i*2
|
133
|
+
end
|
134
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'bundler/setup'
|
3
2
|
|
4
3
|
if Bundler.definition.specs['debugger'].first
|
@@ -12,53 +11,6 @@ require 'minitest/autorun'
|
|
12
11
|
require 'minitest/reporters'
|
13
12
|
MiniTest::Reporters.use!
|
14
13
|
|
15
|
-
|
16
|
-
require 'logger'
|
17
|
-
ActiveRecord::Base.logger = Logger.new $stderr
|
18
|
-
ActiveRecord::Base.logger.level = (ENV['VERBOSE'] == 'true') ? Logger::DEBUG : Logger::INFO
|
19
|
-
|
20
|
-
ActiveRecord::Base.mass_assignment_sanitizer = :strict
|
21
|
-
|
22
|
-
require 'active_record_inline_schema'
|
14
|
+
require_relative 'support/database'
|
23
15
|
|
24
16
|
require 'data_miner'
|
25
|
-
|
26
|
-
def init_database
|
27
|
-
case ENV['DATABASE']
|
28
|
-
when /postgr/i
|
29
|
-
system %{dropdb test_data_miner}
|
30
|
-
system %{createdb test_data_miner}
|
31
|
-
ActiveRecord::Base.establish_connection(
|
32
|
-
'adapter' => 'postgresql',
|
33
|
-
'encoding' => 'utf8',
|
34
|
-
'database' => 'test_data_miner',
|
35
|
-
'username' => `whoami`.chomp
|
36
|
-
)
|
37
|
-
when /sqlite/i
|
38
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
39
|
-
else
|
40
|
-
system %{mysql -u root -ppassword -e "DROP DATABASE test_data_miner"}
|
41
|
-
system %{mysql -u root -ppassword -e "CREATE DATABASE test_data_miner CHARSET utf8"}
|
42
|
-
ActiveRecord::Base.establish_connection(
|
43
|
-
'adapter' => (RUBY_PLATFORM == 'java' ? 'mysql' : 'mysql2'),
|
44
|
-
'encoding' => 'utf8',
|
45
|
-
'database' => 'test_data_miner',
|
46
|
-
'username' => 'root',
|
47
|
-
'password' => 'password'
|
48
|
-
)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def init_models
|
53
|
-
require 'support/breed'
|
54
|
-
require 'support/pet'
|
55
|
-
require 'support/pet2'
|
56
|
-
require 'support/pet3'
|
57
|
-
Pet.auto_upgrade!
|
58
|
-
Pet2.auto_upgrade!
|
59
|
-
Pet3.auto_upgrade!
|
60
|
-
|
61
|
-
ActiveRecord::Base.descendants.each do |model|
|
62
|
-
model.attr_accessible nil
|
63
|
-
end
|
64
|
-
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'logger'
|
3
|
+
ActiveRecord::Base.logger = Logger.new $stderr
|
4
|
+
ActiveRecord::Base.logger.level = (ENV['VERBOSE'] == 'true') ? Logger::DEBUG : Logger::INFO
|
5
|
+
|
6
|
+
ActiveRecord::Base.mass_assignment_sanitizer = :strict
|
7
|
+
|
8
|
+
require 'active_record_inline_schema'
|
9
|
+
|
10
|
+
require 'data_miner'
|
11
|
+
|
12
|
+
def init_database
|
13
|
+
case ENV['DATABASE']
|
14
|
+
when /postgr/i
|
15
|
+
system %{dropdb test_data_miner}
|
16
|
+
system %{createdb test_data_miner}
|
17
|
+
ActiveRecord::Base.establish_connection(
|
18
|
+
'adapter' => 'postgresql',
|
19
|
+
'encoding' => 'utf8',
|
20
|
+
'database' => 'test_data_miner',
|
21
|
+
'username' => `whoami`.chomp
|
22
|
+
)
|
23
|
+
when /sqlite/i
|
24
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
25
|
+
else
|
26
|
+
system %{mysql -u root -ppassword -e "DROP DATABASE test_data_miner"}
|
27
|
+
system %{mysql -u root -ppassword -e "CREATE DATABASE test_data_miner CHARSET utf8"}
|
28
|
+
ActiveRecord::Base.establish_connection(
|
29
|
+
'adapter' => (RUBY_PLATFORM == 'java' ? 'mysql' : 'mysql2'),
|
30
|
+
'encoding' => 'utf8',
|
31
|
+
'database' => 'test_data_miner',
|
32
|
+
'username' => 'root',
|
33
|
+
'password' => 'password'
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_models
|
39
|
+
require_relative 'breed'
|
40
|
+
require_relative 'pet'
|
41
|
+
require_relative 'pet2'
|
42
|
+
require_relative 'pet3'
|
43
|
+
Pet.auto_upgrade!
|
44
|
+
Pet2.auto_upgrade!
|
45
|
+
Pet3.auto_upgrade!
|
46
|
+
|
47
|
+
ActiveRecord::Base.descendants.each do |model|
|
48
|
+
model.attr_accessible nil
|
49
|
+
end
|
50
|
+
end
|
data/test/support/pet.rb
CHANGED
@@ -15,9 +15,15 @@ class Pet < ActiveRecord::Base
|
|
15
15
|
col :command_phrase
|
16
16
|
col :emphatic_command_phrase
|
17
17
|
belongs_to :breed
|
18
|
+
|
19
|
+
|
20
|
+
|
18
21
|
data_miner do
|
22
|
+
|
19
23
|
process :auto_upgrade!
|
24
|
+
|
20
25
|
process :run_data_miner_on_parent_associations!
|
26
|
+
|
21
27
|
import("A list of pets", :url => "file://#{PETS}") do
|
22
28
|
key :name
|
23
29
|
store :age
|
@@ -31,5 +37,6 @@ class Pet < ActiveRecord::Base
|
|
31
37
|
(row['command_phrase'] + "!!!!!") if row['command_phrase']
|
32
38
|
end
|
33
39
|
end
|
40
|
+
|
34
41
|
end
|
35
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_miner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.
|
4
|
+
version: 3.0.0.beta
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-07-
|
16
|
+
date: 2013-07-26 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: activerecord
|
@@ -143,6 +143,38 @@ dependencies:
|
|
143
143
|
- - ! '>='
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: 1.10.3
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: rspec-expectations
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
type: :runtime
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
- !ruby/object:Gem::Dependency
|
163
|
+
name: rspec
|
164
|
+
requirement: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
166
|
+
requirements:
|
167
|
+
- - ! '>='
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
type: :development
|
171
|
+
prerelease: false
|
172
|
+
version_requirements: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
146
178
|
- !ruby/object:Gem::Dependency
|
147
179
|
name: pry
|
148
180
|
requirement: !ruby/object:Gem::Requirement
|
@@ -333,6 +365,7 @@ extensions: []
|
|
333
365
|
extra_rdoc_files: []
|
334
366
|
files:
|
335
367
|
- .gitignore
|
368
|
+
- .rspec
|
336
369
|
- .yardopts
|
337
370
|
- CHANGELOG
|
338
371
|
- Gemfile
|
@@ -348,7 +381,10 @@ files:
|
|
348
381
|
- lib/data_miner/step/import.rb
|
349
382
|
- lib/data_miner/step/process.rb
|
350
383
|
- lib/data_miner/step/sql.rb
|
384
|
+
- lib/data_miner/step/test.rb
|
351
385
|
- lib/data_miner/version.rb
|
386
|
+
- spec/spec_helper.rb
|
387
|
+
- spec/test_step_spec.rb
|
352
388
|
- test/data_miner/step/test_sql.rb
|
353
389
|
- test/data_miner/test_attribute.rb
|
354
390
|
- test/helper.rb
|
@@ -356,6 +392,7 @@ files:
|
|
356
392
|
- test/support/breed_by_license_number.csv
|
357
393
|
- test/support/breeds.xls
|
358
394
|
- test/support/data_miner_with_alchemist.rb
|
395
|
+
- test/support/database.rb
|
359
396
|
- test/support/pet.rb
|
360
397
|
- test/support/pet2.rb
|
361
398
|
- test/support/pet3.rb
|
@@ -390,6 +427,8 @@ specification_version: 3
|
|
390
427
|
summary: Download, pull out of a ZIP/TAR/GZ/BZ2 archive, parse, correct, and import
|
391
428
|
XLS, ODS, XML, CSV, HTML, etc. into your ActiveRecord models.
|
392
429
|
test_files:
|
430
|
+
- spec/spec_helper.rb
|
431
|
+
- spec/test_step_spec.rb
|
393
432
|
- test/data_miner/step/test_sql.rb
|
394
433
|
- test/data_miner/test_attribute.rb
|
395
434
|
- test/helper.rb
|
@@ -397,6 +436,7 @@ test_files:
|
|
397
436
|
- test/support/breed_by_license_number.csv
|
398
437
|
- test/support/breeds.xls
|
399
438
|
- test/support/data_miner_with_alchemist.rb
|
439
|
+
- test/support/database.rb
|
400
440
|
- test/support/pet.rb
|
401
441
|
- test/support/pet2.rb
|
402
442
|
- test/support/pet3.rb
|