activerecord-import 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  activerecord-import is a library for bulk inserting data using ActiveRecord.
4
4
 
5
- For more information on activerecord-import please see its wiki: http://wiki.github.com/zdennis/activerecord-import/
5
+ For more information on activerecord-import please see its wiki: https://github.com/zdennis/activerecord-import/wiki
6
6
 
7
7
  # License
8
8
 
data/Rakefile CHANGED
@@ -63,7 +63,7 @@ rescue LoadError
63
63
  end
64
64
  end
65
65
 
66
- require 'rake/rdoctask'
66
+ require 'rdoc/task'
67
67
  Rake::RDocTask.new do |rdoc|
68
68
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
69
69
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.9
1
+ 0.2.10
@@ -5,10 +5,12 @@ module ActiveRecord::Import::MysqlAdapter
5
5
  # Returns the maximum number of bytes that the server will allow
6
6
  # in a single packet
7
7
  def max_allowed_packet # :nodoc:
8
- result = execute( "SHOW VARIABLES like 'max_allowed_packet';" )
9
- # original Mysql gem responds to #fetch_row while Mysql2 responds to #first
10
- val = result.respond_to?(:fetch_row) ? result.fetch_row[1] : result.first[1]
11
- val.to_i
8
+ @max_allowed_packet ||= begin
9
+ result = execute( "SHOW VARIABLES like 'max_allowed_packet';" )
10
+ # original Mysql gem responds to #fetch_row while Mysql2 responds to #first
11
+ val = result.respond_to?(:fetch_row) ? result.fetch_row[1] : result.first[1]
12
+ val.to_i
13
+ end
12
14
  end
13
15
 
14
16
  # Returns a generated ON DUPLICATE KEY UPDATE statement given the passed
@@ -297,7 +297,7 @@ class ActiveRecord::Base
297
297
  array_of_attributes.map do |arr|
298
298
  my_values = arr.each_with_index.map do |val,j|
299
299
  column = columns[j]
300
- if !sequence_name.blank? && column.name == primary_key && val.nil?
300
+ if val.nil? && !sequence_name.blank? && column.name == primary_key
301
301
  connection.next_value_for_sequence(sequence_name)
302
302
  else
303
303
  connection.quote(column.type_cast(val), column)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-import
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.2.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-20 00:00:00.000000000Z
12
+ date: 2012-08-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &70098107427660 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70098107427660
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rake
27
- requirement: &70098107425120 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70098107425120
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: jeweler
38
- requirement: &70098107421120 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: 1.4.0
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70098107421120
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.4.0
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: activerecord
49
- requirement: &70098107418880 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,7 +69,12 @@ dependencies:
54
69
  version: '3.0'
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *70098107418880
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.0'
58
78
  description: Extraction of the ActiveRecord::Base#import functionality from ar-extensions
59
79
  for Rails 3 and beyond
60
80
  email: zach.dennis@gmail.com
@@ -84,30 +104,6 @@ files:
84
104
  - lib/activerecord-import/postgresql.rb
85
105
  - lib/activerecord-import/sqlite3.rb
86
106
  - lib/activerecord-import/synchronize.rb
87
- - test/active_record/connection_adapter_test.rb
88
- - test/adapters/jdbcmysql.rb
89
- - test/adapters/mysql.rb
90
- - test/adapters/mysql2.rb
91
- - test/adapters/postgresql.rb
92
- - test/adapters/sqlite3.rb
93
- - test/import_test.rb
94
- - test/jdbcmysql/import_test.rb
95
- - test/models/book.rb
96
- - test/models/group.rb
97
- - test/models/topic.rb
98
- - test/mysql/import_test.rb
99
- - test/mysql2/import_test.rb
100
- - test/postgresql/import_test.rb
101
- - test/schema/generic_schema.rb
102
- - test/schema/mysql_schema.rb
103
- - test/schema/version.rb
104
- - test/support/active_support/test_case_extensions.rb
105
- - test/support/factories.rb
106
- - test/support/generate.rb
107
- - test/support/mysql/assertions.rb
108
- - test/support/mysql/import_examples.rb
109
- - test/synchronize_test.rb
110
- - test/test_helper.rb
111
107
  homepage: http://github.com/zdennis/activerecord-import
112
108
  licenses: []
113
109
  post_install_message:
@@ -122,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
118
  version: '0'
123
119
  segments:
124
120
  - 0
125
- hash: -2341236183371821495
121
+ hash: -4211512731730455509
126
122
  required_rubygems_version: !ruby/object:Gem::Requirement
127
123
  none: false
128
124
  requirements:
@@ -131,32 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
127
  version: '0'
132
128
  requirements: []
133
129
  rubyforge_project:
134
- rubygems_version: 1.8.10
130
+ rubygems_version: 1.8.24
135
131
  signing_key:
136
132
  specification_version: 3
137
133
  summary: Bulk-loading extension for ActiveRecord
138
- test_files:
139
- - test/active_record/connection_adapter_test.rb
140
- - test/adapters/jdbcmysql.rb
141
- - test/adapters/mysql.rb
142
- - test/adapters/mysql2.rb
143
- - test/adapters/postgresql.rb
144
- - test/adapters/sqlite3.rb
145
- - test/import_test.rb
146
- - test/jdbcmysql/import_test.rb
147
- - test/models/book.rb
148
- - test/models/group.rb
149
- - test/models/topic.rb
150
- - test/mysql/import_test.rb
151
- - test/mysql2/import_test.rb
152
- - test/postgresql/import_test.rb
153
- - test/schema/generic_schema.rb
154
- - test/schema/mysql_schema.rb
155
- - test/schema/version.rb
156
- - test/support/active_support/test_case_extensions.rb
157
- - test/support/factories.rb
158
- - test/support/generate.rb
159
- - test/support/mysql/assertions.rb
160
- - test/support/mysql/import_examples.rb
161
- - test/synchronize_test.rb
162
- - test/test_helper.rb
134
+ test_files: []
@@ -1,52 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
-
3
- describe "ActiveRecord::ConnectionAdapter::AbstractAdapter" do
4
- context "#get_insert_value_sets - computing insert value sets" do
5
- let(:adapter){ ActiveRecord::ConnectionAdapters::AbstractAdapter }
6
- let(:base_sql){ "INSERT INTO atable (a,b,c)" }
7
- let(:values){ [ "(1,2,3)", "(2,3,4)", "(3,4,5)" ] }
8
-
9
- context "when the max allowed bytes is 33 and the base SQL is 26 bytes" do
10
- it "should return 3 value sets when given 3 value sets of 7 bytes a piece" do
11
- value_sets = adapter.get_insert_value_sets values, base_sql.size, max_allowed_bytes = 33
12
- assert_equal 3, value_sets.size
13
- end
14
- end
15
-
16
- context "when the max allowed bytes is 40 and the base SQL is 26 bytes" do
17
- it "should return 3 value sets when given 3 value sets of 7 bytes a piece" do
18
- value_sets = adapter.get_insert_value_sets values, base_sql.size, max_allowed_bytes = 40
19
- assert_equal 3, value_sets.size
20
- end
21
- end
22
-
23
- context "when the max allowed bytes is 41 and the base SQL is 26 bytes" do
24
- it "should return 2 value sets when given 2 value sets of 7 bytes a piece" do
25
- value_sets = adapter.get_insert_value_sets values, base_sql.size, max_allowed_bytes = 41
26
- assert_equal 2, value_sets.size
27
- end
28
- end
29
-
30
- context "when the max allowed bytes is 48 and the base SQL is 26 bytes" do
31
- it "should return 2 value sets when given 2 value sets of 7 bytes a piece" do
32
- value_sets = adapter.get_insert_value_sets values, base_sql.size, max_allowed_bytes = 48
33
- assert_equal 2, value_sets.size
34
- end
35
- end
36
-
37
- context "when the max allowed bytes is 49 and the base SQL is 26 bytes" do
38
- it "should return 1 value sets when given 1 value sets of 7 bytes a piece" do
39
- value_sets = adapter.get_insert_value_sets values, base_sql.size, max_allowed_bytes = 49
40
- assert_equal 1, value_sets.size
41
- end
42
- end
43
-
44
- context "when the max allowed bytes is 999999 and the base SQL is 26 bytes" do
45
- it "should return 1 value sets when given 1 value sets of 7 bytes a piece" do
46
- value_sets = adapter.get_insert_value_sets values, base_sql.size, max_allowed_bytes = 999999
47
- assert_equal 1, value_sets.size
48
- end
49
- end
50
- end
51
-
52
- end
@@ -1 +0,0 @@
1
- ENV["ARE_DB"] = "jdbcmysql"
@@ -1 +0,0 @@
1
- ENV["ARE_DB"] = "mysql"
@@ -1 +0,0 @@
1
- ENV["ARE_DB"] = "mysql2"
@@ -1 +0,0 @@
1
- ENV["ARE_DB"] = "postgresql"
@@ -1 +0,0 @@
1
- ENV["ARE_DB"] = "sqlite3"
data/test/import_test.rb DELETED
@@ -1,242 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- describe "#import" do
4
- it "should return the number of inserts performed" do
5
- # see ActiveRecord::ConnectionAdapters::AbstractAdapter test for more specifics
6
- assert_difference "Topic.count", +10 do
7
- result = Topic.import Build(3, :topics)
8
- assert result.num_inserts > 0
9
-
10
- result = Topic.import Build(7, :topics)
11
- assert result.num_inserts > 0
12
- end
13
- end
14
-
15
- it "should not produce an error when importing empty arrays" do
16
- assert_nothing_raised do
17
- Topic.import []
18
- Topic.import %w(title author_name), []
19
- end
20
- end
21
-
22
- context "with :validation option" do
23
- let(:columns) { %w(title author_name) }
24
- let(:valid_values) { [[ "LDAP", "Jerry Carter"], ["Rails Recipes", "Chad Fowler"]] }
25
- let(:invalid_values) { [[ "The RSpec Book", ""], ["Agile+UX", ""]] }
26
-
27
- context "with validation checks turned off" do
28
- it "should import valid data" do
29
- assert_difference "Topic.count", +2 do
30
- result = Topic.import columns, valid_values, :validate => false
31
- end
32
- end
33
-
34
- it "should import invalid data" do
35
- assert_difference "Topic.count", +2 do
36
- result = Topic.import columns, invalid_values, :validate => false
37
- end
38
- end
39
- end
40
-
41
- context "with validation checks turned on" do
42
- it "should import valid data" do
43
- assert_difference "Topic.count", +2 do
44
- result = Topic.import columns, valid_values, :validate => true
45
- end
46
- end
47
-
48
- it "should not import invalid data" do
49
- assert_no_difference "Topic.count" do
50
- result = Topic.import columns, invalid_values, :validate => true
51
- end
52
- end
53
-
54
- it "should report the failed instances" do
55
- results = Topic.import columns, invalid_values, :validate => true
56
- assert_equal invalid_values.size, results.failed_instances.size
57
- results.failed_instances.each{ |e| assert_kind_of Topic, e }
58
- end
59
-
60
- it "should import valid data when mixed with invalid data" do
61
- assert_difference "Topic.count", +2 do
62
- result = Topic.import columns, valid_values + invalid_values, :validate => true
63
- end
64
- assert_equal 0, Topic.find_all_by_title(invalid_values.map(&:first)).count
65
- end
66
- end
67
- end
68
-
69
- context "with :synchronize option" do
70
- context "synchronizing on new records" do
71
- let(:new_topics) { Build(3, :topics) }
72
-
73
- it "doesn't reload any data (doesn't work)" do
74
- Topic.import new_topics, :synchronize => new_topics
75
- assert new_topics.all?(&:new_record?), "No record should have been reloaded"
76
- end
77
- end
78
-
79
- context "synchronizing on new records with explicit conditions" do
80
- let(:new_topics) { Build(3, :topics) }
81
-
82
- it "reloads data for existing in-memory instances" do
83
- Topic.import(new_topics, :synchronize => new_topics, :synchronize_key => [:title] )
84
- assert new_topics.all?(&:new_record?), "Records should have been reloaded"
85
- end
86
- end
87
- end
88
-
89
- context "with an array of unsaved model instances" do
90
- let(:topic) { Build(:topic, :title => "The RSpec Book", :author_name => "David Chelimsky")}
91
- let(:topics) { Build(9, :topics) }
92
- let(:invalid_topics){ Build(7, :invalid_topics)}
93
-
94
- it "should import records based on those model's attributes" do
95
- assert_difference "Topic.count", +9 do
96
- result = Topic.import topics
97
- end
98
-
99
- Topic.import [topic]
100
- assert Topic.find_by_title_and_author_name("The RSpec Book", "David Chelimsky")
101
- end
102
-
103
- it "should not overwrite existing records" do
104
- topic = Generate(:topic, :title => "foobar")
105
- assert_no_difference "Topic.count" do
106
- begin
107
- Topic.transaction do
108
- topic.title = "baz"
109
- Topic.import [topic]
110
- end
111
- rescue Exception
112
- # PostgreSQL raises PgError due to key constraints
113
- # I don't know why ActiveRecord doesn't catch these. *sigh*
114
- end
115
- end
116
- assert_equal "foobar", topic.reload.title
117
- end
118
-
119
- context "with validation checks turned on" do
120
- it "should import valid models" do
121
- assert_difference "Topic.count", +9 do
122
- result = Topic.import topics, :validate => true
123
- end
124
- end
125
-
126
- it "should not import invalid models" do
127
- assert_no_difference "Topic.count" do
128
- result = Topic.import invalid_topics, :validate => true
129
- end
130
- end
131
- end
132
-
133
- context "with validation checks turned off" do
134
- it "should import invalid models" do
135
- assert_difference "Topic.count", +7 do
136
- result = Topic.import invalid_topics, :validate => false
137
- end
138
- end
139
- end
140
- end
141
-
142
- context "with an array of columns and an array of unsaved model instances" do
143
- let(:topics) { Build(2, :topics) }
144
-
145
- it "should import records populating the supplied columns with the corresponding model instance attributes" do
146
- assert_difference "Topic.count", +2 do
147
- result = Topic.import [:author_name, :title], topics
148
- end
149
-
150
- # imported topics should be findable by their imported attributes
151
- assert Topic.find_by_author_name(topics.first.author_name)
152
- assert Topic.find_by_author_name(topics.last.author_name)
153
- end
154
-
155
- it "should not populate fields for columns not imported" do
156
- topics.first.author_email_address = "zach.dennis@gmail.com"
157
- assert_difference "Topic.count", +2 do
158
- result = Topic.import [:author_name, :title], topics
159
- end
160
-
161
- assert !Topic.find_by_author_email_address("zach.dennis@gmail.com")
162
- end
163
- end
164
-
165
- context "with an array of columns and an array of values" do
166
- it "should import ids when specified" do
167
- Topic.import [:id, :author_name, :title], [[99, "Bob Jones", "Topic 99"]]
168
- assert_equal 99, Topic.last.id
169
- end
170
- end
171
-
172
- context "ActiveRecord timestamps" do
173
- context "when the timestamps columns are present" do
174
- setup do
175
- Delorean.time_travel_to("5 minutes ago") do
176
- assert_difference "Book.count", +1 do
177
- result = Book.import [:title, :author_name, :publisher], [["LDAP", "Big Bird", "Del Rey"]]
178
- end
179
- end
180
- @book = Book.last
181
- end
182
-
183
- it "should set the created_at column for new records" do
184
- assert_equal 5.minutes.ago.strftime("%H:%M"), @book.created_at.strftime("%H:%M")
185
- end
186
-
187
- it "should set the created_on column for new records" do
188
- assert_equal 5.minutes.ago.strftime("%H:%M"), @book.created_on.strftime("%H:%M")
189
- end
190
-
191
- it "should set the updated_at column for new records" do
192
- assert_equal 5.minutes.ago.strftime("%H:%M"), @book.updated_at.strftime("%H:%M")
193
- end
194
-
195
- it "should set the updated_on column for new records" do
196
- assert_equal 5.minutes.ago.strftime("%H:%M"), @book.updated_on.strftime("%H:%M")
197
- end
198
- end
199
-
200
- context "when a custom time zone is set" do
201
- setup do
202
- original_timezone = ActiveRecord::Base.default_timezone
203
- ActiveRecord::Base.default_timezone = :utc
204
- Delorean.time_travel_to("5 minutes ago") do
205
- assert_difference "Book.count", +1 do
206
- result = Book.import [:title, :author_name, :publisher], [["LDAP", "Big Bird", "Del Rey"]]
207
- end
208
- end
209
- ActiveRecord::Base.default_timezone = original_timezone
210
- @book = Book.last
211
- end
212
-
213
- it "should set the created_at and created_on timestamps for new records" do
214
- assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.created_at.strftime("%H:%M")
215
- assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.created_on.strftime("%H:%M")
216
- end
217
-
218
- it "should set the updated_at and updated_on timestamps for new records" do
219
- assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.updated_at.strftime("%H:%M")
220
- assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.updated_on.strftime("%H:%M")
221
- end
222
- end
223
- end
224
-
225
- context "importing with database reserved words" do
226
- let(:group) { Build(:group, :order => "superx") }
227
-
228
- it "should import just fine" do
229
- assert_difference "Group.count", +1 do
230
- result = Group.import [group]
231
- end
232
- assert_equal "superx", Group.first.order
233
- end
234
- end
235
-
236
- context "importing a datetime field" do
237
- it "should import a date with YYYY/MM/DD format just fine" do
238
- Topic.import [:author_name, :title, :last_read], [["Bob Jones", "Topic 2", "2010/05/14"]]
239
- assert_equal "2010/05/14".to_date, Topic.last.last_read.to_date
240
- end
241
- end
242
- end
@@ -1,6 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/assertions')
4
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/import_examples')
5
-
6
- should_support_mysql_import_functionality
data/test/models/book.rb DELETED
@@ -1,3 +0,0 @@
1
- class Book < ActiveRecord::Base
2
- belongs_to :topic
3
- end
data/test/models/group.rb DELETED
@@ -1,3 +0,0 @@
1
- class Group < ActiveRecord::Base
2
- self.table_name = 'group'
3
- end
data/test/models/topic.rb DELETED
@@ -1,7 +0,0 @@
1
- class Topic < ActiveRecord::Base
2
- validates_presence_of :author_name
3
- has_many :books
4
- belongs_to :parent, :class_name => "Topic"
5
-
6
- composed_of :description, :mapping => [ %w(title title), %w(author_name author_name)], :allow_nil => true, :class_name => "TopicDescription"
7
- end
@@ -1,6 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/assertions')
4
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/import_examples')
5
-
6
- should_support_mysql_import_functionality
@@ -1,6 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/assertions')
4
- require File.expand_path(File.dirname(__FILE__) + '/../support/mysql/import_examples')
5
-
6
- should_support_mysql_import_functionality
@@ -1,20 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
-
3
- describe "#supports_imports?" do
4
- it "should support import" do
5
- assert ActiveRecord::Base.supports_import?
6
- end
7
- end
8
-
9
- describe "#import" do
10
- it "should import with a single insert" do
11
- # see ActiveRecord::ConnectionAdapters::AbstractAdapter test for more specifics
12
- assert_difference "Topic.count", +10 do
13
- result = Topic.import Build(3, :topics)
14
- assert_equal 1, result.num_inserts
15
-
16
- result = Topic.import Build(7, :topics)
17
- assert_equal 1, result.num_inserts
18
- end
19
- end
20
- end
@@ -1,98 +0,0 @@
1
- ActiveRecord::Schema.define do
2
-
3
- create_table :schema_info, :force=>true do |t|
4
- t.column :version, :integer, :unique=>true
5
- end
6
- SchemaInfo.create :version=>SchemaInfo::VERSION
7
-
8
- create_table :group, :force => true do |t|
9
- t.column :order, :string
10
- t.timestamps
11
- end
12
-
13
- create_table :topics, :force=>true do |t|
14
- t.column :title, :string, :null => false
15
- t.column :author_name, :string
16
- t.column :author_email_address, :string
17
- t.column :written_on, :datetime
18
- t.column :bonus_time, :time
19
- t.column :last_read, :datetime
20
- t.column :content, :text
21
- t.column :approved, :boolean, :default=>'1'
22
- t.column :replies_count, :integer
23
- t.column :parent_id, :integer
24
- t.column :type, :string
25
- t.column :created_at, :datetime
26
- t.column :created_on, :datetime
27
- t.column :updated_at, :datetime
28
- t.column :updated_on, :datetime
29
- end
30
-
31
- create_table :projects, :force=>true do |t|
32
- t.column :name, :string
33
- t.column :type, :string
34
- end
35
-
36
- create_table :developers, :force=>true do |t|
37
- t.column :name, :string
38
- t.column :salary, :integer, :default=>'70000'
39
- t.column :created_at, :datetime
40
- t.column :team_id, :integer
41
- t.column :updated_at, :datetime
42
- end
43
-
44
- create_table :addresses, :force=>true do |t|
45
- t.column :address, :string
46
- t.column :city, :string
47
- t.column :state, :string
48
- t.column :zip, :string
49
- t.column :developer_id, :integer
50
- end
51
-
52
- create_table :teams, :force=>true do |t|
53
- t.column :name, :string
54
- end
55
-
56
- create_table :books, :force=>true do |t|
57
- t.column :title, :string, :null=>false
58
- t.column :publisher, :string, :null=>false, :default => 'Default Publisher'
59
- t.column :author_name, :string, :null=>false
60
- t.column :created_at, :datetime
61
- t.column :created_on, :datetime
62
- t.column :updated_at, :datetime
63
- t.column :updated_on, :datetime
64
- t.column :publish_date, :date
65
- t.column :topic_id, :integer
66
- t.column :for_sale, :boolean, :default => true
67
- end
68
-
69
- create_table :languages, :force=>true do |t|
70
- t.column :name, :string
71
- t.column :developer_id, :integer
72
- end
73
-
74
- create_table :shopping_carts, :force=>true do |t|
75
- t.column :name, :string, :null => true
76
- t.column :created_at, :datetime
77
- t.column :updated_at, :datetime
78
- end
79
-
80
- create_table :cart_items, :force => true do |t|
81
- t.column :shopping_cart_id, :string, :null => false
82
- t.column :book_id, :string, :null => false
83
- t.column :copies, :integer, :default => 1
84
- t.column :created_at, :datetime
85
- t.column :updated_at, :datetime
86
- end
87
-
88
- add_index :cart_items, [:shopping_cart_id, :book_id], :unique => true, :name => 'uk_shopping_cart_books'
89
-
90
- create_table :animals, :force => true do |t|
91
- t.column :name, :string, :null => false
92
- t.column :size, :string, :default => nil
93
- t.column :created_at, :datetime
94
- t.column :updated_at, :datetime
95
- end
96
-
97
- add_index :animals, [:name], :unique => true, :name => 'uk_animals'
98
- end
@@ -1,17 +0,0 @@
1
- ActiveRecord::Schema.define do
2
-
3
- create_table :books, :options=>'ENGINE=MyISAM', :force=>true do |t|
4
- t.column :title, :string, :null=>false
5
- t.column :publisher, :string, :null=>false, :default => 'Default Publisher'
6
- t.column :author_name, :string, :null=>false
7
- t.column :created_at, :datetime
8
- t.column :created_on, :datetime
9
- t.column :updated_at, :datetime
10
- t.column :updated_on, :datetime
11
- t.column :publish_date, :date
12
- t.column :topic_id, :integer
13
- t.column :for_sale, :boolean, :default => true
14
- end
15
- execute "ALTER TABLE books ADD FULLTEXT( `title`, `publisher`, `author_name` )"
16
-
17
- end
@@ -1,4 +0,0 @@
1
- class SchemaInfo < ActiveRecord::Base
2
- set_table_name 'schema_info'
3
- VERSION = 12
4
- end
@@ -1,67 +0,0 @@
1
- class ActiveSupport::TestCase
2
- include ActiveRecord::TestFixtures
3
- self.use_transactional_fixtures = true
4
-
5
- class << self
6
- def assertion(name, &block)
7
- mc = class << self ; self ; end
8
- mc.class_eval do
9
- define_method(name) do
10
- it(name, &block)
11
- end
12
- end
13
- end
14
-
15
- def asssertion_group(name, &block)
16
- mc = class << self ; self ; end
17
- mc.class_eval do
18
- define_method(name, &block)
19
- end
20
- end
21
-
22
- def macro(name, &block)
23
- class_eval do
24
- define_method(name, &block)
25
- end
26
- end
27
-
28
- def describe(description, toplevel=nil, &blk)
29
- text = toplevel ? description : "#{name} #{description}"
30
- klass = Class.new(self)
31
-
32
- klass.class_eval <<-RUBY_EVAL
33
- def self.name
34
- "#{text}"
35
- end
36
- RUBY_EVAL
37
-
38
- # do not inherit test methods from the superclass
39
- klass.class_eval do
40
- instance_methods.grep(/^test.+/) do |method|
41
- undef_method method
42
- end
43
- end
44
-
45
- klass.instance_eval &blk
46
- end
47
- alias_method :context, :describe
48
-
49
- def let(name, &blk)
50
- values = {}
51
- define_method(name) do
52
- return values[name] if values.has_key?(name)
53
- values[name] = instance_eval(&blk)
54
- end
55
- end
56
-
57
- def it(description, &blk)
58
- define_method("test: #{name} #{description}", &blk)
59
- end
60
- end
61
-
62
- end
63
-
64
- def describe(description, &blk)
65
- ActiveSupport::TestCase.describe(description, true, &blk)
66
- end
67
-
@@ -1,13 +0,0 @@
1
- Factory.define :group do |m|
2
- m.sequence(:order) { |n| "Order #{n}" }
3
- end
4
-
5
- Factory.define :invalid_topic, :class => "Topic" do |m|
6
- m.sequence(:title){ |n| "Title #{n}"}
7
- m.author_name nil
8
- end
9
-
10
- Factory.define :topic do |m|
11
- m.sequence(:title){ |n| "Title #{n}"}
12
- m.sequence(:author_name){ |n| "Author #{n}"}
13
- end
@@ -1,29 +0,0 @@
1
- class ActiveSupport::TestCase
2
- def Build(*args)
3
- n = args.shift if args.first.is_a?(Numeric)
4
- factory = args.shift
5
- factory_girl_args = args.shift || {}
6
-
7
- if n
8
- Array.new.tap do |collection|
9
- n.times.each { collection << Factory.build(factory.to_s.singularize.to_sym, factory_girl_args) }
10
- end
11
- else
12
- Factory.build(factory.to_s.singularize.to_sym, factory_girl_args)
13
- end
14
- end
15
-
16
- def Generate(*args)
17
- n = args.shift if args.first.is_a?(Numeric)
18
- factory = args.shift
19
- factory_girl_args = args.shift || {}
20
-
21
- if n
22
- Array.new.tap do |collection|
23
- n.times.each { collection << Factory.create(factory.to_s.singularize.to_sym, factory_girl_args) }
24
- end
25
- else
26
- Factory.create(factory.to_s.singularize.to_sym, factory_girl_args)
27
- end
28
- end
29
- end
@@ -1,55 +0,0 @@
1
- class ActiveSupport::TestCase
2
- module MySQLAssertions
3
- def self.extended(klass)
4
- klass.instance_eval do
5
- assertion(:should_not_update_created_at_on_timestamp_columns) do
6
- Delorean.time_travel_to("5 minutes from now") do
7
- perform_import
8
- assert_equal @topic.created_at.to_i, updated_topic.created_at.to_i
9
- assert_equal @topic.created_on.to_i, updated_topic.created_on.to_i
10
- end
11
- end
12
-
13
- assertion(:should_update_updated_at_on_timestamp_columns) do
14
- time = Chronic.parse("5 minutes from now")
15
- Delorean.time_travel_to(time) do
16
- perform_import
17
- assert_equal time.to_i, updated_topic.updated_at.to_i
18
- assert_equal time.to_i, updated_topic.updated_on.to_i
19
- end
20
- end
21
-
22
- assertion(:should_not_update_timestamps) do
23
- Delorean.time_travel_to("5 minutes from now") do
24
- perform_import :timestamps => false
25
- assert_equal @topic.created_at.to_i, updated_topic.created_at.to_i
26
- assert_equal @topic.created_on.to_i, updated_topic.created_on.to_i
27
- assert_equal @topic.updated_at.to_i, updated_topic.updated_at.to_i
28
- assert_equal @topic.updated_on.to_i, updated_topic.updated_on.to_i
29
- end
30
- end
31
-
32
- assertion(:should_not_update_fields_not_mentioned) do
33
- assert_equal "John Doe", updated_topic.author_name
34
- end
35
-
36
- assertion(:should_update_fields_mentioned) do
37
- perform_import
38
- assert_equal "Book - 2nd Edition", updated_topic.title
39
- assert_equal "johndoe@example.com", updated_topic.author_email_address
40
- end
41
-
42
- assertion(:should_update_fields_mentioned_with_hash_mappings) do
43
- perform_import
44
- assert_equal "johndoe@example.com", updated_topic.title
45
- assert_equal "Book - 2nd Edition", updated_topic.author_email_address
46
- end
47
-
48
- assertion(:should_update_foreign_keys) do
49
- perform_import
50
- assert_equal 57, updated_topic.parent_id
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,190 +0,0 @@
1
- # encoding: UTF-8
2
- def should_support_mysql_import_functionality
3
-
4
- describe "building insert value sets" do
5
- it "should properly build insert value set based on max packet allowed" do
6
- values = [
7
- "('1','2','3')",
8
- "('4','5','6')",
9
- "('7','8','9')" ]
10
-
11
- adapter = ActiveRecord::Base.connection.class
12
- values_size_in_bytes = values.sum {|value| value.bytesize }
13
- base_sql_size_in_bytes = 15
14
- max_bytes = 30
15
-
16
- value_sets = adapter.get_insert_value_sets( values, base_sql_size_in_bytes, max_bytes )
17
- assert_equal 3, value_sets.size, 'Three value sets were expected!'
18
-
19
- # Each element in the value_sets array must be an array
20
- value_sets.each_with_index { |e,i|
21
- assert_kind_of Array, e, "Element #{i} was expected to be an Array!" }
22
-
23
- # Each element in the values array should have a 1:1 correlation to the elements
24
- # in the returned value_sets arrays
25
- assert_equal values[0], value_sets[0].first
26
- assert_equal values[1], value_sets[1].first
27
- assert_equal values[2], value_sets[2].first
28
- end
29
-
30
- context "data contains multi-byte chars" do
31
- it "should properly build insert value set based on max packet allowed" do
32
- # each accented e should be 2 bytes, so each entry is 6 bytes instead of 5
33
- values = [
34
- "('é')",
35
- "('é')" ]
36
-
37
- adapter = ActiveRecord::Base.connection.class
38
- base_sql_size_in_bytes = 15
39
- max_bytes = 26
40
-
41
- values_size_in_bytes = values.sum {|value| value.bytesize }
42
- value_sets = adapter.get_insert_value_sets( values, base_sql_size_in_bytes, max_bytes )
43
-
44
- assert_equal 2, value_sets.size, 'Two value sets were expected!'
45
- end
46
- end
47
- end
48
-
49
- describe "#import with :on_duplicate_key_update option (mysql specific functionality)" do
50
- extend ActiveSupport::TestCase::MySQLAssertions
51
-
52
- asssertion_group(:should_support_on_duplicate_key_update) do
53
- should_not_update_fields_not_mentioned
54
- should_update_foreign_keys
55
- should_not_update_created_at_on_timestamp_columns
56
- should_update_updated_at_on_timestamp_columns
57
- end
58
-
59
- macro(:perform_import){ raise "supply your own #perform_import in a context below" }
60
- macro(:updated_topic){ Topic.find(@topic) }
61
-
62
- context "given columns and values with :validation checks turned off" do
63
- let(:columns){ %w( id title author_name author_email_address parent_id ) }
64
- let(:values){ [ [ 99, "Book", "John Doe", "john@doe.com", 17 ] ] }
65
- let(:updated_values){ [ [ 99, "Book - 2nd Edition", "Author Should Not Change", "johndoe@example.com", 57 ] ] }
66
-
67
- macro(:perform_import) do |*opts|
68
- Topic.import columns, updated_values, opts.extract_options!.merge(:on_duplicate_key_update => update_columns, :validate => false)
69
- end
70
-
71
- setup do
72
- Topic.import columns, values, :validate => false
73
- @topic = Topic.find 99
74
- end
75
-
76
- context "using string column names" do
77
- let(:update_columns){ [ "title", "author_email_address", "parent_id" ] }
78
- should_support_on_duplicate_key_update
79
- should_update_fields_mentioned
80
- end
81
-
82
- context "using symbol column names" do
83
- let(:update_columns){ [ :title, :author_email_address, :parent_id ] }
84
- should_support_on_duplicate_key_update
85
- should_update_fields_mentioned
86
- end
87
-
88
- context "using string hash map" do
89
- let(:update_columns){ { "title" => "title", "author_email_address" => "author_email_address", "parent_id" => "parent_id" } }
90
- should_support_on_duplicate_key_update
91
- should_update_fields_mentioned
92
- end
93
-
94
- context "using string hash map, but specifying column mismatches" do
95
- let(:update_columns){ { "title" => "author_email_address", "author_email_address" => "title", "parent_id" => "parent_id" } }
96
- should_support_on_duplicate_key_update
97
- should_update_fields_mentioned_with_hash_mappings
98
- end
99
-
100
- context "using symbol hash map" do
101
- let(:update_columns){ { :title => :title, :author_email_address => :author_email_address, :parent_id => :parent_id } }
102
- should_support_on_duplicate_key_update
103
- should_update_fields_mentioned
104
- end
105
-
106
- context "using symbol hash map, but specifying column mismatches" do
107
- let(:update_columns){ { :title => :author_email_address, :author_email_address => :title, :parent_id => :parent_id } }
108
- should_support_on_duplicate_key_update
109
- should_update_fields_mentioned_with_hash_mappings
110
- end
111
- end
112
-
113
- context "given array of model instances with :validation checks turned off" do
114
- macro(:perform_import) do |*opts|
115
- @topic.title = "Book - 2nd Edition"
116
- @topic.author_name = "Author Should Not Change"
117
- @topic.author_email_address = "johndoe@example.com"
118
- @topic.parent_id = 57
119
- Topic.import [@topic], opts.extract_options!.merge(:on_duplicate_key_update => update_columns, :validate => false)
120
- end
121
-
122
- setup do
123
- @topic = Generate(:topic, :id => 99, :author_name => "John Doe", :parent_id => 17)
124
- end
125
-
126
- context "using string column names" do
127
- let(:update_columns){ [ "title", "author_email_address", "parent_id" ] }
128
- should_support_on_duplicate_key_update
129
- should_update_fields_mentioned
130
- end
131
-
132
- context "using symbol column names" do
133
- let(:update_columns){ [ :title, :author_email_address, :parent_id ] }
134
- should_support_on_duplicate_key_update
135
- should_update_fields_mentioned
136
- end
137
-
138
- context "using string hash map" do
139
- let(:update_columns){ { "title" => "title", "author_email_address" => "author_email_address", "parent_id" => "parent_id" } }
140
- should_support_on_duplicate_key_update
141
- should_update_fields_mentioned
142
- end
143
-
144
- context "using string hash map, but specifying column mismatches" do
145
- let(:update_columns){ { "title" => "author_email_address", "author_email_address" => "title", "parent_id" => "parent_id" } }
146
- should_support_on_duplicate_key_update
147
- should_update_fields_mentioned_with_hash_mappings
148
- end
149
-
150
- context "using symbol hash map" do
151
- let(:update_columns){ { :title => :title, :author_email_address => :author_email_address, :parent_id => :parent_id } }
152
- should_support_on_duplicate_key_update
153
- should_update_fields_mentioned
154
- end
155
-
156
- context "using symbol hash map, but specifying column mismatches" do
157
- let(:update_columns){ { :title => :author_email_address, :author_email_address => :title, :parent_id => :parent_id } }
158
- should_support_on_duplicate_key_update
159
- should_update_fields_mentioned_with_hash_mappings
160
- end
161
- end
162
-
163
- end
164
-
165
- describe "#import with :synchronization option" do
166
- let(:topics){ Array.new }
167
- let(:values){ [ [topics.first.id, "Jerry Carter"], [topics.last.id, "Chad Fowler"] ]}
168
- let(:columns){ %W(id author_name) }
169
-
170
- setup do
171
- topics << Topic.create!(:title=>"LDAP", :author_name=>"Big Bird")
172
- topics << Topic.create!(:title=>"Rails Recipes", :author_name=>"Elmo")
173
- end
174
-
175
- it "synchronizes passed in ActiveRecord model instances with the data just imported" do
176
- columns2update = [ 'author_name' ]
177
-
178
- expected_count = Topic.count
179
- Topic.import( columns, values,
180
- :validate=>false,
181
- :on_duplicate_key_update=>columns2update,
182
- :synchronize=>topics )
183
-
184
- assert_equal expected_count, Topic.count, "no new records should have been created!"
185
- assert_equal "Jerry Carter", topics.first.author_name, "wrong author!"
186
- assert_equal "Chad Fowler", topics.last.author_name, "wrong author!"
187
- end
188
- end
189
-
190
- end
@@ -1,22 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- describe ".synchronize" do
4
- let(:topics){ Generate(3, :topics) }
5
- let(:titles){ %w(one two three) }
6
-
7
- setup do
8
- # update records outside of ActiveRecord knowing about it
9
- Topic.connection.execute( "UPDATE #{Topic.table_name} SET title='#{titles[0]}_haha' WHERE id=#{topics[0].id}", "Updating record 1 without ActiveRecord" )
10
- Topic.connection.execute( "UPDATE #{Topic.table_name} SET title='#{titles[1]}_haha' WHERE id=#{topics[1].id}", "Updating record 2 without ActiveRecord" )
11
- Topic.connection.execute( "UPDATE #{Topic.table_name} SET title='#{titles[2]}_haha' WHERE id=#{topics[2].id}", "Updating record 3 without ActiveRecord" )
12
- end
13
-
14
- it "reloads data for the specified records" do
15
- Book.synchronize topics
16
-
17
- actual_titles = topics.map(&:title)
18
- assert_equal "#{titles[0]}_haha", actual_titles[0], "the first record was not correctly updated"
19
- assert_equal "#{titles[1]}_haha", actual_titles[1], "the second record was not correctly updated"
20
- assert_equal "#{titles[2]}_haha", actual_titles[2], "the third record was not correctly updated"
21
- end
22
- end
data/test/test_helper.rb DELETED
@@ -1,46 +0,0 @@
1
- require 'pathname'
2
- test_dir = Pathname.new File.dirname(__FILE__)
3
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
- $LOAD_PATH.unshift(File.dirname(__FILE__))
5
-
6
- require "fileutils"
7
- require "rubygems"
8
-
9
- ENV["RAILS_ENV"] = "test"
10
-
11
- require "bundler"
12
- Bundler.setup
13
-
14
- require "logger"
15
- require 'test/unit'
16
- require "active_record"
17
- require "active_record/fixtures"
18
- require "active_support/test_case"
19
-
20
- require "delorean"
21
- require "ruby-debug"
22
-
23
- adapter = ENV["ARE_DB"] || "sqlite3"
24
-
25
- FileUtils.mkdir_p 'log'
26
- ActiveRecord::Base.logger = Logger.new("log/test.log")
27
- ActiveRecord::Base.logger.level = Logger::DEBUG
28
- ActiveRecord::Base.configurations["test"] = YAML.load(test_dir.join("database.yml").open)[adapter]
29
-
30
- require "activerecord-import"
31
- ActiveRecord::Base.establish_connection "test"
32
-
33
- ActiveSupport::Notifications.subscribe(/active_record.sql/) do |event, _, _, _, hsh|
34
- ActiveRecord::Base.logger.info hsh[:sql]
35
- end
36
-
37
- require "factory_girl"
38
- Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each{ |file| require file }
39
-
40
- # Load base/generic schema
41
- require test_dir.join("schema/version")
42
- require test_dir.join("schema/generic_schema")
43
- adapter_schema = test_dir.join("schema/#{adapter}_schema.rb")
44
- require adapter_schema if File.exists?(adapter_schema)
45
-
46
- Dir[File.dirname(__FILE__) + "/models/*.rb"].each{ |file| require file }