activerecord-oracle_enhanced-adapter 1.4.3 → 5.2.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.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +1162 -2
  3. data/README.md +567 -155
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +3 -1
  6. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +19 -0
  7. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +132 -0
  8. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +345 -0
  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 +280 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +64 -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 +538 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +38 -0
  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 +435 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +44 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +196 -0
  19. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +164 -0
  20. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +95 -0
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +79 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +194 -0
  23. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +709 -0
  24. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +28 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +353 -0
  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 +3 -0
  28. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +385 -1083
  29. data/lib/active_record/type/oracle_enhanced/boolean.rb +20 -0
  30. data/lib/active_record/type/oracle_enhanced/integer.rb +15 -0
  31. data/lib/active_record/type/oracle_enhanced/json.rb +10 -0
  32. data/lib/active_record/type/oracle_enhanced/national_character_string.rb +26 -0
  33. data/lib/active_record/type/oracle_enhanced/national_character_text.rb +36 -0
  34. data/lib/active_record/type/oracle_enhanced/raw.rb +25 -0
  35. data/lib/active_record/type/oracle_enhanced/string.rb +29 -0
  36. data/lib/active_record/type/oracle_enhanced/text.rb +32 -0
  37. data/lib/active_record/type/oracle_enhanced/timestampltz.rb +25 -0
  38. data/lib/active_record/type/oracle_enhanced/timestamptz.rb +25 -0
  39. data/lib/activerecord-oracle_enhanced-adapter.rb +5 -13
  40. data/spec/active_record/connection_adapters/{oracle_enhanced_emulate_oracle_adapter_spec.rb → emulation/oracle_adapter_spec.rb} +5 -4
  41. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +469 -0
  42. data/spec/active_record/connection_adapters/{oracle_enhanced_context_index_spec.rb → oracle_enhanced/context_index_spec.rb} +140 -128
  43. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +112 -0
  44. data/spec/active_record/connection_adapters/{oracle_enhanced_dbms_output_spec.rb → oracle_enhanced/dbms_output_spec.rb} +13 -13
  45. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +365 -0
  46. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +196 -0
  47. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +492 -0
  48. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +1433 -0
  49. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +478 -0
  50. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +385 -550
  51. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +92 -1249
  52. data/spec/active_record/oracle_enhanced/type/binary_spec.rb +119 -0
  53. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +208 -0
  54. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +139 -0
  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_config.yaml.template +11 -0
  64. data/spec/spec_helper.rb +100 -93
  65. data/spec/support/alter_system_set_open_cursors.sql +1 -0
  66. data/spec/support/alter_system_user_password.sql +2 -0
  67. data/spec/support/create_oracle_enhanced_users.sql +31 -0
  68. metadata +105 -152
  69. data/.rspec +0 -2
  70. data/Gemfile +0 -52
  71. data/RUNNING_TESTS.md +0 -45
  72. data/Rakefile +0 -59
  73. data/activerecord-oracle_enhanced-adapter.gemspec +0 -130
  74. data/lib/active_record/connection_adapters/oracle_enhanced.rake +0 -105
  75. data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +0 -41
  76. data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +0 -121
  77. data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +0 -151
  78. data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +0 -119
  79. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +0 -359
  80. data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +0 -25
  81. data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +0 -21
  82. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +0 -46
  83. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +0 -572
  84. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +0 -497
  85. data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +0 -260
  86. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +0 -227
  87. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +0 -260
  88. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +0 -428
  89. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +0 -258
  90. data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +0 -294
  91. data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +0 -17
  92. data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +0 -1
  93. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +0 -334
  94. data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +0 -19
  95. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +0 -113
  96. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +0 -141
  97. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +0 -378
  98. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +0 -440
  99. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +0 -1400
  100. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +0 -339
data/README.md CHANGED
@@ -6,26 +6,114 @@ Oracle enhanced adapter for ActiveRecord
6
6
  DESCRIPTION
7
7
  -----------
8
8
 
9
- Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby on Rails applications. Oracle enhanced adapter can be used from Ruby on Rails versions 2.3.x and 3.x and it is working with Oracle database versions 10g and 11g.
9
+ Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby on Rails applications. Oracle enhanced adapter can be used from Ruby on Rails versions between 2.3.x and 5.1 and it is working with Oracle database versions from 10g to 12c.
10
10
 
11
11
  INSTALLATION
12
12
  ------------
13
+ ### Rails 5.2
14
+
15
+ Oracle enhanced adapter version 5.2 supports Rails 5.2.
16
+ When using Ruby on Rails version 5.2 then in Gemfile include
17
+
18
+ ```ruby
19
+ # Use oracle as the database for Active Record
20
+ gem 'activerecord-oracle_enhanced-adapter', '~> 5.2.0'
21
+ gem 'ruby-oci8' # only for CRuby users
22
+ ```
23
+
24
+ ### Rails 5.1
25
+
26
+ Oracle enhanced adapter version 1.8 just supports Rails 5.1 and does not support Rails 5.0 or lower version of Rails.
27
+ When using Ruby on Rails version 5.1 then in Gemfile include
28
+
29
+ ```ruby
30
+ # Use oracle as the database for Active Record
31
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.8.0'
32
+ gem 'ruby-oci8' # only for CRuby users
33
+ ```
34
+
35
+ ### Rails 5.0
36
+
37
+ Oracle enhanced adapter version 1.7 just supports Rails 5.0 and does not support Rails 4.2 or lower version of Rails.
38
+ When using Ruby on Rails version 5.0 then in Gemfile include
39
+
40
+ ```ruby
41
+ # Use oracle as the database for Active Record
42
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.7.0'
43
+ gem 'ruby-oci8' # only for CRuby users
44
+ ```
45
+
46
+ ### Rails 4.2
47
+
48
+ Oracle enhanced adapter version 1.6 just supports Rails 4.2 and does not support Rails 4.1 or lower version of Rails.
49
+ When using Ruby on Rails version 4.2 then in Gemfile include
50
+
51
+ ```ruby
52
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0'
53
+ ```
54
+
55
+ where instead of 1.6.0 you can specify any other desired version. It is recommended to specify version with `~>` which means that use specified version or later patch versions (in this example any later 1.6.x version but not 1.7.x version). Oracle enhanced adapter maintains API backwards compatibility during patch version upgrades and therefore it is safe to always upgrade to latest patch version.
56
+
57
+ ### Rails 4.0 and 4.1
58
+
59
+ Oracle enhanced adapter version 1.5 supports Rails 4.0 and 4.1 and does not support Rails 3.2 or lower version of Rails.
60
+
61
+ When using Ruby on Rails version 4.0 and 4.1 then in Gemfile include
62
+
63
+ ```ruby
64
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.5.0'
65
+ ```
66
+
67
+ where instead of 1.5.0 you can specify any other desired version. It is recommended to specify version with `~>` which means that use specified version or later patch versions (in this example any later 1.5.x version but not 1.6.x version). Oracle enhanced adapter maintains API backwards compatibility during patch version upgrades and therefore it is safe to always upgrade to latest patch version.
68
+
69
+ If you would like to use latest adapter version from github then specify
70
+
71
+ ```ruby
72
+ gem 'activerecord-oracle_enhanced-adapter', :git => 'git://github.com/rsim/oracle-enhanced.git'
73
+ ```
74
+
75
+ If you are using CRuby >= 1.9.3 then you need to install ruby-oci8 gem as well as Oracle client, e.g. [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html). Include in Gemfile also ruby-oci8:
76
+
77
+ ```ruby
78
+ gem 'ruby-oci8', '~> 2.1.0'
79
+ ```
80
+
81
+ If you are using JRuby then you need to download latest [Oracle JDBC driver](http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html) - either ojdbc7.jar or ojdbc6.jar for Java 7, ojdbc6.jar for Java 6 or ojdbc5.jar for Java 5. And copy this file to one of these locations:
82
+
83
+ * in `./lib` directory of Rails application
84
+ * in some directory which is in `PATH`
85
+ * in `JRUBY_HOME/lib` directory
86
+ * or include path to JDBC driver jar file in Java `CLASSPATH`
87
+
88
+ After specifying necessary gems in Gemfile run
89
+
90
+ ```bash
91
+ bundle install
92
+ ```
93
+
94
+ to install the adapter (or later run `bundle update` to force updating to latest version).
13
95
 
14
96
  ### Rails 3
15
97
 
16
98
  When using Ruby on Rails version 3 then in Gemfile include
17
99
 
18
- gem 'activerecord-oracle_enhanced-adapter', '~> 1.4.0'
100
+ ```ruby
101
+ gem 'activerecord-oracle_enhanced-adapter', '~> 1.4.0'
102
+ ```
19
103
 
20
104
  where instead of 1.4.0 you can specify any other desired version. It is recommended to specify version with `~>` which means that use specified version or later patch versions (in this example any later 1.4.x version but not 1.5.x version). Oracle enhanced adapter maintains API backwards compatibility during patch version upgrades and therefore it is safe to always upgrade to latest patch version.
21
105
 
22
106
  If you would like to use latest adapter version from github then specify
23
107
 
24
- gem 'activerecord-oracle_enhanced-adapter', :git => 'git://github.com/rsim/oracle-enhanced.git'
108
+ ```ruby
109
+ gem 'activerecord-oracle_enhanced-adapter', :git => 'git://github.com/rsim/oracle-enhanced.git'
110
+ ```
25
111
 
26
112
  If you are using MRI 1.8 or 1.9 Ruby implementation then you need to install ruby-oci8 gem as well as Oracle client, e.g. [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html). Include in Gemfile also ruby-oci8:
27
113
 
28
- gem 'ruby-oci8', '~> 2.1.0'
114
+ ```ruby
115
+ gem 'ruby-oci8', '~> 2.1.0'
116
+ ```
29
117
 
30
118
  If you are using JRuby then you need to download latest [Oracle JDBC driver](http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html) - either ojdbc6.jar for Java 6 or ojdbc5.jar for Java 5. And copy this file to one of these locations:
31
119
 
@@ -36,7 +124,9 @@ If you are using JRuby then you need to download latest [Oracle JDBC driver](htt
36
124
 
37
125
  After specifying necessary gems in Gemfile run
38
126
 
39
- bundle install
127
+ ```bash
128
+ bundle install
129
+ ```
40
130
 
41
131
  to install the adapter (or later run `bundle update` to force updating to latest version).
42
132
 
@@ -44,12 +134,14 @@ to install the adapter (or later run `bundle update` to force updating to latest
44
134
 
45
135
  If you don't use Bundler in Rails 2 application then you need to specify gems in `config/environment.rb`, e.g.
46
136
 
47
- Rails::Initializer.run do |config|
48
- #...
49
- config.gem 'activerecord-oracle_enhanced-adapter', :lib => "active_record/connection_adapters/oracle_enhanced_adapter"
50
- config.gem 'ruby-oci8'
51
- #...
52
- end
137
+ ```ruby
138
+ Rails::Initializer.run do |config|
139
+ # ...
140
+ config.gem 'activerecord-oracle_enhanced-adapter', :lib => 'active_record/connection_adapters/oracle_enhanced_adapter'
141
+ config.gem 'ruby-oci8'
142
+ # ...
143
+ end
144
+ ```
53
145
 
54
146
  But it is recommended to use Bundler for gem version management also for Rails 2.3 applications (search for instructions in Google).
55
147
 
@@ -57,7 +149,9 @@ But it is recommended to use Bundler for gem version management also for Rails 2
57
149
 
58
150
  If you want to use ActiveRecord and Oracle enhanced adapter without Rails and Bundler then install it just as a gem:
59
151
 
60
- gem install activerecord-oracle_enhanced-adapter
152
+ ```bash
153
+ gem install activerecord-oracle_enhanced-adapter
154
+ ```
61
155
 
62
156
  USAGE
63
157
  -----
@@ -66,52 +160,81 @@ USAGE
66
160
 
67
161
  In Rails application `config/database.yml` use oracle_enhanced as adapter name, e.g.
68
162
 
69
- development:
70
- adapter: oracle_enhanced
71
- database: xe
72
- username: user
73
- password: secret
163
+ ```yml
164
+ development:
165
+ adapter: oracle_enhanced
166
+ database: xe
167
+ username: user
168
+ password: secret
169
+ ```
74
170
 
75
171
  If you're connecting to a service name, indicate the service with a
76
172
  leading slash on the database parameter:
77
173
 
78
- development:
79
- adapter: oracle_enhanced
80
- database: /xe
81
- username: user
82
- password: secret
174
+ ```yml
175
+ development:
176
+ adapter: oracle_enhanced
177
+ database: /xe
178
+ username: user
179
+ password: secret
180
+ ```
83
181
 
84
182
  If `TNS_ADMIN` environment variable is pointing to directory where `tnsnames.ora` file is located then you can use TNS connection name in `database` parameter. Otherwise you can directly specify database host, port (defaults to 1521) and database name in the following way:
85
183
 
86
- development:
87
- adapter: oracle_enhanced
88
- host: localhost
89
- port: 1521
90
- database: xe
91
- username: user
92
- password: secret
184
+ ```yml
185
+ development:
186
+ adapter: oracle_enhanced
187
+ host: localhost
188
+ port: 1521
189
+ database: xe
190
+ username: user
191
+ password: secret
192
+ ```
93
193
 
94
194
  or you can use Oracle specific format in `database` parameter:
95
195
 
96
- development:
97
- adapter: oracle_enhanced
98
- database: //localhost:1521/xe
99
- username: user
100
- password: secret
196
+ ```yml
197
+ development:
198
+ adapter: oracle_enhanced
199
+ database: //localhost:1521/xe
200
+ username: user
201
+ password: secret
202
+ ```
101
203
 
102
204
  or you can even use Oracle specific TNS connection description:
103
205
 
104
- development:
105
- adapter: oracle_enhanced
106
- database: "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=xe)))"
107
- username: user
108
- password: secret
206
+ ```yml
207
+ development:
208
+ adapter: oracle_enhanced
209
+ database: "(DESCRIPTION=
210
+ (ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))
211
+ (CONNECT_DATA=(SERVICE_NAME=xe))
212
+ )"
213
+ username: user
214
+ password: secret
215
+ ```
216
+
217
+
218
+ If you choose to specify your database connection via the `DATABASE_URL`
219
+ environment variable, note that the adapter name uses a dash instead of an underscore:
220
+
221
+ ```bash
222
+ DATABASE_URL=oracle-enhanced://localhost/XE
223
+ ```
224
+
225
+ You can also specify a connection string via the `DATABASE_URL`, as long as it doesn't have any whitespace:
226
+
227
+ ```bash
228
+ DATABASE_URL=oracle-enhanced://user:secret@connection-string/(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=xe)))
229
+ ```
109
230
 
110
231
  If you deploy JRuby on Rails application in Java application server that supports JNDI connections then you can specify JNDI connection as well:
111
232
 
112
- development:
113
- adapter: oracle_enhanced
114
- jndi: "jdbc/jndi_connection_name"
233
+ ```yml
234
+ development:
235
+ adapter: oracle_enhanced
236
+ jndi: "jdbc/jndi_connection_name"
237
+ ```
115
238
 
116
239
  To use jndi with Tomcat you need to set the accessToUnderlyingConnectionAllowed to true property on the pool. See the [Tomcat Documentation](http://tomcat.apache.org/tomcat-7.0-doc/jndi-resources-howto.html) for reference.
117
240
 
@@ -121,22 +244,25 @@ You can find other available database.yml connection parameters in [oracle_enhan
121
244
 
122
245
  If you want to change Oracle enhanced adapter default settings then create initializer file e.g. `config/initializers/oracle.rb` specify there necessary defaults, e.g.:
123
246
 
124
- # It is recommended to set time zone in TZ environment variable so that the same timezone will be used by Ruby and by Oracle session
125
- ENV['TZ'] = 'UTC'
126
-
127
- ActiveSupport.on_load(:active_record) do
128
- ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
129
- # id columns and columns which end with _id will always be converted to integers
130
- self.emulate_integers_by_column_name = true
131
- # DATE columns which include "date" in name will be converted to Date, otherwise to Time
132
- self.emulate_dates_by_column_name = true
133
- # true and false will be stored as 'Y' and 'N'
134
- self.emulate_booleans_from_strings = true
135
- # start primary key sequences from 1 (and not 10000) and take just one next value in each session
136
- self.default_sequence_start_value = "1 NOCACHE INCREMENT BY 1"
137
- # other settings ...
138
- end
139
- end
247
+ ```ruby
248
+ # It is recommended to set time zone in TZ environment variable so that the same timezone will be used by Ruby and by Oracle session
249
+ ENV['TZ'] = 'UTC'
250
+
251
+ ActiveSupport.on_load(:active_record) do
252
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
253
+ # true and false will be stored as 'Y' and 'N'
254
+ self.emulate_booleans_from_strings = true
255
+
256
+ # start primary key sequences from 1 (and not 10000) and take just one next value in each session
257
+ self.default_sequence_start_value = "1 NOCACHE INCREMENT BY 1"
258
+
259
+ # Use old visitor for Oracle 12c database
260
+ self.use_old_oracle_visitor = true
261
+
262
+ # other settings ...
263
+ end
264
+ end
265
+ ```
140
266
 
141
267
  In case of Rails 2 application you do not need to use `ActiveSupport.on_load(:active_record) do ... end` around settings code block.
142
268
 
@@ -146,57 +272,140 @@ See other adapter settings in [oracle_enhanced_adapter.rb](http://github.com/rsi
146
272
 
147
273
  If you want to put Oracle enhanced adapter on top of existing schema tables then there are several methods how to override ActiveRecord defaults, see example:
148
274
 
149
- class Employee < ActiveRecord::Base
150
- # specify schema and table name
151
- set_table_name "hr.hr_employees"
152
- # specify primary key name
153
- set_primary_key "employee_id"
154
- # specify sequence name
155
- set_sequence_name "hr.hr_employee_s"
156
- # set which DATE columns should be converted to Ruby Date
157
- set_date_columns :hired_on, :birth_date_on
158
- # set which DATE columns should be converted to Ruby Time
159
- set_datetime_columns :last_login_time
160
- # set which VARCHAR2 columns should be converted to true and false
161
- set_boolean_columns :manager, :active
162
- # set which columns should be ignored in ActiveRecord
163
- ignore_table_columns :attribute1, :attribute2
164
- end
275
+ ```ruby
276
+ class Employee < ActiveRecord::Base
277
+ # specify schema and table name
278
+ self.table_name = "hr.hr_employees"
279
+
280
+ # specify primary key name
281
+ self.primary_key = "employee_id"
282
+
283
+ # specify sequence name
284
+ self.sequence_name = "hr.hr_employee_s"
285
+
286
+ # set which DATE columns should be converted to Ruby Date using ActiveRecord Attribute API
287
+ # Starting from Oracle enhanced adapter 1.7 Oracle `DATE` columns are mapped to Ruby `Date` by default.
288
+ attribute :hired_on, :date
289
+ attribute :birth_date_on, :date
290
+
291
+ # set which DATE columns should be converted to Ruby Time using ActiveRecord Attribute API
292
+ attribute :last_login_time, :datetime
293
+
294
+ # set which VARCHAR2 columns should be converted to true and false using ActiveRecord Attribute API
295
+ attribute :manager, :boolean
296
+ attribute :active, :boolean
297
+
298
+ # set which columns should be ignored in ActiveRecord
299
+ ignore_table_columns :attribute1, :attribute2
300
+ end
301
+ ```
302
+
303
+ You can also access remote tables over database link using
304
+
305
+ ```ruby
306
+ self.table_name "hr_employees@db_link"
307
+ ```
308
+
309
+ Examples for Rails 4.x
310
+
311
+ ```ruby
312
+ class Employee < ActiveRecord::Base
313
+ # specify schema and table name
314
+ self.table_name = "hr.hr_employees"
315
+
316
+ # specify primary key name
317
+ self.primary_key = "employee_id"
318
+
319
+ # specify sequence name
320
+ self.sequence_name = "hr.hr_employee_s"
321
+
322
+ # If you're using Rails 4.2 or earlier you can do this
323
+
324
+ # set which DATE columns should be converted to Ruby Date
325
+ set_date_columns :hired_on, :birth_date_on
326
+
327
+ # set which DATE columns should be converted to Ruby Time
328
+ set_datetime_columns :last_login_time
329
+
330
+ # set which VARCHAR2 columns should be converted to true and false
331
+ set_boolean_columns :manager, :active
332
+
333
+ # set which columns should be ignored in ActiveRecord
334
+ ignore_table_columns :attribute1, :attribute2
335
+ end
336
+ ```
337
+
338
+ Examples for Rails 3.2 and lower version of Rails
339
+
340
+ ```ruby
341
+ class Employee < ActiveRecord::Base
342
+ # specify schema and table name
343
+ set_table_name "hr.hr_employees"
344
+
345
+ # specify primary key name
346
+ set_primary_key "employee_id"
347
+
348
+ # specify sequence name
349
+ set_sequence_name "hr.hr_employee_s"
350
+
351
+ # set which DATE columns should be converted to Ruby Date
352
+ set_date_columns :hired_on, :birth_date_on
353
+
354
+ # set which DATE columns should be converted to Ruby Time
355
+ set_datetime_columns :last_login_time
356
+
357
+ # set which VARCHAR2 columns should be converted to true and false
358
+ set_boolean_columns :manager, :active
359
+
360
+ # set which columns should be ignored in ActiveRecord
361
+ ignore_table_columns :attribute1, :attribute2
362
+ end
363
+ ```
165
364
 
166
365
  You can also access remote tables over database link using
167
366
 
168
- set_table_name "hr_employees@db_link"
367
+ ```ruby
368
+ set_table_name "hr_employees@db_link"
369
+ ```
169
370
 
170
371
  ### Custom create, update and delete methods
171
372
 
172
- If you have legacy schema and you are not allowed to do direct INSERTs, UPDATEs and DELETEs in legacy schema tables and need to use existing PL/SQL procedures for create, updated, delete operations then you should add `ruby-plsql` gem to your application and then define custom create, update and delete methods, see example:
173
-
174
- class Employee < ActiveRecord::Base
175
- # when defining create method then return ID of new record that will be assigned to id attribute of new object
176
- set_create_method do
177
- plsql.employees_pkg.create_employee(
178
- :p_first_name => first_name,
179
- :p_last_name => last_name,
180
- :p_employee_id => nil
181
- )[:p_employee_id]
182
- end
183
- set_update_method do
184
- plsql.employees_pkg.update_employee(
185
- :p_employee_id => id,
186
- :p_first_name => first_name,
187
- :p_last_name => last_name
188
- )
189
- end
190
- set_delete_method do
191
- plsql.employees_pkg.delete_employee(
192
- :p_employee_id => id
193
- )
194
- end
195
- end
373
+ If you have legacy schema and you are not allowed to do direct INSERTs, UPDATEs and DELETEs in legacy schema tables and need to use existing PL/SQL procedures for create, updated, delete operations then you should add `ruby-plsql` gem to your application, include `ActiveRecord::OracleEnhancedProcedures` in your model and then define custom create, update and delete methods, see example:
374
+
375
+ ```ruby
376
+ class Employee < ActiveRecord::Base
377
+ include ActiveRecord::OracleEnhancedProcedures
378
+
379
+ # when defining create method then return ID of new record that will be assigned to id attribute of new object
380
+ set_create_method do
381
+ plsql.employees_pkg.create_employee(
382
+ :p_first_name => first_name,
383
+ :p_last_name => last_name,
384
+ :p_employee_id => nil
385
+ )[:p_employee_id]
386
+ end
387
+
388
+ set_update_method do
389
+ plsql.employees_pkg.update_employee(
390
+ :p_employee_id => id,
391
+ :p_first_name => first_name,
392
+ :p_last_name => last_name
393
+ )
394
+ end
395
+
396
+ set_delete_method do
397
+ plsql.employees_pkg.delete_employee(
398
+ :p_employee_id => id
399
+ )
400
+ end
401
+ end
402
+ ```
196
403
 
197
404
  In addition in `config/initializers/oracle.rb` initializer specify that ruby-plsql should use ActiveRecord database connection:
198
405
 
199
- plsql.activerecord_class = ActiveRecord::Base
406
+ ```ruby
407
+ plsql.activerecord_class = ActiveRecord::Base
408
+ ```
200
409
 
201
410
  ### Oracle CONTEXT index support
202
411
 
@@ -204,60 +413,86 @@ Every edition of Oracle database includes [Oracle Text](http://www.oracle.com/te
204
413
 
205
414
  To create simple single column index create migration with, e.g.
206
415
 
207
- add_context_index :posts, :title
416
+ ```ruby
417
+ add_context_index :posts, :title
418
+ ```
208
419
 
209
420
  and you can remove context index with
210
421
 
211
- remove_context_index :posts, :title
422
+ ```ruby
423
+ remove_context_index :posts, :title
424
+ ```
212
425
 
213
426
  Include in class definition
214
427
 
215
- has_context_index
428
+ ```ruby
429
+ has_context_index
430
+ ```
216
431
 
217
432
  and then you can do full text search with
218
433
 
219
- Post.contains(:title, 'word')
434
+ ```ruby
435
+ Post.contains(:title, 'word')
436
+ ```
220
437
 
221
438
  You can create index on several columns (which will generate additional stored procedure for providing XML document with specified columns to indexer):
222
439
 
223
- add_context_index :posts, [:title, :body]
440
+ ```ruby
441
+ add_context_index :posts, [:title, :body]
442
+ ```
224
443
 
225
444
  And you can search either in all columns or specify in which column you want to search (as first argument you need to specify first column name as this is the column which is referenced during index creation):
226
445
 
227
- Post.contains(:title, 'word')
228
- Post.contains(:title, 'word within title')
229
- Post.contains(:title, 'word within body')
446
+ ```ruby
447
+ Post.contains(:title, 'word')
448
+ Post.contains(:title, 'word within title')
449
+ Post.contains(:title, 'word within body')
450
+ ```
230
451
 
231
452
  See Oracle Text documentation for syntax that you can use in CONTAINS function in SELECT WHERE clause.
232
453
 
233
454
  You can also specify some dummy main column name when creating multiple column index as well as specify to update index automatically after each commit (as otherwise you need to synchronize index manually or schedule periodic update):
234
455
 
235
- add_context_index :posts, [:title, :body], :index_column => :all_text, :sync => 'ON COMMIT'
456
+ ```ruby
457
+ add_context_index :posts, [:title, :body], :index_column => :all_text, :sync => 'ON COMMIT'
236
458
 
237
- Post.contains(:all_text, 'word')
459
+ Post.contains(:all_text, 'word')
460
+ ```
238
461
 
239
462
  Or you can specify that index should be updated when specified columns are updated (e.g. in ActiveRecord you can specify to trigger index update when created_at or updated_at columns are updated). Otherwise index is updated only when main index column is updated.
240
463
 
241
- add_context_index :posts, [:title, :body], :index_column => :all_text,
242
- :sync => 'ON COMMIT', :index_column_trigger_on => [:created_at, :updated_at]
464
+ ```ruby
465
+ add_context_index :posts, [:title, :body], :index_column => :all_text,
466
+ :sync => 'ON COMMIT', :index_column_trigger_on => [:created_at, :updated_at]
467
+ ```
243
468
 
244
469
  And you can even create index on multiple tables by providing SELECT statements which should be used to fetch necessary columns from related tables:
245
470
 
246
- add_context_index :posts,
247
- [:title, :body,
248
- # specify aliases always with AS keyword
249
- "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"
250
- ],
251
- :name => 'post_and_comments_index',
252
- :index_column => :all_text,
253
- :index_column_trigger_on => [:updated_at, :comments_count],
254
- :sync => 'ON COMMIT'
255
-
256
- # search in any table columns
257
- Post.contains(:all_text, 'word')
258
- # search in specified column
259
- Post.contains(:all_text, "aaa within title")
260
- Post.contains(:all_text, "bbb within comment_author")
471
+ ```ruby
472
+ add_context_index :posts,
473
+ [:title, :body,
474
+ # specify aliases always with AS keyword
475
+ "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"
476
+ ],
477
+ :name => 'post_and_comments_index',
478
+ :index_column => :all_text,
479
+ :index_column_trigger_on => [:updated_at, :comments_count],
480
+ :sync => 'ON COMMIT'
481
+
482
+ # search in any table columns
483
+ Post.contains(:all_text, 'word')
484
+ # search in specified column
485
+ Post.contains(:all_text, "aaa within title")
486
+ Post.contains(:all_text, "bbb within comment_author")
487
+ ```
488
+
489
+ Please note that `index_column` must be a real column in your database and it's value will be overridden every time your `index_column_trigger_on` columns are changed. So, _do not use columns with real data as `index_column`_.
490
+
491
+ Index column can be created as:
492
+
493
+ ```ruby
494
+ add_column :posts, :all_text, :string, limit: 2, comment: 'Service column for context search index'
495
+ ```
261
496
 
262
497
  ### Oracle virtual columns support
263
498
 
@@ -266,43 +501,53 @@ They can be used as normal fields in the queries, in the foreign key contstraint
266
501
 
267
502
  To define virtual column you can use `virtual` method in the `create_table` block, providing column expression in the `:as` option:
268
503
 
269
- create_table :mytable do |t|
270
- t.decimal :price, :precision => 15, :scale => 2
271
- t.decimal :quantity, :precision => 15, :scale => 2
272
- t.virtual :amount, :as => 'price * quantity'
273
- end
504
+ ```ruby
505
+ create_table :mytable do |t|
506
+ t.decimal :price, :precision => 15, :scale => 2
507
+ t.decimal :quantity, :precision => 15, :scale => 2
508
+ t.virtual :amount, :as => 'price * quantity'
509
+ end
510
+ ```
274
511
 
275
512
  Oracle tries to predict type of the virtual column, based on its expression but sometimes it is necessary to state type explicitly.
276
513
  This can be done by providing `:type` option to the `virtual` method:
277
514
 
278
- ...
279
- t.virtual :amount_2, :as => 'ROUND(price * quantity,2)', :type => :decimal, :precision => 15, :scale => 2
280
- t.virtual :amount_str, :as => "TO_CHAR(quantity) || ' x ' || TO_CHAR(price) || ' USD = ' || TO_CHAR(quantity*price) || ' USD'",
281
- :type => :string, :limit => 100
282
- ...
515
+ ```ruby
516
+ # ...
517
+ t.virtual :amount_2, :as => 'ROUND(price * quantity,2)', :type => :decimal, :precision => 15, :scale => 2
518
+ t.virtual :amount_str, :as => "TO_CHAR(quantity) || ' x ' || TO_CHAR(price) || ' USD = ' || TO_CHAR(quantity*price) || ' USD'",
519
+ :type => :string, :limit => 100
520
+ # ...
521
+ ```
283
522
 
284
523
  It is possible to add virtual column to existing table:
285
524
 
286
- add_column :mytable, :amount_4, :virtual, :as => 'ROUND(price * quantity,4)', :precision => 38, :scale => 4
525
+ ```ruby
526
+ add_column :mytable, :amount_4, :virtual, :as => 'ROUND(price * quantity,4)', :precision => 38, :scale => 4
527
+ ```
287
528
 
288
529
  You can use the same options here as in the `create_table` `virtual` method.
289
530
 
290
531
  Changing virtual columns is also possible:
291
532
 
292
- change_column :mytable, :amount, :virtual, :as => 'ROUND(price * quantity,0)', :type => :integer
533
+ ```ruby
534
+ change_column :mytable, :amount, :virtual, :as => 'ROUND(price * quantity,0)', :type => :integer
535
+ ```
293
536
 
294
537
  Virtual columns allowed in the foreign key constraints.
295
538
  For example it can be used to force foreign key constraint on polymorphic association:
296
539
 
297
- create_table :comments do |t|
298
- t.string :subject_type
299
- t.integer :subject_id
300
- t.virtual :subject_photo_id, :as => "CASE subject_type WHEN 'Photo' THEN subject_id END"
301
- t.virtual :subject_event_id, :as => "CASE subject_type WHEN 'Event' THEN subject_id END"
302
- end
540
+ ```ruby
541
+ create_table :comments do |t|
542
+ t.string :subject_type
543
+ t.integer :subject_id
544
+ t.virtual :subject_photo_id, :as => "CASE subject_type WHEN 'Photo' THEN subject_id END"
545
+ t.virtual :subject_event_id, :as => "CASE subject_type WHEN 'Event' THEN subject_id END"
546
+ end
303
547
 
304
- add_foreign_key :comments, :photos, :column => :subject_photo_id
305
- add_foreign_key :comments, :events, :column => :subject_event_id
548
+ add_foreign_key :comments, :photos, :column => :subject_photo_id
549
+ add_foreign_key :comments, :events, :column => :subject_event_id
550
+ ```
306
551
 
307
552
  For backward compatibility reasons it is possible to use `:default` option in the `create_table` instead of `:as` option.
308
553
  But this is deprecated and may be removed in the future version.
@@ -318,8 +563,165 @@ There are several additional schema statements and data types available that you
318
563
  * You can add table and column comments with `:comment` option
319
564
  * Default tablespaces can be specified for tables, indexes, clobs and blobs, for example:
320
565
 
321
- ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces =
322
- {:clob => 'TS_LOB', :blob => 'TS_LOB', :index => 'TS_INDEX', :table => 'TS_DATA'}
566
+ ```ruby
567
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces =
568
+ {:clob => 'TS_LOB', :blob => 'TS_LOB', :index => 'TS_INDEX', :table => 'TS_DATA'}
569
+ ```
570
+
571
+ ### Switching to another schema
572
+
573
+ There are some requirements to connect to Oracle database first and switch to another user.
574
+ Oracle enhanced adapter supports schema: option.
575
+
576
+ Note: Oracle enhanced adapter does not take care if the database user specified in username: parameter
577
+ has appropriate privilege to select, insert, update and delete database objects owned by the schema specified in schema: parameter.
578
+
579
+ ```yml
580
+ development:
581
+ adapter: oracle_enhanced
582
+ database: xe
583
+ username: user
584
+ password: secret
585
+ schema: tableowner
586
+ ```
587
+
588
+ ### Timeouts
589
+
590
+ By default, OCI libraries set a connect timeout of 60 seconds (as of v12.0), and do not set a data receive timeout.
591
+
592
+ While this may desirable if you process queries that take several minutes to complete, it may also lead to resource exhaustion if
593
+ connections are teared down improperly during a query, e.g. by misbehaving networking equipment that does not inform both peers of
594
+ connection reset. In this scenario, the OCI libraries will wait indefinitely for data to arrive, thus blocking indefinitely the application
595
+ that initiated the query.
596
+
597
+ You can set a connect timeout, in seconds, using the following TNSNAMES parameters:
598
+
599
+ * `CONNECT_TIMEOUT`
600
+ * `TCP_CONNECT_TIMEOUT`
601
+
602
+ Example setting a 5 seconds connect timeout:
603
+
604
+ ```yml
605
+ development:
606
+ database: "(DESCRIPTION=
607
+ (ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))
608
+ (CONNECT_TIMEOUT=5)(TCP_CONNECT_TIMEOUT=5)
609
+ (CONNECT_DATA=(SERVICE_NAME=xe))
610
+ )"
611
+ ```
612
+ You should set a timeout value dependant on your network topology, and the time needed to establish a TCP connection with your ORACLE
613
+ server. In real-world scenarios, a value larger than 5 should be avoided.
614
+
615
+ You can set receive and send timeouts, in seconds, using the following TNSNAMES parameters:
616
+
617
+ * `RECV_TIMEOUT` - the maximum time the OCI libraries should wait for data to arrive on the TCP socket. Internally, it is implemented
618
+ through a `setsockopt(s, SOL_SOCKET, SO_RCVTIMEO)`. You should set this value to an integer larger than the server-side execution time
619
+ of your longest-running query.
620
+ * `SEND_TIMEOUT` the maximum time the OCI libraries should wait for write operations to complete on the TCP socket. Internally, it is
621
+ implemented through a `setsockopt(s, SOL_SOCKET, SO_SNDTIMEO)`. Values larger than 5 are a sign of poorly performing network, and as
622
+ such it should be avoided.
623
+
624
+ Example setting a 60 seconds receive timeout and 5 seconds send timeout:
625
+
626
+ ```yml
627
+ development:
628
+ database: "(DESCRIPTION=
629
+ (ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))
630
+ (RECV_TIMEOUT=60)(SEND_TIMEOUT=5)
631
+ (CONNECT_DATA=(SERVICE_NAME=xe))
632
+ )"
633
+ ```
634
+
635
+ Example setting the above send/recv timeout plus a 5 seconds connect timeout:
636
+
637
+ ```yml
638
+ development:
639
+ database: "(DESCRIPTION=
640
+ (ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))
641
+ (CONNECT_TIMEOUT=5)(TCP_CONNECT_TIMEOUT=5)
642
+ (RECV_TIMEOUT=60)(SEND_TIMEOUT=5)
643
+ (CONNECT_DATA=(SERVICE_NAME=xe))
644
+ )"
645
+ ```
646
+
647
+ ### Schema cache
648
+
649
+ `rails db:schema:cache:dump` generates `db/schema_cache.yml` to avoid queries for Oracle database dictionary, which could help your application response time if it takes time to look up database structure.
650
+
651
+ if any database structure changed by migrations, execute `rails db:schema:cache:dump` again and restart Rails server to reflect changes.
652
+
653
+ UPGRADE
654
+ ---------------
655
+ ### Upgrade Rails 5.0 or older version to Rails 5.2
656
+
657
+ * `emulate_booleans_from_strings = true` change
658
+
659
+ `VARCHAR2(1)` sql type is not registered as `Type:Boolean` even if `emulate_booleans_from_strings = true`
660
+
661
+ Configure each model attribute as follows:
662
+
663
+ ```ruby
664
+ class Post < ActiveRecord::Base
665
+ attribute :is_default, :boolean
666
+ end
667
+ ```
668
+
669
+ * Respect database instance `cursor_sharing` value exact by default
670
+
671
+ Oracle enhanced adapter changed `cursor_sharing` parameter value to `force` in Rails 5.1 or lower. However, Oracle enhanced adapter 5.2 supports prepared statements for dictionary queries There is no need to change `cursor_sharing` value to `exact` anymore.
672
+
673
+ If you want to keep the old behavior in Rails 5.2, set `cursor_sharing: :force` explicitly in the database.yml.
674
+
675
+ * Remove `OracleEnhancedAdapter.cache_columns` to use Rails `db:schema:cache:dump`
676
+
677
+ Refer https://github.com/rsim/oracle-enhanced#schema-cache
678
+
679
+ ### Upgrade Rails 5.0 or older version to Rails 5.1
680
+
681
+ If your application gets `ORA-01000: maximum open cursors exceeded`
682
+ after upgrading to Rails 5.1,
683
+ check these two values and configure `open_cursors` parameter value
684
+ at Oracle database instance is larger than `:statement_limit` value at database.yml.
685
+
686
+ * `open_cursors` value at Oracle database instance
687
+
688
+ ```sql
689
+ SQL> select name,value from v$parameter where name = 'open_cursors';
690
+
691
+ NAME
692
+ --------------------------------------------------------------------------------
693
+ VALUE
694
+ --------------------------------------------------------------------------------
695
+ open_cursors
696
+ 1200
697
+
698
+ ```
699
+
700
+ * `:statement_limit` value at database.yml
701
+
702
+ Since Oracle enhanced adapter 1.8.0 this default value changed from 250 to 1000.
703
+
704
+ ### Upgrade Rails 4.2 or older version to Rails 5
705
+
706
+ If your Oracle table columns have been created for Rails `:datetime` attributes in Rails 4.2 or earlier,
707
+ they need to migrate to `:datetime` in Rails 5 using one of two following ways:
708
+
709
+ * Rails migration code example:
710
+ ```ruby
711
+ change_column :posts, :created_at, :datetime
712
+ change_column :posts, :updated_at, :datetime
713
+ ```
714
+
715
+ or
716
+
717
+ * SQL statement example
718
+ ```sql
719
+ ALTER TABLE "POSTS" MODIFY "CREATED_AT" TIMESTAMP
720
+ ALTER TABLE "POSTS" MODIFY "UPDATED_AT" TIMESTAMP
721
+ ```
722
+
723
+ In Rails 5 without running this migration or sql statement,
724
+ these attributes will be handled as Rails `:date` type.
323
725
 
324
726
  TROUBLESHOOTING
325
727
  ---------------
@@ -340,13 +742,15 @@ Please verify that
340
742
 
341
743
  3. Verify that activerecord-oracle_enhanced-adapter is working from irb
342
744
 
343
- require 'rubygems'
344
- gem 'activerecord'
345
- gem 'activerecord-oracle_enhanced-adapter'
346
- require 'active_record'
347
- ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced", :database => "database",:username => "user",:password => "password")
745
+ ```ruby
746
+ require 'rubygems'
747
+ gem 'activerecord'
748
+ gem 'activerecord-oracle_enhanced-adapter'
749
+ require 'active_record'
750
+ ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced", :database => "database",:username => "user",:password => "password")
751
+ ```
348
752
 
349
- and see if it is successful (use your correct database, username and password)
753
+ and see if it is successful (use your correct database, username and password)
350
754
 
351
755
  ### What to do if Oracle enhanced adapter is not working with Phusion Passenger?
352
756
 
@@ -365,6 +769,14 @@ When Apache with Phusion Passenger (mod_passenger or previously mod_rails) is us
365
769
  * Create wrapper script as described in [Phusion blog](http://blog.phusion.nl/2008/12/16/passing-environment-variables-to-ruby-from-phusion-passenger) or [RayApps::Blog](http://blog.rayapps.com/2008/05/21/using-mod_rails-with-rails-applications-on-oracle)
366
770
  * Set environment variables in the file which is used by Apache before launching Apache worker processes - on Linux it typically is envvars file (look in apachectl or apache2ctl script where it is looking for envvars file) or /System/Library/LaunchDaemons/org.apache.httpd.plist on Mac OS X. See the following [discussion thread](http://groups.google.com/group/oracle-enhanced/browse_thread/thread/c5f64106569fadd0) for more hints.
367
771
 
772
+ ### What to do if my application is stuck?
773
+
774
+ If you see established TCP connections that do not exchange data, and you are unable to terminate your application using a TERM or an INT
775
+ signal, and you are forced to use the KILL signal, then the OCI libraries may be waiting indefinitely for a network read operation to
776
+ complete.
777
+
778
+ See the **Timeouts** section above.
779
+
368
780
  RUNNING TESTS
369
781
  -------------
370
782