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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +49 -0
  3. data/.rubocop_todo.yml +36 -0
  4. data/.travis.yml +31 -7
  5. data/CHANGELOG.md +19 -0
  6. data/Gemfile +5 -2
  7. data/README.markdown +6 -1
  8. data/Rakefile +5 -2
  9. data/activerecord-import.gemspec +1 -1
  10. data/benchmarks/benchmark.rb +67 -68
  11. data/benchmarks/lib/base.rb +136 -137
  12. data/benchmarks/lib/cli_parser.rb +106 -107
  13. data/benchmarks/lib/mysql2_benchmark.rb +19 -21
  14. data/benchmarks/lib/output_to_csv.rb +2 -1
  15. data/benchmarks/lib/output_to_html.rb +8 -13
  16. data/benchmarks/schema/mysql_schema.rb +8 -8
  17. data/gemfiles/4.0.gemfile +1 -1
  18. data/gemfiles/4.1.gemfile +1 -1
  19. data/gemfiles/4.2.gemfile +1 -1
  20. data/gemfiles/5.0.gemfile +1 -1
  21. data/lib/activerecord-import.rb +2 -0
  22. data/lib/activerecord-import/active_record/adapters/sqlite3_adapter.rb +0 -1
  23. data/lib/activerecord-import/adapters/abstract_adapter.rb +9 -9
  24. data/lib/activerecord-import/adapters/mysql_adapter.rb +17 -17
  25. data/lib/activerecord-import/adapters/postgresql_adapter.rb +20 -22
  26. data/lib/activerecord-import/adapters/sqlite3_adapter.rb +9 -9
  27. data/lib/activerecord-import/base.rb +3 -3
  28. data/lib/activerecord-import/import.rb +152 -131
  29. data/lib/activerecord-import/synchronize.rb +20 -20
  30. data/lib/activerecord-import/value_sets_parser.rb +7 -6
  31. data/lib/activerecord-import/version.rb +1 -1
  32. data/test/adapters/mysql2spatial.rb +1 -1
  33. data/test/adapters/postgis.rb +1 -1
  34. data/test/adapters/postgresql.rb +1 -1
  35. data/test/adapters/spatialite.rb +1 -1
  36. data/test/adapters/sqlite3.rb +1 -1
  37. data/test/import_test.rb +121 -70
  38. data/test/models/book.rb +5 -6
  39. data/test/models/chapter.rb +2 -2
  40. data/test/models/discount.rb +3 -0
  41. data/test/models/end_note.rb +2 -2
  42. data/test/models/promotion.rb +1 -1
  43. data/test/models/question.rb +1 -1
  44. data/test/models/rule.rb +2 -2
  45. data/test/models/topic.rb +3 -3
  46. data/test/models/widget.rb +1 -1
  47. data/test/postgis/import_test.rb +1 -1
  48. data/test/schema/generic_schema.rb +100 -96
  49. data/test/schema/mysql_schema.rb +5 -7
  50. data/test/sqlite3/import_test.rb +0 -2
  51. data/test/support/active_support/test_case_extensions.rb +12 -15
  52. data/test/support/assertions.rb +1 -1
  53. data/test/support/factories.rb +15 -16
  54. data/test/support/generate.rb +4 -4
  55. data/test/support/mysql/import_examples.rb +21 -21
  56. data/test/support/postgresql/import_examples.rb +83 -55
  57. data/test/support/shared_examples/on_duplicate_key_update.rb +23 -23
  58. data/test/synchronize_test.rb +2 -2
  59. data/test/test_helper.rb +6 -8
  60. data/test/value_sets_bytes_parser_test.rb +14 -17
  61. data/test/value_sets_records_parser_test.rb +6 -6
  62. metadata +7 -4
  63. data/test/travis/build.sh +0 -34
@@ -1,8 +1,7 @@
1
1
  class Book < ActiveRecord::Base
2
- belongs_to :topic, :inverse_of => :books
3
- has_many :chapters, :inverse_of => :book
4
- has_many :end_notes, :inverse_of => :book
5
- if ENV['AR_VERSION'].to_f >= 4.1
6
- enum status: [:draft, :published]
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
@@ -1,4 +1,4 @@
1
1
  class Chapter < ActiveRecord::Base
2
- belongs_to :book, :inverse_of=>:chapters
3
- validates :title, :presence => true
2
+ belongs_to :book, inverse_of: :chapters
3
+ validates :title, presence: true
4
4
  end
@@ -0,0 +1,3 @@
1
+ class Discount < ActiveRecord::Base
2
+ belongs_to :discountable, polymorphic: true
3
+ end
@@ -1,4 +1,4 @@
1
1
  class EndNote < ActiveRecord::Base
2
- belongs_to :book, :inverse_of=>:end_notes
3
- validates :note, :presence => true
2
+ belongs_to :book, inverse_of: :end_notes
3
+ validates :note, presence: true
4
4
  end
@@ -1,3 +1,3 @@
1
1
  class Promotion < ActiveRecord::Base
2
- self.primary_key = :promotion_id
2
+ self.primary_key = :promotion_id
3
3
  end
@@ -1,3 +1,3 @@
1
1
  class Question < ActiveRecord::Base
2
- has_one :rule
2
+ has_one :rule
3
3
  end
@@ -1,3 +1,3 @@
1
1
  class Rule < ActiveRecord::Base
2
- belongs_to :question
3
- end
2
+ belongs_to :question
3
+ end
@@ -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, :inverse_of => :topic
6
- belongs_to :parent, :class_name => "Topic"
5
+ has_many :books, inverse_of: :topic
6
+ belongs_to :parent, class_name: "Topic"
7
7
 
8
- composed_of :description, :mapping => [ %w(title title), %w(author_name author_name)], :allow_nil => true, :class_name => "TopicDescription"
8
+ composed_of :description, mapping: [%w(title title), %w(author_name author_name)], allow_nil: true, class_name: "TopicDescription"
9
9
  end
@@ -1,7 +1,7 @@
1
1
  class Widget < ActiveRecord::Base
2
2
  self.primary_key = :w_id
3
3
 
4
- default_scope lambda { where(active: true) }
4
+ default_scope -> { where(active: true) }
5
5
 
6
6
  serialize :data, Hash
7
7
  serialize :json_data, JSON
@@ -1,4 +1,4 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
2
  require File.expand_path(File.dirname(__FILE__) + '/../support/postgresql/import_examples')
3
3
 
4
- should_support_postgresql_import_functionality
4
+ should_support_postgresql_import_functionality
@@ -1,138 +1,142 @@
1
1
  ActiveRecord::Schema.define do
2
-
3
- create_table :schema_info, :force=>true do |t|
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 :version=>SchemaInfo::VERSION
5
+ SchemaInfo.create version: SchemaInfo::VERSION
7
6
 
8
- create_table :group, :force => true do |t|
9
- t.column :order, :string
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, :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
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, :force=>true do |t|
32
- t.column :name, :string
33
- t.column :type, :string
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, :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
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, :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
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, :force=>true do |t|
53
- t.column :name, :string
51
+ create_table :teams, force: :cascade do |t|
52
+ t.string :name
54
53
  end
55
54
 
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
- t.column :status, :integer, :default => 0
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, :force => true do |t|
71
- t.column :title, :string
72
- t.column :book_id, :integer, :null => false
73
- t.column :created_at, :datetime
74
- t.column :updated_at, :datetime
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, :force => true do |t|
78
- t.column :note, :string
79
- t.column :book_id, :integer, :null => false
80
- t.column :created_at, :datetime
81
- t.column :updated_at, :datetime
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
- create_table :languages, :force=>true do |t|
86
- t.column :name, :string
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, :force=>true do |t|
91
- t.column :name, :string, :null => true
92
- t.column :created_at, :datetime
93
- t.column :updated_at, :datetime
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, :force => true do |t|
97
- t.column :shopping_cart_id, :string, :null => false
98
- t.column :book_id, :string, :null => false
99
- t.column :copies, :integer, :default => 1
100
- t.column :created_at, :datetime
101
- t.column :updated_at, :datetime
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], :unique => true, :name => 'uk_shopping_cart_books'
102
+ add_index :cart_items, [:shopping_cart_id, :book_id], unique: true, name: 'uk_shopping_cart_books'
105
103
 
106
- create_table :animals, :force => true do |t|
107
- t.column :name, :string, :null => false
108
- t.column :size, :string, :default => nil
109
- t.column :created_at, :datetime
110
- t.column :updated_at, :datetime
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], :unique => true, :name => 'uk_animals'
111
+ add_index :animals, [:name], unique: true, name: 'uk_animals'
114
112
 
115
- create_table :widgets, :id => false, :force => true do |t|
113
+ create_table :widgets, id: false, force: :cascade do |t|
116
114
  t.integer :w_id
117
- t.boolean :active, :default => false
118
- t.text :data
119
- t.text :json_data
115
+ t.boolean :active, default: false
116
+ t.text :data
117
+ t.text :json_data
120
118
  end
121
119
 
122
- create_table "promotions", primary_key: "promotion_id", force: :cascade do |t|
123
- t.string :code
124
- t.string :description
125
- t.decimal :discount
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], :unique => true, :name => 'uk_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: true do |t|
131
- t.column :condition_text, :string
132
- t.column :question_id, :integer
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: true do |t|
136
- t.column :body, :string
139
+ create_table :questions, force: :cascade do |t|
140
+ t.string :body
137
141
  end
138
142
  end
@@ -1,18 +1,16 @@
1
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
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, :default => true
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
@@ -47,6 +47,4 @@ describe "#import" do
47
47
  assert_equal 2500, Topic.count, "Failed to insert all records. Make sure you have a supported version of SQLite3 (3.7.11 or higher) installed"
48
48
  end
49
49
  end
50
-
51
50
  end
52
-
@@ -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
- if Gem::Dependency.new("expected",version_string).match?("actual", ActiveRecord::VERSION::STRING)
8
- instance_eval(&blk)
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 ; self ; end
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 ; self ; end
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 &blk
50
+ klass.instance_eval(&blk)
52
51
  end
53
- alias_method :context, :describe
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
-
@@ -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 :timestamps => false
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
@@ -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, :class => "Topic" do
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, :parent=>:topic do |m|
38
+ factory :topic_with_book, parent: :topic do
39
39
  after(:build) do |topic|
40
40
  2.times do
41
- book = topic.books.build(:title=>FactoryGirl.generate(:book_title), :author_name=>'Stephen King')
41
+ book = topic.books.build(title: FactoryGirl.generate(:book_title), author_name: 'Stephen King')
42
42
  3.times do
43
- book.chapters.build(:title => FactoryGirl.generate(:chapter_title))
43
+ book.chapters.build(title: FactoryGirl.generate(:chapter_title))
44
44
  end
45
45
 
46
46
  4.times do
47
- book.end_notes.build(:note => FactoryGirl.generate(:end_note))
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