activerecord-oracle_enhanced-adapter 1.8.2 → 5.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +190 -5
  3. data/README.md +10 -10
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +2 -0
  6. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +9 -71
  7. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +84 -73
  8. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +12 -12
  9. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +52 -0
  10. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +35 -7
  11. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +2 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +59 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +379 -402
  14. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +7 -1
  15. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +46 -0
  16. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +242 -247
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +9 -1
  18. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +3 -1
  19. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +25 -9
  20. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +9 -6
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +10 -5
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +48 -51
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +261 -59
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +2 -34
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +267 -222
  26. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +33 -0
  27. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +2 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +136 -547
  29. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/boolean.rb +4 -2
  30. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/integer.rb +4 -2
  31. data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
  32. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/national_character_string.rb +5 -3
  33. data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
  34. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/raw.rb +4 -2
  35. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/string.rb +4 -2
  36. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/text.rb +4 -2
  37. data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
  38. data/lib/active_record/{oracle_enhanced/type → type/oracle_enhanced}/timestamptz.rb +4 -2
  39. data/lib/activerecord-oracle_enhanced-adapter.rb +2 -6
  40. data/spec/active_record/connection_adapters/{oracle_enhanced_emulate_oracle_adapter_spec.rb → emulation/oracle_adapter_spec.rb} +2 -0
  41. data/spec/active_record/connection_adapters/{oracle_enhanced_connection_spec.rb → oracle_enhanced/connection_spec.rb} +82 -38
  42. data/spec/active_record/connection_adapters/{oracle_enhanced_context_index_spec.rb → oracle_enhanced/context_index_spec.rb} +20 -16
  43. data/spec/active_record/connection_adapters/{oracle_enhanced_database_tasks_spec.rb → oracle_enhanced/database_tasks_spec.rb} +17 -5
  44. data/spec/active_record/connection_adapters/{oracle_enhanced_dbms_output_spec.rb → oracle_enhanced/dbms_output_spec.rb} +2 -0
  45. data/spec/active_record/connection_adapters/{oracle_enhanced_procedures_spec.rb → oracle_enhanced/procedures_spec.rb} +26 -33
  46. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +196 -0
  47. data/spec/active_record/connection_adapters/{oracle_enhanced_schema_dump_spec.rb → oracle_enhanced/schema_dumper_spec.rb} +61 -90
  48. data/spec/active_record/connection_adapters/{oracle_enhanced_schema_statements_spec.rb → oracle_enhanced/schema_statements_spec.rb} +95 -28
  49. data/spec/active_record/connection_adapters/{oracle_enhanced_structure_dump_spec.rb → oracle_enhanced/structure_dump_spec.rb} +48 -2
  50. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +202 -331
  51. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +15 -1106
  52. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  53. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +207 -0
  54. data/spec/active_record/{connection_adapters/oracle_enhanced_dirty_spec.rb → oracle_enhanced/type/dirty_spec.rb} +3 -1
  55. data/spec/active_record/oracle_enhanced/type/float_spec.rb +48 -0
  56. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +91 -0
  57. data/spec/active_record/oracle_enhanced/type/json_spec.rb +57 -0
  58. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +55 -0
  59. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +230 -0
  60. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +122 -0
  61. data/spec/active_record/oracle_enhanced/type/text_spec.rb +229 -0
  62. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +75 -0
  63. data/spec/spec_helper.rb +15 -1
  64. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  65. metadata +63 -48
  66. data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +0 -28
  67. data/lib/active_record/oracle_enhanced/type/json.rb +0 -8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module OracleEnhanced
@@ -8,10 +10,14 @@ module ActiveRecord
8
10
  blob = Java::OracleSql::BLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::BLOB::DURATION_SESSION)
9
11
  blob.setBytes(1, value.to_s.to_java_bytes)
10
12
  blob
11
- when ActiveRecord::OracleEnhanced::Type::Text::Data
13
+ when Type::OracleEnhanced::Text::Data
12
14
  clob = Java::OracleSql::CLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
13
15
  clob.setString(1, value.to_s)
14
16
  clob
17
+ when Type::OracleEnhanced::NationalCharacterText::Data
18
+ clob = Java::OracleSql::NCLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::NCLOB::DURATION_SESSION)
19
+ clob.setString(1, value.to_s)
20
+ clob
15
21
  else
16
22
  super
17
23
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord #:nodoc:
4
+ module ConnectionAdapters #:nodoc:
5
+ module OracleEnhanced #:nodoc:
6
+ module Lob #:nodoc:
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ class_attribute :custom_create_method, :custom_update_method, :custom_delete_method
11
+
12
+ # After setting large objects to empty, select the OCI8::LOB
13
+ # and write back the data.
14
+ before_update :record_changed_lobs
15
+ after_update :enhanced_write_lobs
16
+ end
17
+
18
+ module ClassMethods
19
+ def lob_columns
20
+ columns.select do |column|
21
+ column.sql_type_metadata.sql_type =~ /LOB$/
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def enhanced_write_lobs
29
+ if self.class.connection.is_a?(ConnectionAdapters::OracleEnhancedAdapter) &&
30
+ !(self.class.custom_create_method || self.class.custom_update_method)
31
+ self.class.connection.write_lobs(self.class.table_name, self.class, attributes, @changed_lob_columns)
32
+ end
33
+ end
34
+ def record_changed_lobs
35
+ @changed_lob_columns = self.class.lob_columns.select do |col|
36
+ self.will_save_change_to_attribute?(col.name) && !self.class.readonly_attributes.to_a.include?(col.name)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ ActiveSupport.on_load(:active_record) do
45
+ ActiveRecord::Base.send(:include, ActiveRecord::ConnectionAdapters::OracleEnhanced::Lob)
46
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "delegate"
2
4
 
3
5
  begin
@@ -10,258 +12,245 @@ rescue LoadError => e
10
12
  end
11
13
 
12
14
  # check ruby-oci8 version
13
- required_oci8_version = [2, 2, 0]
15
+ required_oci8_version = [2, 2, 4]
14
16
  oci8_version_ints = OCI8::VERSION.scan(/\d+/).map { |s| s.to_i }
15
17
  if (oci8_version_ints <=> required_oci8_version) < 0
16
- raise LoadError, "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
18
+ $stderr.puts <<-EOS.strip_heredoc
19
+ "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
20
+ EOS
21
+
22
+ exit!
17
23
  end
18
24
 
19
25
  module ActiveRecord
20
26
  module ConnectionAdapters
21
27
  # OCI database interface for MRI
22
- class OracleEnhancedOCIConnection < OracleEnhancedConnection #:nodoc:
23
- def initialize(config)
24
- @raw_connection = OCI8EnhancedAutoRecover.new(config, OracleEnhancedOCIFactory)
25
- # default schema owner
26
- @owner = config[:schema]
27
- @owner ||= config[:username]
28
- @owner = @owner.to_s.upcase
29
- end
30
-
31
- def raw_oci_connection
32
- if @raw_connection.is_a? OCI8
33
- @raw_connection
34
- # ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
35
- # in this case we need to pass original OCI8 connection
36
- else
37
- @raw_connection.instance_variable_get(:@connection)
28
+ module OracleEnhanced
29
+ class OCIConnection < OracleEnhanced::Connection #:nodoc:
30
+ def initialize(config)
31
+ @raw_connection = OCI8EnhancedAutoRecover.new(config, OracleEnhancedOCIFactory)
32
+ # default schema owner
33
+ @owner = config[:schema]
34
+ @owner ||= config[:username]
35
+ @owner = @owner.to_s.upcase
38
36
  end
39
- end
40
37
 
41
- def auto_retry
42
- @raw_connection.auto_retry if @raw_connection
43
- end
38
+ def raw_oci_connection
39
+ if @raw_connection.is_a? OCI8
40
+ @raw_connection
41
+ # ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
42
+ # in this case we need to pass original OCI8 connection
43
+ else
44
+ @raw_connection.instance_variable_get(:@connection)
45
+ end
46
+ end
44
47
 
45
- def auto_retry=(value)
46
- @raw_connection.auto_retry = value if @raw_connection
47
- end
48
+ def auto_retry
49
+ @raw_connection.auto_retry if @raw_connection
50
+ end
48
51
 
49
- def logoff
50
- @raw_connection.logoff
51
- @raw_connection.active = false
52
- end
52
+ def auto_retry=(value)
53
+ @raw_connection.auto_retry = value if @raw_connection
54
+ end
53
55
 
54
- def commit
55
- @raw_connection.commit
56
- end
56
+ def logoff
57
+ @raw_connection.logoff
58
+ @raw_connection.active = false
59
+ end
57
60
 
58
- def rollback
59
- @raw_connection.rollback
60
- end
61
+ def commit
62
+ @raw_connection.commit
63
+ end
61
64
 
62
- def autocommit?
63
- @raw_connection.autocommit?
64
- end
65
+ def rollback
66
+ @raw_connection.rollback
67
+ end
65
68
 
66
- def autocommit=(value)
67
- @raw_connection.autocommit = value
68
- end
69
+ def autocommit?
70
+ @raw_connection.autocommit?
71
+ end
69
72
 
70
- # Checks connection, returns true if active. Note that ping actively
71
- # checks the connection, while #active? simply returns the last
72
- # known state.
73
- def ping
74
- @raw_connection.ping
75
- rescue OCIException => e
76
- raise OracleEnhancedConnectionException, e.message
77
- end
73
+ def autocommit=(value)
74
+ @raw_connection.autocommit = value
75
+ end
78
76
 
79
- def active?
80
- @raw_connection.active?
81
- end
77
+ # Checks connection, returns true if active. Note that ping actively
78
+ # checks the connection, while #active? simply returns the last
79
+ # known state.
80
+ def ping
81
+ @raw_connection.ping
82
+ rescue OCIException => e
83
+ raise OracleEnhanced::ConnectionException, e.message
84
+ end
82
85
 
83
- def reset!
84
- @raw_connection.reset!
85
- rescue OCIException => e
86
- raise OracleEnhancedConnectionException, e.message
87
- end
86
+ def active?
87
+ @raw_connection.active?
88
+ end
88
89
 
89
- def exec(sql, *bindvars, &block)
90
- @raw_connection.exec(sql, *bindvars, &block)
91
- end
90
+ def reset!
91
+ @raw_connection.reset!
92
+ rescue OCIException => e
93
+ raise OracleEnhanced::ConnectionException, e.message
94
+ end
92
95
 
93
- def returning_clause(quoted_pk)
94
- " RETURNING #{quoted_pk} INTO :insert_id"
95
- end
96
+ def exec(sql, *bindvars, &block)
97
+ @raw_connection.exec(sql, *bindvars, &block)
98
+ end
96
99
 
97
- # execute sql with RETURNING ... INTO :insert_id
98
- # and return :insert_id value
99
- def exec_with_returning(sql)
100
- cursor = @raw_connection.parse(sql)
101
- cursor.bind_param(":insert_id", nil, Integer)
102
- cursor.exec
103
- cursor[":insert_id"]
104
- ensure
105
- cursor.close rescue nil
106
- end
100
+ def prepare(sql)
101
+ Cursor.new(self, @raw_connection.parse(sql))
102
+ end
107
103
 
108
- def prepare(sql)
109
- Cursor.new(self, @raw_connection.parse(sql))
110
- end
104
+ class Cursor
105
+ def initialize(connection, raw_cursor)
106
+ @connection = connection
107
+ @raw_cursor = raw_cursor
108
+ end
111
109
 
112
- class Cursor
113
- def initialize(connection, raw_cursor)
114
- @connection = connection
115
- @raw_cursor = raw_cursor
116
- end
110
+ def bind_params(*bind_vars)
111
+ index = 1
112
+ bind_vars.flatten.each do |var|
113
+ if Hash === var
114
+ var.each { |key, val| bind_param key, val }
115
+ else
116
+ bind_param index, var
117
+ index += 1
118
+ end
119
+ end
120
+ end
117
121
 
118
- def bind_params(*bind_vars)
119
- index = 1
120
- bind_vars.flatten.each do |var|
121
- if Hash === var
122
- var.each { |key, val| bind_param key, val }
122
+ def bind_param(position, value)
123
+ case value
124
+ when Type::OracleEnhanced::Raw
125
+ @raw_cursor.bind_param(position, OracleEnhanced::Quoting.encode_raw(value))
126
+ when ActiveModel::Type::Decimal
127
+ @raw_cursor.bind_param(position, BigDecimal.new(value.to_s))
128
+ when NilClass
129
+ @raw_cursor.bind_param(position, nil, String)
123
130
  else
124
- bind_param index, var
125
- index += 1
131
+ @raw_cursor.bind_param(position, value)
126
132
  end
127
133
  end
128
- end
129
134
 
130
- def bind_param(position, value)
131
- case value
132
- when ActiveRecord::OracleEnhanced::Type::Raw
133
- @raw_cursor.bind_param(position, ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.encode_raw(value))
134
- when ActiveModel::Type::Decimal
135
- @raw_cursor.bind_param(position, BigDecimal.new(value.to_s))
136
- when NilClass
137
- @raw_cursor.bind_param(position, nil, String)
138
- else
139
- @raw_cursor.bind_param(position, value)
135
+ def bind_returning_param(position, bind_type)
136
+ @raw_cursor.bind_param(position, nil, bind_type)
140
137
  end
141
- end
142
-
143
- def bind_returning_param(position, bind_type)
144
- @raw_cursor.bind_param(position, nil, bind_type)
145
- end
146
138
 
147
- def exec
148
- @raw_cursor.exec
149
- end
139
+ def exec
140
+ @raw_cursor.exec
141
+ end
150
142
 
151
- def exec_update
152
- @raw_cursor.exec
153
- end
143
+ def exec_update
144
+ @raw_cursor.exec
145
+ end
154
146
 
155
- def get_col_names
156
- @raw_cursor.get_col_names
157
- end
147
+ def get_col_names
148
+ @raw_cursor.get_col_names
149
+ end
158
150
 
159
- def fetch(options = {})
160
- if row = @raw_cursor.fetch
161
- get_lob_value = options[:get_lob_value]
162
- row.map do |col|
163
- @connection.typecast_result_value(col, get_lob_value)
151
+ def fetch(options = {})
152
+ if row = @raw_cursor.fetch
153
+ get_lob_value = options[:get_lob_value]
154
+ row.map do |col|
155
+ @connection.typecast_result_value(col, get_lob_value)
156
+ end
164
157
  end
165
158
  end
166
- end
167
159
 
168
- def get_returning_param(position, type)
169
- @raw_cursor[position]
170
- end
160
+ def get_returning_param(position, type)
161
+ @raw_cursor[position]
162
+ end
171
163
 
172
- def close
173
- @raw_cursor.close
164
+ def close
165
+ @raw_cursor.close
166
+ end
174
167
  end
175
- end
176
168
 
177
- def select(sql, name = nil, return_column_names = false)
178
- cursor = @raw_connection.exec(sql)
179
- cols = []
180
- # Ignore raw_rnum_ which is used to simulate LIMIT and OFFSET
181
- cursor.get_col_names.each do |col_name|
182
- col_name = oracle_downcase(col_name)
183
- cols << col_name unless col_name == "raw_rnum_"
184
- end
185
- # Reuse the same hash for all rows
186
- column_hash = {}
187
- cols.each { |c| column_hash[c] = nil }
188
- rows = []
189
- get_lob_value = !(name == "Writable Large Object")
169
+ def select(sql, name = nil, return_column_names = false)
170
+ cursor = @raw_connection.exec(sql)
171
+ cols = []
172
+ # Ignore raw_rnum_ which is used to simulate LIMIT and OFFSET
173
+ cursor.get_col_names.each do |col_name|
174
+ col_name = _oracle_downcase(col_name)
175
+ cols << col_name unless col_name == "raw_rnum_"
176
+ end
177
+ # Reuse the same hash for all rows
178
+ column_hash = {}
179
+ cols.each { |c| column_hash[c] = nil }
180
+ rows = []
181
+ get_lob_value = !(name == "Writable Large Object")
182
+
183
+ while row = cursor.fetch
184
+ hash = column_hash.dup
190
185
 
191
- while row = cursor.fetch
192
- hash = column_hash.dup
186
+ cols.each_with_index do |col, i|
187
+ hash[col] = typecast_result_value(row[i], get_lob_value)
188
+ end
193
189
 
194
- cols.each_with_index do |col, i|
195
- hash[col] = typecast_result_value(row[i], get_lob_value)
190
+ rows << hash
196
191
  end
197
192
 
198
- rows << hash
193
+ return_column_names ? [rows, cols] : rows
194
+ ensure
195
+ cursor.close if cursor
199
196
  end
200
197
 
201
- return_column_names ? [rows, cols] : rows
202
- ensure
203
- cursor.close if cursor
204
- end
205
-
206
- def write_lob(lob, value, is_binary = false)
207
- lob.write value
208
- end
198
+ def write_lob(lob, value, is_binary = false)
199
+ lob.write value
200
+ end
209
201
 
210
- def describe(name)
211
- # fall back to SELECT based describe if using database link
212
- return super if name.to_s.include?("@")
213
- quoted_name = ActiveRecord::ConnectionAdapters::OracleEnhanced::Quoting.valid_table_name?(name) ? name : "\"#{name}\""
214
- @raw_connection.describe(quoted_name)
215
- rescue OCIException => e
216
- if e.code == 4043
217
- raise OracleEnhancedConnectionException, %Q{"DESC #{name}" failed; does it exist?}
218
- else
219
- # fall back to SELECT which can handle synonyms to database links
220
- super
202
+ def describe(name)
203
+ # fall back to SELECT based describe if using database link
204
+ return super if name.to_s.include?("@")
205
+ quoted_name = OracleEnhanced::Quoting.valid_table_name?(name) ? name : "\"#{name}\""
206
+ @raw_connection.describe(quoted_name)
207
+ rescue OCIException => e
208
+ if e.code == 4043
209
+ raise OracleEnhanced::ConnectionException, %Q{"DESC #{name}" failed; does it exist?}
210
+ else
211
+ # fall back to SELECT which can handle synonyms to database links
212
+ super
213
+ end
221
214
  end
222
- end
223
215
 
224
- # Return OCIError error code
225
- def error_code(exception)
226
- case exception
227
- when OCIError
228
- exception.code
229
- else
230
- nil
216
+ # Return OCIError error code
217
+ def error_code(exception)
218
+ case exception
219
+ when OCIError
220
+ exception.code
221
+ else
222
+ nil
223
+ end
231
224
  end
232
- end
233
225
 
234
- def typecast_result_value(value, get_lob_value)
235
- case value
236
- when Integer
237
- value
238
- when String
239
- value
240
- when Float, BigDecimal
241
- # return Integer if value is integer (to avoid issues with _before_type_cast values for id attributes)
242
- value == (v_to_i = value.to_i) ? v_to_i : value
243
- when OraNumber
244
- # change OraNumber value (returned in early versions of ruby-oci8 2.0.x) to BigDecimal
245
- value == (v_to_i = value.to_i) ? v_to_i : BigDecimal.new(value.to_s)
246
- when OCI8::LOB
247
- if get_lob_value
248
- data = value.read || "" # if value.read returns nil, then we have an empty_clob() i.e. an empty string
249
- # In Ruby 1.9.1 always change encoding to ASCII-8BIT for binaries
250
- data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding) && value.is_a?(OCI8::BLOB)
251
- data
226
+ def typecast_result_value(value, get_lob_value)
227
+ case value
228
+ when Integer
229
+ value
230
+ when String
231
+ value
232
+ when Float, BigDecimal
233
+ # return Integer if value is integer (to avoid issues with _before_type_cast values for id attributes)
234
+ value == (v_to_i = value.to_i) ? v_to_i : value
235
+ when OCI8::LOB
236
+ if get_lob_value
237
+ data = value.read || "" # if value.read returns nil, then we have an empty_clob() i.e. an empty string
238
+ # In Ruby 1.9.1 always change encoding to ASCII-8BIT for binaries
239
+ data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding) && value.is_a?(OCI8::BLOB)
240
+ data
241
+ else
242
+ value
243
+ end
244
+ when Time, DateTime
245
+ create_time_with_default_timezone(value)
252
246
  else
253
247
  value
254
248
  end
255
- when Time, DateTime
256
- create_time_with_default_timezone(value)
257
- else
258
- value
259
249
  end
260
- end
261
250
 
262
- def database_version
263
- @database_version ||= (version = raw_connection.oracle_server_version) && [version.major, version.minor]
264
- end
251
+ def database_version
252
+ @database_version ||= (version = raw_connection.oracle_server_version) && [version.major, version.minor]
253
+ end
265
254
 
266
255
  private
267
256
 
@@ -291,60 +280,66 @@ module ActiveRecord
291
280
  ::DateTime.civil(year, month, day, hour, min, sec, offset)
292
281
  end
293
282
  end
294
- end
283
+ end
295
284
 
296
- # The OracleEnhancedOCIFactory factors out the code necessary to connect and
297
- # configure an Oracle/OCI connection.
298
- class OracleEnhancedOCIFactory #:nodoc:
299
- def self.new_connection(config)
300
- # to_s needed if username, password or database is specified as number in database.yml file
301
- username = config[:username] && config[:username].to_s
302
- password = config[:password] && config[:password].to_s
303
- database = config[:database] && config[:database].to_s
304
- schema = config[:schema] && config[:schema].to_s
305
- host, port = config[:host], config[:port]
306
- privilege = config[:privilege] && config[:privilege].to_sym
307
- async = config[:allow_concurrency]
308
- prefetch_rows = config[:prefetch_rows] || 100
309
- cursor_sharing = config[:cursor_sharing] || "force"
310
- # get session time_zone from configuration or from TZ environment variable
311
- time_zone = config[:time_zone] || ENV["TZ"]
312
-
313
- # using a connection string via DATABASE_URL
314
- connection_string = if host == "connection-string"
315
- database
316
- # connection using host, port and database name
317
- elsif host || port
318
- host ||= "localhost"
319
- host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
320
- port ||= 1521
321
- database = "/#{database}" unless database.match(/^\//)
322
- "//#{host}:#{port}#{database}"
323
- # if no host is specified then assume that
324
- # database parameter is TNS alias or TNS connection string
325
- else
326
- database
327
- end
328
- conn = OCI8.new username, password, connection_string, privilege
329
- conn.autocommit = true
330
- conn.non_blocking = true if async
331
- conn.prefetch_rows = prefetch_rows
332
- conn.exec "alter session set cursor_sharing = #{cursor_sharing}" rescue nil
333
- if ActiveRecord::Base.default_timezone == :local
334
- conn.exec "alter session set time_zone = '#{time_zone}'" unless time_zone.blank?
335
- elsif ActiveRecord::Base.default_timezone == :utc
336
- conn.exec "alter session set time_zone = '+00:00'"
337
- end
338
- conn.exec "alter session set current_schema = #{schema}" unless schema.blank?
285
+ # The OracleEnhancedOCIFactory factors out the code necessary to connect and
286
+ # configure an Oracle/OCI connection.
287
+ class OracleEnhancedOCIFactory #:nodoc:
288
+ def self.new_connection(config)
289
+ # to_s needed if username, password or database is specified as number in database.yml file
290
+ username = config[:username] && config[:username].to_s
291
+ password = config[:password] && config[:password].to_s
292
+ database = config[:database] && config[:database].to_s
293
+ schema = config[:schema] && config[:schema].to_s
294
+ host, port = config[:host], config[:port]
295
+ privilege = config[:privilege] && config[:privilege].to_sym
296
+ async = config[:allow_concurrency]
297
+ prefetch_rows = config[:prefetch_rows] || 100
298
+ cursor_sharing = config[:cursor_sharing]
299
+ # get session time_zone from configuration or from TZ environment variable
300
+ time_zone = config[:time_zone] || ENV["TZ"]
301
+
302
+ # using a connection string via DATABASE_URL
303
+ connection_string = if host == "connection-string"
304
+ database
305
+ # connection using host, port and database name
306
+ elsif host || port
307
+ host ||= "localhost"
308
+ host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
309
+ port ||= 1521
310
+ database = "/#{database}" unless database.match(/^\//)
311
+ "//#{host}:#{port}#{database}"
312
+ # if no host is specified then assume that
313
+ # database parameter is TNS alias or TNS connection string
314
+ else
315
+ database
316
+ end
317
+ OCI8.properties[:tcp_keepalive] = true
318
+ begin
319
+ OCI8.properties[:tcp_keepalive_time] = 600
320
+ rescue NotImplementedError
321
+ end
322
+ conn = OCI8.new username, password, connection_string, privilege
323
+ conn.autocommit = true
324
+ conn.non_blocking = true if async
325
+ conn.prefetch_rows = prefetch_rows
326
+ conn.exec "alter session set cursor_sharing = #{cursor_sharing}" rescue nil if cursor_sharing
327
+ if ActiveRecord::Base.default_timezone == :local
328
+ conn.exec "alter session set time_zone = '#{time_zone}'" unless time_zone.blank?
329
+ elsif ActiveRecord::Base.default_timezone == :utc
330
+ conn.exec "alter session set time_zone = '+00:00'"
331
+ end
332
+ conn.exec "alter session set current_schema = #{schema}" unless schema.blank?
339
333
 
340
- # Initialize NLS parameters
341
- OracleEnhancedAdapter::DEFAULT_NLS_PARAMETERS.each do |key, default_value|
342
- value = config[key] || ENV[key.to_s.upcase] || default_value
343
- if value
344
- conn.exec "alter session set #{key} = '#{value}'"
334
+ # Initialize NLS parameters
335
+ OracleEnhancedAdapter::DEFAULT_NLS_PARAMETERS.each do |key, default_value|
336
+ value = config[key] || ENV[key.to_s.upcase] || default_value
337
+ if value
338
+ conn.exec "alter session set #{key} = '#{value}'"
339
+ end
345
340
  end
341
+ conn
346
342
  end
347
- conn
348
343
  end
349
344
  end
350
345
  end