activerecord-import 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +49 -0
- data/.rubocop_todo.yml +36 -0
- data/.travis.yml +31 -7
- data/CHANGELOG.md +19 -0
- data/Gemfile +5 -2
- data/README.markdown +6 -1
- data/Rakefile +5 -2
- data/activerecord-import.gemspec +1 -1
- data/benchmarks/benchmark.rb +67 -68
- data/benchmarks/lib/base.rb +136 -137
- data/benchmarks/lib/cli_parser.rb +106 -107
- data/benchmarks/lib/mysql2_benchmark.rb +19 -21
- data/benchmarks/lib/output_to_csv.rb +2 -1
- data/benchmarks/lib/output_to_html.rb +8 -13
- data/benchmarks/schema/mysql_schema.rb +8 -8
- data/gemfiles/4.0.gemfile +1 -1
- data/gemfiles/4.1.gemfile +1 -1
- data/gemfiles/4.2.gemfile +1 -1
- data/gemfiles/5.0.gemfile +1 -1
- data/lib/activerecord-import.rb +2 -0
- data/lib/activerecord-import/active_record/adapters/sqlite3_adapter.rb +0 -1
- data/lib/activerecord-import/adapters/abstract_adapter.rb +9 -9
- data/lib/activerecord-import/adapters/mysql_adapter.rb +17 -17
- data/lib/activerecord-import/adapters/postgresql_adapter.rb +20 -22
- data/lib/activerecord-import/adapters/sqlite3_adapter.rb +9 -9
- data/lib/activerecord-import/base.rb +3 -3
- data/lib/activerecord-import/import.rb +152 -131
- data/lib/activerecord-import/synchronize.rb +20 -20
- data/lib/activerecord-import/value_sets_parser.rb +7 -6
- data/lib/activerecord-import/version.rb +1 -1
- data/test/adapters/mysql2spatial.rb +1 -1
- data/test/adapters/postgis.rb +1 -1
- data/test/adapters/postgresql.rb +1 -1
- data/test/adapters/spatialite.rb +1 -1
- data/test/adapters/sqlite3.rb +1 -1
- data/test/import_test.rb +121 -70
- data/test/models/book.rb +5 -6
- data/test/models/chapter.rb +2 -2
- data/test/models/discount.rb +3 -0
- data/test/models/end_note.rb +2 -2
- data/test/models/promotion.rb +1 -1
- data/test/models/question.rb +1 -1
- data/test/models/rule.rb +2 -2
- data/test/models/topic.rb +3 -3
- data/test/models/widget.rb +1 -1
- data/test/postgis/import_test.rb +1 -1
- data/test/schema/generic_schema.rb +100 -96
- data/test/schema/mysql_schema.rb +5 -7
- data/test/sqlite3/import_test.rb +0 -2
- data/test/support/active_support/test_case_extensions.rb +12 -15
- data/test/support/assertions.rb +1 -1
- data/test/support/factories.rb +15 -16
- data/test/support/generate.rb +4 -4
- data/test/support/mysql/import_examples.rb +21 -21
- data/test/support/postgresql/import_examples.rb +83 -55
- data/test/support/shared_examples/on_duplicate_key_update.rb +23 -23
- data/test/synchronize_test.rb +2 -2
- data/test/test_helper.rb +6 -8
- data/test/value_sets_bytes_parser_test.rb +14 -17
- data/test/value_sets_records_parser_test.rb +6 -6
- metadata +7 -4
- data/test/travis/build.sh +0 -34
data/test/models/book.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
class Book < ActiveRecord::Base
|
2
|
-
belongs_to :topic, :
|
3
|
-
has_many :chapters, :
|
4
|
-
has_many :
|
5
|
-
|
6
|
-
|
7
|
-
end
|
2
|
+
belongs_to :topic, inverse_of: :books
|
3
|
+
has_many :chapters, inverse_of: :book
|
4
|
+
has_many :discounts, as: :discountable
|
5
|
+
has_many :end_notes, inverse_of: :book
|
6
|
+
enum status: [:draft, :published] if ENV['AR_VERSION'].to_f >= 4.1
|
8
7
|
end
|
data/test/models/chapter.rb
CHANGED
data/test/models/end_note.rb
CHANGED
data/test/models/promotion.rb
CHANGED
data/test/models/question.rb
CHANGED
data/test/models/rule.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
class Rule < ActiveRecord::Base
|
2
|
-
|
3
|
-
end
|
2
|
+
belongs_to :question
|
3
|
+
end
|
data/test/models/topic.rb
CHANGED
@@ -2,8 +2,8 @@ class Topic < ActiveRecord::Base
|
|
2
2
|
validates_presence_of :author_name
|
3
3
|
validates :title, numericality: { only_integer: true }, on: :context_test
|
4
4
|
|
5
|
-
has_many :books, :
|
6
|
-
belongs_to :parent, :
|
5
|
+
has_many :books, inverse_of: :topic
|
6
|
+
belongs_to :parent, class_name: "Topic"
|
7
7
|
|
8
|
-
composed_of :description, :
|
8
|
+
composed_of :description, mapping: [%w(title title), %w(author_name author_name)], allow_nil: true, class_name: "TopicDescription"
|
9
9
|
end
|
data/test/models/widget.rb
CHANGED
data/test/postgis/import_test.rb
CHANGED
@@ -1,138 +1,142 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
|
-
|
3
|
-
|
4
|
-
t.column :version, :integer, :unique=>true
|
2
|
+
create_table :schema_info, force: :cascade do |t|
|
3
|
+
t.integer :version, unique: true
|
5
4
|
end
|
6
|
-
SchemaInfo.create :
|
5
|
+
SchemaInfo.create version: SchemaInfo::VERSION
|
7
6
|
|
8
|
-
create_table :group, :
|
9
|
-
t.
|
7
|
+
create_table :group, force: :cascade do |t|
|
8
|
+
t.string :order
|
10
9
|
t.timestamps null: true
|
11
10
|
end
|
12
11
|
|
13
|
-
create_table :topics, :
|
14
|
-
t.
|
15
|
-
t.
|
16
|
-
t.
|
17
|
-
t.
|
18
|
-
t.
|
19
|
-
t.
|
20
|
-
t.
|
21
|
-
t.
|
22
|
-
t.
|
23
|
-
t.
|
24
|
-
t.
|
25
|
-
t.
|
26
|
-
t.
|
27
|
-
t.
|
28
|
-
t.
|
12
|
+
create_table :topics, force: :cascade do |t|
|
13
|
+
t.string :title, null: false
|
14
|
+
t.string :author_name
|
15
|
+
t.string :author_email_address
|
16
|
+
t.datetime :written_on
|
17
|
+
t.time :bonus_time
|
18
|
+
t.datetime :last_read
|
19
|
+
t.text :content
|
20
|
+
t.boolean :approved, default: '1'
|
21
|
+
t.integer :replies_count
|
22
|
+
t.integer :parent_id
|
23
|
+
t.string :type
|
24
|
+
t.datetime :created_at
|
25
|
+
t.datetime :created_on
|
26
|
+
t.datetime :updated_at
|
27
|
+
t.datetime :updated_on
|
29
28
|
end
|
30
29
|
|
31
|
-
create_table :projects, :
|
32
|
-
t.
|
33
|
-
t.
|
30
|
+
create_table :projects, force: :cascade do |t|
|
31
|
+
t.string :name
|
32
|
+
t.string :type
|
34
33
|
end
|
35
34
|
|
36
|
-
create_table :developers, :
|
37
|
-
t.
|
38
|
-
t.
|
39
|
-
t.
|
40
|
-
t.
|
41
|
-
t.
|
35
|
+
create_table :developers, force: :cascade do |t|
|
36
|
+
t.string :name
|
37
|
+
t.integer :salary, default: '70000'
|
38
|
+
t.datetime :created_at
|
39
|
+
t.integer :team_id
|
40
|
+
t.datetime :updated_at
|
42
41
|
end
|
43
42
|
|
44
|
-
create_table :addresses, :
|
45
|
-
t.
|
46
|
-
t.
|
47
|
-
t.
|
48
|
-
t.
|
49
|
-
t.
|
43
|
+
create_table :addresses, force: :cascade do |t|
|
44
|
+
t.string :address
|
45
|
+
t.string :city
|
46
|
+
t.string :state
|
47
|
+
t.string :zip
|
48
|
+
t.integer :developer_id
|
50
49
|
end
|
51
50
|
|
52
|
-
create_table :teams, :
|
53
|
-
t.
|
51
|
+
create_table :teams, force: :cascade do |t|
|
52
|
+
t.string :name
|
54
53
|
end
|
55
54
|
|
56
|
-
create_table :books, :
|
57
|
-
t.
|
58
|
-
t.
|
59
|
-
t.
|
60
|
-
t.
|
61
|
-
t.
|
62
|
-
t.
|
63
|
-
t.
|
64
|
-
t.
|
65
|
-
t.
|
66
|
-
t.
|
67
|
-
t.
|
55
|
+
create_table :books, force: :cascade do |t|
|
56
|
+
t.string :title, null: false
|
57
|
+
t.string :publisher, null: false, default: 'Default Publisher'
|
58
|
+
t.string :author_name, null: false
|
59
|
+
t.datetime :created_at
|
60
|
+
t.datetime :created_on
|
61
|
+
t.datetime :updated_at
|
62
|
+
t.datetime :updated_on
|
63
|
+
t.date :publish_date
|
64
|
+
t.integer :topic_id
|
65
|
+
t.boolean :for_sale, default: true
|
66
|
+
t.integer :status, default: 0
|
68
67
|
end
|
69
68
|
|
70
|
-
create_table :chapters, :
|
71
|
-
t.
|
72
|
-
t.
|
73
|
-
t.
|
74
|
-
t.
|
69
|
+
create_table :chapters, force: :cascade do |t|
|
70
|
+
t.string :title
|
71
|
+
t.integer :book_id, null: false
|
72
|
+
t.datetime :created_at
|
73
|
+
t.datetime :updated_at
|
75
74
|
end
|
76
75
|
|
77
|
-
create_table :end_notes, :
|
78
|
-
t.
|
79
|
-
t.
|
80
|
-
t.
|
81
|
-
t.
|
76
|
+
create_table :end_notes, force: :cascade do |t|
|
77
|
+
t.string :note
|
78
|
+
t.integer :book_id, null: false
|
79
|
+
t.datetime :created_at
|
80
|
+
t.datetime :updated_at
|
82
81
|
end
|
83
82
|
|
84
|
-
|
85
|
-
|
86
|
-
t.
|
87
|
-
t.column :developer_id, :integer
|
83
|
+
create_table :languages, force: :cascade do |t|
|
84
|
+
t.string :name
|
85
|
+
t.integer :developer_id
|
88
86
|
end
|
89
87
|
|
90
|
-
create_table :shopping_carts, :
|
91
|
-
t.
|
92
|
-
t.
|
93
|
-
t.
|
88
|
+
create_table :shopping_carts, force: :cascade do |t|
|
89
|
+
t.string :name, null: true
|
90
|
+
t.datetime :created_at
|
91
|
+
t.datetime :updated_at
|
94
92
|
end
|
95
93
|
|
96
|
-
create_table :cart_items, :
|
97
|
-
t.
|
98
|
-
t.
|
99
|
-
t.
|
100
|
-
t.
|
101
|
-
t.
|
94
|
+
create_table :cart_items, force: :cascade do |t|
|
95
|
+
t.string :shopping_cart_id, null: false
|
96
|
+
t.string :book_id, null: false
|
97
|
+
t.integer :copies, default: 1
|
98
|
+
t.datetime :created_at
|
99
|
+
t.datetime :updated_at
|
102
100
|
end
|
103
101
|
|
104
|
-
add_index :cart_items, [:shopping_cart_id, :book_id], :
|
102
|
+
add_index :cart_items, [:shopping_cart_id, :book_id], unique: true, name: 'uk_shopping_cart_books'
|
105
103
|
|
106
|
-
create_table :animals, :
|
107
|
-
t.
|
108
|
-
t.
|
109
|
-
t.
|
110
|
-
t.
|
104
|
+
create_table :animals, force: :cascade do |t|
|
105
|
+
t.string :name, null: false
|
106
|
+
t.string :size, default: nil
|
107
|
+
t.datetime :created_at
|
108
|
+
t.datetime :updated_at
|
111
109
|
end
|
112
110
|
|
113
|
-
add_index :animals, [:name], :
|
111
|
+
add_index :animals, [:name], unique: true, name: 'uk_animals'
|
114
112
|
|
115
|
-
create_table :widgets, :
|
113
|
+
create_table :widgets, id: false, force: :cascade do |t|
|
116
114
|
t.integer :w_id
|
117
|
-
t.boolean :active, :
|
118
|
-
t.text
|
119
|
-
t.text
|
115
|
+
t.boolean :active, default: false
|
116
|
+
t.text :data
|
117
|
+
t.text :json_data
|
120
118
|
end
|
121
119
|
|
122
|
-
create_table
|
123
|
-
t.string
|
124
|
-
t.string
|
125
|
-
t.decimal
|
120
|
+
create_table :promotions, primary_key: :promotion_id, force: :cascade do |t|
|
121
|
+
t.string :code
|
122
|
+
t.string :description
|
123
|
+
t.decimal :discount
|
126
124
|
end
|
127
125
|
|
128
|
-
add_index :promotions, [:code], :
|
126
|
+
add_index :promotions, [:code], unique: true, name: 'uk_code'
|
127
|
+
|
128
|
+
create_table :discounts, force: :cascade do |t|
|
129
|
+
t.decimal :amount
|
130
|
+
t.integer :discountable_id
|
131
|
+
t.string :discountable_type
|
132
|
+
end
|
129
133
|
|
130
|
-
create_table :rules, force:
|
131
|
-
t.
|
132
|
-
t.
|
134
|
+
create_table :rules, force: :cascade do |t|
|
135
|
+
t.string :condition_text
|
136
|
+
t.integer :question_id
|
133
137
|
end
|
134
138
|
|
135
|
-
create_table :questions, force:
|
136
|
-
t.
|
139
|
+
create_table :questions, force: :cascade do |t|
|
140
|
+
t.string :body
|
137
141
|
end
|
138
142
|
end
|
data/test/schema/mysql_schema.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
|
-
|
3
|
-
|
4
|
-
t.column :
|
5
|
-
t.column :
|
6
|
-
t.column :author_name, :string, :null=>false
|
2
|
+
create_table :books, options: 'ENGINE=MyISAM', force: true do |t|
|
3
|
+
t.column :title, :string, null: false
|
4
|
+
t.column :publisher, :string, null: false, default: 'Default Publisher'
|
5
|
+
t.column :author_name, :string, null: false
|
7
6
|
t.column :created_at, :datetime
|
8
7
|
t.column :created_on, :datetime
|
9
8
|
t.column :updated_at, :datetime
|
10
9
|
t.column :updated_on, :datetime
|
11
10
|
t.column :publish_date, :date
|
12
11
|
t.column :topic_id, :integer
|
13
|
-
t.column :for_sale, :boolean, :
|
12
|
+
t.column :for_sale, :boolean, default: true
|
14
13
|
t.column :status, :integer
|
15
14
|
end
|
16
15
|
execute "ALTER TABLE books ADD FULLTEXT( `title`, `publisher`, `author_name` )"
|
17
|
-
|
18
16
|
end
|
data/test/sqlite3/import_test.rb
CHANGED
@@ -1,25 +1,24 @@
|
|
1
1
|
class ActiveSupport::TestCase
|
2
2
|
include ActiveRecord::TestFixtures
|
3
3
|
self.use_transactional_fixtures = true
|
4
|
-
|
4
|
+
|
5
5
|
class << self
|
6
6
|
def requires_active_record_version(version_string, &blk)
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
return unless Gem::Dependency.new('', version_string).match?('', ActiveRecord::VERSION::STRING)
|
8
|
+
instance_eval(&blk)
|
10
9
|
end
|
11
10
|
|
12
11
|
def assertion(name, &block)
|
13
|
-
mc = class << self
|
12
|
+
mc = class << self; self; end
|
14
13
|
mc.class_eval do
|
15
14
|
define_method(name) do
|
16
15
|
it(name, &block)
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
20
|
-
|
19
|
+
|
21
20
|
def asssertion_group(name, &block)
|
22
|
-
mc = class << self
|
21
|
+
mc = class << self; self; end
|
23
22
|
mc.class_eval do
|
24
23
|
define_method(name, &block)
|
25
24
|
end
|
@@ -30,8 +29,8 @@ class ActiveSupport::TestCase
|
|
30
29
|
define_method(name, &block)
|
31
30
|
end
|
32
31
|
end
|
33
|
-
|
34
|
-
def describe(description, toplevel=nil, &blk)
|
32
|
+
|
33
|
+
def describe(description, toplevel = nil, &blk)
|
35
34
|
text = toplevel ? description : "#{name} #{description}"
|
36
35
|
klass = Class.new(self)
|
37
36
|
|
@@ -48,10 +47,10 @@ class ActiveSupport::TestCase
|
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
51
|
-
klass.instance_eval
|
50
|
+
klass.instance_eval(&blk)
|
52
51
|
end
|
53
|
-
|
54
|
-
|
52
|
+
alias context describe
|
53
|
+
|
55
54
|
def let(name, &blk)
|
56
55
|
define_method(name) do
|
57
56
|
instance_variable_name = "@__let_#{name}"
|
@@ -59,15 +58,13 @@ class ActiveSupport::TestCase
|
|
59
58
|
instance_variable_set(instance_variable_name, instance_eval(&blk))
|
60
59
|
end
|
61
60
|
end
|
62
|
-
|
61
|
+
|
63
62
|
def it(description, &blk)
|
64
63
|
define_method("test_#{name}_#{description}", &blk)
|
65
64
|
end
|
66
65
|
end
|
67
|
-
|
68
66
|
end
|
69
67
|
|
70
68
|
def describe(description, &blk)
|
71
69
|
ActiveSupport::TestCase.describe(description, true, &blk)
|
72
70
|
end
|
73
|
-
|
data/test/support/assertions.rb
CHANGED
@@ -30,7 +30,7 @@ class ActiveSupport::TestCase
|
|
30
30
|
|
31
31
|
assertion(:should_not_update_timestamps) do
|
32
32
|
Timecop.freeze Chronic.parse("5 minutes from now") do
|
33
|
-
perform_import :
|
33
|
+
perform_import timestamps: false
|
34
34
|
assert_in_delta @topic.created_at.to_i, updated_topic.created_at.to_i, 1
|
35
35
|
assert_in_delta @topic.created_on.to_i, updated_topic.created_on.to_i, 1
|
36
36
|
assert_in_delta @topic.updated_at.to_i, updated_topic.updated_at.to_i, 1
|
data/test/support/factories.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
FactoryGirl.define do
|
2
|
-
sequence(:book_title) {|n| "Book #{n}"}
|
3
|
-
sequence(:chapter_title) {|n| "Chapter #{n}"}
|
4
|
-
sequence(:end_note) {|n| "Endnote #{n}"}
|
2
|
+
sequence(:book_title) { |n| "Book #{n}" }
|
3
|
+
sequence(:chapter_title) { |n| "Chapter #{n}" }
|
4
|
+
sequence(:end_note) { |n| "Endnote #{n}" }
|
5
5
|
|
6
6
|
factory :group do
|
7
7
|
sequence(:order) { |n| "Order #{n}" }
|
8
8
|
end
|
9
9
|
|
10
|
-
factory :invalid_topic, :
|
11
|
-
sequence(:title){ |n| "Title #{n}"}
|
10
|
+
factory :invalid_topic, class: "Topic" do
|
11
|
+
sequence(:title) { |n| "Title #{n}" }
|
12
12
|
author_name nil
|
13
13
|
end
|
14
14
|
|
15
15
|
factory :topic do
|
16
|
-
sequence(:title){ |n| "Title #{n}"}
|
17
|
-
sequence(:author_name){ |n| "Author #{n}"}
|
16
|
+
sequence(:title) { |n| "Title #{n}" }
|
17
|
+
sequence(:author_name) { |n| "Author #{n}" }
|
18
18
|
end
|
19
19
|
|
20
20
|
factory :widget do
|
21
|
-
sequence(:w_id){ |n| n}
|
21
|
+
sequence(:w_id) { |n| n }
|
22
22
|
end
|
23
23
|
|
24
24
|
factory :question do
|
25
|
-
sequence(:body) { |n| "Text #{n}"}
|
25
|
+
sequence(:body) { |n| "Text #{n}" }
|
26
26
|
|
27
27
|
trait :with_rule do
|
28
28
|
after(:build) do |question|
|
@@ -30,24 +30,23 @@ FactoryGirl.define do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
factory :rule do
|
35
|
-
sequence(:condition_text){ |n| "q_#{n}_#{n}"}
|
35
|
+
sequence(:condition_text) { |n| "q_#{n}_#{n}" }
|
36
36
|
end
|
37
37
|
|
38
|
-
factory :topic_with_book, :
|
38
|
+
factory :topic_with_book, parent: :topic do
|
39
39
|
after(:build) do |topic|
|
40
40
|
2.times do
|
41
|
-
book = topic.books.build(:
|
41
|
+
book = topic.books.build(title: FactoryGirl.generate(:book_title), author_name: 'Stephen King')
|
42
42
|
3.times do
|
43
|
-
book.chapters.build(:
|
43
|
+
book.chapters.build(title: FactoryGirl.generate(:chapter_title))
|
44
44
|
end
|
45
45
|
|
46
46
|
4.times do
|
47
|
-
book.end_notes.build(:
|
47
|
+
book.end_notes.build(note: FactoryGirl.generate(:end_note))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
53
52
|
end
|