activerecord-oracle_enhanced-adapter 1.2.0 → 1.2.1
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.
- data/History.txt +11 -0
- data/{README.txt → README.rdoc} +11 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +65 -34
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +57 -68
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +40 -35
- data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +15 -2
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -5
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +42 -5
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +82 -16
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +25 -3
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +64 -0
- data/spec/spec_helper.rb +17 -10
- metadata +44 -12
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 1.2.1 2009-06-07
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
* caching of table indexes query which makes schema dump much faster
|
5
|
+
* Bug fixes:
|
6
|
+
* return Date (and not DateTime) values for :date column value before year 1970
|
7
|
+
* fixed after_create/update/destroy callbacks with plsql custom methods
|
8
|
+
* fixed creation of large integers in JRuby
|
9
|
+
* Made test tasks respect RAILS_ENV
|
10
|
+
* fixed support for composite primary keys for tables with LOBs
|
11
|
+
|
1
12
|
== 1.2.0 2009-03-22
|
2
13
|
|
3
14
|
* Enhancements
|
data/{README.txt → README.rdoc}
RENAMED
@@ -29,6 +29,17 @@ Bugs and enhancement requests can be reported at http://rsim.lighthouseapp.com/p
|
|
29
29
|
|
30
30
|
* sudo gem install activerecord-oracle_enhanced-adapter
|
31
31
|
|
32
|
+
== CONTRIBUTORS:
|
33
|
+
|
34
|
+
* Raimonds Simanovskis
|
35
|
+
* Jorge Dias
|
36
|
+
* James Wylder
|
37
|
+
* Rob Christie
|
38
|
+
* Nate Wieger
|
39
|
+
* Edgars Beigarts
|
40
|
+
* Lachlan Laycock
|
41
|
+
* toddwf
|
42
|
+
|
32
43
|
== LICENSE:
|
33
44
|
|
34
45
|
(The MIT License)
|
@@ -137,9 +137,9 @@ module ActiveRecord
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
# RSI: convert Time value to Date for :date columns
|
140
|
+
# RSI: convert Time or DateTime value to Date for :date columns
|
141
141
|
def self.string_to_date(string)
|
142
|
-
return string.to_date if string.is_a?(Time)
|
142
|
+
return string.to_date if string.is_a?(Time) || string.is_a?(DateTime)
|
143
143
|
super
|
144
144
|
end
|
145
145
|
|
@@ -346,8 +346,11 @@ module ActiveRecord
|
|
346
346
|
# unescaped table name should start with letter and
|
347
347
|
# contain letters, digits, _, $ or #
|
348
348
|
# can be prefixed with schema name
|
349
|
+
# CamelCase table names should be quoted
|
349
350
|
def self.valid_table_name?(name)
|
350
|
-
name.to_s
|
351
|
+
name = name.to_s
|
352
|
+
name =~ /^([A-Za-z_0-9]+\.)?[a-z][a-z_0-9\$#]*$/ ||
|
353
|
+
name =~ /^([A-Za-z_0-9]+\.)?[A-Z][A-Z_0-9\$#]*$/ ? true : false
|
351
354
|
end
|
352
355
|
|
353
356
|
# abstract_adapter calls quote_column_name from quote_table_name, so prevent that
|
@@ -515,15 +518,26 @@ module ActiveRecord
|
|
515
518
|
|
516
519
|
# Writes LOB values from attributes, as indicated by the LOB columns of klass.
|
517
520
|
def write_lobs(table_name, klass, attributes)
|
518
|
-
|
521
|
+
# is class with composite primary key>
|
522
|
+
is_with_cpk = klass.respond_to?(:composite?) && klass.composite?
|
523
|
+
if is_with_cpk
|
524
|
+
id = klass.primary_key.map {|pk| attributes[pk.to_s] }
|
525
|
+
else
|
526
|
+
id = quote(attributes[klass.primary_key])
|
527
|
+
end
|
519
528
|
klass.columns.select { |col| col.sql_type =~ /LOB$/i }.each do |col|
|
520
529
|
value = attributes[col.name]
|
521
530
|
# RSI: changed sequence of next two lines - should check if value is nil before converting to yaml
|
522
531
|
next if value.nil? || (value == '')
|
523
532
|
value = value.to_yaml if col.text? && klass.serialized_attributes[col.name]
|
524
533
|
uncached do
|
525
|
-
|
534
|
+
if is_with_cpk
|
535
|
+
lob = select_one("SELECT #{col.name} FROM #{table_name} WHERE #{klass.composite_where_clause(id)} FOR UPDATE",
|
536
|
+
'Writable Large Object')[col.name]
|
537
|
+
else
|
538
|
+
lob = select_one("SELECT #{col.name} FROM #{table_name} WHERE #{klass.primary_key} = #{id} FOR UPDATE",
|
526
539
|
'Writable Large Object')[col.name]
|
540
|
+
end
|
527
541
|
@connection.write_lob(lob, value, col.type == :binary)
|
528
542
|
end
|
529
543
|
end
|
@@ -556,36 +570,45 @@ module ActiveRecord
|
|
556
570
|
|
557
571
|
# RSI: changed select from user_tables to all_tables - much faster in large data dictionaries
|
558
572
|
def tables(name = nil) #:nodoc:
|
559
|
-
select_all("select lower(table_name) name from all_tables where owner = sys_context('userenv','session_user')").map {|t| t['name']}
|
573
|
+
select_all("select decode(table_name,upper(table_name),lower(table_name),table_name) name from all_tables where owner = sys_context('userenv','session_user')").map {|t| t['name']}
|
560
574
|
end
|
561
575
|
|
562
|
-
|
563
|
-
(owner, table_name) = @connection.describe(table_name)
|
564
|
-
result = select_all(<<-SQL, name)
|
565
|
-
SELECT lower(i.index_name) as index_name, i.uniqueness, lower(c.column_name) as column_name
|
566
|
-
FROM all_indexes i, all_ind_columns c
|
567
|
-
WHERE i.table_name = '#{table_name}'
|
568
|
-
AND i.owner = '#{owner}'
|
569
|
-
AND i.table_owner = '#{owner}'
|
570
|
-
AND c.index_name = i.index_name
|
571
|
-
AND c.index_owner = i.owner
|
572
|
-
AND NOT EXISTS (SELECT uc.index_name FROM all_constraints uc WHERE uc.index_name = i.index_name AND uc.owner = i.owner AND uc.constraint_type = 'P')
|
573
|
-
ORDER BY i.index_name, c.column_position
|
574
|
-
SQL
|
575
|
-
|
576
|
-
current_index = nil
|
577
|
-
indexes = []
|
576
|
+
cattr_accessor :all_schema_indexes
|
578
577
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
578
|
+
# This method selects all indexes at once, and caches them in a class variable.
|
579
|
+
# Subsequent index calls get them from the variable, without going to the DB.
|
580
|
+
def indexes(table_name, name = nil)
|
581
|
+
(owner, table_name) = @connection.describe(table_name)
|
582
|
+
unless all_schema_indexes
|
583
|
+
result = select_all(<<-SQL)
|
584
|
+
SELECT lower(i.table_name) as table_name, lower(i.index_name) as index_name, i.uniqueness, lower(c.column_name) as column_name
|
585
|
+
FROM all_indexes i, all_ind_columns c
|
586
|
+
WHERE i.owner = '#{owner}'
|
587
|
+
AND i.table_owner = '#{owner}'
|
588
|
+
AND c.index_name = i.index_name
|
589
|
+
AND c.index_owner = i.owner
|
590
|
+
AND NOT EXISTS (SELECT uc.index_name FROM all_constraints uc WHERE uc.index_name = i.index_name AND uc.owner = i.owner AND uc.constraint_type = 'P')
|
591
|
+
ORDER BY i.index_name, c.column_position
|
592
|
+
SQL
|
593
|
+
|
594
|
+
current_index = nil
|
595
|
+
self.all_schema_indexes = []
|
596
|
+
|
597
|
+
result.each do |row|
|
598
|
+
# have to keep track of indexes because above query returns dups
|
599
|
+
# there is probably a better query we could figure out
|
600
|
+
if current_index != row['index_name']
|
601
|
+
self.all_schema_indexes << ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(row['table_name'], row['index_name'], row['uniqueness'] == "UNIQUE", [])
|
602
|
+
current_index = row['index_name']
|
603
|
+
end
|
604
|
+
|
605
|
+
self.all_schema_indexes.last.columns << row['column_name']
|
583
606
|
end
|
584
|
-
|
585
|
-
indexes.last.columns << row['column_name']
|
586
607
|
end
|
587
|
-
|
588
|
-
indexes
|
608
|
+
|
609
|
+
# Return the indexes just for the requested table, since AR is structured that way
|
610
|
+
table_name = table_name.downcase
|
611
|
+
all_schema_indexes.select{|i| i.table == table_name}
|
589
612
|
end
|
590
613
|
|
591
614
|
# RSI: set ignored columns for table
|
@@ -723,7 +746,15 @@ module ActiveRecord
|
|
723
746
|
execute "DROP SEQUENCE #{seq_name}" rescue nil
|
724
747
|
end
|
725
748
|
|
749
|
+
# clear cached indexes when adding new index
|
750
|
+
def add_index(table_name, column_name, options = {})
|
751
|
+
self.all_schema_indexes = nil
|
752
|
+
super
|
753
|
+
end
|
754
|
+
|
755
|
+
# clear cached indexes when removing index
|
726
756
|
def remove_index(table_name, options = {}) #:nodoc:
|
757
|
+
self.all_schema_indexes = nil
|
727
758
|
execute "DROP INDEX #{index_name(table_name, options)}"
|
728
759
|
end
|
729
760
|
|
@@ -822,12 +853,12 @@ module ActiveRecord
|
|
822
853
|
end
|
823
854
|
|
824
855
|
def structure_dump #:nodoc:
|
825
|
-
s = select_all("select sequence_name from user_sequences").inject("") do |structure, seq|
|
856
|
+
s = select_all("select sequence_name from user_sequences order by 1").inject("") do |structure, seq|
|
826
857
|
structure << "create sequence #{seq.to_a.first.last};\n\n"
|
827
858
|
end
|
828
859
|
|
829
860
|
# RSI: changed select from user_tables to all_tables - much faster in large data dictionaries
|
830
|
-
select_all("select table_name from all_tables where owner = sys_context('userenv','session_user')").inject(s) do |structure, table|
|
861
|
+
select_all("select table_name from all_tables where owner = sys_context('userenv','session_user') order by 1").inject(s) do |structure, table|
|
831
862
|
ddl = "create table #{table.to_a.first.last} (\n "
|
832
863
|
cols = select_all(%Q{
|
833
864
|
select column_name, data_type, data_length, char_used, char_length, data_precision, data_scale, data_default, nullable
|
@@ -855,12 +886,12 @@ module ActiveRecord
|
|
855
886
|
end
|
856
887
|
|
857
888
|
def structure_drop #:nodoc:
|
858
|
-
s = select_all("select sequence_name from user_sequences").inject("") do |drop, seq|
|
889
|
+
s = select_all("select sequence_name from user_sequences order by 1").inject("") do |drop, seq|
|
859
890
|
drop << "drop sequence #{seq.to_a.first.last};\n\n"
|
860
891
|
end
|
861
892
|
|
862
893
|
# RSI: changed select from user_tables to all_tables - much faster in large data dictionaries
|
863
|
-
select_all("select table_name from all_tables where owner = sys_context('userenv','session_user')").inject(s) do |drop, table|
|
894
|
+
select_all("select table_name from all_tables where owner = sys_context('userenv','session_user') order by 1").inject(s) do |drop, table|
|
864
895
|
drop << "drop table #{table.to_a.first.last} cascade constraints;\n\n"
|
865
896
|
end
|
866
897
|
end
|
@@ -72,6 +72,9 @@ module ActiveRecord
|
|
72
72
|
# Set session time zone to current time zone
|
73
73
|
@raw_connection.setSessionTimeZone(java.util.TimeZone.default.getID)
|
74
74
|
|
75
|
+
# Set default number of rows to prefetch
|
76
|
+
# @raw_connection.setDefaultRowPrefetch(prefetch_rows) if prefetch_rows
|
77
|
+
|
75
78
|
# default schema owner
|
76
79
|
@owner = username.upcase
|
77
80
|
|
@@ -156,7 +159,7 @@ module ActiveRecord
|
|
156
159
|
end
|
157
160
|
|
158
161
|
def exec_no_retry(sql)
|
159
|
-
cs =
|
162
|
+
cs = @raw_connection.prepareCall(sql)
|
160
163
|
case sql
|
161
164
|
when /\A\s*UPDATE/i, /\A\s*INSERT/i, /\A\s*DELETE/i
|
162
165
|
cs.executeUpdate
|
@@ -175,59 +178,35 @@ module ActiveRecord
|
|
175
178
|
end
|
176
179
|
|
177
180
|
def select_no_retry(sql, name = nil, return_column_names = false)
|
178
|
-
stmt =
|
181
|
+
stmt = @raw_connection.prepareStatement(sql)
|
179
182
|
rset = stmt.executeQuery
|
183
|
+
|
184
|
+
# Reuse the same hash for all rows
|
185
|
+
column_hash = {}
|
186
|
+
|
180
187
|
metadata = rset.getMetaData
|
181
188
|
column_count = metadata.getColumnCount
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
189
|
+
|
190
|
+
cols_types_index = (1..column_count).map do |i|
|
191
|
+
col_name = oracle_downcase(metadata.getColumnName(i))
|
192
|
+
next if col_name == 'raw_rnum_'
|
193
|
+
column_hash[col_name] = nil
|
194
|
+
[col_name, metadata.getColumnTypeName(i).to_sym, i]
|
187
195
|
end
|
196
|
+
cols_types_index.delete(nil)
|
188
197
|
|
189
198
|
rows = []
|
190
|
-
|
199
|
+
get_lob_value = !(name == 'Writable Large Object')
|
200
|
+
|
191
201
|
while rset.next
|
192
|
-
hash =
|
193
|
-
|
194
|
-
|
195
|
-
i = i0 + 1
|
196
|
-
hash[col] =
|
197
|
-
case column_type = col_types[i0]
|
198
|
-
when /CLOB/
|
199
|
-
name == 'Writable Large Object' ? rset.getClob(i) : get_ruby_value_from_result_set(rset, i, column_type)
|
200
|
-
when /BLOB/
|
201
|
-
name == 'Writable Large Object' ? rset.getBlob(i) : get_ruby_value_from_result_set(rset, i, column_type)
|
202
|
-
when 'DATE'
|
203
|
-
t = get_ruby_value_from_result_set(rset, i, column_type)
|
204
|
-
# RSI: added emulate_dates_by_column_name functionality
|
205
|
-
# if emulate_dates_by_column_name && self.class.is_date_column?(col)
|
206
|
-
# d.to_date
|
207
|
-
# elsif
|
208
|
-
if t && OracleEnhancedAdapter.emulate_dates && (t.hour == 0 && t.min == 0 && t.sec == 0)
|
209
|
-
t.to_date
|
210
|
-
else
|
211
|
-
# JRuby Time supports time before year 1900 therefore now need to fall back to DateTime
|
212
|
-
t
|
213
|
-
end
|
214
|
-
# RSI: added emulate_integers_by_column_name functionality
|
215
|
-
when "NUMBER"
|
216
|
-
n = get_ruby_value_from_result_set(rset, i, column_type)
|
217
|
-
if n && n.is_a?(Float) && OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(col)
|
218
|
-
n.to_i
|
219
|
-
else
|
220
|
-
n
|
221
|
-
end
|
222
|
-
else
|
223
|
-
get_ruby_value_from_result_set(rset, i, column_type)
|
224
|
-
end unless col == 'raw_rnum_'
|
202
|
+
hash = column_hash.dup
|
203
|
+
cols_types_index.each do |col, column_type, i|
|
204
|
+
hash[col] = get_ruby_value_from_result_set(rset, i, column_type, get_lob_value)
|
225
205
|
end
|
226
|
-
|
227
206
|
rows << hash
|
228
207
|
end
|
229
208
|
|
230
|
-
return_column_names ? [rows,
|
209
|
+
return_column_names ? [rows, cols_types_index.map(&:first)] : rows
|
231
210
|
ensure
|
232
211
|
rset.close rescue nil
|
233
212
|
stmt.close rescue nil
|
@@ -284,50 +263,62 @@ module ActiveRecord
|
|
284
263
|
|
285
264
|
private
|
286
265
|
|
287
|
-
def prepare_statement(sql)
|
288
|
-
|
289
|
-
end
|
266
|
+
# def prepare_statement(sql)
|
267
|
+
# @raw_connection.prepareStatement(sql)
|
268
|
+
# end
|
290
269
|
|
291
|
-
def prepare_call(sql, *bindvars)
|
292
|
-
|
293
|
-
end
|
270
|
+
# def prepare_call(sql, *bindvars)
|
271
|
+
# @raw_connection.prepareCall(sql)
|
272
|
+
# end
|
294
273
|
|
295
|
-
def get_ruby_value_from_result_set(rset, i, type_name)
|
274
|
+
def get_ruby_value_from_result_set(rset, i, type_name, get_lob_value = true)
|
296
275
|
case type_name
|
297
|
-
when
|
298
|
-
rset.
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
276
|
+
when :NUMBER
|
277
|
+
# d = rset.getBigDecimal(i)
|
278
|
+
# if d.nil?
|
279
|
+
# nil
|
280
|
+
# elsif d.scale == 0
|
281
|
+
# d.toBigInteger+0
|
282
|
+
# else
|
283
|
+
# # Is there better way how to convert Java BigDecimal to Ruby BigDecimal?
|
284
|
+
# d.toString.to_d
|
285
|
+
# end
|
286
|
+
d = rset.getNUMBER(i)
|
305
287
|
if d.nil?
|
306
288
|
nil
|
307
|
-
elsif d.
|
308
|
-
d.
|
289
|
+
elsif d.isInt
|
290
|
+
Integer(d.stringValue)
|
309
291
|
else
|
310
|
-
|
311
|
-
d.toString.to_d
|
292
|
+
BigDecimal.new(d.stringValue)
|
312
293
|
end
|
313
|
-
when
|
294
|
+
when :VARCHAR2, :CHAR, :LONG
|
295
|
+
rset.getString(i)
|
296
|
+
when :DATE
|
314
297
|
if dt = rset.getDATE(i)
|
315
298
|
d = dt.dateValue
|
316
299
|
t = dt.timeValue
|
317
|
-
|
300
|
+
if OracleEnhancedAdapter.emulate_dates && t.hours == 0 && t.minutes == 0 && t.seconds == 0
|
301
|
+
Date.new(d.year + 1900, d.month + 1, d.date)
|
302
|
+
else
|
303
|
+
Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
|
304
|
+
end
|
318
305
|
else
|
319
306
|
nil
|
320
307
|
end
|
321
|
-
when
|
308
|
+
when :TIMESTAMP, :TIMESTAMPTZ, :TIMESTAMPLTZ
|
322
309
|
ts = rset.getTimestamp(i)
|
323
310
|
ts && Time.send(Base.default_timezone, ts.year + 1900, ts.month + 1, ts.date, ts.hours, ts.minutes, ts.seconds,
|
324
311
|
ts.nanos / 1000)
|
312
|
+
when :CLOB
|
313
|
+
get_lob_value ? lob_to_ruby_value(rset.getClob(i)) : rset.getClob(i)
|
314
|
+
when :BLOB
|
315
|
+
get_lob_value ? lob_to_ruby_value(rset.getBlob(i)) : rset.getBlob(i)
|
325
316
|
else
|
326
317
|
nil
|
327
318
|
end
|
328
319
|
end
|
329
320
|
|
330
|
-
def
|
321
|
+
def lob_to_ruby_value(val)
|
331
322
|
case val
|
332
323
|
when ::Java::OracleSql::CLOB
|
333
324
|
if val.isEmptyLob
|
@@ -341,8 +332,6 @@ module ActiveRecord
|
|
341
332
|
else
|
342
333
|
String.from_java_bytes(val.getBytes(1, val.length))
|
343
334
|
end
|
344
|
-
else
|
345
|
-
val
|
346
335
|
end
|
347
336
|
end
|
348
337
|
|
@@ -84,70 +84,75 @@ module ActiveRecord
|
|
84
84
|
|
85
85
|
def select(sql, name = nil, return_column_names = false)
|
86
86
|
cursor = @raw_connection.exec(sql)
|
87
|
-
cols =
|
87
|
+
cols = []
|
88
|
+
# Ignore raw_rnum_ which is used to simulate LIMIT and OFFSET
|
89
|
+
cursor.get_col_names.each do |col_name|
|
90
|
+
col_name = oracle_downcase(col_name)
|
91
|
+
cols << col_name unless col_name == 'raw_rnum_'
|
92
|
+
end
|
93
|
+
# Reuse the same hash for all rows
|
94
|
+
column_hash = {}
|
95
|
+
cols.each {|c| column_hash[c] = nil}
|
88
96
|
rows = []
|
97
|
+
get_lob_value = !(name == 'Writable Large Object')
|
89
98
|
|
90
99
|
while row = cursor.fetch
|
91
|
-
hash =
|
100
|
+
hash = column_hash.dup
|
92
101
|
|
93
102
|
cols.each_with_index do |col, i|
|
94
103
|
hash[col] =
|
95
|
-
case row[i]
|
104
|
+
case v = row[i]
|
105
|
+
# RSI: added emulate_integers_by_column_name functionality
|
106
|
+
when Float
|
107
|
+
# if OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(col)
|
108
|
+
# v.to_i
|
109
|
+
# else
|
110
|
+
# v
|
111
|
+
# end
|
112
|
+
v == (v_to_i = v.to_i) ? v_to_i : v
|
113
|
+
# ruby-oci8 2.0 returns OraNumber - convert it to Integer or BigDecimal
|
114
|
+
when OraNumber
|
115
|
+
v == (v_to_i = v.to_i) ? v_to_i : BigDecimal.new(v.to_s)
|
116
|
+
when String
|
117
|
+
v
|
96
118
|
when OCI8::LOB
|
97
|
-
if
|
98
|
-
|
99
|
-
else
|
100
|
-
data = row[i].read
|
119
|
+
if get_lob_value
|
120
|
+
data = v.read
|
101
121
|
# In Ruby 1.9.1 always change encoding to ASCII-8BIT for binaries
|
102
|
-
data.force_encoding('ASCII-8BIT') if data.respond_to?(:force_encoding) &&
|
122
|
+
data.force_encoding('ASCII-8BIT') if data.respond_to?(:force_encoding) && v.is_a?(OCI8::BLOB)
|
103
123
|
data
|
124
|
+
else
|
125
|
+
v
|
104
126
|
end
|
105
127
|
# ruby-oci8 1.0 returns OraDate
|
106
128
|
when OraDate
|
107
|
-
d = row[i]
|
108
129
|
# RSI: added emulate_dates_by_column_name functionality
|
109
|
-
|
110
|
-
|
111
|
-
# elsif
|
112
|
-
if OracleEnhancedAdapter.emulate_dates && (d.hour == 0 && d.minute == 0 && d.second == 0)
|
113
|
-
d.to_date
|
130
|
+
if OracleEnhancedAdapter.emulate_dates && (v.hour == 0 && v.minute == 0 && v.second == 0)
|
131
|
+
v.to_date
|
114
132
|
else
|
115
133
|
# code from Time.time_with_datetime_fallback
|
116
134
|
begin
|
117
|
-
Time.send(Base.default_timezone,
|
135
|
+
Time.send(Base.default_timezone, v.year, v.month, v.day, v.hour, v.minute, v.second)
|
118
136
|
rescue
|
119
137
|
offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
|
120
|
-
::DateTime.civil(
|
138
|
+
::DateTime.civil(v.year, v.month, v.day, v.hour, v.minute, v.second, offset)
|
121
139
|
end
|
122
140
|
end
|
123
141
|
# ruby-oci8 2.0 returns Time or DateTime
|
124
142
|
when Time, DateTime
|
125
|
-
|
126
|
-
|
127
|
-
d.to_date
|
143
|
+
if OracleEnhancedAdapter.emulate_dates && (v.hour == 0 && v.min == 0 && v.sec == 0)
|
144
|
+
v.to_date
|
128
145
|
else
|
129
146
|
# recreate Time or DateTime using Base.default_timezone
|
130
147
|
begin
|
131
|
-
Time.send(Base.default_timezone,
|
148
|
+
Time.send(Base.default_timezone, v.year, v.month, v.day, v.hour, v.min, v.sec)
|
132
149
|
rescue
|
133
150
|
offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
|
134
|
-
::DateTime.civil(
|
151
|
+
::DateTime.civil(v.year, v.month, v.day, v.hour, v.min, v.sec, offset)
|
135
152
|
end
|
136
153
|
end
|
137
|
-
|
138
|
-
|
139
|
-
n = row[i]
|
140
|
-
if OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(col)
|
141
|
-
n.to_i
|
142
|
-
else
|
143
|
-
n
|
144
|
-
end
|
145
|
-
# ruby-oci8 2.0 returns OraNumber - convert it to Integer or BigDecimal
|
146
|
-
when OraNumber
|
147
|
-
n = row[i]
|
148
|
-
n == (n_to_i = n.to_i) ? n_to_i : BigDecimal.new(n.to_s)
|
149
|
-
else row[i]
|
150
|
-
end unless col == 'raw_rnum_'
|
154
|
+
else v
|
155
|
+
end
|
151
156
|
end
|
152
157
|
|
153
158
|
rows << hash
|
@@ -38,17 +38,30 @@ module ActiveRecord #:nodoc:
|
|
38
38
|
module InstanceMethods
|
39
39
|
def self.included(base)
|
40
40
|
base.instance_eval do
|
41
|
-
|
41
|
+
if private_instance_methods.include?('create_without_callbacks') || private_instance_methods.include?(:create_without_callbacks)
|
42
|
+
alias_method :create_without_custom_method, :create_without_callbacks
|
43
|
+
alias_method :create_without_callbacks, :create_with_custom_method
|
44
|
+
else
|
45
|
+
alias_method_chain :create, :custom_method
|
46
|
+
end
|
42
47
|
# insert after dirty checking in Rails 2.1
|
43
48
|
# in Ruby 1.9 methods names are returned as symbols
|
44
49
|
if private_instance_methods.include?('update_without_dirty') || private_instance_methods.include?(:update_without_dirty)
|
45
50
|
alias_method :update_without_custom_method, :update_without_dirty
|
46
51
|
alias_method :update_without_dirty, :update_with_custom_method
|
52
|
+
elsif private_instance_methods.include?('update_without_callbacks') || private_instance_methods.include?(:update_without_callbacks)
|
53
|
+
alias_method :update_without_custom_method, :update_without_callbacks
|
54
|
+
alias_method :update_without_callbacks, :update_with_custom_method
|
47
55
|
else
|
48
56
|
alias_method_chain :update, :custom_method
|
49
57
|
end
|
50
58
|
private :create, :update
|
51
|
-
|
59
|
+
if public_instance_methods.include?('destroy_without_callbacks') || public_instance_methods.include?(:destroy_without_callbacks)
|
60
|
+
alias_method :destroy_without_custom_method, :destroy_without_callbacks
|
61
|
+
alias_method :destroy_without_callbacks, :destroy_with_custom_method
|
62
|
+
else
|
63
|
+
alias_method_chain :destroy, :custom_method
|
64
|
+
end
|
52
65
|
public :destroy
|
53
66
|
end
|
54
67
|
end
|
@@ -47,6 +47,17 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
47
47
|
@new_conn = ActiveRecord::Base.oracle_enhanced_connection(CONNECTION_PARAMS)
|
48
48
|
@new_conn.class.should == ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
49
49
|
end
|
50
|
+
|
51
|
+
after(:all) do
|
52
|
+
# Workaround for undefining callback that was defined by JDBC adapter
|
53
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
54
|
+
ActiveRecord::Base.class_eval do
|
55
|
+
def after_save_with_oracle_lob
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
50
61
|
|
51
62
|
unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION =~ /^1\.9/
|
52
63
|
it "should return the same tables list as original oracle adapter" do
|
@@ -66,11 +77,11 @@ describe "OracleEnhancedAdapter schema dump" do
|
|
66
77
|
end
|
67
78
|
|
68
79
|
it "should return the same structure dump as original oracle adapter" do
|
69
|
-
@new_conn.structure_dump.should == @old_conn.structure_dump
|
80
|
+
@new_conn.structure_dump.split(";\n\n").sort.should == @old_conn.structure_dump.split(";\n\n").sort
|
70
81
|
end
|
71
82
|
|
72
83
|
it "should return the same structure drop as original oracle adapter" do
|
73
|
-
@new_conn.structure_drop.should == @old_conn.structure_drop
|
84
|
+
@new_conn.structure_drop.split(";\n\n").sort.should == @old_conn.structure_drop.split(";\n\n").sort
|
74
85
|
end
|
75
86
|
end
|
76
87
|
|
@@ -530,14 +541,26 @@ describe "OracleEnhancedAdapter table quoting" do
|
|
530
541
|
end
|
531
542
|
end
|
532
543
|
|
544
|
+
def create_camel_case_table
|
545
|
+
ActiveRecord::Schema.define do
|
546
|
+
suppress_messages do
|
547
|
+
create_table "CamelCase" do |t|
|
548
|
+
t.string :name
|
549
|
+
t.integer :foo
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
533
555
|
after(:each) do
|
534
556
|
ActiveRecord::Schema.define do
|
535
557
|
suppress_messages do
|
536
|
-
drop_table "warehouse-things"
|
558
|
+
drop_table "warehouse-things" rescue nil
|
559
|
+
drop_table "CamelCase" rescue nil
|
537
560
|
end
|
538
561
|
end
|
539
|
-
Object.send(:remove_const, "WarehouseThing")
|
540
|
-
|
562
|
+
Object.send(:remove_const, "WarehouseThing") rescue nil
|
563
|
+
Object.send(:remove_const, "CamelCase") rescue nil
|
541
564
|
end
|
542
565
|
|
543
566
|
it "should allow creation of a table with non alphanumeric characters" do
|
@@ -548,6 +571,20 @@ describe "OracleEnhancedAdapter table quoting" do
|
|
548
571
|
|
549
572
|
wh = WarehouseThing.create!(:name => "Foo", :foo => 2)
|
550
573
|
wh.id.should_not be_nil
|
574
|
+
|
575
|
+
@conn.tables.should include("warehouse-things")
|
576
|
+
end
|
577
|
+
|
578
|
+
it "should allow creation of a table with CamelCase name" do
|
579
|
+
create_camel_case_table
|
580
|
+
class ::CamelCase < ActiveRecord::Base
|
581
|
+
set_table_name "CamelCase"
|
582
|
+
end
|
583
|
+
|
584
|
+
cc = CamelCase.create!(:name => "Foo", :foo => 2)
|
585
|
+
cc.id.should_not be_nil
|
586
|
+
|
587
|
+
@conn.tables.should include("CamelCase")
|
551
588
|
end
|
552
589
|
|
553
590
|
end
|
@@ -3,35 +3,101 @@ require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
|
3
3
|
describe "OracleEnhancedAdapter composite_primary_keys support" do
|
4
4
|
|
5
5
|
before(:all) do
|
6
|
-
if defined?(ActiveRecord::ConnectionAdapters::OracleAdapter)
|
7
|
-
@old_oracle_adapter = ActiveRecord::ConnectionAdapters::OracleAdapter
|
8
|
-
ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
6
|
+
if defined?(::ActiveRecord::ConnectionAdapters::OracleAdapter)
|
7
|
+
@old_oracle_adapter = ::ActiveRecord::ConnectionAdapters::OracleAdapter
|
8
|
+
::ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
9
9
|
end
|
10
10
|
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
set_primary_keys :employee_id, :start_date
|
11
|
+
if $cpk_oracle_adapter
|
12
|
+
::ActiveRecord::ConnectionAdapters::OracleAdapter = $cpk_oracle_adapter
|
13
|
+
$cpk_oracle_adapter = nil
|
15
14
|
end
|
15
|
+
require 'composite_primary_keys'
|
16
16
|
end
|
17
17
|
|
18
18
|
after(:all) do
|
19
|
-
Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
|
20
|
-
|
19
|
+
# Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
|
20
|
+
if defined?(::ActiveRecord::ConnectionAdapters::OracleAdapter)
|
21
|
+
$cpk_oracle_adapter = ::ActiveRecord::ConnectionAdapters::OracleAdapter
|
22
|
+
::ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
23
|
+
end
|
21
24
|
if @old_oracle_adapter
|
22
|
-
ActiveRecord::ConnectionAdapters
|
23
|
-
|
25
|
+
::ActiveRecord::ConnectionAdapters::OracleAdapter = @old_oracle_adapter
|
26
|
+
@old_oracle_adapter = nil
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
describe "do not use count distinct" do
|
31
|
+
before(:all) do
|
32
|
+
class ::JobHistory < ActiveRecord::Base
|
33
|
+
set_table_name "job_history"
|
34
|
+
set_primary_keys :employee_id, :start_date
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
after(:all) do
|
39
|
+
Object.send(:remove_const, 'JobHistory') if defined?(JobHistory)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should tell ActiveRecord that count distinct is not supported" do
|
43
|
+
ActiveRecord::Base.connection.supports_count_distinct?.should be_false
|
44
|
+
end
|
30
45
|
|
31
|
-
|
32
|
-
|
46
|
+
it "should execute correct SQL COUNT DISTINCT statement on table with composite primary keys" do
|
47
|
+
lambda { JobHistory.count(:distinct => true) }.should_not raise_error
|
48
|
+
end
|
33
49
|
end
|
34
50
|
|
51
|
+
describe "table with LOB" do
|
52
|
+
before(:all) do
|
53
|
+
ActiveRecord::Schema.define do
|
54
|
+
suppress_messages do
|
55
|
+
create_table :cpk_write_lobs_test, :primary_key => [:type_category, :date_value], :force => true do |t|
|
56
|
+
t.string :type_category, :limit => 15, :null => false
|
57
|
+
t.date :date_value, :null => false
|
58
|
+
t.text :results, :null => false
|
59
|
+
t.timestamps
|
60
|
+
end
|
61
|
+
create_table :non_cpk_write_lobs_test, :force => true do |t|
|
62
|
+
t.date :date_value, :null => false
|
63
|
+
t.text :results, :null => false
|
64
|
+
t.timestamps
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
class ::CpkWriteLobsTest < ActiveRecord::Base
|
69
|
+
set_table_name 'cpk_write_lobs_test'
|
70
|
+
set_primary_keys :type_category, :date_value
|
71
|
+
end
|
72
|
+
class ::NonCpkWriteLobsTest < ActiveRecord::Base
|
73
|
+
set_table_name 'non_cpk_write_lobs_test'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
after(:all) do
|
78
|
+
ActiveRecord::Schema.define do
|
79
|
+
suppress_messages do
|
80
|
+
drop_table :cpk_write_lobs_test
|
81
|
+
drop_table :non_cpk_write_lobs_test
|
82
|
+
end
|
83
|
+
end
|
84
|
+
Object.send(:remove_const, "CpkWriteLobsTest")
|
85
|
+
Object.send(:remove_const, "NonCpkWriteLobsTest")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should create new record in table with CPK and LOB" do
|
89
|
+
lambda {
|
90
|
+
CpkWriteLobsTest.create(:type_category => 'AAA', :date_value => Date.today, :results => 'DATA '*10)
|
91
|
+
}.should_not raise_error
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should create new record in table without CPK and with LOB" do
|
95
|
+
lambda {
|
96
|
+
NonCpkWriteLobsTest.create(:date_value => Date.today, :results => 'DATA '*10)
|
97
|
+
}.should_not raise_error
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
35
101
|
# Other testing was done based on composite_primary_keys tests
|
36
102
|
|
37
103
|
end
|
@@ -74,6 +74,13 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
|
|
74
74
|
column.type_cast(Time.now).class.should == Date
|
75
75
|
end
|
76
76
|
|
77
|
+
it "should typecast DateTime value to Date value from DATE column if column name contains 'date' and emulate_dates_by_column_name is true" do
|
78
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
79
|
+
columns = @conn.columns('test_employees')
|
80
|
+
column = columns.detect{|c| c.name == "hire_date"}
|
81
|
+
column.type_cast(DateTime.new(1900,1,1)).class.should == Date
|
82
|
+
end
|
83
|
+
|
77
84
|
describe "/ DATE values from ActiveRecord model" do
|
78
85
|
before(:each) do
|
79
86
|
ActiveRecord::Base.connection.clear_types_for_columns
|
@@ -85,9 +92,9 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
|
|
85
92
|
end
|
86
93
|
end
|
87
94
|
|
88
|
-
def create_test_employee
|
89
|
-
@today = Date.new(2008,8,19)
|
90
|
-
@now = Time.local(2008,8,19,17,03,59)
|
95
|
+
def create_test_employee(params={})
|
96
|
+
@today = params[:today] || Date.new(2008,8,19)
|
97
|
+
@now = params[:now] || Time.local(2008,8,19,17,03,59)
|
91
98
|
@employee = TestEmployee.create(
|
92
99
|
:first_name => "First",
|
93
100
|
:last_name => "Last",
|
@@ -114,6 +121,12 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
|
|
114
121
|
@employee.hire_date.class.should == Date
|
115
122
|
end
|
116
123
|
|
124
|
+
it "should return Date value from DATE column with old date value if column name contains 'date' and emulate_dates_by_column_name is true" do
|
125
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
126
|
+
create_test_employee(:today => Date.new(1900,1,1))
|
127
|
+
@employee.hire_date.class.should == Date
|
128
|
+
end
|
129
|
+
|
117
130
|
it "should return Time value from DATE column if column name does not contain 'date' and emulate_dates_by_column_name is true" do
|
118
131
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
|
119
132
|
create_test_employee
|
@@ -129,6 +142,15 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
|
|
129
142
|
@employee.hire_date.class.should == Date
|
130
143
|
end
|
131
144
|
|
145
|
+
it "should return Date value from DATE column with old date value if emulate_dates_by_column_name is false but column is defined as date" do
|
146
|
+
class ::TestEmployee < ActiveRecord::Base
|
147
|
+
set_date_columns :hire_date
|
148
|
+
end
|
149
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
|
150
|
+
create_test_employee(:today => Date.new(1900,1,1))
|
151
|
+
@employee.hire_date.class.should == Date
|
152
|
+
end
|
153
|
+
|
132
154
|
it "should return Time value from DATE column if emulate_dates_by_column_name is true but column is defined as datetime" do
|
133
155
|
class ::TestEmployee < ActiveRecord::Base
|
134
156
|
set_datetime_columns :hire_date
|
@@ -159,6 +159,26 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
|
|
159
159
|
@employee.update_time.should_not be_nil
|
160
160
|
end
|
161
161
|
|
162
|
+
it "should rollback record when exception is raised in after_create callback" do
|
163
|
+
@employee = TestEmployee.new(
|
164
|
+
:first_name => "First",
|
165
|
+
:last_name => "Last",
|
166
|
+
:hire_date => @today
|
167
|
+
)
|
168
|
+
TestEmployee.class_eval { def after_create() raise "Make the transaction rollback" end }
|
169
|
+
begin
|
170
|
+
employees_count = TestEmployee.count
|
171
|
+
@employee.save
|
172
|
+
fail "Did not raise exception"
|
173
|
+
rescue => e
|
174
|
+
e.message.should == "Make the transaction rollback"
|
175
|
+
@employee.id.should == nil
|
176
|
+
TestEmployee.count.should == employees_count
|
177
|
+
ensure
|
178
|
+
TestEmployee.class_eval { remove_method :after_create }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
162
182
|
it "should update record" do
|
163
183
|
@employee = TestEmployee.create(
|
164
184
|
:first_name => "First",
|
@@ -173,6 +193,29 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
|
|
173
193
|
@employee.description.should == "Second Last"
|
174
194
|
end
|
175
195
|
|
196
|
+
it "should rollback record when exception is raised in after_update callback" do
|
197
|
+
TestEmployee.class_eval { def after_update() raise "Make the transaction rollback" end }
|
198
|
+
begin
|
199
|
+
@employee = TestEmployee.create(
|
200
|
+
:first_name => "First",
|
201
|
+
:last_name => "Last",
|
202
|
+
:hire_date => @today,
|
203
|
+
:description => "description"
|
204
|
+
)
|
205
|
+
empl_id = @employee.id
|
206
|
+
@employee.reload
|
207
|
+
@employee.first_name = "Second"
|
208
|
+
@employee.save!
|
209
|
+
fail "Did not raise exception"
|
210
|
+
rescue => e
|
211
|
+
e.message.should == "Make the transaction rollback"
|
212
|
+
@employee.reload
|
213
|
+
@employee.first_name.should == "First"
|
214
|
+
ensure
|
215
|
+
TestEmployee.class_eval { remove_method :after_update }
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
176
219
|
it "should not update record if nothing is changed and partial updates are enabled" do
|
177
220
|
return pending("Not in this ActiveRecord version") unless TestEmployee.respond_to?(:partial_updates=)
|
178
221
|
TestEmployee.partial_updates = true
|
@@ -214,6 +257,27 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
|
|
214
257
|
TestEmployee.find_by_employee_id(empl_id).should be_nil
|
215
258
|
end
|
216
259
|
|
260
|
+
it "should rollback record when exception is raised in after_desotry callback" do
|
261
|
+
TestEmployee.class_eval { def after_destroy() raise "Make the transaction rollback" end }
|
262
|
+
@employee = TestEmployee.create(
|
263
|
+
:first_name => "First",
|
264
|
+
:last_name => "Last",
|
265
|
+
:hire_date => @today
|
266
|
+
)
|
267
|
+
@employee.reload
|
268
|
+
empl_id = @employee.id
|
269
|
+
begin
|
270
|
+
@employee.destroy
|
271
|
+
fail "Did not raise exception"
|
272
|
+
rescue => e
|
273
|
+
e.message.should == "Make the transaction rollback"
|
274
|
+
@employee.id.should == empl_id
|
275
|
+
TestEmployee.find_by_employee_id(empl_id).should_not be_nil
|
276
|
+
ensure
|
277
|
+
TestEmployee.class_eval { remove_method :after_destroy }
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
217
281
|
it "should log create record" do
|
218
282
|
log_to @buffer
|
219
283
|
# reestablish plsql.connection as log_to might reset existing connection
|
data/spec/spec_helper.rb
CHANGED
@@ -58,28 +58,35 @@ module LoggerSpecHelper
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
DATABASE_NAME = ENV['DATABASE_NAME'] || 'orcl'
|
62
|
+
DATABASE_HOST = ENV['DATABASE_HOST'] || 'localhost'
|
63
|
+
DATABASE_PORT = ENV['DATABASE_PORT'] || 1521
|
64
|
+
DATABASE_USER = ENV['DATABASE_USER'] || 'hr'
|
65
|
+
DATABASE_PASSWORD = ENV['DATABASE_PASSWORD'] || 'hr'
|
66
|
+
DATABASE_SYS_PASSWORD = ENV['DATABASE_SYS_PASSWORD'] || 'admin'
|
67
|
+
|
61
68
|
CONNECTION_PARAMS = {
|
62
69
|
:adapter => "oracle_enhanced",
|
63
|
-
:database =>
|
64
|
-
:host =>
|
65
|
-
:username =>
|
66
|
-
:password =>
|
70
|
+
:database => DATABASE_NAME,
|
71
|
+
:host => DATABASE_HOST,
|
72
|
+
:username => DATABASE_USER,
|
73
|
+
:password => DATABASE_PASSWORD
|
67
74
|
}
|
68
75
|
|
69
76
|
JDBC_CONNECTION_PARAMS = {
|
70
77
|
:adapter => "jdbc",
|
71
78
|
:driver => "oracle.jdbc.driver.OracleDriver",
|
72
|
-
:url => "jdbc:oracle:thin
|
73
|
-
:username =>
|
74
|
-
:password =>
|
79
|
+
:url => "jdbc:oracle:thin:@#{DATABASE_HOST}:#{DATABASE_PORT}:#{DATABASE_NAME}",
|
80
|
+
:username => DATABASE_USER,
|
81
|
+
:password => DATABASE_PASSWORD
|
75
82
|
}
|
76
83
|
|
77
84
|
SYS_CONNECTION_PARAMS = {
|
78
85
|
:adapter => "oracle_enhanced",
|
79
|
-
:database =>
|
80
|
-
:host =>
|
86
|
+
:database => DATABASE_NAME,
|
87
|
+
:host => DATABASE_HOST,
|
81
88
|
:username => "sys",
|
82
|
-
:password =>
|
89
|
+
:password => DATABASE_SYS_PASSWORD,
|
83
90
|
:privilege => "SYSDBA"
|
84
91
|
}
|
85
92
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-oracle_enhanced-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Raimonds Simanovskis
|
@@ -9,9 +9,29 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-06-08 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: newgem
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.0
|
34
|
+
version:
|
15
35
|
- !ruby/object:Gem::Dependency
|
16
36
|
name: hoe
|
17
37
|
type: :development
|
@@ -20,11 +40,21 @@ dependencies:
|
|
20
40
|
requirements:
|
21
41
|
- - ">="
|
22
42
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.8.
|
43
|
+
version: 1.8.0
|
24
44
|
version:
|
25
|
-
description:
|
45
|
+
description: |-
|
46
|
+
Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases
|
47
|
+
from Rails which are extracted from current real projects' monkey patches of original Oracle adapter.
|
48
|
+
|
49
|
+
See http://github.com/rsim/oracle-enhanced/wikis for more information.
|
50
|
+
|
51
|
+
For questions and feature discussion please use http://groups.google.com/group/oracle-enhanced
|
52
|
+
|
53
|
+
Blog posts about oracle-enahnced can be found at http://blog.rayapps.com/category/oracle-enhanced
|
54
|
+
|
55
|
+
Bugs and enhancement requests can be reported at http://rsim.lighthouseapp.com/projects/11468-oracle-enhanced
|
26
56
|
email:
|
27
|
-
-
|
57
|
+
- raimonds.simanovskis@gmail.com
|
28
58
|
executables: []
|
29
59
|
|
30
60
|
extensions: []
|
@@ -32,11 +62,11 @@ extensions: []
|
|
32
62
|
extra_rdoc_files:
|
33
63
|
- History.txt
|
34
64
|
- License.txt
|
35
|
-
- README.
|
65
|
+
- README.rdoc
|
36
66
|
files:
|
37
67
|
- History.txt
|
38
68
|
- License.txt
|
39
|
-
- README.
|
69
|
+
- README.rdoc
|
40
70
|
- lib/active_record/connection_adapters/emulation/oracle_adapter.rb
|
41
71
|
- lib/active_record/connection_adapters/oracle_enhanced.rake
|
42
72
|
- lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
|
@@ -61,11 +91,13 @@ files:
|
|
61
91
|
- spec/spec.opts
|
62
92
|
- spec/spec_helper.rb
|
63
93
|
has_rdoc: true
|
64
|
-
homepage: http://oracle-enhanced
|
65
|
-
|
94
|
+
homepage: http://rubyforge.org/projects/oracle-enhanced/
|
95
|
+
licenses: []
|
96
|
+
|
97
|
+
post_install_message:
|
66
98
|
rdoc_options:
|
67
99
|
- --main
|
68
|
-
- README.
|
100
|
+
- README.rdoc
|
69
101
|
require_paths:
|
70
102
|
- lib
|
71
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -83,9 +115,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
115
|
requirements: []
|
84
116
|
|
85
117
|
rubyforge_project: oracle-enhanced
|
86
|
-
rubygems_version: 1.3.
|
118
|
+
rubygems_version: 1.3.3
|
87
119
|
signing_key:
|
88
|
-
specification_version:
|
120
|
+
specification_version: 3
|
89
121
|
summary: Oracle enhaced adapter for Active Record
|
90
122
|
test_files: []
|
91
123
|
|