mass_insert 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +2 -0
  3. data/.travis.yml +12 -10
  4. data/Gemfile +9 -8
  5. data/LICENSE.txt +1 -1
  6. data/README.md +34 -78
  7. data/Rakefile +19 -24
  8. data/lib/mass_insert/adapters/abstract_adapter.rb +54 -0
  9. data/lib/mass_insert/adapters/mysql2_adapter.rb +5 -0
  10. data/lib/mass_insert/adapters/postgresql_adapter.rb +5 -0
  11. data/lib/mass_insert/adapters/sqlite3_adapter.rb +5 -0
  12. data/lib/mass_insert/base.rb +3 -84
  13. data/lib/mass_insert/builder.rb +8 -0
  14. data/lib/mass_insert/executer.rb +2 -6
  15. data/lib/mass_insert/process.rb +14 -14
  16. data/lib/mass_insert/utilities.rb +25 -0
  17. data/lib/mass_insert/version.rb +1 -1
  18. data/lib/mass_insert.rb +9 -5
  19. data/mass_insert.gemspec +10 -10
  20. data/test/adapters/mysql2/example_test.rb +3 -0
  21. data/test/adapters/postgresql/example_test.rb +3 -0
  22. data/test/adapters/sqlite3/example_test.rb +3 -0
  23. data/test/database.yml.example +18 -0
  24. data/test/models/user.rb +2 -0
  25. data/test/schema.rb +11 -0
  26. data/test/support/adapters/mysql2.rb +1 -0
  27. data/test/support/adapters/postgresql.rb +1 -0
  28. data/test/support/adapters/sqlite3.rb +1 -0
  29. data/test/support/shared_examples.rb +57 -0
  30. data/test/test_helper.rb +20 -0
  31. metadata +42 -188
  32. data/.rvmrc +0 -62
  33. data/lib/mass_insert/builder/adapters/adapter.rb +0 -52
  34. data/lib/mass_insert/builder/adapters/helpers/abstract_query.rb +0 -52
  35. data/lib/mass_insert/builder/adapters/helpers/column_value.rb +0 -90
  36. data/lib/mass_insert/builder/adapters/mysql2_adapter.rb +0 -7
  37. data/lib/mass_insert/builder/adapters/postgresql_adapter.rb +0 -7
  38. data/lib/mass_insert/builder/adapters/sqlite3_adapter.rb +0 -27
  39. data/lib/mass_insert/builder/adapters/sqlserver_adapter.rb +0 -20
  40. data/lib/mass_insert/builder/adapters.rb +0 -16
  41. data/lib/mass_insert/builder/base.rb +0 -28
  42. data/lib/mass_insert/builder/utilities.rb +0 -13
  43. data/lib/mass_insert/result.rb +0 -33
  44. data/spec/adapters/column_types/binary_spec.rb +0 -64
  45. data/spec/adapters/column_types/boolean_spec.rb +0 -48
  46. data/spec/adapters/column_types/date_spec.rb +0 -14
  47. data/spec/adapters/column_types/datetime_spec.rb +0 -14
  48. data/spec/adapters/column_types/decimal_spec.rb +0 -59
  49. data/spec/adapters/column_types/integer_spec.rb +0 -59
  50. data/spec/adapters/column_types/string_spec.rb +0 -46
  51. data/spec/adapters/column_types/time_spec.rb +0 -14
  52. data/spec/adapters/model_spec.rb +0 -83
  53. data/spec/dummy/.gitignore +0 -15
  54. data/spec/dummy/Gemfile +0 -40
  55. data/spec/dummy/README.rdoc +0 -261
  56. data/spec/dummy/Rakefile +0 -7
  57. data/spec/dummy/app/assets/images/rails.png +0 -0
  58. data/spec/dummy/app/assets/javascripts/application.js +0 -15
  59. data/spec/dummy/app/assets/stylesheets/application.css +0 -13
  60. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  61. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  62. data/spec/dummy/app/mailers/.gitkeep +0 -0
  63. data/spec/dummy/app/models/.gitkeep +0 -0
  64. data/spec/dummy/app/models/user.rb +0 -3
  65. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  66. data/spec/dummy/config/application.rb +0 -68
  67. data/spec/dummy/config/boot.rb +0 -6
  68. data/spec/dummy/config/database.yml +0 -49
  69. data/spec/dummy/config/environment.rb +0 -5
  70. data/spec/dummy/config/environments/development.rb +0 -37
  71. data/spec/dummy/config/environments/mysql2.rb +0 -37
  72. data/spec/dummy/config/environments/postgresql.rb +0 -37
  73. data/spec/dummy/config/environments/production.rb +0 -67
  74. data/spec/dummy/config/environments/sqlite3.rb +0 -37
  75. data/spec/dummy/config/environments/test.rb +0 -37
  76. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  77. data/spec/dummy/config/initializers/inflections.rb +0 -15
  78. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  79. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  80. data/spec/dummy/config/initializers/session_store.rb +0 -8
  81. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  82. data/spec/dummy/config/locales/en.yml +0 -5
  83. data/spec/dummy/config/routes.rb +0 -58
  84. data/spec/dummy/config.ru +0 -4
  85. data/spec/dummy/db/migrate/20130412154541_create_users.rb +0 -16
  86. data/spec/dummy/db/schema.rb +0 -29
  87. data/spec/dummy/db/seeds.rb +0 -7
  88. data/spec/dummy/lib/assets/.gitkeep +0 -0
  89. data/spec/dummy/lib/tasks/.gitkeep +0 -0
  90. data/spec/dummy/log/.gitkeep +0 -0
  91. data/spec/dummy/public/404.html +0 -26
  92. data/spec/dummy/public/422.html +0 -26
  93. data/spec/dummy/public/500.html +0 -25
  94. data/spec/dummy/public/favicon.ico +0 -0
  95. data/spec/dummy/public/index.html +0 -241
  96. data/spec/dummy/public/robots.txt +0 -5
  97. data/spec/dummy/script/rails +0 -6
  98. data/spec/dummy/vendor/assets/javascripts/.gitkeep +0 -0
  99. data/spec/dummy/vendor/assets/stylesheets/.gitkeep +0 -0
  100. data/spec/dummy/vendor/plugins/.gitkeep +0 -0
  101. data/spec/lib/mass_insert/base_spec.rb +0 -40
  102. data/spec/lib/mass_insert/builder/adapters/adapter_spec.rb +0 -116
  103. data/spec/lib/mass_insert/builder/adapters/helpers/abstract_query_spec.rb +0 -130
  104. data/spec/lib/mass_insert/builder/adapters/helpers/column_value_spec.rb +0 -222
  105. data/spec/lib/mass_insert/builder/adapters/mysql_adapter_spec.rb +0 -9
  106. data/spec/lib/mass_insert/builder/adapters/postgresql_adapter_spec.rb +0 -9
  107. data/spec/lib/mass_insert/builder/adapters/sqlite3_adapter_spec.rb +0 -52
  108. data/spec/lib/mass_insert/builder/adapters/sqlserver_adapter_spec.rb +0 -32
  109. data/spec/lib/mass_insert/builder/adapters_spec.rb +0 -31
  110. data/spec/lib/mass_insert/builder/base_spec.rb +0 -28
  111. data/spec/lib/mass_insert/builder/utilities_spec.rb +0 -11
  112. data/spec/lib/mass_insert/executer_spec.rb +0 -33
  113. data/spec/lib/mass_insert/process_spec.rb +0 -58
  114. data/spec/lib/mass_insert/result_spec.rb +0 -45
  115. data/spec/lib/mass_insert_spec.rb +0 -35
  116. data/spec/spec_helper.rb +0 -15
  117. data/spec/support/mass_insert_support.rb +0 -12
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- Zjc0YmM2NTg0MTRmYjg2NWQyNTcxMWQzZjdhY2VmMzVjOGE1ODFlNg==
5
- data.tar.gz: !binary |-
6
- ZTE4MGExN2IwY2NmOTBkYTUwNmVmYzNjZDZkM2IxZTNhMmY1MmYyNw==
2
+ SHA1:
3
+ metadata.gz: 048a8940b6950ce71e156538ee9e3e49fc4093e7
4
+ data.tar.gz: c06223f8ded6fb2f4596fdb1514a57c02c90038e
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NzM2ZjNiODg1ODFkYjk0ZmJlM2Y1NGQ2MmI3Zjg1N2ZkYzU2OTBjMDM5MTUx
10
- OTQxZDI4MTEyZGI2MTFjZWI5NzJiMWE2YzQxMTJiZTliZWYyMzIyOTEzNTkx
11
- ZWE0MTZkYjIxODE2ZDMyYTJkMDE0Mzg4NTRhZDQ2MmVlNDNiZDM=
12
- data.tar.gz: !binary |-
13
- M2Q1MjFlYmVhNzc2ZDRlNDY4MTM0MTk3NjA0ODg4NDNkYmMwZDU4YjJkNWZm
14
- N2IxZTZhMTI3MGFiNjI3Y2RjZGM1ZWUyYzNlODlkOTEzMDliMzM3ZjA2NzAz
15
- MTA0ZmVjMmExNjNmNWYwNDE3MTRiNmJkYzMxYTEzMjI1OGMzYmU=
6
+ metadata.gz: 8016065eb3fc0076411860b949f4e0499a0754f7b3c4e2469573dc3094eb3f40a81fe2d50f60d947318c9db2504d648ef2ad17750914c631dc008d4bf37c151b
7
+ data.tar.gz: fe0d19f977031e25ae993d9ccc8bb2534d442ca0cea307c63afc4bc3630cd4c4d036a41a7037e69b06fdcefe151e84adb7ac4b7c0399cb98d2e1b3c5d28a9f98
data/.gitignore CHANGED
@@ -8,12 +8,14 @@ InstalledFiles
8
8
  _yardoc
9
9
  coverage
10
10
  doc/
11
+ log/
11
12
  lib/bundler/man
12
13
  pkg
13
14
  rdoc
14
15
  spec/reports
15
16
  test/tmp
16
17
  test/version_tmp
18
+ test/database.yml
17
19
  tmp
18
20
  .rvmrc
19
21
  .rspec
data/.travis.yml CHANGED
@@ -1,14 +1,16 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "1.9.2"
4
- - "1.9.3"
5
- - "2.0.0"
3
+ - '1.9.3'
4
+ - '2.0.0'
5
+ - '2.1.0'
6
+
7
+ #env:
8
+ #- 'AR_VERSION=3.2.17'
9
+ #- 'AR_VERSION=4.0.3'
10
+ #- 'AR_VERSION=4.1.0'
11
+ #- 'AR_VERSION=master'
6
12
 
7
13
  before_script:
8
- - mysql -e 'create database mysql2_test;'
9
- - psql -c 'create database postgresql_test;' -U postgres
10
- - cd spec/dummy
11
- - rake db:migrate RAILS_ENV=mysql2
12
- - rake db:migrate RAILS_ENV=postgresql
13
- - rake db:migrate RAILS_ENV=sqlite3
14
- - cd ../..
14
+ - cp test/database.yml.example test/database.yml
15
+ - mysql -e 'CREATE DATABASE mass_insert_test;'
16
+ - psql -c 'CREATE DATABASE mass_insert_test;' -U postgres
data/Gemfile CHANGED
@@ -2,11 +2,12 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rails", "3.2.13"
6
- gem "mysql2"
7
- gem "sqlite3"
8
- gem "pg"
9
- gem "rspec"
10
- gem "simplecov"
11
- gem "rake"
12
- gem "coveralls", require: false
5
+ gem 'mysql2'
6
+ gem 'sqlite3'
7
+ gem 'pg'
8
+
9
+ gem 'simplecov'
10
+ gem 'coveralls', require: false
11
+
12
+ gem 'rake'
13
+ gem 'activerecord', '>= 3.2'
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 TODO: Write your name
1
+ Copyright (c) 2014 Alejandro Gutiérrez
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -3,99 +3,55 @@
3
3
  This gem aims to provide an easy and faster way to do single database insertions in Rails.
4
4
  Support Mysql, PostgreSQL and SQLite3 adapters. It depends on ActiveRecord.
5
5
 
6
- ## Installation
7
6
 
7
+ ## Installation
8
8
  Add this line to your application's Gemfile:
9
+ ```ruby
10
+ gem 'mass_insert'
11
+ ```
12
+ Run the bundle command to install it.
9
13
 
10
- gem 'mass_insert'
11
-
12
- And then execute:
13
-
14
- $ bundle install
15
-
16
- Or install it yourself with:
17
-
18
- $ gem install mass_insert
19
14
 
20
15
  ## Advantages
21
-
22
16
  Faster. It's depending of the computer but these are some results...
23
-
24
17
  * PostgreSQL - Saving 10,000 records in 0.49s
25
18
 
19
+
26
20
  ## Attention
21
+ Since this is a single database insertion your model validations will be ignored,
22
+ then if you use this gem you need to be sure that information is OK to be persisted.
27
23
 
28
- Since this is a single database insertion your model validations will be ignored, then if you use this gem you need to be sure that information is OK to be persisted.
29
24
 
30
25
  ## Basic Usage
26
+ To use MassInsert gem you need to call `mass_insert` method from your ActiveRecord model
27
+ and pass it an array with the values that you want to persist into the database.
28
+ ```ruby
29
+ values = [
30
+ {
31
+ name: 'Jay',
32
+ email: 'tremendous_gamer@gmail.com',
33
+ age: 15
34
+ },
35
+ {
36
+ name: 'Beverly',
37
+ email: 'nippy_programmer@gmail.com',
38
+ age: 24
39
+ }
40
+ ]
41
+
42
+ User.mass_insert(values)
43
+ ```
44
+
45
+
46
+ ## Insertion per batches
47
+ Due you can get a database timeout error you can specify that the insertion will be in batches.
48
+ Just pass the `per_batch` option with the records per batch. Example...
49
+ ```ruby
50
+ User.mass_insert(values, per_batch: 1000)
51
+ ```
31
52
 
32
- To use MassInsert gem you need to call mass_insert method from your ActiveRecord model and pass it an array with the values that you want to persist into the database.
33
-
34
- The array of values:
35
-
36
- values = [
37
- {
38
- :name => "Jay",
39
- :email => "tremendous_gamer@gmail.com",
40
- :age => 15
41
- },
42
- {
43
- :name => "Beverly",
44
- :email => "nippy_programmer@gmail.com",
45
- :age => 24
46
- }
47
- ]
48
-
49
- And call mass_insert method from your model:
50
-
51
- User.mass_insert(values)
52
-
53
-
54
- ## Results
55
-
56
- Sometimes after MassInsert process you need to see information about the process. MassInsert provides a simple way to do it. Just call the next methods from your model after MassInsert execution.
57
-
58
- User.mass_insert_results.records # => 120000
59
-
60
- Some result options are...
61
-
62
- 1. `records` : Returns the amount of records that were persisted.
63
- 2. `time` : Returns the time that took to do all the MassInsert process.
64
- 3. `building_time` : Returns the time that took to create the query string that was persisted.
65
- 4. `execution_time` : Returns the time that took to execute the query string that was persisted.
66
-
67
-
68
- ## Options
69
-
70
- MassInsert accepts options hash by second param when you call `mass_insert` from your model. These options allow you to configure the way that records will be persisted. Example...
71
-
72
- options = {
73
- :some_option => some_value,
74
- :some_option => some_value
75
- }
76
-
77
- User.mass_insert(values, options)
78
-
79
- OR directly
80
-
81
- User.mass_insert(values, :option => value)
82
-
83
- Some options you can include are...
84
-
85
- **Primary key**
86
-
87
- By default primary key is generated automatically. If you wish to set primary key manually you need to pass the `primary_key` option on true. Example...
88
-
89
- User.mass_insert(values, :primary_key => true)
90
-
91
- **Each slice**
92
-
93
- Due you can get a database timeout error you can specify that the insertion will be in batches. Just pass the `each_slice` option with the records per batch. Example...
94
-
95
- User.mass_insert(values, :each_slice => 10000)
96
53
 
97
54
  ## Contributing
98
-
99
55
  1. Fork it
100
56
  2. Create your feature branch (`git checkout -b my-new-feature`)
101
57
  3. Commit your changes (`git commit -am 'Add some feature'`)
data/Rakefile CHANGED
@@ -1,33 +1,28 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
2
3
 
3
- namespace :spec do
4
- desc "Runs unit tests"
5
- task :unit do
6
- system("echo '\e[00;32m\033[1mRunning unit tests...\e[00m'")
7
- system("bundle exec rspec spec/lib")
8
- end
9
-
10
- adapters = [:mysql2, :postgresql, :sqlite3]
4
+ ADAPTERS = %w(mysql2 postgresql sqlite3)
11
5
 
12
- adapters.each do |adapter|
13
- desc "Runs test suite to #{adapter}"
14
- task adapter do
15
- ENV["RAILS_ENV"] = adapter.to_s
16
- system("echo '\e[00;32m\033[1mRunning test suite to #{adapter}...\e[00m'")
17
- system("bundle exec rspec spec/adapters")
6
+ ADAPTERS.each do |adapter|
7
+ namespace :test do
8
+ desc "Runs #{adapter} tests."
9
+ Rake::TestTask.new(adapter) do |t|
10
+ t.libs << 'test'
11
+ t.test_files = FileList[
12
+ "test/support/adapters/#{adapter}.rb",
13
+ "test/adapters/#{adapter}/**/*_test.rb"]
18
14
  end
19
15
  end
16
+ end
20
17
 
21
- desc "Runs all specs"
22
- task :all do
23
- Rake.application['spec:unit'].invoke
24
- raise "Unit test failed!" unless $?.exitstatus == 0
25
-
26
- adapters.each do |adapter|
27
- Rake.application["spec:#{adapter}"].invoke
28
- raise "Test suite to #{adapter} failed!" unless $?.exitstatus == 0
18
+ namespace :test do
19
+ desc 'Runs tests.'
20
+ task :all do |t|
21
+ ADAPTERS.each do |adapter|
22
+ Rake.application["test:#{adapter}"].invoke
29
23
  end
30
24
  end
31
25
  end
32
26
 
33
- task default: 'spec:all'
27
+
28
+ task default: 'test:postgresql'
@@ -0,0 +1,54 @@
1
+ module MassInsert
2
+ module Adapters
3
+ class AbstractAdapter < SimpleDelegator
4
+ attr_accessor :values, :options
5
+
6
+ def initialize(class_name, values, options)
7
+ @values = values
8
+ @options = options
9
+ super(class_name)
10
+ end
11
+
12
+ def to_sql
13
+ "#{insert_sql} #{values_sql}"
14
+ end
15
+
16
+ private
17
+
18
+ def columns
19
+ @columns ||= begin
20
+ columns = column_names
21
+ columns.delete(primary_key)
22
+ columns.map(&:to_sym)
23
+ end
24
+ end
25
+
26
+ def quoted_columns
27
+ columns.map do |name|
28
+ connection.quote_column_name(name)
29
+ end
30
+ end
31
+
32
+ def insert_sql
33
+ "INSERT INTO #{quoted_table_name} #{columns_sql} VALUES"
34
+ end
35
+
36
+ def columns_sql
37
+ "(#{quoted_columns.join(',')})"
38
+ end
39
+
40
+ def values_sql
41
+ "(#{array_of_attributes_sql.join('),(')});"
42
+ end
43
+
44
+ def array_of_attributes_sql
45
+ values.map do |attrs|
46
+ columns.map do |name|
47
+ value = attrs[name.to_sym] || attrs[name.to_s]
48
+ connection.quote(value, columns_hash[name.to_s])
49
+ end.join(',')
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ module MassInsert
2
+ module Adapters
3
+ class Mysql2Adapter < AbstractAdapter; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module MassInsert
2
+ module Adapters
3
+ class PostgreSQLAdapter < AbstractAdapter; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module MassInsert
2
+ module Adapters
3
+ class SQLite3Adapter < AbstractAdapter; end
4
+ end
5
+ end
@@ -1,89 +1,8 @@
1
1
  module MassInsert
2
2
  module Base
3
-
4
- # = MassInsert
5
- #
6
- # Invoke mass insert just calling this from your ActiveRecord model...
7
- #
8
- # User.mass_insert(values)
9
- #
10
- # The values should be an array of hashes. Include attributes and values
11
- # in every hash. Example...
12
- #
13
- # values = [
14
- # {:name => "user name", :email => "user email"},
15
- # {:name => "user name", :email => "user email"}
16
- # ]
17
- #
18
- # == Options
19
- #
20
- # MassInset gem allow you to send it options as second param. Example...
21
- #
22
- # User.mass_insert(values, options)
23
- #
24
- # === Primary key
25
- #
26
- # By default primary key is ignored. If you wish primary key doesn't
27
- # be ignored you need to pass the primary_key option on true.
28
- #
29
- # User.mass_insert(values, :primary_key => true)
30
- #
31
- # === Each slice
32
- #
33
- # Due you can get a database timeout error you can specify that the
34
- # insertion will be in batches. You need to pass the each_slice option
35
- # with the records per batch. Example...
36
- #
37
- # User.mass_insert(values, :each_slice => 10000)
38
- #
39
- def mass_insert values, options = {}
40
- extend ClassMethods
41
-
42
- options[:class_name] ||= self
43
- options[:each_slice] ||= false
44
- options[:primary_key] ||= false
45
-
46
- @mass_insert_process = Process.new(values, options)
47
- @mass_insert_process.start
48
- end
49
-
50
-
51
- module ClassMethods
52
-
53
- # == Results
54
- #
55
- # Sometimes after MassInsert process you need to see information about
56
- # the process. MassInsert provides a simple way to do it. Just call the
57
- # next methods from your model after MassInsert execution:
58
- #
59
- # === Records
60
- #
61
- # Returns the amount of records that were persisted.
62
- #
63
- # User.mass_insert_results.records # => 120000
64
- #
65
- # === Time
66
- #
67
- # Returns the time that took to do all the MassInsert process.
68
- #
69
- # User.mass_insert_results.time # => 0.67
70
- #
71
- # === Building time
72
- #
73
- # Returns the time that took to create the query string that was persisted.
74
- #
75
- # User.mass_insert_results.building_time # => 0.58
76
- #
77
- # === Execution time
78
- #
79
- # Returns the time that took to execute the query string that was persisted.
80
- #
81
- # User.mass_insert_results.execution_time # => 0.09
82
- #
83
- def mass_insert_results
84
- Result.new(@mass_insert_process)
85
- end
86
-
3
+ def mass_insert(values, options = {})
4
+ options[:class_name] ||= self
5
+ Process.new(values, options).start
87
6
  end
88
7
  end
89
8
  end
@@ -0,0 +1,8 @@
1
+ module MassInsert
2
+ class Builder
3
+ def build(values, options)
4
+ class_name = options[:class_name]
5
+ Utilities.adapter_class.new(class_name, values, options).to_sql
6
+ end
7
+ end
8
+ end
@@ -1,13 +1,9 @@
1
1
  module MassInsert
2
- # This class is responsible to execute the queries into the database.
3
- # Uses the ActiveRecord::Base.connection.execute functionality.
4
2
  class Executer
5
-
6
- def execute queries
7
- Array(queries).each do |query|
3
+ def execute(query)
4
+ ActiveRecord::Base.transaction do
8
5
  ActiveRecord::Base.connection.execute(query)
9
6
  end
10
7
  end
11
-
12
8
  end
13
9
  end
@@ -1,33 +1,33 @@
1
- require 'benchmark'
2
-
3
1
  module MassInsert
4
2
  class Process
3
+ attr_reader :values, :options
5
4
 
6
- def initialize values, options
5
+ def initialize(values, options)
7
6
  @values = values
8
7
  @options = options
9
8
  end
10
9
 
11
10
  def start
12
- # MassInsert process is completed by two actions. The first one
13
- # gets queries that will be persisted.
14
- @building_time = Benchmark.measure do
15
- @queries = builder.build(@values, @options)
16
- end
17
-
18
- # The second one executes queries into the database using an
19
- # ActiveRecord connection.
20
- @execution_time = Benchmark.measure do
21
- executer.execute(@queries)
11
+ ActiveRecord::Base.transaction do
12
+ values.each_slice(per_batch).each do |batch|
13
+ query = builder.build(batch, options)
14
+ executer.execute(query)
15
+ end
22
16
  end
23
17
  end
24
18
 
19
+ private
20
+
25
21
  def builder
26
- @builder ||= Builder::Base.new
22
+ @builder ||= Builder.new
27
23
  end
28
24
 
29
25
  def executer
30
26
  @executer ||= Executer.new
31
27
  end
28
+
29
+ def per_batch
30
+ options[:per_batch] || Utilities.per_batch
31
+ end
32
32
  end
33
33
  end
@@ -0,0 +1,25 @@
1
+ module MassInsert
2
+ class Utilities
3
+ ADAPTERS = {
4
+ mysql2: Adapters::Mysql2Adapter,
5
+ postgresql: Adapters::PostgreSQLAdapter,
6
+ sqlite3: Adapters::SQLite3Adapter,
7
+ }
8
+
9
+ def self.adapter
10
+ database_config[:adapter].to_sym
11
+ end
12
+
13
+ def self.database_config
14
+ ActiveRecord::Base.connection.instance_values['config']
15
+ end
16
+
17
+ def self.adapter_class
18
+ ADAPTERS[Utilities.adapter]
19
+ end
20
+
21
+ def self.per_batch
22
+ 500
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module MassInsert
2
- VERSION = '0.1.3'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/mass_insert.rb CHANGED
@@ -1,14 +1,18 @@
1
+ require 'delegate'
2
+
1
3
  module MassInsert
2
4
  autoload :Base, 'mass_insert/base.rb'
3
- autoload :Result, 'mass_insert/result.rb'
5
+ autoload :Builder, 'mass_insert/builder.rb'
4
6
  autoload :Process, 'mass_insert/process.rb'
5
7
  autoload :Executer, 'mass_insert/executer.rb'
8
+ autoload :Utilities, 'mass_insert/utilities.rb'
6
9
  autoload :VERSION, 'mass_insert/version.rb'
7
10
 
8
- module Builder
9
- autoload :Base, 'mass_insert/builder/base.rb'
10
- autoload :Adapters, 'mass_insert/builder/adapters.rb'
11
- autoload :Utilities, 'mass_insert/builder/utilities.rb'
11
+ module Adapters
12
+ autoload :AbstractAdapter, 'mass_insert/adapters/abstract_adapter.rb'
13
+ autoload :Mysql2Adapter, 'mass_insert/adapters/mysql2_adapter.rb'
14
+ autoload :PostgreSQLAdapter, 'mass_insert/adapters/postgresql_adapter.rb'
15
+ autoload :SQLite3Adapter, 'mass_insert/adapters/sqlite3_adapter.rb'
12
16
  end
13
17
  end
14
18
 
data/mass_insert.gemspec CHANGED
@@ -4,20 +4,20 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'mass_insert/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "mass_insert"
7
+ spec.name = 'mass_insert'
8
8
  spec.version = MassInsert::VERSION
9
- spec.authors = ["Alejandro Gutiérrez"]
10
- spec.email = ["alejandrodevs@gmail.com"]
11
- spec.summary = "Mass database insertion in Rails"
12
- spec.description = "This gem aims to provide an easy and faster way to do single database insertions in Rails."
13
- spec.homepage = "https://github.com/alejandrogutierrez/mass_insert"
14
- spec.license = "MIT"
9
+ spec.authors = ['Alejandro Gutiérrez']
10
+ spec.email = ['alejandrodevs@gmail.com']
11
+ spec.summary = 'Mass database insertion in Rails'
12
+ spec.description = 'This gem aims to provide an easy and faster way to do single database insertions in Rails.'
13
+ spec.homepage = 'https://github.com/alejandrogutierrez/mass_insert'
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+ spec.add_dependency 'activerecord', '>= 3.2'
23
23
  end
@@ -0,0 +1,3 @@
1
+ require 'test_helper'
2
+
3
+ shared_examples
@@ -0,0 +1,3 @@
1
+ require 'test_helper'
2
+
3
+ shared_examples
@@ -0,0 +1,3 @@
1
+ require 'test_helper'
2
+
3
+ shared_examples
@@ -0,0 +1,18 @@
1
+ common: &common
2
+ username: root
3
+ password:
4
+ encoding: utf8
5
+ database: mass_insert_test
6
+
7
+ mysql2: &mysql2
8
+ <<: *common
9
+ adapter: mysql2
10
+
11
+ postgresql: &postgresql
12
+ <<: *common
13
+ username: postgres
14
+ adapter: postgresql
15
+
16
+ sqlite3: &sqlite3
17
+ adapter: sqlite3
18
+ database: tmp/test.db
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,11 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :users, force: true do |t|
3
+ t.string :name
4
+ t.boolean :active
5
+ t.integer :age
6
+ t.decimal :money, precision: 10, scale: 2
7
+ t.date :birth_date
8
+
9
+ t.timestamps
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ ENV['DATABASE_ADAPTER'] = 'mysql2'
@@ -0,0 +1 @@
1
+ ENV['DATABASE_ADAPTER'] = 'postgresql'
@@ -0,0 +1 @@
1
+ ENV['DATABASE_ADAPTER'] = 'sqlite3'