activerecord_bulkoperation 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 16b6f4dcc796822bf9f70be61cee8aef893a8d5b
4
- data.tar.gz: 630df700c5c08a83135f2a09259fd72727f67ad0
2
+ SHA256:
3
+ metadata.gz: 8e7fa80792d9dbf81a8bf8225784e00ba349ac447a4fa4fd3f8fa3f36526318a
4
+ data.tar.gz: 305ed3af749bbd57818e540a3c53e5a9f537096665d74102e54f9c85f765ea4b
5
5
  SHA512:
6
- metadata.gz: bd8cfc6f348ad5ef658a7fd9c776c88d8601cd9ad1833e50b82058ccbb41b68759f866dd1c14905714b3dbecebeacbccd0c1da354afcfbbbb0a6b39478a7a68d
7
- data.tar.gz: f99d1aba3e113a7100c502176322af7a8899060628024976c9fc9f1733cb72b38064a851dbe9a19d06bf03211394094161e417485bed5e826c53ddac368f713d
6
+ metadata.gz: a03cd834a7fb83f0ee6bcd14787fb9de4230f70e7479bc611bec79cf2c9b456e1dd0608ec4b4b286f98372823ab37a33fe269102781a0031fcd374e7289fb8d7
7
+ data.tar.gz: 6195763a68be42ef7ab69f241d10b47a0b8cc2714c0f2ec95cab0df0dcbcca2acf8de9660e50d4c31c0e19594520c8ab4de2545727bed8ce7f1eda4b91bf106e
@@ -21,10 +21,44 @@ module ActiveRecord
21
21
  end
22
22
 
23
23
  oci_conn = connection.raw_connection if connected?
24
- fail 'Unable to access the raw OCI connection.' unless oci_conn
24
+ fail 'Unable to access the raw OCI connection.' unless oci_conn
25
25
  cursor = oci_conn.parse(sql)
26
26
  fail "Unable to obtain cursor for this statement:\n#{sql}." unless cursor
27
27
 
28
+ if check_date_homogeneously(types, values)
29
+ affected_rows = execute_batch_update_array(cursor, sql, types, values, optimistic)
30
+ else
31
+ affected_rows = execute_batch_update_single(cursor, sql, types, values, optimistic)
32
+ end
33
+
34
+ affected_rows
35
+ end
36
+
37
+ private
38
+
39
+ # checks if all date values in one column of a row are of the same date type (Date/DateTime)
40
+ def check_date_homogeneously(types, rows)
41
+ types.each_with_index do |type, i|
42
+ if type == :date
43
+ common_type = nil
44
+ rows.each do |row|
45
+ type = get_date_type(row[i])
46
+
47
+ if common_type.nil?
48
+ common_type = type
49
+ elsif common_type != type
50
+ return false
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ return true
57
+ end
58
+
59
+ # execute batch update by single statement execution.
60
+ # slower than array statement execution, only used when date values in a column have inhomogeneous date types
61
+ def execute_batch_update_single(cursor, sql, types, values, optimistic)
28
62
  affected_rows = 0
29
63
 
30
64
  begin
@@ -63,44 +97,105 @@ module ActiveRecord
63
97
  affected_rows
64
98
  end
65
99
 
66
- private
100
+ # execute batch update by array statement execution.
101
+ # faster than single statement execution, can only be used when all date values
102
+ # in a column have homogeneous date types
103
+ def execute_batch_update_array(cursor, sql, types, values, optimistic)
104
+ affected_rows = 0
105
+
106
+ begin
107
+ values_columnwise = convert_rows_to_columns(values, types.size)
108
+
109
+ cursor.max_array_size = values.size
110
+
111
+ (0..types.size - 1).each do |i|
112
+ bind_column(cursor, i + 1, types[i], values_columnwise[i])
113
+ end
114
+
115
+ result = cursor.exec_array
116
+
117
+ fail ExternalDataChange.new(sql) if result != values.count and optimistic
118
+
119
+ affected_rows += result
120
+
121
+ connection.send(:log, sql, 'Update') {}
122
+ ensure
123
+ cursor.close
124
+ end
67
125
 
68
- def get_value(value)
69
- if(value.respond_to? :value)
126
+ affected_rows
127
+ end
128
+
129
+ def convert_rows_to_columns(values_rowise, count)
130
+ values_columnwise = []
131
+ (0..count-1).each do |i|
132
+ column = []
133
+ values_rowise.each do |row|
134
+ column << get_value(row[i])
135
+ end
136
+ values_columnwise << column
137
+ end
138
+ values_columnwise
139
+ end
140
+
141
+ def get_value(value)
142
+ if(value.respond_to? :value)
70
143
  value.value
71
- else
144
+ else
72
145
  value
73
146
  end
74
147
  end
75
148
 
76
- def bind(cursor, index, type, input_value)
77
- value = get_value(input_value)
149
+ def bind(cursor, index, type, input_value)
150
+ value = get_value(input_value)
78
151
  if type == :string
79
152
  cursor.bind_param(":#{index}", value, String)
80
153
 
81
- elsif type == :integer
154
+ elsif type == :integer
82
155
  cursor.bind_param(":#{index}", value, Fixnum)
83
156
 
84
157
  elsif type == :float
85
158
  cursor.bind_param(":#{index}", value, Float)
86
159
 
87
160
  elsif type == :date
88
- if value.nil?
89
- cursor.bind_param(":#{index}", nil, Date)
90
- else
91
- if ( value.kind_of?(DateTime) or value.kind_of?(Time)) and value.hour == 0 and value.min == 0 and value.sec == 0
92
- cursor.bind_param(":#{index}", value, Date)
93
- else
94
- cursor.bind_param(":#{index}", value, DateTime)
95
- end
96
- end
161
+ cursor.bind_param(":#{index}", value, get_date_type(value))
97
162
 
98
163
  else
99
164
 
100
165
  fail ArgumentError.new("unsupported type #{type}")
101
166
  end
102
167
  end
168
+
169
+ def bind_column(cursor, index, type, column)
170
+ if type == :string
171
+ cursor.bind_param_array(":#{index}", column, String)
172
+
173
+ elsif type == :integer
174
+ cursor.bind_param_array(":#{index}", column, Fixnum)
175
+
176
+ elsif type == :float
177
+ cursor.bind_param_array(":#{index}", column, Float)
178
+
179
+ elsif type == :date
180
+ cursor.bind_param_array(":#{index}", column, get_date_type(column[0]))
181
+
182
+ else
183
+
184
+ fail ArgumentError.new("unsupported type #{type}")
185
+ end
186
+ end
187
+
188
+ def get_date_type(value)
189
+ return Date if value.nil?
190
+
191
+ if ( value.kind_of?(DateTime) or value.kind_of?(Time)) and value.hour == 0 and value.min == 0 and value.sec == 0
192
+ return Date
193
+ else
194
+ return DateTime
195
+ end
196
+ end
197
+
103
198
  end
104
199
  end
105
- end
200
+ end
106
201
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Bulkoperation
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord_bulkoperation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - OSP
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-24 00:00:00.000000000 Z
11
+ date: 2019-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -112,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  version: '0'
113
113
  requirements: []
114
114
  rubyforge_project:
115
- rubygems_version: 2.6.1
115
+ rubygems_version: 2.7.6.2
116
116
  signing_key:
117
117
  specification_version: 4
118
118
  summary: ''