activerecord_bulkoperation 0.0.3 → 0.0.4

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 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: ''