active-record-transactioner 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +9 -3
- data/Gemfile.lock +52 -18
- data/README.md +21 -5
- data/Rakefile +19 -16
- data/VERSION +1 -1
- data/active-record-transactioner.gemspec +24 -10
- data/config/best_project_practice_rubocop.yml +7 -0
- data/config/best_project_practice_rubocop_todo.yml +21 -0
- data/lib/active-record-transactioner.rb +139 -31
- data/shippable.yml +4 -4
- data/spec/active-record-transactioner_spec.rb +8 -8
- data/spec/dummy/Rakefile +1 -1
- data/spec/dummy/bin/bundle +2 -2
- data/spec/dummy/bin/rails +3 -3
- data/spec/dummy/bin/rake +2 -2
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/config/application.rb +13 -14
- data/spec/dummy/config/boot.rb +3 -3
- data/spec/dummy/config/database.example.yml +3 -5
- data/spec/dummy/config/database.shippable.yml +1 -3
- data/spec/dummy/config/database.yml +3 -5
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/initializers/secret_token.rb +2 -1
- data/spec/dummy/config/initializers/session_store.rb +1 -1
- data/spec/spec_helper.rb +18 -7
- data/spec/support/basic_user_operations.rb +41 -6
- data/spec/test_classes/active-record-transactioner-test-class.rb +2 -2
- metadata +64 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47b2ab9839e7398fbbfa1684d0e205596df258ab
|
4
|
+
data.tar.gz: e0197e8fbd713edd92990767c92711b8fe286c8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25fd2e63c7d0e7ba9bcb8d674a8cf236e657a18243e172d07b4fa327b92196da22f5773cbb2dbf4a64da6157f4419432b32764812acc91f7019b32af87e438dd
|
7
|
+
data.tar.gz: 65fdf15c694d40a88c2aee97dbaeb638516b1b19a6491b7e7b70f158ef9a383e08f32a892e0c1501dc085f761ee9e05b2b3724545b4c8a27222e7931bd75816a
|
data/Gemfile
CHANGED
@@ -7,14 +7,20 @@ source "http://rubygems.org"
|
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
group :development do
|
9
9
|
gem "rails", "~> 4.0.10"
|
10
|
-
gem "rspec-rails", "~> 3.
|
10
|
+
gem "rspec-rails", "~> 3.4.0"
|
11
11
|
gem "rdoc", "~> 3.12"
|
12
12
|
gem "bundler", ">= 1.0.0"
|
13
13
|
gem "jeweler", ">= 1.8.4"
|
14
14
|
gem "builder"
|
15
15
|
gem "activerecord"
|
16
|
-
gem "
|
16
|
+
gem "sqlite3", "1.3.11"
|
17
|
+
gem "mysql2", "0.3.20"
|
17
18
|
gem "pry"
|
19
|
+
gem "best_practice_project", github: "kaspernj/best_practice_project" # path: "/home/kaspernj/Dev/Ruby/best_practice_project"
|
20
|
+
gem "rubocop", "0.35.1"
|
21
|
+
gem "database_cleaner"
|
18
22
|
end
|
19
23
|
|
20
|
-
|
24
|
+
group :test do
|
25
|
+
gem "codeclimate-test-reporter", require: nil
|
26
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/kaspernj/best_practice_project.git
|
3
|
+
revision: a733a53ffa7fcf2af0b49c30fa7d949579319782
|
4
|
+
specs:
|
5
|
+
best_practice_project (0.0.5)
|
6
|
+
psych (~> 2.0.0)
|
7
|
+
|
1
8
|
GEM
|
2
9
|
remote: http://rubygems.org/
|
3
10
|
specs:
|
@@ -27,10 +34,14 @@ GEM
|
|
27
34
|
tzinfo (~> 0.3.37)
|
28
35
|
addressable (2.3.6)
|
29
36
|
arel (4.0.2)
|
37
|
+
ast (2.1.0)
|
38
|
+
astrolabe (1.3.1)
|
39
|
+
parser (~> 2.2)
|
30
40
|
builder (3.1.4)
|
31
41
|
codeclimate-test-reporter (0.4.2)
|
32
42
|
simplecov (>= 0.7.1, < 1.0.0)
|
33
43
|
coderay (1.1.0)
|
44
|
+
database_cleaner (1.4.1)
|
34
45
|
descendants_tracker (0.0.4)
|
35
46
|
thread_safe (~> 0.3, >= 0.3.1)
|
36
47
|
diff-lcs (1.2.5)
|
@@ -72,7 +83,7 @@ GEM
|
|
72
83
|
multi_json (1.10.0)
|
73
84
|
multi_xml (0.5.5)
|
74
85
|
multipart-post (2.0.0)
|
75
|
-
mysql2 (0.3.
|
86
|
+
mysql2 (0.3.20)
|
76
87
|
nokogiri (1.6.2.1)
|
77
88
|
mini_portile (= 0.6.0)
|
78
89
|
oauth2 (0.9.3)
|
@@ -81,10 +92,14 @@ GEM
|
|
81
92
|
multi_json (~> 1.3)
|
82
93
|
multi_xml (~> 0.5)
|
83
94
|
rack (~> 1.2)
|
95
|
+
parser (2.2.3.0)
|
96
|
+
ast (>= 1.1, < 3.0)
|
97
|
+
powerpack (0.1.1)
|
84
98
|
pry (0.10.1)
|
85
99
|
coderay (~> 1.1.0)
|
86
100
|
method_source (~> 0.8.1)
|
87
101
|
slop (~> 3.4)
|
102
|
+
psych (2.0.15)
|
88
103
|
rack (1.5.2)
|
89
104
|
rack-test (0.6.2)
|
90
105
|
rack (>= 1.0)
|
@@ -101,25 +116,35 @@ GEM
|
|
101
116
|
activesupport (= 4.0.12)
|
102
117
|
rake (>= 0.8.7)
|
103
118
|
thor (>= 0.18.1, < 2.0)
|
119
|
+
rainbow (2.0.0)
|
104
120
|
rake (10.3.2)
|
105
121
|
rdoc (3.12.2)
|
106
122
|
json (~> 1.4)
|
107
|
-
rspec-core (3.1
|
108
|
-
rspec-support (~> 3.
|
109
|
-
rspec-expectations (3.
|
123
|
+
rspec-core (3.4.1)
|
124
|
+
rspec-support (~> 3.4.0)
|
125
|
+
rspec-expectations (3.4.0)
|
110
126
|
diff-lcs (>= 1.2.0, < 2.0)
|
111
|
-
rspec-support (~> 3.
|
112
|
-
rspec-mocks (3.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
rspec-
|
120
|
-
rspec-
|
121
|
-
rspec-
|
122
|
-
|
127
|
+
rspec-support (~> 3.4.0)
|
128
|
+
rspec-mocks (3.4.0)
|
129
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
130
|
+
rspec-support (~> 3.4.0)
|
131
|
+
rspec-rails (3.4.0)
|
132
|
+
actionpack (>= 3.0, < 4.3)
|
133
|
+
activesupport (>= 3.0, < 4.3)
|
134
|
+
railties (>= 3.0, < 4.3)
|
135
|
+
rspec-core (~> 3.4.0)
|
136
|
+
rspec-expectations (~> 3.4.0)
|
137
|
+
rspec-mocks (~> 3.4.0)
|
138
|
+
rspec-support (~> 3.4.0)
|
139
|
+
rspec-support (3.4.1)
|
140
|
+
rubocop (0.35.1)
|
141
|
+
astrolabe (~> 1.3)
|
142
|
+
parser (>= 2.2.3.0, < 3.0)
|
143
|
+
powerpack (~> 0.1)
|
144
|
+
rainbow (>= 1.99.1, < 3.0)
|
145
|
+
ruby-progressbar (~> 1.7)
|
146
|
+
tins (<= 1.6.0)
|
147
|
+
ruby-progressbar (1.7.5)
|
123
148
|
simplecov (0.9.1)
|
124
149
|
docile (~> 1.1.0)
|
125
150
|
multi_json (~> 1.0)
|
@@ -135,9 +160,11 @@ GEM
|
|
135
160
|
actionpack (>= 3.0)
|
136
161
|
activesupport (>= 3.0)
|
137
162
|
sprockets (>= 2.8, < 4.0)
|
163
|
+
sqlite3 (1.3.11)
|
138
164
|
thor (0.19.1)
|
139
165
|
thread_safe (0.3.4)
|
140
166
|
tilt (1.4.1)
|
167
|
+
tins (1.6.0)
|
141
168
|
tzinfo (0.3.42)
|
142
169
|
|
143
170
|
PLATFORMS
|
@@ -145,12 +172,19 @@ PLATFORMS
|
|
145
172
|
|
146
173
|
DEPENDENCIES
|
147
174
|
activerecord
|
175
|
+
best_practice_project!
|
148
176
|
builder
|
149
177
|
bundler (>= 1.0.0)
|
150
178
|
codeclimate-test-reporter
|
179
|
+
database_cleaner
|
151
180
|
jeweler (>= 1.8.4)
|
152
|
-
mysql2
|
181
|
+
mysql2 (= 0.3.20)
|
153
182
|
pry
|
154
183
|
rails (~> 4.0.10)
|
155
184
|
rdoc (~> 3.12)
|
156
|
-
rspec-rails (~> 3.
|
185
|
+
rspec-rails (~> 3.4.0)
|
186
|
+
rubocop (= 0.35.1)
|
187
|
+
sqlite3 (= 1.3.11)
|
188
|
+
|
189
|
+
BUNDLED WITH
|
190
|
+
1.10.6
|
data/README.md
CHANGED
@@ -28,8 +28,6 @@ end
|
|
28
28
|
You can also do it a bit more complicated with some custom options.
|
29
29
|
```ruby
|
30
30
|
ActiveRecordTransactioner.new(
|
31
|
-
call_args: ["Hello world!"],
|
32
|
-
call_method: :save!,
|
33
31
|
transaction_method: :transaction,
|
34
32
|
transaction_size: 1000,
|
35
33
|
threadded: false
|
@@ -41,6 +39,24 @@ ActiveRecordTransactioner.new(
|
|
41
39
|
end
|
42
40
|
```
|
43
41
|
|
42
|
+
### Update columns
|
43
|
+
```ruby
|
44
|
+
ActiveRecordTransactioner.new do |trans|
|
45
|
+
models.each do |model|
|
46
|
+
trans.update_columns(model, some_column: "new_value")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
### Inserts in a single SQL statement (bulk inserts)
|
52
|
+
```ruby
|
53
|
+
ActiveRecordTransactioner.new do |trans|
|
54
|
+
1000.times do |count|
|
55
|
+
trans.bulk_create!(User.new(email: "test#{count}@example.com"))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
44
60
|
### Destroy
|
45
61
|
```ruby
|
46
62
|
ActiveRecordTransactioner.new do |trans|
|
@@ -52,9 +68,9 @@ end
|
|
52
68
|
|
53
69
|
### Threadded
|
54
70
|
|
55
|
-
The "threadded" and "max_running_threads" options will start new threads to
|
71
|
+
The "threadded" and "max_running_threads" options will start new threads to do the saving of the models, while continuing to queue up new models in the primary thread. This way the database can utilize multiple cores, and if you use a threadded VM like JRuby or Rubinius, you will utilize even more.
|
56
72
|
|
57
|
-
This can help greatly speed up the processing.
|
73
|
+
This can help greatly speed up the processing of records.
|
58
74
|
|
59
75
|
Be aware that the saving of only one type of model, will be limited to only one thread, so it will make sense to try and queue up as many type of models as possible. Like users, orders and so on.
|
60
76
|
|
@@ -71,7 +87,7 @@ end
|
|
71
87
|
```
|
72
88
|
|
73
89
|
## Contributing to active-record-transactioner
|
74
|
-
|
90
|
+
|
75
91
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
76
92
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
77
93
|
* Fork the project.
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler"
|
5
5
|
begin
|
6
6
|
Bundler.setup(:default, :development)
|
7
7
|
rescue Bundler::BundlerError => e
|
@@ -9,41 +9,44 @@ rescue Bundler::BundlerError => e
|
|
9
9
|
$stderr.puts "Run `bundle install` to install missing gems"
|
10
10
|
exit e.status_code
|
11
11
|
end
|
12
|
-
require
|
12
|
+
require "rake"
|
13
13
|
|
14
|
-
require
|
14
|
+
require "jeweler"
|
15
15
|
Jeweler::Tasks.new do |gem|
|
16
16
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
17
|
gem.name = "active-record-transactioner"
|
18
18
|
gem.homepage = "http://github.com/kaspernj/active-record-transactioner"
|
19
19
|
gem.license = "MIT"
|
20
|
-
gem.summary =
|
21
|
-
gem.description =
|
20
|
+
gem.summary = "Queue up calls to specific models and execute them in transactions, after a certain number of models have been added."
|
21
|
+
gem.description = "Queue up calls to specific models and execute them in transactions, after a certain number of models have been added."
|
22
22
|
gem.email = "kj@gfish.com"
|
23
23
|
gem.authors = ["Kasper Johansen"]
|
24
24
|
# dependencies defined in Gemfile
|
25
25
|
end
|
26
26
|
Jeweler::RubygemsDotOrgTasks.new
|
27
27
|
|
28
|
-
require
|
29
|
-
require
|
28
|
+
require "rspec/core"
|
29
|
+
require "rspec/core/rake_task"
|
30
30
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
-
spec.pattern = FileList[
|
31
|
+
spec.pattern = FileList["spec/**/*_spec.rb"]
|
32
32
|
end
|
33
33
|
|
34
34
|
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
-
spec.pattern =
|
35
|
+
spec.pattern = "spec/**/*_spec.rb"
|
36
36
|
spec.rcov = true
|
37
37
|
end
|
38
38
|
|
39
|
-
task :
|
39
|
+
task default: :spec
|
40
40
|
|
41
|
-
require
|
41
|
+
require "rdoc/task"
|
42
42
|
Rake::RDocTask.new do |rdoc|
|
43
|
-
version = File.exist?(
|
43
|
+
version = File.exist?("VERSION") ? File.read("VERSION") : ""
|
44
44
|
|
45
|
-
rdoc.rdoc_dir =
|
45
|
+
rdoc.rdoc_dir = "rdoc"
|
46
46
|
rdoc.title = "active-record-transactioner #{version}"
|
47
|
-
rdoc.rdoc_files.include(
|
48
|
-
rdoc.rdoc_files.include(
|
47
|
+
rdoc.rdoc_files.include("README*")
|
48
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
49
49
|
end
|
50
|
+
|
51
|
+
require "best_practice_project"
|
52
|
+
BestPracticeProject.load_tasks
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.7
|
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: active-record-transactioner 0.0.
|
5
|
+
# stub: active-record-transactioner 0.0.7 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "active-record-transactioner"
|
9
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.7"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Kasper Johansen"]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2015-12-05"
|
15
15
|
s.description = "Queue up calls to specific models and execute them in transactions, after a certain number of models have been added."
|
16
16
|
s.email = "kj@gfish.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -28,6 +28,8 @@ Gem::Specification.new do |s|
|
|
28
28
|
"Rakefile",
|
29
29
|
"VERSION",
|
30
30
|
"active-record-transactioner.gemspec",
|
31
|
+
"config/best_project_practice_rubocop.yml",
|
32
|
+
"config/best_project_practice_rubocop_todo.yml",
|
31
33
|
"lib/active-record-transactioner.rb",
|
32
34
|
"shippable.yml",
|
33
35
|
"spec/active-record-transactioner_spec.rb",
|
@@ -81,7 +83,7 @@ Gem::Specification.new do |s|
|
|
81
83
|
]
|
82
84
|
s.homepage = "http://github.com/kaspernj/active-record-transactioner"
|
83
85
|
s.licenses = ["MIT"]
|
84
|
-
s.rubygems_version = "2.
|
86
|
+
s.rubygems_version = "2.2.2"
|
85
87
|
s.summary = "Queue up calls to specific models and execute them in transactions, after a certain number of models have been added."
|
86
88
|
|
87
89
|
if s.respond_to? :specification_version then
|
@@ -89,35 +91,47 @@ Gem::Specification.new do |s|
|
|
89
91
|
|
90
92
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
91
93
|
s.add_development_dependency(%q<rails>, ["~> 4.0.10"])
|
92
|
-
s.add_development_dependency(%q<rspec-rails>, ["~> 3.
|
94
|
+
s.add_development_dependency(%q<rspec-rails>, ["~> 3.4.0"])
|
93
95
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
94
96
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
95
97
|
s.add_development_dependency(%q<jeweler>, [">= 1.8.4"])
|
96
98
|
s.add_development_dependency(%q<builder>, [">= 0"])
|
97
99
|
s.add_development_dependency(%q<activerecord>, [">= 0"])
|
98
|
-
s.add_development_dependency(%q<
|
100
|
+
s.add_development_dependency(%q<sqlite3>, ["= 1.3.11"])
|
101
|
+
s.add_development_dependency(%q<mysql2>, ["= 0.3.20"])
|
99
102
|
s.add_development_dependency(%q<pry>, [">= 0"])
|
103
|
+
s.add_development_dependency(%q<best_practice_project>, [">= 0"])
|
104
|
+
s.add_development_dependency(%q<rubocop>, ["= 0.35.1"])
|
105
|
+
s.add_development_dependency(%q<database_cleaner>, [">= 0"])
|
100
106
|
else
|
101
107
|
s.add_dependency(%q<rails>, ["~> 4.0.10"])
|
102
|
-
s.add_dependency(%q<rspec-rails>, ["~> 3.
|
108
|
+
s.add_dependency(%q<rspec-rails>, ["~> 3.4.0"])
|
103
109
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
104
110
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
105
111
|
s.add_dependency(%q<jeweler>, [">= 1.8.4"])
|
106
112
|
s.add_dependency(%q<builder>, [">= 0"])
|
107
113
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
108
|
-
s.add_dependency(%q<
|
114
|
+
s.add_dependency(%q<sqlite3>, ["= 1.3.11"])
|
115
|
+
s.add_dependency(%q<mysql2>, ["= 0.3.20"])
|
109
116
|
s.add_dependency(%q<pry>, [">= 0"])
|
117
|
+
s.add_dependency(%q<best_practice_project>, [">= 0"])
|
118
|
+
s.add_dependency(%q<rubocop>, ["= 0.35.1"])
|
119
|
+
s.add_dependency(%q<database_cleaner>, [">= 0"])
|
110
120
|
end
|
111
121
|
else
|
112
122
|
s.add_dependency(%q<rails>, ["~> 4.0.10"])
|
113
|
-
s.add_dependency(%q<rspec-rails>, ["~> 3.
|
123
|
+
s.add_dependency(%q<rspec-rails>, ["~> 3.4.0"])
|
114
124
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
115
125
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
116
126
|
s.add_dependency(%q<jeweler>, [">= 1.8.4"])
|
117
127
|
s.add_dependency(%q<builder>, [">= 0"])
|
118
128
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
119
|
-
s.add_dependency(%q<
|
129
|
+
s.add_dependency(%q<sqlite3>, ["= 1.3.11"])
|
130
|
+
s.add_dependency(%q<mysql2>, ["= 0.3.20"])
|
120
131
|
s.add_dependency(%q<pry>, [">= 0"])
|
132
|
+
s.add_dependency(%q<best_practice_project>, [">= 0"])
|
133
|
+
s.add_dependency(%q<rubocop>, ["= 0.35.1"])
|
134
|
+
s.add_dependency(%q<database_cleaner>, [">= 0"])
|
121
135
|
end
|
122
136
|
end
|
123
137
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
# This configuration was generated by
|
8
|
+
# `rubocop --auto-gen-config`
|
9
|
+
# on 2015-12-05 17:13:03 +0100 using RuboCop version 0.35.1.
|
10
|
+
# The point is for the user to remove these configuration records
|
11
|
+
# one by one as the offenses are removed from the code base.
|
12
|
+
# Note that changes in the inspected code, or installation of new
|
13
|
+
# versions of RuboCop, may require this file to be generated again.
|
14
|
+
|
15
|
+
# Offense count: 1
|
16
|
+
Metrics/CyclomaticComplexity:
|
17
|
+
Max: 8
|
18
|
+
|
19
|
+
# Offense count: 1
|
20
|
+
Metrics/PerceivedComplexity:
|
21
|
+
Max: 9
|
@@ -11,21 +11,23 @@ class ActiveRecordTransactioner
|
|
11
11
|
debug: false
|
12
12
|
}
|
13
13
|
|
14
|
+
EMPTY_ARGS = []
|
15
|
+
|
14
16
|
ALLOWED_ARGS = DEFAULT_ARGS.keys
|
15
17
|
|
16
18
|
def initialize(args = {})
|
17
|
-
args.
|
19
|
+
args.each_key { |key| raise "Invalid key: '#{key}'." unless ALLOWED_ARGS.include?(key) }
|
18
20
|
|
19
21
|
@args = DEFAULT_ARGS.merge(args)
|
20
22
|
parse_and_set_args
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
return unless block_given?
|
25
|
+
|
26
|
+
begin
|
27
|
+
yield self
|
28
|
+
ensure
|
29
|
+
flush
|
30
|
+
join if threadded?
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -35,6 +37,27 @@ class ActiveRecordTransactioner
|
|
35
37
|
queue(model, type: :save!, validate: false)
|
36
38
|
end
|
37
39
|
|
40
|
+
def bulk_create!(model)
|
41
|
+
attributes = model.attributes
|
42
|
+
attributes.delete("id")
|
43
|
+
attributes.delete("created_at")
|
44
|
+
attributes.delete("updated_at")
|
45
|
+
|
46
|
+
klass = model.class
|
47
|
+
@bulk_creates[klass] ||= []
|
48
|
+
@bulk_creates[klass] << attributes
|
49
|
+
|
50
|
+
@count += 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def update_columns(model, updates)
|
54
|
+
queue(model, type: :update_columns, validate: false, method_args: [updates])
|
55
|
+
end
|
56
|
+
|
57
|
+
def update_column(model, column_name, new_value)
|
58
|
+
update_columns(model, column_name => new_value)
|
59
|
+
end
|
60
|
+
|
38
61
|
def destroy!(model)
|
39
62
|
queue(model, type: :destroy!)
|
40
63
|
end
|
@@ -49,8 +72,15 @@ class ActiveRecordTransactioner
|
|
49
72
|
validate = args.key?(:validate) ? args[:validate] : true
|
50
73
|
|
51
74
|
@lock_models[klass] ||= Monitor.new
|
75
|
+
|
52
76
|
@models[klass] ||= []
|
53
|
-
@models[klass] << {
|
77
|
+
@models[klass] << {
|
78
|
+
model: model,
|
79
|
+
type: args.fetch(:type),
|
80
|
+
validate: validate,
|
81
|
+
method_args: args[:method_args] || EMPTY_ARGS
|
82
|
+
}
|
83
|
+
|
54
84
|
@count += 1
|
55
85
|
end
|
56
86
|
|
@@ -62,6 +92,14 @@ class ActiveRecordTransactioner
|
|
62
92
|
wait_for_threads if threadded?
|
63
93
|
|
64
94
|
@lock.synchronize do
|
95
|
+
@bulk_creates.each do |klass, attribute_array|
|
96
|
+
if threadded?
|
97
|
+
bulk_insert_attribute_array_threadded(klass, attribute_array)
|
98
|
+
else
|
99
|
+
bulk_insert_attribute_array(klass, attribute_array)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
65
103
|
@models.each do |klass, models|
|
66
104
|
next if models.empty?
|
67
105
|
|
@@ -82,9 +120,7 @@ class ActiveRecordTransactioner
|
|
82
120
|
threads_to_join = @lock_threads.synchronize { @threads.clone }
|
83
121
|
|
84
122
|
debug "Threads to join: #{threads_to_join}" if @debug
|
85
|
-
threads_to_join.each
|
86
|
-
thread.join
|
87
|
-
end
|
123
|
+
threads_to_join.each(&:join)
|
88
124
|
end
|
89
125
|
|
90
126
|
def threadded?
|
@@ -95,6 +131,7 @@ private
|
|
95
131
|
|
96
132
|
def parse_and_set_args
|
97
133
|
@models = {}
|
134
|
+
@bulk_creates = {}
|
98
135
|
@threads = []
|
99
136
|
@count = 0
|
100
137
|
@lock = Monitor.new
|
@@ -110,16 +147,15 @@ private
|
|
110
147
|
end
|
111
148
|
|
112
149
|
def wait_for_threads
|
113
|
-
|
114
|
-
while !break_loop
|
150
|
+
loop do
|
115
151
|
debug "Running threads: #{@threads.length} / #{@max_running_threads}" if @debug
|
116
152
|
if allowed_to_start_new_thread?
|
117
|
-
|
153
|
+
break
|
118
154
|
else
|
119
155
|
debug "Waiting for threads #{@threads.length} / #{@max_running_threads}" if @debug
|
120
156
|
end
|
121
157
|
|
122
|
-
sleep 0.2
|
158
|
+
sleep 0.2
|
123
159
|
end
|
124
160
|
|
125
161
|
debug "Done waiting." if @debug
|
@@ -132,23 +168,30 @@ private
|
|
132
168
|
debug "Opening new transaction by using '#{@args[:transaction_method]}'." if @debug
|
133
169
|
|
134
170
|
klass.__send__(@args[:transaction_method]) do
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
171
|
+
work_models(models)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def work_models(models)
|
177
|
+
debug "Going through models." if @debug
|
178
|
+
models.each do |work|
|
179
|
+
debug work if @debug
|
180
|
+
|
181
|
+
work_type = work.fetch(:type)
|
182
|
+
model = work.fetch(:model)
|
148
183
|
|
149
|
-
|
184
|
+
if work_type == :save!
|
185
|
+
validate = work.key?(:validate) ? work[:validate] : true
|
186
|
+
model.save! validate: validate
|
187
|
+
elsif work_type == :update_columns || work_type == :destroy!
|
188
|
+
model.__send__(work_type, *work.fetch(:method_args))
|
189
|
+
else
|
190
|
+
raise "Invalid type: '#{work[:type]}'."
|
150
191
|
end
|
151
192
|
end
|
193
|
+
|
194
|
+
debug "Done working with models." if @debug
|
152
195
|
end
|
153
196
|
|
154
197
|
def work_threadded(klass, models)
|
@@ -159,7 +202,7 @@ private
|
|
159
202
|
work_models_through_transaction(klass, models)
|
160
203
|
end
|
161
204
|
rescue => e
|
162
|
-
|
205
|
+
puts e.inspect
|
163
206
|
puts e.backtrace
|
164
207
|
|
165
208
|
raise e
|
@@ -182,4 +225,69 @@ private
|
|
182
225
|
def allowed_to_start_new_thread?
|
183
226
|
@lock_threads.synchronize { return @threads.length < @max_running_threads }
|
184
227
|
end
|
228
|
+
|
229
|
+
def bulk_insert_attribute_array_threadded(klass, attribute_array)
|
230
|
+
@lock_threads.synchronize do
|
231
|
+
@threads << Thread.new do
|
232
|
+
begin
|
233
|
+
bulk_insert_attribute_array(klass, attribute_array)
|
234
|
+
rescue => e
|
235
|
+
puts e.inspect
|
236
|
+
puts e.backtrace
|
237
|
+
|
238
|
+
raise e
|
239
|
+
ensure
|
240
|
+
debug "Removing thread #{Thread.current.__id__}" if @debug
|
241
|
+
@lock_threads.synchronize { @threads.delete(Thread.current) }
|
242
|
+
|
243
|
+
debug "Threads count after remove: #{@threads.length}" if @debug
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def bulk_insert_attribute_array(klass, attribute_array)
|
250
|
+
sql = "INSERT INTO `#{klass.table_name}` ("
|
251
|
+
|
252
|
+
first = true
|
253
|
+
attribute_array.first.each_key do |key|
|
254
|
+
if first
|
255
|
+
first = false
|
256
|
+
else
|
257
|
+
sql << ", "
|
258
|
+
end
|
259
|
+
|
260
|
+
sql << "`#{key}`"
|
261
|
+
end
|
262
|
+
|
263
|
+
sql << ") VALUES ("
|
264
|
+
|
265
|
+
first_insert = true
|
266
|
+
attribute_array.each do |attributes|
|
267
|
+
if first_insert
|
268
|
+
first_insert = false
|
269
|
+
else
|
270
|
+
sql << "), ("
|
271
|
+
end
|
272
|
+
|
273
|
+
first_value = true
|
274
|
+
attributes.each_value do |value|
|
275
|
+
if first_value
|
276
|
+
first_value = false
|
277
|
+
else
|
278
|
+
sql << ", "
|
279
|
+
end
|
280
|
+
|
281
|
+
sql << klass.connection.quote(value)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
sql << ")"
|
286
|
+
|
287
|
+
klass.connection.execute(sql)
|
288
|
+
|
289
|
+
@lock.synchronize do
|
290
|
+
@count -= attribute_array.length
|
291
|
+
end
|
292
|
+
end
|
185
293
|
end
|
data/shippable.yml
CHANGED
@@ -4,13 +4,13 @@ archive: true
|
|
4
4
|
rvm:
|
5
5
|
- 2.1.2
|
6
6
|
before_script:
|
7
|
-
-
|
8
|
-
- mysql -e 'DROP DATABASE IF EXISTS transactioner;'
|
9
|
-
- mysql -e 'CREATE DATABASE transactioner;'
|
7
|
+
- mysql -e "CREATE DATABASE IF NOT EXISTS shippa;"
|
10
8
|
- cd spec/dummy
|
11
|
-
-
|
9
|
+
- cp config/database.shippable.yml config/database.yml
|
10
|
+
- RAILS_ENV=test bundle exec rake db:schema:load
|
12
11
|
- cd ../..
|
13
12
|
script:
|
14
13
|
- CODECLIMATE_REPO_TOKEN=b7d9c971bea2879b81bdf35f600b985bf3a016c6104169b2c29c213a5d2e7142 bundle exec rspec
|
14
|
+
- bundle exec rake best_practice_project:run
|
15
15
|
notifications:
|
16
16
|
email: false
|
@@ -16,25 +16,25 @@ describe "ActiveRecordTransactioner" do
|
|
16
16
|
|
17
17
|
trans.join
|
18
18
|
|
19
|
-
model1.save_called.
|
20
|
-
model2.save_called.
|
21
|
-
model3.save_called.
|
19
|
+
expect(model1.save_called).to eq true
|
20
|
+
expect(model2.save_called).to eq true
|
21
|
+
expect(model3.save_called).to eq false
|
22
22
|
|
23
23
|
called = false
|
24
|
-
ActiveRecordTransactioner.new do |
|
24
|
+
ActiveRecordTransactioner.new do |transactioner|
|
25
25
|
called = true
|
26
|
-
|
26
|
+
expect(transactioner).to be_a ActiveRecordTransactioner
|
27
27
|
end
|
28
28
|
|
29
|
-
called.
|
29
|
+
expect(called).to eq true
|
30
30
|
end
|
31
31
|
|
32
|
-
it "
|
32
|
+
it "doesnt fail under the Rails reverse bug" do
|
33
33
|
trans = ActiveRecordTransactioner.new(transaction_size: 1)
|
34
34
|
model1 = ActiveRecordTransactionerTestClass.new
|
35
35
|
trans.save!(model1)
|
36
36
|
trans.join
|
37
37
|
|
38
|
-
ActiveRecordTransactionerTestClass::ARGS[:nilraise].
|
38
|
+
expect(ActiveRecordTransactionerTestClass::ARGS[:nilraise]).to eq false
|
39
39
|
end
|
40
40
|
end
|
data/spec/dummy/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
2
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
3
|
|
4
|
-
require File.expand_path(
|
4
|
+
require File.expand_path("../config/application", __FILE__)
|
5
5
|
|
6
6
|
Dummy::Application.load_tasks
|
data/spec/dummy/bin/bundle
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
ENV[
|
3
|
-
load Gem.bin_path(
|
2
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
|
3
|
+
load Gem.bin_path("bundler", "bundle")
|
data/spec/dummy/bin/rails
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
APP_PATH = File.expand_path(
|
3
|
-
require_relative
|
4
|
-
require
|
2
|
+
APP_PATH = File.expand_path("../../config/application", __FILE__)
|
3
|
+
require_relative "../config/boot"
|
4
|
+
require "rails/commands"
|
data/spec/dummy/bin/rake
CHANGED
data/spec/dummy/config.ru
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.expand_path(
|
1
|
+
require File.expand_path("../boot", __FILE__)
|
2
2
|
|
3
3
|
# Pick the frameworks you want:
|
4
4
|
require "active_record/railtie"
|
@@ -10,19 +10,18 @@ require "sprockets/railtie"
|
|
10
10
|
Bundler.require(*Rails.groups)
|
11
11
|
require "active-record-transactioner"
|
12
12
|
|
13
|
-
module Dummy
|
14
|
-
class Application < Rails::Application
|
15
|
-
# Settings in config/environments/* take precedence over those specified here.
|
16
|
-
# Application configuration should go into files in config/initializers
|
17
|
-
# -- all .rb files in that directory are automatically loaded.
|
13
|
+
module Dummy; end
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
class Dummy::Application < Rails::Application
|
16
|
+
# Settings in config/environments/* take precedence over those specified here.
|
17
|
+
# Application configuration should go into files in config/initializers
|
18
|
+
# -- all .rb files in that directory are automatically loaded.
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
20
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
21
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
22
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
28
23
|
|
24
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
25
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
26
|
+
# config.i18n.default_locale = :de
|
27
|
+
end
|
data/spec/dummy/config/boot.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Set up gems listed in the Gemfile.
|
2
|
-
ENV[
|
2
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile", __FILE__)
|
3
3
|
|
4
|
-
require
|
5
|
-
$LOAD_PATH.unshift File.expand_path(
|
4
|
+
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
|
5
|
+
$LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
|
@@ -33,7 +33,7 @@ Dummy::Application.configure do
|
|
33
33
|
config.assets.digest = true
|
34
34
|
|
35
35
|
# Version of your assets, change this if you want to expire all your assets.
|
36
|
-
config.assets.version =
|
36
|
+
config.assets.version = "1.0"
|
37
37
|
|
38
38
|
# Specifies the header that your server uses for sending files.
|
39
39
|
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
|
@@ -9,4 +9,5 @@
|
|
9
9
|
|
10
10
|
# Make sure your secret_key_base is kept private
|
11
11
|
# if you're sharing your code publicly.
|
12
|
-
Dummy::Application.config.secret_key_base =
|
12
|
+
Dummy::Application.config.secret_key_base =
|
13
|
+
"6512c5484d76faa4df05f364d5681de25ee5e657672d98b0177cdb0a489862795e63d12244848be4d8b68f716f27b847654ac307c69f517f8fbc296796b06546"
|
data/spec/spec_helper.rb
CHANGED
@@ -1,27 +1,38 @@
|
|
1
1
|
require "codeclimate-test-reporter"
|
2
2
|
CodeClimate::TestReporter.start
|
3
3
|
|
4
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__),
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
5
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "active_record"
|
7
|
+
require "active-record-transactioner"
|
8
|
+
require "database_cleaner"
|
8
9
|
|
9
|
-
ENV["RAILS_ENV"] ||=
|
10
|
+
ENV["RAILS_ENV"] ||= "test"
|
10
11
|
require_relative "dummy/config/environment"
|
11
|
-
require
|
12
|
+
require "rspec/rails"
|
12
13
|
|
13
14
|
# Requires supporting files with custom matchers and macros, etc,
|
14
15
|
# in ./support/ and its subdirectories.
|
15
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
16
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
16
17
|
|
17
18
|
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
|
18
19
|
|
19
20
|
RSpec.configure do |config|
|
20
21
|
config.expect_with :rspec do |c|
|
21
|
-
c.syntax = [:
|
22
|
+
c.syntax = [:expect]
|
22
23
|
end
|
23
24
|
|
24
25
|
config.infer_base_class_for_anonymous_controllers = false
|
25
26
|
config.infer_spec_type_from_file_location!
|
26
27
|
config.use_transactional_fixtures = false
|
28
|
+
|
29
|
+
config.before(:suite) do
|
30
|
+
DatabaseCleaner.strategy = :truncation
|
31
|
+
end
|
32
|
+
|
33
|
+
config.around(:each) do |example|
|
34
|
+
DatabaseCleaner.cleaning do
|
35
|
+
example.run
|
36
|
+
end
|
37
|
+
end
|
27
38
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
shared_examples_for "basic user operations" do
|
2
2
|
before do
|
3
|
-
ActiveRecord::Base.connection.execute("TRUNCATE TABLE users")
|
4
|
-
|
5
3
|
transactioner do |trans|
|
6
4
|
100.times do |count|
|
7
5
|
user = User.new(username: "User #{count}", email: "user#{count}@example.com")
|
@@ -11,7 +9,7 @@ shared_examples_for "basic user operations" do
|
|
11
9
|
end
|
12
10
|
|
13
11
|
it "can create a lot of models" do
|
14
|
-
User.count.
|
12
|
+
expect(User.count).to eq 100
|
15
13
|
end
|
16
14
|
|
17
15
|
it "can both insert and update a lot of records correct" do
|
@@ -19,17 +17,36 @@ shared_examples_for "basic user operations" do
|
|
19
17
|
200.times do |count|
|
20
18
|
user = User.find_or_initialize_by(email: "user#{count}@example.com")
|
21
19
|
user.username = "User upsert #{count}"
|
20
|
+
|
22
21
|
trans.save!(user)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
count = 0
|
27
26
|
User.find_each do |user|
|
28
|
-
user.email.
|
27
|
+
expect(user.email).to eq "user#{count}@example.com"
|
28
|
+
count += 1
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(User.count).to eq 200
|
32
|
+
end
|
33
|
+
|
34
|
+
it "#update_columns" do
|
35
|
+
transactioner do |trans|
|
36
|
+
count = 0
|
37
|
+
User.find_each do |user|
|
38
|
+
trans.update_columns(user, email: "test#{count}@example.com")
|
39
|
+
count += 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
count = 0
|
44
|
+
User.find_each do |user|
|
45
|
+
expect(user.email).to eq "test#{count}@example.com"
|
29
46
|
count += 1
|
30
47
|
end
|
31
48
|
|
32
|
-
User.count.
|
49
|
+
expect(User.count).to eq 100
|
33
50
|
end
|
34
51
|
|
35
52
|
it "can delete a lot of records" do
|
@@ -39,6 +56,24 @@ shared_examples_for "basic user operations" do
|
|
39
56
|
end
|
40
57
|
end
|
41
58
|
|
42
|
-
User.count.
|
59
|
+
expect(User.count).to eq 50
|
60
|
+
end
|
61
|
+
|
62
|
+
it "does bulk inserts" do
|
63
|
+
User.delete_all
|
64
|
+
|
65
|
+
transactioner do |trans|
|
66
|
+
300.times do |count|
|
67
|
+
trans.bulk_create!(User.new(email: "test#{count}@example.com"))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
count = 0
|
72
|
+
User.order(:id).each do |user|
|
73
|
+
expect(user.email).to eq "test#{count}@example.com"
|
74
|
+
count += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
expect(count).to eq 300
|
43
78
|
end
|
44
79
|
end
|
@@ -8,7 +8,7 @@ class ActiveRecordTransactionerTestClass
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.transaction
|
11
|
-
Thread.current[:trans] =
|
11
|
+
Thread.current[:trans] = name
|
12
12
|
|
13
13
|
begin
|
14
14
|
yield
|
@@ -17,7 +17,7 @@ class ActiveRecordTransactionerTestClass
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def save!(
|
20
|
+
def save!(_args = {})
|
21
21
|
raise "Failure - no transaction: #{Thread.current[:trans]}, #{self.class.name}" if Thread.current[:trans] != self.class.name
|
22
22
|
@save_called = true
|
23
23
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active-record-transactioner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Johansen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
33
|
+
version: 3.4.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
40
|
+
version: 3.4.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rdoc
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,8 +108,36 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sqlite3
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.3.11
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.3.11
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: mysql2
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.3.20
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.3.20
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
143
|
- - ">="
|
@@ -123,7 +151,35 @@ dependencies:
|
|
123
151
|
- !ruby/object:Gem::Version
|
124
152
|
version: '0'
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
154
|
+
name: best_practice_project
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.35.1
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - '='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.35.1
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: database_cleaner
|
127
183
|
requirement: !ruby/object:Gem::Requirement
|
128
184
|
requirements:
|
129
185
|
- - ">="
|
@@ -154,6 +210,8 @@ files:
|
|
154
210
|
- Rakefile
|
155
211
|
- VERSION
|
156
212
|
- active-record-transactioner.gemspec
|
213
|
+
- config/best_project_practice_rubocop.yml
|
214
|
+
- config/best_project_practice_rubocop_todo.yml
|
157
215
|
- lib/active-record-transactioner.rb
|
158
216
|
- shippable.yml
|
159
217
|
- spec/active-record-transactioner_spec.rb
|
@@ -224,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
282
|
version: '0'
|
225
283
|
requirements: []
|
226
284
|
rubyforge_project:
|
227
|
-
rubygems_version: 2.
|
285
|
+
rubygems_version: 2.2.2
|
228
286
|
signing_key:
|
229
287
|
specification_version: 4
|
230
288
|
summary: Queue up calls to specific models and execute them in transactions, after
|