mass_insert 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/.travis.yml +10 -0
- data/Gemfile +0 -2
- data/README.md +15 -23
- data/Rakefile +22 -33
- data/lib/mass_insert.rb +11 -7
- data/lib/mass_insert/base.rb +22 -58
- data/lib/mass_insert/builder/adapters.rb +16 -0
- data/lib/mass_insert/builder/adapters/adapter.rb +65 -0
- data/lib/mass_insert/builder/adapters/helpers/abstract_query.rb +52 -0
- data/lib/mass_insert/builder/adapters/helpers/column_value.rb +90 -0
- data/lib/mass_insert/builder/adapters/mysql2_adapter.rb +15 -0
- data/lib/mass_insert/builder/adapters/postgresql_adapter.rb +7 -0
- data/lib/mass_insert/builder/adapters/sqlite3_adapter.rb +27 -0
- data/lib/mass_insert/builder/adapters/sqlserver_adapter.rb +26 -0
- data/lib/mass_insert/builder/base.rb +28 -0
- data/lib/mass_insert/builder/utilities.rb +13 -0
- data/lib/mass_insert/executer.rb +13 -0
- data/lib/mass_insert/process.rb +24 -0
- data/lib/mass_insert/result.rb +33 -0
- data/lib/mass_insert/version.rb +1 -1
- data/mass_insert.gemspec +2 -2
- data/spec/adapters/column_types/binary_spec.rb +64 -0
- data/spec/adapters/column_types/boolean_spec.rb +48 -0
- data/spec/adapters/column_types/decimal_spec.rb +59 -0
- data/spec/adapters/column_types/integer_spec.rb +59 -0
- data/spec/adapters/column_types/string_spec.rb +46 -0
- data/spec/{active_record_models → adapters}/model_spec.rb +1 -21
- data/spec/{active_record_dummy → dummy}/.gitignore +0 -0
- data/spec/{active_record_dummy → dummy}/Gemfile +1 -1
- data/spec/{active_record_dummy → dummy}/README.rdoc +0 -0
- data/spec/{active_record_dummy → dummy}/Rakefile +0 -0
- data/spec/{active_record_dummy → dummy}/app/assets/images/rails.png +0 -0
- data/spec/{active_record_dummy → dummy}/app/assets/javascripts/application.js +0 -0
- data/spec/{active_record_dummy → dummy}/app/assets/stylesheets/application.css +0 -0
- data/spec/{active_record_dummy → dummy}/app/controllers/application_controller.rb +0 -0
- data/spec/{active_record_dummy → dummy}/app/helpers/application_helper.rb +0 -0
- data/spec/{active_record_dummy → dummy}/app/mailers/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/app/models/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/app/models/user.rb +0 -0
- data/spec/{active_record_dummy → dummy}/app/views/layouts/application.html.erb +0 -0
- data/spec/{active_record_dummy → dummy}/config.ru +0 -0
- data/spec/{active_record_dummy → dummy}/config/application.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/boot.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/database.yml +3 -8
- data/spec/{active_record_dummy → dummy}/config/environment.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/environments/development.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/environments/mysql2.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/environments/postgresql.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/environments/production.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/environments/sqlite3.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/environments/test.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/initializers/backtrace_silencers.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/initializers/inflections.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/initializers/mime_types.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/initializers/secret_token.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/initializers/session_store.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/initializers/wrap_parameters.rb +0 -0
- data/spec/{active_record_dummy → dummy}/config/locales/en.yml +0 -0
- data/spec/{active_record_dummy → dummy}/config/routes.rb +0 -0
- data/spec/{active_record_dummy → dummy}/db/migrate/20130412154541_create_users.rb +0 -0
- data/spec/{active_record_dummy → dummy}/db/schema.rb +0 -0
- data/spec/{active_record_dummy → dummy}/db/seeds.rb +0 -0
- data/spec/{active_record_dummy → dummy}/lib/assets/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/lib/tasks/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/log/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/public/404.html +0 -0
- data/spec/{active_record_dummy → dummy}/public/422.html +0 -0
- data/spec/{active_record_dummy → dummy}/public/500.html +0 -0
- data/spec/{active_record_dummy → dummy}/public/favicon.ico +0 -0
- data/spec/{active_record_dummy → dummy}/public/index.html +0 -0
- data/spec/{active_record_dummy → dummy}/public/robots.txt +0 -0
- data/spec/{active_record_dummy → dummy}/script/rails +0 -0
- data/spec/{active_record_dummy → dummy}/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/{active_record_dummy → dummy}/vendor/plugins/.gitkeep +0 -0
- data/spec/lib/mass_insert/base_spec.rb +40 -0
- data/spec/lib/mass_insert/builder/adapters/adapter_spec.rb +129 -0
- data/spec/lib/mass_insert/builder/adapters/helpers/abstract_query_spec.rb +130 -0
- data/spec/{mass_insert/adapters/adapter_helpers → lib/mass_insert/builder/adapters/helpers}/column_value_spec.rb +42 -94
- data/spec/lib/mass_insert/builder/adapters/mysql_adapter_spec.rb +15 -0
- data/spec/lib/mass_insert/builder/adapters/postgresql_adapter_spec.rb +9 -0
- data/spec/lib/mass_insert/builder/adapters/sqlite3_adapter_spec.rb +52 -0
- data/spec/lib/mass_insert/builder/adapters/sqlserver_adapter_spec.rb +38 -0
- data/spec/lib/mass_insert/builder/adapters_spec.rb +31 -0
- data/spec/lib/mass_insert/builder/base_spec.rb +28 -0
- data/spec/lib/mass_insert/builder/utilities_spec.rb +11 -0
- data/spec/lib/mass_insert/executer_spec.rb +33 -0
- data/spec/lib/mass_insert/process_spec.rb +44 -0
- data/spec/lib/mass_insert/result_spec.rb +45 -0
- data/spec/lib/mass_insert_spec.rb +35 -0
- data/spec/spec_helper.rb +7 -2
- data/spec/support/mass_insert_support.rb +12 -0
- metadata +160 -163
- data/lib/mass_insert/adapters.rb +0 -10
- data/lib/mass_insert/adapters/adapter.rb +0 -26
- data/lib/mass_insert/adapters/adapter_helpers.rb +0 -11
- data/lib/mass_insert/adapters/adapter_helpers/abstract_query.rb +0 -56
- data/lib/mass_insert/adapters/adapter_helpers/column_value.rb +0 -110
- data/lib/mass_insert/adapters/adapter_helpers/sanitizer.rb +0 -21
- data/lib/mass_insert/adapters/adapter_helpers/timestamp.rb +0 -33
- data/lib/mass_insert/adapters/mysql2_adapter.rb +0 -13
- data/lib/mass_insert/adapters/postgresql_adapter.rb +0 -5
- data/lib/mass_insert/adapters/sqlite3_adapter.rb +0 -37
- data/lib/mass_insert/adapters/sqlserver_adapter.rb +0 -29
- data/lib/mass_insert/process_control.rb +0 -46
- data/lib/mass_insert/query_builder.rb +0 -39
- data/lib/mass_insert/query_execution.rb +0 -29
- data/spec/active_record_models/column_types/binary_spec.rb +0 -60
- data/spec/active_record_models/column_types/boolean_spec.rb +0 -52
- data/spec/active_record_models/column_types/decimal_spec.rb +0 -49
- data/spec/active_record_models/column_types/integer_spec.rb +0 -49
- data/spec/active_record_models/column_types/string_spec.rb +0 -50
- data/spec/dummy_models/test.rb +0 -5
- data/spec/mass_insert/adapters/adapter_helpers/abstract_query_spec.rb +0 -119
- data/spec/mass_insert/adapters/adapter_helpers/sanitizer_spec.rb +0 -46
- data/spec/mass_insert/adapters/adapter_helpers/timestamp_spec.rb +0 -75
- data/spec/mass_insert/adapters/adapter_helpers_spec.rb +0 -24
- data/spec/mass_insert/adapters/adapter_spec.rb +0 -79
- data/spec/mass_insert/adapters/mysql_adapter_spec.rb +0 -22
- data/spec/mass_insert/adapters/postgresql_adapter_spec.rb +0 -11
- data/spec/mass_insert/adapters/sqlite3_adapter_spec.rb +0 -84
- data/spec/mass_insert/adapters/sqlserver_adapter_spec.rb +0 -61
- data/spec/mass_insert/adapters_spec.rb +0 -32
- data/spec/mass_insert/base_spec.rb +0 -114
- data/spec/mass_insert/process_control_spec.rb +0 -125
- data/spec/mass_insert/query_builder_spec.rb +0 -84
- data/spec/mass_insert/query_execution_spec.rb +0 -50
- data/spec/mass_insert_spec.rb +0 -28
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -2,3 +2,13 @@ language: ruby
|
|
|
2
2
|
rvm:
|
|
3
3
|
- "1.9.2"
|
|
4
4
|
- "1.9.3"
|
|
5
|
+
- "2.0.0"
|
|
6
|
+
|
|
7
|
+
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 ../..
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# MassInsert [](https://travis-ci.org/alejandrogutierrez/mass_insert)
|
|
2
2
|
|
|
3
3
|
This gem aims to provide an easy and faster way to do single database insertions in Rails.
|
|
4
|
-
Support Mysql, PostgreSQL
|
|
4
|
+
Support Mysql, PostgreSQL and SQLite3 adapters.
|
|
5
5
|
|
|
6
6
|
## Installation
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ Or install it yourself with:
|
|
|
21
21
|
|
|
22
22
|
Faster. It's depending of the computer but these are some results...
|
|
23
23
|
|
|
24
|
-
* PostgreSQL - Saving 10,000 records in 0.
|
|
24
|
+
* PostgreSQL - Saving 10,000 records in 0.49s
|
|
25
25
|
|
|
26
26
|
## Attention
|
|
27
27
|
|
|
@@ -43,11 +43,6 @@ The array of values:
|
|
|
43
43
|
:name => "Beverly",
|
|
44
44
|
:email => "nippy_programmer@gmail.com",
|
|
45
45
|
:age => 24
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
:name => "Scottie",
|
|
49
|
-
:email => "angry_programmer@gmail.com",
|
|
50
|
-
:age => 32
|
|
51
46
|
}
|
|
52
47
|
]
|
|
53
48
|
|
|
@@ -58,7 +53,7 @@ And call mass_insert method from your model:
|
|
|
58
53
|
|
|
59
54
|
## Results
|
|
60
55
|
|
|
61
|
-
Sometimes after MassInsert process you need to see some necessary information about the process. MassInsert gem provides a simple way to do it.
|
|
56
|
+
Sometimes after MassInsert process you need to see some necessary information about the process. MassInsert gem provides a simple way to do it. Just call the next methods from your model after MassInsert execution.
|
|
62
57
|
|
|
63
58
|
User.mass_insert_results.records # => 120000
|
|
64
59
|
|
|
@@ -66,8 +61,8 @@ Some result options are...
|
|
|
66
61
|
|
|
67
62
|
1. `records` : Returns the amount of records that were persisted.
|
|
68
63
|
2. `time` : Returns the time that took to do all the MassInsert process.
|
|
69
|
-
3. `
|
|
70
|
-
4. `
|
|
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.
|
|
71
66
|
|
|
72
67
|
|
|
73
68
|
## Options
|
|
@@ -75,32 +70,29 @@ Some result options are...
|
|
|
75
70
|
MassInsert accepts options hash by second param when you call `mass_insert` from your model. This options allow you to configure the way that the records will be created. Example...
|
|
76
71
|
|
|
77
72
|
options = {
|
|
78
|
-
:
|
|
79
|
-
:
|
|
73
|
+
:some_option => some_value,
|
|
74
|
+
:some_option => some_value
|
|
80
75
|
}
|
|
81
76
|
|
|
82
77
|
User.mass_insert(values, options)
|
|
83
78
|
|
|
84
79
|
OR directly
|
|
85
80
|
|
|
86
|
-
User.mass_insert(values, :
|
|
81
|
+
User.mass_insert(values, :option => value)
|
|
87
82
|
|
|
88
|
-
Some options
|
|
83
|
+
Some options you can include are...
|
|
89
84
|
|
|
90
|
-
**
|
|
91
|
-
- Default value is the table name to your model. This options rarely needs to change but you can do it if you pass a string with the table name. Example...
|
|
85
|
+
**Primary key**
|
|
92
86
|
|
|
93
|
-
|
|
87
|
+
By default primary key is ignored. If you wish primary key doesn't be ignored you need to pass the `primary_key` option on true. Example...
|
|
94
88
|
|
|
95
|
-
|
|
96
|
-
- Default value is `:id`. You can change the name of primary key column send it a symbol with the column name.
|
|
89
|
+
User.mass_insert(values, :primary_key => true)
|
|
97
90
|
|
|
98
|
-
|
|
91
|
+
**Each slice**
|
|
99
92
|
|
|
100
|
-
|
|
101
|
-
- Default value is `:auto`. When is `:auto` MassInsert knows that the database will generate the value of the primary key column automatically. If you pass `:manual` as primary key mode you need to create your value hashes with the key and value of the primary key column.
|
|
93
|
+
Due you can get a database timeout error you can specify that the insertion will be in batches. You need to pass the `each_slice` option with the records per batch. Example...
|
|
102
94
|
|
|
103
|
-
|
|
95
|
+
User.mass_insert(values, :each_slice => 10000)
|
|
104
96
|
|
|
105
97
|
## Contributing
|
|
106
98
|
|
data/Rakefile
CHANGED
|
@@ -1,44 +1,33 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
|
|
3
3
|
namespace :spec do
|
|
4
|
-
desc "
|
|
5
|
-
task :
|
|
6
|
-
system("
|
|
7
|
-
|
|
8
|
-
cd spec/active_record_dummy
|
|
9
|
-
rake db:drop db:create db:migrate RAILS_ENV=mysql2
|
|
10
|
-
rake db:drop db:create db:migrate RAILS_ENV=postgresql
|
|
11
|
-
rake db:drop db:create db:migrate RAILS_ENV=sqlite3
|
|
12
|
-
")
|
|
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")
|
|
13
8
|
end
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
task :all do
|
|
17
|
-
system("echo '\e[00;32m\033[1mRunning all unit tests...\e[00m'")
|
|
18
|
-
system("bundle exec rspec spec/mass_insert_spec.rb spec/mass_insert")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
desc "Runs all the mysql2 specs"
|
|
22
|
-
task :mysql2 do
|
|
23
|
-
ENV["RAILS_ENV"] = "mysql2"
|
|
24
|
-
system("echo '\e[00;32m\033[1mRunning the Mysql2 adapter tests...\e[00m'")
|
|
25
|
-
system("bundle exec rspec spec/active_record_models")
|
|
26
|
-
end
|
|
10
|
+
adapters = [:mysql2, :postgresql, :sqlite3]
|
|
27
11
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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")
|
|
18
|
+
end
|
|
33
19
|
end
|
|
34
20
|
|
|
35
|
-
desc "Runs all
|
|
36
|
-
task :
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
29
|
+
end
|
|
40
30
|
end
|
|
41
31
|
end
|
|
42
32
|
|
|
43
|
-
|
|
44
|
-
task default: ['spec:mysql2', 'spec:postgresql', 'spec:sqlite3', 'spec:all']
|
|
33
|
+
task default: 'spec:all'
|
data/lib/mass_insert.rb
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
require "mass_insert/version"
|
|
2
|
-
|
|
3
1
|
module MassInsert
|
|
4
|
-
autoload :
|
|
5
|
-
autoload :
|
|
6
|
-
autoload :
|
|
7
|
-
autoload :
|
|
8
|
-
autoload :
|
|
2
|
+
autoload :Base, 'mass_insert/base.rb'
|
|
3
|
+
autoload :Result, 'mass_insert/result.rb'
|
|
4
|
+
autoload :Process, 'mass_insert/process.rb'
|
|
5
|
+
autoload :Executer, 'mass_insert/executer.rb'
|
|
6
|
+
autoload :VERSION, 'mass_insert/version.rb'
|
|
7
|
+
|
|
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'
|
|
12
|
+
end
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
if defined?(ActiveRecord::Base)
|
data/lib/mass_insert/base.rb
CHANGED
|
@@ -3,93 +3,57 @@ module MassInsert
|
|
|
3
3
|
|
|
4
4
|
# = MassInsert
|
|
5
5
|
#
|
|
6
|
-
#
|
|
7
|
-
# ActiveRecord model. Example...
|
|
6
|
+
# Invoke mass insert just calling this from your ActiveRecord model...
|
|
8
7
|
#
|
|
9
8
|
# User.mass_insert(values)
|
|
10
9
|
#
|
|
11
|
-
# The values should be an array
|
|
12
|
-
# Example...
|
|
10
|
+
# The values should be an array of hashes. Include attributes and values
|
|
11
|
+
# in every hash. Example...
|
|
13
12
|
#
|
|
14
13
|
# values = [
|
|
15
14
|
# {:name => "user name", :email => "user email"},
|
|
16
|
-
# {:name => "user name", :email => "user email"},
|
|
17
15
|
# {:name => "user name", :email => "user email"}
|
|
18
16
|
# ]
|
|
19
17
|
#
|
|
20
18
|
# == Options
|
|
21
19
|
#
|
|
22
|
-
#
|
|
23
|
-
# Example...
|
|
20
|
+
# MassInset gem allow you to send it options as second param. Example...
|
|
24
21
|
#
|
|
25
22
|
# User.mass_insert(values, options)
|
|
26
23
|
#
|
|
27
|
-
# ===
|
|
28
|
-
#
|
|
29
|
-
# Default value is the table name to your model. This options rarely
|
|
30
|
-
# needs to change but you can do it if you pass a string with the table
|
|
31
|
-
# name. Example...
|
|
32
|
-
#
|
|
33
|
-
# options = {:table_name => "users"}
|
|
34
|
-
#
|
|
35
|
-
# === primary_key
|
|
36
|
-
#
|
|
37
|
-
# Default value is :id. You can change the name of primary key column
|
|
38
|
-
# send it a symbol with the column name.
|
|
24
|
+
# === Primary key
|
|
39
25
|
#
|
|
40
|
-
#
|
|
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.
|
|
41
28
|
#
|
|
42
|
-
#
|
|
29
|
+
# options = {:primary_key => true}
|
|
43
30
|
#
|
|
44
|
-
#
|
|
45
|
-
# will generate the value of the primary key column automatically. If
|
|
46
|
-
# you pass :manual as primary key mode you need to create your value
|
|
47
|
-
# hashes with the key and value of the primary key column.
|
|
31
|
+
# === Each slice
|
|
48
32
|
#
|
|
49
|
-
#
|
|
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...
|
|
50
36
|
#
|
|
51
|
-
#
|
|
52
|
-
# is going to extend the methods in ClassMethods module. This module
|
|
53
|
-
# contains some methods that provides some necessary functionality.
|
|
37
|
+
# User.mass_insert(values, :each_slice => 10000)
|
|
54
38
|
#
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
extend ClassMethods
|
|
62
|
-
end
|
|
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
|
|
63
45
|
|
|
64
|
-
|
|
65
|
-
@mass_insert_process = ProcessControl.new(values, options)
|
|
46
|
+
@mass_insert_process = Process.new(values, options)
|
|
66
47
|
@mass_insert_process.start
|
|
67
48
|
end
|
|
68
49
|
|
|
69
50
|
|
|
70
51
|
module ClassMethods
|
|
71
|
-
|
|
72
|
-
# results of MassInsert process. This method calls results method
|
|
73
|
-
# in ProcessControl class. Returns nil if there is not a instance
|
|
74
|
-
# variable with the MassInset process.
|
|
52
|
+
|
|
75
53
|
def mass_insert_results
|
|
76
|
-
|
|
54
|
+
Result.new(@mass_insert_process)
|
|
77
55
|
end
|
|
78
56
|
|
|
79
|
-
private
|
|
80
|
-
# Sanitizes the MassInset options that were passed by params.
|
|
81
|
-
# Prepares default options that come in the class that invokes the
|
|
82
|
-
# mass_insert function and attributes options that were configured
|
|
83
|
-
# and if the options weren't passed, they would be initialized with
|
|
84
|
-
# the default values.
|
|
85
|
-
def mass_insert_options options = {}
|
|
86
|
-
options[:class_name] ||= self
|
|
87
|
-
options[:table_name] ||= self.table_name
|
|
88
|
-
options[:primary_key] ||= :id
|
|
89
|
-
options[:primary_key_mode] ||= :auto
|
|
90
|
-
options
|
|
91
|
-
end
|
|
92
|
-
|
|
93
57
|
end
|
|
94
58
|
end
|
|
95
59
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module MassInsert
|
|
2
|
+
module Builder
|
|
3
|
+
module Adapters
|
|
4
|
+
autoload :Adapter, 'mass_insert/builder/adapters/adapter.rb'
|
|
5
|
+
autoload :Mysql2Adapter, 'mass_insert/builder/adapters/mysql2_adapter.rb'
|
|
6
|
+
autoload :PostgreSQLAdapter, 'mass_insert/builder/adapters/postgresql_adapter.rb'
|
|
7
|
+
autoload :SQLite3Adapter, 'mass_insert/builder/adapters/sqlite3_adapter.rb'
|
|
8
|
+
autoload :SQLServerAdapter, 'mass_insert/builder/adapters/sqlserver_adapter.rb'
|
|
9
|
+
|
|
10
|
+
module Helpers
|
|
11
|
+
autoload :AbstractQuery, 'mass_insert/builder/adapters/helpers/abstract_query.rb'
|
|
12
|
+
autoload :ColumnValue, 'mass_insert/builder/adapters/helpers/column_value.rb'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module MassInsert
|
|
2
|
+
module Builder
|
|
3
|
+
module Adapters
|
|
4
|
+
class Adapter
|
|
5
|
+
include Helpers::AbstractQuery
|
|
6
|
+
|
|
7
|
+
attr_accessor :values, :options
|
|
8
|
+
|
|
9
|
+
def initialize values, options
|
|
10
|
+
@values = values
|
|
11
|
+
@options = options
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the options according to the method that wasn't found.
|
|
15
|
+
def method_missing method, *args
|
|
16
|
+
@options.has_key?(method) ? @options[method] : super
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns an array according to the options with the column names
|
|
20
|
+
# that will be included in the queries.
|
|
21
|
+
def columns
|
|
22
|
+
@columns ||= sanitized_columns
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Prepare array with the column names according to the options.
|
|
26
|
+
def sanitized_columns
|
|
27
|
+
columns = class_name.column_names
|
|
28
|
+
columns.delete(class_name.primary_key) unless primary_key
|
|
29
|
+
columns.map(&:to_sym)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns true o false if the database table has timestamp columns.
|
|
33
|
+
def timestamp?
|
|
34
|
+
columns.include?(:created_at) && columns.include?(:updated_at)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns timestamp format according to the database adapter. This
|
|
38
|
+
# function can be overwrite in database adapters classes.
|
|
39
|
+
def timestamp_format
|
|
40
|
+
"%Y-%m-%d %H:%M:%S.%6N"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns the timestamp value according to the correct timestamp
|
|
44
|
+
# format to that database engine.
|
|
45
|
+
def timestamp
|
|
46
|
+
Time.now.strftime(timestamp_format)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns the timestamp hash to be merge into row values that will
|
|
50
|
+
# be saved in the database.
|
|
51
|
+
def timestamp_hash
|
|
52
|
+
timestamp_value = timestamp
|
|
53
|
+
{:created_at => timestamp_value, :updated_at => timestamp_value}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns the amount of records to each query. Tries to take the
|
|
57
|
+
# each_slice option value or the length of values.
|
|
58
|
+
def values_per_insertion
|
|
59
|
+
each_slice || @values.count
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module MassInsert
|
|
2
|
+
module Builder
|
|
3
|
+
module Adapters
|
|
4
|
+
module Helpers
|
|
5
|
+
module AbstractQuery
|
|
6
|
+
|
|
7
|
+
# Returns a basic beginning of the query.
|
|
8
|
+
def begin_string
|
|
9
|
+
"INSERT INTO #{class_name.table_name} "
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Returns a basic part of the query with the columns definition.
|
|
13
|
+
def string_columns
|
|
14
|
+
"(#{columns.join(", ")}) "
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Returns a basic part of the query with all the records values.
|
|
18
|
+
def string_values
|
|
19
|
+
"VALUES (#{string_rows_values});"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns all the column values to all the records
|
|
23
|
+
def string_rows_values
|
|
24
|
+
values.map{ |row| string_single_row_values(row) }.join("), (")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Returns all the column values to a single record.
|
|
28
|
+
def string_single_row_values row
|
|
29
|
+
row.merge!(timestamp_hash) if timestamp?
|
|
30
|
+
columns.map{ |col| string_single_value(row, col) }.join(", ")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Returns a single column value. According to the database
|
|
34
|
+
# configuration, column type and presence.
|
|
35
|
+
def string_single_value row, column
|
|
36
|
+
ColumnValue.new(row, column, class_name).build
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Values will be treated in batches according to the values per
|
|
40
|
+
# insertion value. It'll generate an array with queries.
|
|
41
|
+
def execute
|
|
42
|
+
@values.each_slice(values_per_insertion).map do |slice|
|
|
43
|
+
@values = slice;
|
|
44
|
+
"#{begin_string}#{string_columns}#{string_values}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|