activerecord_bulkoperation 0.0.8 → 0.1.0
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/Gemfile +4 -7
- data/README.md +12 -0
- data/Rakefile +1 -1
- data/activerecord_bulkoperation.gemspec +4 -2
- data/gemfiles/5.0.gemfile +7 -0
- data/gemfiles/5.1.gemfile +7 -0
- data/gemfiles/5.2.gemfile +7 -0
- data/gemfiles/6.0.gemfile +7 -0
- data/lib/activerecord_bulkoperation.rb +9 -4
- data/lib/activerecord_bulkoperation/active_record/associations/associations.rb +6 -2
- data/lib/activerecord_bulkoperation/bulkoperation.rb +4 -4
- data/lib/activerecord_bulkoperation/connection_adapters/oracle_enhanced/oci_connection.rb +2 -2
- data/lib/activerecord_bulkoperation/group_operations.rb +91 -83
- data/lib/activerecord_bulkoperation/util/sequence_cache.rb +9 -2
- data/lib/activerecord_bulkoperation/version.rb +1 -1
- data/test/bulkoperation_test.rb +14 -15
- data/test/database.yml +4 -5
- data/test/test_helper.rb +3 -7
- metadata +44 -8
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 12fc174b11b0a39fa81778b9c0d0b66d7f698956777c747390aa14873521d91c
|
4
|
+
data.tar.gz: 89dd91a3338c3057fb91ba2d54e2ffe95a60b8d2764bd90427ce79e9e63c50c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8db1e56b50b1e5e1a58f779bbfe93df7c2f7d9055a08c29b6bee5a13a193476b36813d023d0e8155a8d3a3aa1feb8065e7dd7e3e34d6884ec8b84a7fc7a500f
|
7
|
+
data.tar.gz: f4450aaf3303b8fc9b4ba7f0c5704b9fef2fd1e170d574bec83b5c52f7be3057c53ec628c7cc749a827a96a6bd403f9723fb3778a2034ec975660b15bdbc46bf
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
#gemspec
|
3
|
+
# gemspec
|
4
4
|
|
5
5
|
version = ENV['AR_VERSION'] || "4.2"
|
6
6
|
|
7
|
-
|
8
|
-
gem "minitest"
|
9
|
-
end
|
10
|
-
|
7
|
+
gem "minitest"
|
11
8
|
gem 'mocha'
|
12
|
-
|
13
|
-
eval_gemfile File.expand_path("../gemfiles/#{version}.gemfile", __FILE__)
|
9
|
+
gem 'rake'
|
10
|
+
eval_gemfile File.expand_path("../gemfiles/#{version}.gemfile", __FILE__)
|
data/README.md
CHANGED
@@ -1 +1,13 @@
|
|
1
1
|
# activerecord_bulkoperation
|
2
|
+
AR 4.2, 5.0, 5.1 and 5.2 are supported
|
3
|
+
## Database Driver support
|
4
|
+
currently only oracle_enhanced is supported
|
5
|
+
|
6
|
+
## Install
|
7
|
+
|
8
|
+
## Test
|
9
|
+
```bash
|
10
|
+
# You can use the env variables: DB_USER, DB_PASSWORD and DB_CONNECTION to specify the DB connection.
|
11
|
+
# A running ORACLE DB is neccessary to execute the tests.
|
12
|
+
rake test:oracle_enhanced
|
13
|
+
```
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ require 'rake/testtask'
|
|
7
7
|
namespace :display do
|
8
8
|
task :notice do
|
9
9
|
puts
|
10
|
-
puts "To run tests you must supply the adapter, see rake -T for more information."
|
10
|
+
puts "To run tests you must supply the adapter, see rake -T for more information. e.g. rake test:oracle_enhanced"
|
11
11
|
puts
|
12
12
|
end
|
13
13
|
end
|
@@ -16,8 +16,10 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.version = ActiveRecord::Bulkoperation::VERSION
|
18
18
|
|
19
|
-
gem.required_ruby_version = ">=
|
19
|
+
gem.required_ruby_version = ">=2.3"
|
20
20
|
|
21
|
-
gem.add_runtime_dependency "activerecord", "
|
21
|
+
gem.add_runtime_dependency "activerecord", ">=4.2", "<6"
|
22
22
|
gem.add_development_dependency "rake"
|
23
|
+
gem.add_development_dependency "mocha"
|
24
|
+
gem.add_development_dependency "minitest"
|
23
25
|
end
|
@@ -1,13 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module ActiveRecord
|
2
|
+
module Bulkoperation
|
3
|
+
ActiveRecordVersion = Gem.loaded_specs['activerecord'].version
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
4
7
|
class ActiveRecord::Base
|
5
8
|
class << self
|
9
|
+
|
6
10
|
def establish_connection_with_activerecord_bulkoperation(*args)
|
7
11
|
establish_connection_without_activerecord_bulkoperation(*args)
|
8
12
|
ActiveSupport.run_load_hooks(:active_record_connection_established, connection_pool)
|
9
13
|
end
|
10
|
-
|
14
|
+
alias_method :establish_connection_without_activerecord_bulkoperation, :establish_connection
|
15
|
+
alias_method :establish_connection, :establish_connection_with_activerecord_bulkoperation
|
11
16
|
end
|
12
17
|
end
|
13
18
|
|
@@ -23,7 +23,7 @@ module ActiveRecord
|
|
23
23
|
class CollectionProxy
|
24
24
|
|
25
25
|
def schedule_merge(record)
|
26
|
-
|
26
|
+
proxy_association.reflection.options
|
27
27
|
macro = proxy_association.reflection.macro
|
28
28
|
if(proxy_association.is_a?(ActiveRecord::Associations::HasManyThroughAssociation))
|
29
29
|
handle_has_many_through_schedule_merge(record)
|
@@ -80,7 +80,11 @@ module ActiveRecord
|
|
80
80
|
#TODO remove
|
81
81
|
alias_method :count_without_merges, :count
|
82
82
|
def count
|
83
|
-
|
83
|
+
if defined?(@internal_new_count)
|
84
|
+
count_without_merges + ( @internal_new_count.to_i)
|
85
|
+
else
|
86
|
+
count_without_merges
|
87
|
+
end
|
84
88
|
end
|
85
89
|
|
86
90
|
def handle_has_many_through_schedule_merge(record)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module ActiveRecord
|
2
|
-
|
2
|
+
class NoPersistentRecord < ActiveRecordError
|
3
3
|
end
|
4
4
|
|
5
5
|
class NoOrginalRecordFound < ActiveRecordError
|
@@ -52,7 +52,7 @@ module ActiveRecord
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def self.find_detail_references(table_name)
|
55
|
-
|
55
|
+
connection.find_detail_references_sql_array(table_name)
|
56
56
|
sql = sanitize_sql([sql, table_name.upcase])
|
57
57
|
find_by_sql(sql)
|
58
58
|
end
|
@@ -208,7 +208,7 @@ module ActiveRecord
|
|
208
208
|
types << type if c.null
|
209
209
|
end
|
210
210
|
|
211
|
-
binds = self.class.columns.map { |
|
211
|
+
binds = self.class.columns.map { |column| read_attribute(column.name) }
|
212
212
|
|
213
213
|
get_optimistic_where_binds.each { |v| binds << v }
|
214
214
|
|
@@ -232,7 +232,7 @@ module ActiveRecord
|
|
232
232
|
end
|
233
233
|
|
234
234
|
self.class.execute_batch_update(sql, types, [binds])
|
235
|
-
|
235
|
+
end
|
236
236
|
|
237
237
|
private
|
238
238
|
|
@@ -158,7 +158,7 @@ module ActiveRecord
|
|
158
158
|
cursor.bind_param(":#{index}", value, String)
|
159
159
|
|
160
160
|
elsif type == :integer
|
161
|
-
cursor.bind_param(":#{index}", value,
|
161
|
+
cursor.bind_param(":#{index}", value, Integer)
|
162
162
|
|
163
163
|
elsif type == :float
|
164
164
|
cursor.bind_param(":#{index}", value, Float)
|
@@ -177,7 +177,7 @@ module ActiveRecord
|
|
177
177
|
cursor.bind_param_array(":#{index}", column, String)
|
178
178
|
|
179
179
|
elsif type == :integer
|
180
|
-
cursor.bind_param_array(":#{index}", column,
|
180
|
+
cursor.bind_param_array(":#{index}", column, Integer)
|
181
181
|
|
182
182
|
elsif type == :float
|
183
183
|
cursor.bind_param_array(":#{index}", column, Float)
|
@@ -1,19 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Base
|
3
|
-
|
4
5
|
attr_reader :orginal_selected_record
|
5
6
|
|
6
|
-
def save_original
|
7
|
-
@orginal_selected_record
|
7
|
+
def save_original
|
8
|
+
unless defined?(@orginal_selected_record) && @orginal_selected_record
|
9
|
+
@orginal_selected_record = @attributes.to_hash.clone
|
10
|
+
end
|
8
11
|
self
|
9
12
|
end
|
10
13
|
|
11
14
|
def callbacks_closed_scheduled_operation
|
12
|
-
(
|
15
|
+
(@callbacks_closed_scheduled_operation ||= Set.new)
|
13
16
|
end
|
14
17
|
|
15
18
|
def on_closed_scheduled_operation
|
16
|
-
@callbacks_closed_scheduled_operation && @callbacks_closed_scheduled_operation
|
19
|
+
defined?(@callbacks_closed_scheduled_operation) && @callbacks_closed_scheduled_operation && @callbacks_closed_scheduled_operation.each(&:on_closed_scheduled_operation)
|
17
20
|
end
|
18
21
|
|
19
22
|
def unset_new_record
|
@@ -26,26 +29,37 @@ module ActiveRecord
|
|
26
29
|
def merge_group(group, options = {})
|
27
30
|
check_group(group)
|
28
31
|
|
29
|
-
to_insert = group.select
|
32
|
+
to_insert = group.select(&:new_record?)
|
30
33
|
|
31
|
-
to_update = group.
|
34
|
+
to_update = group.reject(&:new_record?)
|
32
35
|
|
33
36
|
affected_rows = 0
|
34
37
|
|
35
|
-
|
36
|
-
|
38
|
+
unless to_insert.empty?
|
39
|
+
affected_rows += insert_group(to_insert, options)
|
40
|
+
end
|
41
|
+
unless to_update.empty?
|
42
|
+
affected_rows += update_group(to_update, options)
|
43
|
+
end
|
37
44
|
|
38
45
|
affected_rows
|
39
|
-
end
|
46
|
+
end
|
40
47
|
|
41
48
|
def to_type_symbol(column)
|
42
|
-
return :string
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
return :string if column.sql_type.index('CHAR')
|
50
|
+
if column.sql_type.index('DATE') || column.sql_type.index('TIMESTAMP')
|
51
|
+
return :date
|
52
|
+
end
|
53
|
+
if column.sql_type.index('NUMBER') && (column.sql_type.count(',') == 0)
|
54
|
+
return :integer
|
55
|
+
end
|
56
|
+
if column.sql_type.index('NUMBER') && (column.sql_type.count(',') == 1)
|
57
|
+
return :float
|
58
|
+
end
|
59
|
+
|
60
|
+
raise ArgumentError, "type #{column.sql_type} of #{column.name} is unsupported"
|
47
61
|
end
|
48
|
-
|
62
|
+
|
49
63
|
def foreign_detail_tables
|
50
64
|
@foreign_detail_tables ||= find_foreign_detail_tables(table_name)
|
51
65
|
end
|
@@ -55,45 +69,47 @@ module ActiveRecord
|
|
55
69
|
end
|
56
70
|
|
57
71
|
def check_group(group)
|
58
|
-
|
59
|
-
|
72
|
+
unless group.is_a?(Array) || group.is_a?(Set) || group.is_a?(ActiveRecord::Relation)
|
73
|
+
raise ArgumentError, "Array expected. Got #{group.class.name}."
|
74
|
+
end
|
75
|
+
unless group.reject { |i| i.is_a? self }.empty?
|
76
|
+
raise ArgumentError, "only records of #{name} expected. Unexpected #{group.reject { |i| i.is_a? self }.map { |i| i.class.name }.uniq.join(',')} found."
|
77
|
+
end
|
60
78
|
end
|
61
79
|
|
62
|
-
def insert_group(group,
|
63
|
-
|
80
|
+
def insert_group(group, _options = {})
|
81
|
+
group.reject(&:new_record?)
|
64
82
|
|
65
83
|
sql = "INSERT INTO #{table_name} " \
|
66
|
-
'( '
|
67
|
-
"#{columns.map
|
68
|
-
') VALUES ( '
|
69
|
-
"#{(1..columns.count).map { |i| ":#{i}"
|
84
|
+
'( ' \
|
85
|
+
"#{columns.map(&:name).join(', ')} " \
|
86
|
+
') VALUES ( ' \
|
87
|
+
"#{(1..columns.count).map { |i| ":#{i}" }.join(', ')} " \
|
70
88
|
')'
|
71
89
|
|
72
|
-
types
|
90
|
+
types = []
|
73
91
|
|
74
|
-
|
92
|
+
columns.each do |c|
|
75
93
|
type = to_type_symbol(c)
|
76
94
|
types << type
|
77
95
|
end
|
78
96
|
|
79
97
|
values = []
|
80
98
|
|
81
|
-
|
82
|
-
|
99
|
+
group.each do |record|
|
83
100
|
row = []
|
84
101
|
|
85
|
-
|
102
|
+
columns.each do |c|
|
86
103
|
v = record.read_attribute(c.name)
|
87
104
|
row << v
|
88
105
|
end
|
89
106
|
|
90
107
|
values << row
|
91
|
-
|
92
108
|
end
|
93
109
|
|
94
110
|
result = execute_batch_update(sql, types, values)
|
95
111
|
|
96
|
-
group.each
|
112
|
+
group.each(&:unset_new_record)
|
97
113
|
|
98
114
|
result
|
99
115
|
end
|
@@ -104,20 +120,22 @@ module ActiveRecord
|
|
104
120
|
optimistic = options[:optimistic]
|
105
121
|
optimistic = true if optimistic.nil?
|
106
122
|
|
107
|
-
|
123
|
+
if optimistic && !group.reject(&:orginal_selected_record).empty?
|
124
|
+
raise NoOrginalRecordFound, "#{name} ( #{table_name} )"
|
125
|
+
end
|
108
126
|
|
109
127
|
sql = optimistic ? build_optimistic_update_sql : build_update_by_primary_key_sql
|
110
128
|
|
111
|
-
types
|
129
|
+
types = []
|
112
130
|
|
113
|
-
|
131
|
+
columns.each do |c|
|
114
132
|
type = to_type_symbol(c)
|
115
133
|
types << type
|
116
134
|
end
|
117
135
|
|
118
136
|
if optimistic
|
119
137
|
|
120
|
-
|
138
|
+
columns.each do |c|
|
121
139
|
type = to_type_symbol(c)
|
122
140
|
types << type
|
123
141
|
types << type if c.null
|
@@ -127,7 +145,7 @@ module ActiveRecord
|
|
127
145
|
|
128
146
|
keys = primary_key_columns
|
129
147
|
|
130
|
-
|
148
|
+
keys.each do |c|
|
131
149
|
type = to_type_symbol(c)
|
132
150
|
types << type
|
133
151
|
end
|
@@ -138,33 +156,30 @@ module ActiveRecord
|
|
138
156
|
|
139
157
|
keys = primary_key_columns
|
140
158
|
|
141
|
-
|
159
|
+
group.each do |record|
|
142
160
|
row = []
|
143
161
|
|
144
|
-
|
162
|
+
columns.each do |c|
|
145
163
|
v = record.read_attribute(c.name)
|
146
164
|
row << v
|
147
165
|
end
|
148
166
|
|
149
167
|
if optimistic
|
150
168
|
|
151
|
-
orginal = record.orginal_selected_record
|
152
|
-
|
153
|
-
|
154
|
-
v = orginal[ c.name]
|
169
|
+
orginal = record.orginal_selected_record
|
170
|
+
columns.each do |c|
|
171
|
+
v = orginal[c.name]
|
155
172
|
row << v
|
156
173
|
row << v if c.null
|
157
|
-
|
158
174
|
end
|
159
175
|
|
160
176
|
else
|
161
177
|
|
162
|
-
keys.each { |c| row << record[
|
178
|
+
keys.each { |c| row << record[c.name] }
|
163
179
|
|
164
180
|
end
|
165
181
|
|
166
182
|
values << row
|
167
|
-
|
168
183
|
end
|
169
184
|
|
170
185
|
count = execute_batch_update(sql, types, values, optimistic)
|
@@ -173,68 +188,66 @@ module ActiveRecord
|
|
173
188
|
end
|
174
189
|
|
175
190
|
public
|
176
|
-
def insert_on_missing_group( keys, group, options = {} )
|
177
191
|
|
178
|
-
|
192
|
+
def insert_on_missing_group(keys, group, _options = {})
|
193
|
+
# fail 'the give key array is empty' if keys.empty?
|
179
194
|
|
180
|
-
keys = Array(
|
195
|
+
keys = Array(primary_key) if keys.nil? || keys.empty?
|
181
196
|
|
182
|
-
sql ="
|
183
|
-
merge into #{table_name} target
|
184
|
-
using ( select #{columns.map{|c| ":#{columns.index(c)+1} #{c.name}" }.join(', ')} from dual ) source
|
185
|
-
on ( #{keys.map{|c| "target.#{c} = source.#{c}" }.join(' and ')} )
|
186
|
-
when not matched then
|
187
|
-
insert ( #{columns.map
|
188
|
-
values( #{columns.map{|c| "source.#{c.name}" }.join(', ')} )
|
197
|
+
sql = "
|
198
|
+
merge into #{table_name} target
|
199
|
+
using ( select #{columns.map { |c| ":#{columns.index(c) + 1} #{c.name}" }.join(', ')} from dual ) source
|
200
|
+
on ( #{keys.map { |c| "target.#{c} = source.#{c}" }.join(' and ')} )
|
201
|
+
when not matched then
|
202
|
+
insert ( #{columns.map(&:name).join(', ')} )
|
203
|
+
values( #{columns.map { |c| "source.#{c.name}" }.join(', ')} )
|
189
204
|
"
|
190
205
|
|
191
|
-
|
192
|
-
types = columns.map{ |c| to_type_symbol(c) }
|
206
|
+
types = columns.map { |c| to_type_symbol(c) }
|
193
207
|
|
194
208
|
values = []
|
195
209
|
|
196
|
-
|
197
|
-
|
210
|
+
group.each do |record|
|
198
211
|
row = []
|
199
212
|
|
200
|
-
|
213
|
+
columns.each do |c|
|
201
214
|
v = record.read_attribute(c.name)
|
202
215
|
row << v
|
203
216
|
end
|
204
217
|
|
205
218
|
values << row
|
206
|
-
|
207
219
|
end
|
208
220
|
|
209
221
|
begin
|
210
|
-
result = execute_batch_update(sql, types, values,false)
|
211
|
-
rescue
|
212
|
-
raise ActiveRecord::StatementInvalid
|
222
|
+
result = execute_batch_update(sql, types, values, false)
|
223
|
+
rescue StandardError => e
|
224
|
+
raise ActiveRecord::StatementInvalid, "#{e.message}\n#{sql}"
|
213
225
|
end
|
214
226
|
|
215
|
-
group.each
|
227
|
+
group.each(&:unset_new_record)
|
216
228
|
|
217
229
|
result
|
218
|
-
|
219
230
|
end
|
220
|
-
|
231
|
+
|
221
232
|
def delete_group(group, options = {})
|
222
233
|
check_group(group)
|
223
234
|
|
224
235
|
optimistic = options[:optimistic]
|
225
236
|
optimistic = true if optimistic.nil?
|
226
237
|
|
227
|
-
to_delete = group.
|
238
|
+
to_delete = group.reject(&:new_record?)
|
228
239
|
|
229
|
-
|
240
|
+
if optimistic && !to_delete.reject(&:orginal_selected_record).empty?
|
241
|
+
raise NoOrginalRecordFound
|
242
|
+
end
|
230
243
|
|
231
244
|
sql = optimistic ? build_optimistic_delete_sql : build_delete_by_primary_key_sql
|
232
245
|
|
233
|
-
types
|
246
|
+
types = []
|
234
247
|
|
235
248
|
if optimistic
|
236
249
|
|
237
|
-
|
250
|
+
columns.each do |c|
|
238
251
|
type = to_type_symbol(c)
|
239
252
|
types << type
|
240
253
|
types << type if c.null
|
@@ -244,7 +257,7 @@ module ActiveRecord
|
|
244
257
|
|
245
258
|
keys = primary_key_columns
|
246
259
|
|
247
|
-
|
260
|
+
keys.each do |c|
|
248
261
|
type = to_type_symbol(c)
|
249
262
|
types << type
|
250
263
|
end
|
@@ -255,27 +268,24 @@ module ActiveRecord
|
|
255
268
|
|
256
269
|
if optimistic
|
257
270
|
|
258
|
-
|
271
|
+
to_delete.each do |record|
|
259
272
|
row = []
|
260
273
|
orginal = record.orginal_selected_record
|
261
|
-
|
262
|
-
|
263
|
-
v = orginal[ c.name]
|
274
|
+
columns.each do |c|
|
275
|
+
v = orginal[c.name]
|
264
276
|
row << v
|
265
277
|
row << v if c.null
|
266
|
-
|
267
278
|
end
|
268
279
|
|
269
280
|
values << row
|
270
|
-
|
271
281
|
end
|
272
282
|
|
273
283
|
else
|
274
284
|
|
275
285
|
keys = primary_key_columns
|
276
286
|
|
277
|
-
|
278
|
-
row = keys.map { |c| record[
|
287
|
+
to_delete.each do |record|
|
288
|
+
row = keys.map { |c| record[c.name] }
|
279
289
|
values << row
|
280
290
|
end
|
281
291
|
|
@@ -284,13 +294,11 @@ module ActiveRecord
|
|
284
294
|
count = execute_batch_update(sql, types, values, optimistic)
|
285
295
|
|
286
296
|
count
|
287
|
-
|
288
297
|
rescue ExternalDataChange => e
|
289
298
|
raise e
|
290
299
|
rescue Exception => e
|
291
|
-
raise StatementError
|
300
|
+
raise StatementError, "#{sql} #{e.message}"
|
292
301
|
end
|
293
|
-
|
294
302
|
end
|
295
303
|
end
|
296
304
|
end
|
@@ -32,7 +32,7 @@ module ActiveRecord
|
|
32
32
|
|
33
33
|
def next_value_from_queue
|
34
34
|
@queue.pop(true)
|
35
|
-
rescue ThreadError
|
35
|
+
rescue ThreadError
|
36
36
|
nil
|
37
37
|
end
|
38
38
|
|
@@ -43,7 +43,14 @@ module ActiveRecord
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def fetch
|
46
|
-
|
46
|
+
if ActiveRecord::Bulkoperation::ActiveRecordVersion >= Gem::Version.new('5.0')
|
47
|
+
binds = [ ActiveRecord::Relation::QueryAttribute.new(
|
48
|
+
nil, @prefetch, ActiveRecord::Type::Integer.new
|
49
|
+
)]
|
50
|
+
st = ActiveRecord::Base.connection.exec_query("SELECT #{@seq}.nextval id FROM dual connect by level <= :a", "SQL", binds, prepare: true)
|
51
|
+
else
|
52
|
+
st = ActiveRecord::Base.connection.exec_query("SELECT #{@seq}.nextval id FROM dual connect by level <= :a", "SQL", [[nil, @prefetch]])
|
53
|
+
end
|
47
54
|
st.map {|r| r['id']}
|
48
55
|
end
|
49
56
|
end
|
data/test/bulkoperation_test.rb
CHANGED
@@ -73,7 +73,7 @@ class BulkoperationTest < ActiveSupport::TestCase
|
|
73
73
|
|
74
74
|
def test_update_fk_relation
|
75
75
|
#some problems during database creation and recreation
|
76
|
-
|
76
|
+
skip
|
77
77
|
group = Group.new
|
78
78
|
group.schedule_merge
|
79
79
|
test_obj = TestTable.new
|
@@ -104,8 +104,7 @@ class BulkoperationTest < ActiveSupport::TestCase
|
|
104
104
|
assert_equal(0,TestTable.count)
|
105
105
|
ActiveRecord::Base.connection.commit_db_transaction
|
106
106
|
assert_equal(1,TestTable.count)
|
107
|
-
|
108
|
-
assert_equal('test-1',test_obj.author_name)
|
107
|
+
assert_equal('test-1',TestTable.first.author_name)
|
109
108
|
TestTable.delete_all
|
110
109
|
end
|
111
110
|
|
@@ -145,14 +144,14 @@ class BulkoperationTest < ActiveSupport::TestCase
|
|
145
144
|
course.students.schedule_merge(student)
|
146
145
|
ActiveRecord::Bulkoperation::Util::FlushDirtyObjects.get.flush
|
147
146
|
return
|
148
|
-
db_part = Course.first
|
149
|
-
db_assembly = Assembly.first
|
147
|
+
# db_part = Course.first
|
148
|
+
# db_assembly = Assembly.first
|
150
149
|
|
151
|
-
assert_equal(1,db_part.assemblies.count)
|
152
|
-
assert_equal(db_assembly[:id],db_part.assemblies.first[:id])
|
150
|
+
# assert_equal(1,db_part.assemblies.count)
|
151
|
+
# assert_equal(db_assembly[:id],db_part.assemblies.first[:id])
|
153
152
|
|
154
|
-
assert_equal(1,db_assembly.parts.count)
|
155
|
-
assert_equal(db_part[:id],db_assembly.parts.first[:id])
|
153
|
+
# assert_equal(1,db_assembly.parts.count)
|
154
|
+
# assert_equal(db_part[:id],db_assembly.parts.first[:id])
|
156
155
|
end
|
157
156
|
|
158
157
|
def test_schedule_merge_has_and_belongs_to_many_relation_self_join
|
@@ -162,14 +161,14 @@ class BulkoperationTest < ActiveSupport::TestCase
|
|
162
161
|
product.related_products.schedule_merge(product2)
|
163
162
|
ActiveRecord::Bulkoperation::Util::FlushDirtyObjects.get.flush
|
164
163
|
return
|
165
|
-
db_part = Course.first
|
166
|
-
db_assembly = Assembly.first
|
164
|
+
# db_part = Course.first
|
165
|
+
# db_assembly = Assembly.first
|
167
166
|
|
168
|
-
assert_equal(1,db_part.assemblies.count)
|
169
|
-
assert_equal(db_assembly[:id],db_part.assemblies.first[:id])
|
167
|
+
# assert_equal(1,db_part.assemblies.count)
|
168
|
+
# assert_equal(db_assembly[:id],db_part.assemblies.first[:id])
|
170
169
|
|
171
|
-
assert_equal(1,db_assembly.parts.count)
|
172
|
-
assert_equal(db_part[:id],db_assembly.parts.first[:id])
|
170
|
+
# assert_equal(1,db_assembly.parts.count)
|
171
|
+
# assert_equal(db_part[:id],db_assembly.parts.first[:id])
|
173
172
|
end
|
174
173
|
|
175
174
|
end
|
data/test/database.yml
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
oracle_enhanced:
|
2
2
|
adapter: oracle_enhanced
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
database: ORCL
|
3
|
+
# url: jdbc:oracle:thin:@localhost:1521:XEPDB1
|
4
|
+
username: <%=ENV['DB_USER'] ||= "sample" %>
|
5
|
+
password: <%=ENV['DB_PASSWORD'] ||= "sample" %>
|
6
|
+
database: <%=ENV['DB_CONNECTION'] ||= '//localhost:1521/XEPDB1' %>
|
8
7
|
pool: 200
|
data/test/test_helper.rb
CHANGED
@@ -10,17 +10,13 @@ ENV["RAILS_ENV"] = "test"
|
|
10
10
|
|
11
11
|
require "bundler"
|
12
12
|
Bundler.setup
|
13
|
+
Bundler.require
|
13
14
|
|
14
15
|
require "active_record"
|
15
16
|
require "active_record/fixtures"
|
16
17
|
require "active_support/test_case"
|
17
18
|
|
18
|
-
|
19
|
-
require 'test/unit'
|
20
|
-
else
|
21
|
-
require 'active_support/testing/autorun'
|
22
|
-
end
|
23
|
-
|
19
|
+
require 'active_support/testing/autorun'
|
24
20
|
require "mocha/test_unit"
|
25
21
|
|
26
22
|
ActiveSupport::TestCase.test_order = :sorted
|
@@ -29,7 +25,7 @@ adapter = ENV["DB_ADAPTER"] || "oracle_enhanced"
|
|
29
25
|
FileUtils.mkdir_p 'log'
|
30
26
|
ActiveRecord::Base.logger = Logger.new("log/test.log")
|
31
27
|
ActiveRecord::Base.logger.level = Logger::DEBUG
|
32
|
-
ActiveRecord::Base.configurations['test'] = YAML.
|
28
|
+
ActiveRecord::Base.configurations['test'] = YAML.load(ERB.new(File.read(test_dir.join("database.yml"))).result)[adapter]
|
33
29
|
ActiveRecord::Base.default_timezone = :utc
|
34
30
|
|
35
31
|
require "activerecord_bulkoperation"
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord_bulkoperation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OSP
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '4.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rake
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +44,34 @@ dependencies:
|
|
38
44
|
- - ">="
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mocha
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: minitest
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
41
75
|
description: ''
|
42
76
|
email:
|
43
77
|
- ''
|
@@ -46,12 +80,15 @@ extensions: []
|
|
46
80
|
extra_rdoc_files: []
|
47
81
|
files:
|
48
82
|
- ".gitignore"
|
49
|
-
- ".ruby-version"
|
50
83
|
- Gemfile
|
51
84
|
- README.md
|
52
85
|
- Rakefile
|
53
86
|
- activerecord_bulkoperation.gemspec
|
54
87
|
- gemfiles/4.2.gemfile
|
88
|
+
- gemfiles/5.0.gemfile
|
89
|
+
- gemfiles/5.1.gemfile
|
90
|
+
- gemfiles/5.2.gemfile
|
91
|
+
- gemfiles/6.0.gemfile
|
55
92
|
- lib/activerecord_bulkoperation.rb
|
56
93
|
- lib/activerecord_bulkoperation/active_record/adapters/abstract_adapter.rb
|
57
94
|
- lib/activerecord_bulkoperation/active_record/adapters/oracle_enhanced_adapter.rb
|
@@ -105,15 +142,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
142
|
requirements:
|
106
143
|
- - ">="
|
107
144
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
145
|
+
version: '2.3'
|
109
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
147
|
requirements:
|
111
148
|
- - ">="
|
112
149
|
- !ruby/object:Gem::Version
|
113
150
|
version: '0'
|
114
151
|
requirements: []
|
115
|
-
|
116
|
-
rubygems_version: 2.5.2.1
|
152
|
+
rubygems_version: 3.0.4
|
117
153
|
signing_key:
|
118
154
|
specification_version: 4
|
119
155
|
summary: ''
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.2.3
|