rsim-activerecord-oracle_enhanced-adapter 1.1.9.91 → 1.1.9.92
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/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +70 -19
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +54 -21
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +6 -8
- data/oracle-enhanced.gemspec +1 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +14 -9
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +4 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +44 -14
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +12 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +4 -2
- data/spec/spec_helper.rb +14 -3
- metadata +1 -1
@@ -130,6 +130,8 @@ module ActiveRecord
|
|
130
130
|
def self.value_to_boolean(value)
|
131
131
|
if value == true || value == false
|
132
132
|
value
|
133
|
+
elsif value.is_a?(String) && value.blank?
|
134
|
+
nil
|
133
135
|
else
|
134
136
|
%w(true t 1 y +).include?(value.to_s.downcase)
|
135
137
|
end
|
@@ -326,8 +328,9 @@ module ActiveRecord
|
|
326
328
|
# Returns an array of arrays containing the field values.
|
327
329
|
# Order is the same as that returned by #columns.
|
328
330
|
def select_rows(sql, name = nil)
|
329
|
-
|
330
|
-
result
|
331
|
+
# last parameter indicates to return also column list
|
332
|
+
result, columns = select(sql, name, true)
|
333
|
+
result.map{ |v| columns.map{|c| v[c]} }
|
331
334
|
end
|
332
335
|
|
333
336
|
# QUOTING ==================================================
|
@@ -557,13 +560,16 @@ module ActiveRecord
|
|
557
560
|
end
|
558
561
|
|
559
562
|
def indexes(table_name, name = nil) #:nodoc:
|
563
|
+
(owner, table_name) = @connection.describe(table_name)
|
560
564
|
result = select_all(<<-SQL, name)
|
561
565
|
SELECT lower(i.index_name) as index_name, i.uniqueness, lower(c.column_name) as column_name
|
562
|
-
FROM all_indexes i,
|
563
|
-
WHERE i.table_name = '#{table_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}'
|
564
570
|
AND c.index_name = i.index_name
|
565
|
-
AND
|
566
|
-
AND i.owner =
|
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')
|
567
573
|
ORDER BY i.index_name, c.column_position
|
568
574
|
SQL
|
569
575
|
|
@@ -572,7 +578,7 @@ module ActiveRecord
|
|
572
578
|
|
573
579
|
result.each do |row|
|
574
580
|
if current_index != row['index_name']
|
575
|
-
indexes << IndexDefinition.new(table_name, row['index_name'], row['uniqueness'] == "UNIQUE", [])
|
581
|
+
indexes << IndexDefinition.new(table_name.downcase, row['index_name'], row['uniqueness'] == "UNIQUE", [])
|
576
582
|
current_index = row['index_name']
|
577
583
|
end
|
578
584
|
|
@@ -707,8 +713,8 @@ module ActiveRecord
|
|
707
713
|
end
|
708
714
|
|
709
715
|
def rename_table(name, new_name) #:nodoc:
|
710
|
-
execute "RENAME #{name} TO #{new_name}"
|
711
|
-
execute "RENAME #{name}_seq TO #{new_name}_seq" rescue nil
|
716
|
+
execute "RENAME #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
|
717
|
+
execute "RENAME #{quote_table_name("#{name}_seq")} TO #{quote_table_name("#{new_name}_seq")}" rescue nil
|
712
718
|
end
|
713
719
|
|
714
720
|
def drop_table(name, options = {}) #:nodoc:
|
@@ -721,22 +727,48 @@ module ActiveRecord
|
|
721
727
|
execute "DROP INDEX #{index_name(table_name, options)}"
|
722
728
|
end
|
723
729
|
|
730
|
+
def add_column(table_name, column_name, type, options = {})
|
731
|
+
add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
732
|
+
options[:type] = type
|
733
|
+
add_column_options!(add_column_sql, options)
|
734
|
+
execute(add_column_sql)
|
735
|
+
end
|
736
|
+
|
724
737
|
def change_column_default(table_name, column_name, default) #:nodoc:
|
725
|
-
execute "ALTER TABLE #{table_name} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
|
738
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
|
739
|
+
end
|
740
|
+
|
741
|
+
def change_column_null(table_name, column_name, null, default = nil)
|
742
|
+
column = column_for(table_name, column_name)
|
743
|
+
|
744
|
+
unless null || default.nil?
|
745
|
+
execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
|
746
|
+
end
|
747
|
+
|
748
|
+
change_column table_name, column_name, column.sql_type, :null => null
|
726
749
|
end
|
727
750
|
|
728
751
|
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
729
|
-
|
752
|
+
column = column_for(table_name, column_name)
|
753
|
+
|
754
|
+
# remove :null option if its value is the same as current column definition
|
755
|
+
# otherwise Oracle will raise error
|
756
|
+
if options.has_key?(:null) && options[:null] == column.null
|
757
|
+
options[:null] = nil
|
758
|
+
end
|
759
|
+
|
760
|
+
change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
761
|
+
options[:type] = type
|
730
762
|
add_column_options!(change_column_sql, options)
|
731
763
|
execute(change_column_sql)
|
732
764
|
end
|
733
765
|
|
734
766
|
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
735
|
-
execute "ALTER TABLE #{table_name} RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}"
|
767
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}"
|
736
768
|
end
|
737
769
|
|
738
770
|
def remove_column(table_name, column_name) #:nodoc:
|
739
|
-
execute "ALTER TABLE #{table_name} DROP COLUMN #{quote_column_name(column_name)}"
|
771
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
|
740
772
|
end
|
741
773
|
|
742
774
|
# RSI: table and column comments
|
@@ -777,7 +809,7 @@ module ActiveRecord
|
|
777
809
|
# RSI: changed select from all_constraints to user_constraints - much faster in large data dictionaries
|
778
810
|
pks = select_values(<<-SQL, 'Primary Key')
|
779
811
|
select cc.column_name
|
780
|
-
from user_constraints c,
|
812
|
+
from user_constraints c, user_cons_columns cc
|
781
813
|
where c.owner = '#{owner}'
|
782
814
|
and c.table_name = '#{table_name}'
|
783
815
|
and c.constraint_type = 'P'
|
@@ -834,11 +866,23 @@ module ActiveRecord
|
|
834
866
|
end
|
835
867
|
|
836
868
|
def add_column_options!(sql, options) #:nodoc:
|
869
|
+
type = options[:type] || ((column = options[:column]) && column.type)
|
870
|
+
type = type && type.to_sym
|
837
871
|
# handle case of defaults for CLOB columns, which would otherwise get "quoted" incorrectly
|
838
|
-
if options_include_default?(options)
|
839
|
-
|
872
|
+
if options_include_default?(options)
|
873
|
+
if type == :text
|
874
|
+
sql << " DEFAULT #{quote(options[:default])}"
|
875
|
+
else
|
876
|
+
# from abstract adapter
|
877
|
+
sql << " DEFAULT #{quote(options[:default], options[:column])}"
|
878
|
+
end
|
879
|
+
end
|
880
|
+
# must explicitly add NULL or NOT NULL to allow change_column to work on migrations
|
881
|
+
if options[:null] == false
|
882
|
+
sql << " NOT NULL"
|
883
|
+
elsif options[:null] == true
|
884
|
+
sql << " NULL" unless type == :primary_key
|
840
885
|
end
|
841
|
-
super
|
842
886
|
end
|
843
887
|
|
844
888
|
# SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
|
@@ -879,9 +923,9 @@ module ActiveRecord
|
|
879
923
|
|
880
924
|
private
|
881
925
|
|
882
|
-
def select(sql, name = nil)
|
926
|
+
def select(sql, name = nil, return_column_names = false)
|
883
927
|
log(sql, name) do
|
884
|
-
@connection.select(sql, name)
|
928
|
+
@connection.select(sql, name, return_column_names)
|
885
929
|
end
|
886
930
|
end
|
887
931
|
|
@@ -889,6 +933,13 @@ module ActiveRecord
|
|
889
933
|
@connection.oracle_downcase(column_name)
|
890
934
|
end
|
891
935
|
|
936
|
+
def column_for(table_name, column_name)
|
937
|
+
unless column = columns(table_name).find { |c| c.name == column_name.to_s }
|
938
|
+
raise "No such column: #{table_name}.#{column_name}"
|
939
|
+
end
|
940
|
+
column
|
941
|
+
end
|
942
|
+
|
892
943
|
end
|
893
944
|
end
|
894
945
|
end
|
@@ -8,12 +8,12 @@ module ActiveRecord #:nodoc:
|
|
8
8
|
def field_changed?(attr, old, value)
|
9
9
|
if column = column_for_attribute(attr)
|
10
10
|
# RSI: added also :decimal type
|
11
|
-
if (column.type == :integer || column.type == :decimal) && column.null && (old.nil? || old == 0)
|
11
|
+
if (column.type == :integer || column.type == :decimal) && column.null && (old.nil? || old == 0) && value.blank?
|
12
12
|
# For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
|
13
13
|
# Hence we don't record it as a change if the value changes from nil to ''.
|
14
14
|
# If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
|
15
15
|
# be typecast back to 0 (''.to_i => 0)
|
16
|
-
value = nil
|
16
|
+
value = nil
|
17
17
|
# RSI: Oracle stores empty string '' or empty text (CLOB) as NULL
|
18
18
|
# therefore need to convert empty string value to nil if old value is nil
|
19
19
|
elsif (column.type == :string || column.type == :text) && column.null && old.nil?
|
@@ -157,19 +157,24 @@ module ActiveRecord
|
|
157
157
|
|
158
158
|
def exec_no_retry(sql)
|
159
159
|
cs = prepare_call(sql)
|
160
|
-
|
161
|
-
|
160
|
+
case sql
|
161
|
+
when /\A\s*UPDATE/i, /\A\s*INSERT/i, /\A\s*DELETE/i
|
162
|
+
cs.executeUpdate
|
163
|
+
else
|
164
|
+
cs.execute
|
165
|
+
true
|
166
|
+
end
|
162
167
|
ensure
|
163
168
|
cs.close rescue nil
|
164
169
|
end
|
165
170
|
|
166
|
-
def select(sql, name = nil)
|
171
|
+
def select(sql, name = nil, return_column_names = false)
|
167
172
|
with_retry do
|
168
|
-
select_no_retry(sql, name)
|
173
|
+
select_no_retry(sql, name, return_column_names)
|
169
174
|
end
|
170
175
|
end
|
171
176
|
|
172
|
-
def select_no_retry(sql, name = nil)
|
177
|
+
def select_no_retry(sql, name = nil, return_column_names = false)
|
173
178
|
stmt = prepare_statement(sql)
|
174
179
|
rset = stmt.executeQuery
|
175
180
|
metadata = rset.getMetaData
|
@@ -222,7 +227,7 @@ module ActiveRecord
|
|
222
227
|
rows << hash
|
223
228
|
end
|
224
229
|
|
225
|
-
rows
|
230
|
+
return_column_names ? [rows, cols] : rows
|
226
231
|
ensure
|
227
232
|
rset.close rescue nil
|
228
233
|
stmt.close rescue nil
|
@@ -237,8 +242,8 @@ module ActiveRecord
|
|
237
242
|
end
|
238
243
|
|
239
244
|
def describe(name)
|
240
|
-
real_name = OracleEnhancedAdapter.valid_table_name?(name) ? name.upcase : name
|
241
|
-
if
|
245
|
+
real_name = OracleEnhancedAdapter.valid_table_name?(name) ? name.to_s.upcase : name.to_s
|
246
|
+
if real_name.include?('.')
|
242
247
|
table_owner, table_name = real_name.split('.')
|
243
248
|
else
|
244
249
|
table_owner, table_name = @owner, real_name
|
@@ -262,7 +267,7 @@ module ActiveRecord
|
|
262
267
|
SELECT table_owner, table_name, 'SYNONYM' name_type
|
263
268
|
FROM all_synonyms
|
264
269
|
WHERE owner = 'PUBLIC'
|
265
|
-
AND synonym_name = '#{
|
270
|
+
AND synonym_name = '#{real_name}'
|
266
271
|
SQL
|
267
272
|
if result = select_one(sql)
|
268
273
|
case result['name_type']
|
@@ -289,7 +294,7 @@ module ActiveRecord
|
|
289
294
|
|
290
295
|
def get_ruby_value_from_result_set(rset, i, type_name)
|
291
296
|
case type_name
|
292
|
-
when "CHAR", "VARCHAR2"
|
297
|
+
when "CHAR", "VARCHAR2", "LONG"
|
293
298
|
rset.getString(i)
|
294
299
|
when "CLOB"
|
295
300
|
ora_value_to_ruby_value(rset.getClob(i))
|
@@ -300,13 +305,23 @@ module ActiveRecord
|
|
300
305
|
if d.nil?
|
301
306
|
nil
|
302
307
|
elsif d.scale == 0
|
303
|
-
d.
|
308
|
+
d.toBigInteger+0
|
309
|
+
else
|
310
|
+
# Is there better way how to convert Java BigDecimal to Ruby BigDecimal?
|
311
|
+
d.toString.to_d
|
312
|
+
end
|
313
|
+
when "DATE"
|
314
|
+
if dt = rset.getDATE(i)
|
315
|
+
d = dt.dateValue
|
316
|
+
t = dt.timeValue
|
317
|
+
Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
|
304
318
|
else
|
305
|
-
|
319
|
+
nil
|
306
320
|
end
|
307
|
-
when
|
321
|
+
when /^TIMESTAMP/
|
308
322
|
ts = rset.getTimestamp(i)
|
309
|
-
ts && Time.
|
323
|
+
ts && Time.send(Base.default_timezone, ts.year + 1900, ts.month + 1, ts.date, ts.hours, ts.minutes, ts.seconds,
|
324
|
+
ts.nanos / 1000)
|
310
325
|
else
|
311
326
|
nil
|
312
327
|
end
|
@@ -314,8 +329,6 @@ module ActiveRecord
|
|
314
329
|
|
315
330
|
def ora_value_to_ruby_value(val)
|
316
331
|
case val
|
317
|
-
when Float, BigDecimal
|
318
|
-
ora_number_to_ruby_number(val)
|
319
332
|
when ::Java::OracleSql::CLOB
|
320
333
|
if val.isEmptyLob
|
321
334
|
nil
|
@@ -333,13 +346,33 @@ module ActiveRecord
|
|
333
346
|
end
|
334
347
|
end
|
335
348
|
|
336
|
-
def ora_number_to_ruby_number(num)
|
337
|
-
num.to_i == num.to_f ? num.to_i : num.to_f
|
338
|
-
end
|
339
|
-
|
340
|
-
|
341
349
|
end
|
342
350
|
|
343
351
|
end
|
344
352
|
end
|
345
353
|
|
354
|
+
# add BigDecimal#to_d, Fixnum#to_d and Bignum#to_d methods if not already present
|
355
|
+
require "bigdecimal"
|
356
|
+
unless BigDecimal.instance_methods.include?("to_d")
|
357
|
+
BigDecimal.class_eval do
|
358
|
+
def to_d
|
359
|
+
self
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
unless Bignum.instance_methods.include?("to_d")
|
365
|
+
Bignum.class_eval do
|
366
|
+
def to_d
|
367
|
+
BigDecimal.new(self.to_s)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
unless Fixnum.instance_methods.include?("to_d")
|
373
|
+
Fixnum.class_eval do
|
374
|
+
def to_d
|
375
|
+
BigDecimal.new(self.to_s)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
@@ -82,7 +82,7 @@ module ActiveRecord
|
|
82
82
|
@raw_connection.exec(sql, *bindvars, &block)
|
83
83
|
end
|
84
84
|
|
85
|
-
def select(sql, name = nil)
|
85
|
+
def select(sql, name = nil, return_column_names = false)
|
86
86
|
cursor = @raw_connection.exec(sql)
|
87
87
|
cols = cursor.get_col_names.map { |x| oracle_downcase(x) }
|
88
88
|
rows = []
|
@@ -104,14 +104,12 @@ module ActiveRecord
|
|
104
104
|
if OracleEnhancedAdapter.emulate_dates && (d.hour == 0 && d.minute == 0 && d.second == 0)
|
105
105
|
d.to_date
|
106
106
|
else
|
107
|
-
#
|
108
|
-
time_array = [d.year, d.month, d.day, d.hour, d.minute, d.second]
|
107
|
+
# code from Time.time_with_datetime_fallback
|
109
108
|
begin
|
110
|
-
Time.send(Base.default_timezone,
|
109
|
+
Time.send(Base.default_timezone, d.year, d.month, d.day, d.hour, d.minute, d.second)
|
111
110
|
rescue
|
112
|
-
|
113
|
-
|
114
|
-
DateTime.new(*time_array[0..5] << zone_offset << 0) rescue nil
|
111
|
+
offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
|
112
|
+
::DateTime.civil(d.year, d.month, d.day, d.hour, d.minute, d.second, offset)
|
115
113
|
end
|
116
114
|
end
|
117
115
|
# RSI: added emulate_integers_by_column_name functionality
|
@@ -129,7 +127,7 @@ module ActiveRecord
|
|
129
127
|
rows << hash
|
130
128
|
end
|
131
129
|
|
132
|
-
rows
|
130
|
+
return_column_names ? [rows, cols] : rows
|
133
131
|
ensure
|
134
132
|
cursor.close if cursor
|
135
133
|
end
|
data/oracle-enhanced.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{activerecord-oracle_enhanced-adapter}
|
5
|
-
s.version = "1.1.9.
|
5
|
+
s.version = "1.1.9.92"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Raimonds Simanovskis"]
|
@@ -127,6 +127,11 @@ describe "OracleEnhancedAdapter database session store" do
|
|
127
127
|
CREATE SEQUENCE sessions_seq MINVALUE 1 MAXVALUE 999999999999999999999999999
|
128
128
|
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
129
129
|
SQL
|
130
|
+
if ENV['RAILS_GEM_VERSION'] >= '2.3'
|
131
|
+
SESSION_CLASS = ActiveRecord::SessionStore::Session
|
132
|
+
else
|
133
|
+
SESSION_CLASS = CGI::Session::ActiveRecordStore::Session
|
134
|
+
end
|
130
135
|
end
|
131
136
|
|
132
137
|
after(:all) do
|
@@ -139,29 +144,29 @@ describe "OracleEnhancedAdapter database session store" do
|
|
139
144
|
end
|
140
145
|
|
141
146
|
it "should save session data" do
|
142
|
-
@session =
|
147
|
+
@session = SESSION_CLASS.new :session_id => "111111", :data => "something" #, :updated_at => Time.now
|
143
148
|
@session.save!
|
144
|
-
@session =
|
149
|
+
@session = SESSION_CLASS.find_by_session_id("111111")
|
145
150
|
@session.data.should == "something"
|
146
151
|
end
|
147
152
|
|
148
153
|
it "should change session data when partial updates enabled" do
|
149
|
-
return pending("Not in this ActiveRecord version") unless
|
150
|
-
|
151
|
-
@session =
|
154
|
+
return pending("Not in this ActiveRecord version") unless SESSION_CLASS.respond_to?(:partial_updates=)
|
155
|
+
SESSION_CLASS.partial_updates = true
|
156
|
+
@session = SESSION_CLASS.new :session_id => "222222", :data => "something" #, :updated_at => Time.now
|
152
157
|
@session.save!
|
153
|
-
@session =
|
158
|
+
@session = SESSION_CLASS.find_by_session_id("222222")
|
154
159
|
@session.data = "other thing"
|
155
160
|
@session.save!
|
156
161
|
# second save should call again blob writing callback
|
157
162
|
@session.save!
|
158
|
-
@session =
|
163
|
+
@session = SESSION_CLASS.find_by_session_id("222222")
|
159
164
|
@session.data.should == "other thing"
|
160
165
|
end
|
161
166
|
|
162
167
|
it "should have one enhanced_write_lobs callback" do
|
163
|
-
return pending("Not in this ActiveRecord version") unless
|
164
|
-
|
168
|
+
return pending("Not in this ActiveRecord version") unless SESSION_CLASS.respond_to?(:after_save_callback_chain)
|
169
|
+
SESSION_CLASS.after_save_callback_chain.select{|cb| cb.method == :enhanced_write_lobs}.should have(1).record
|
165
170
|
end
|
166
171
|
|
167
172
|
it "should not set sessions table session_id column type as integer if emulate_integers_by_column_name is true" do
|
@@ -60,6 +60,10 @@ describe "OracleEnhancedConnection SQL execution" do
|
|
60
60
|
@conn.select("SELECT * FROM dual").should == [{'dummy' => 'X'}]
|
61
61
|
end
|
62
62
|
|
63
|
+
it "should execute SQL select and return also columns" do
|
64
|
+
@conn.select("SELECT * FROM dual", nil, true).should == [ [{'dummy' => 'X'}], ['dummy'] ]
|
65
|
+
end
|
66
|
+
|
63
67
|
end
|
64
68
|
|
65
69
|
describe "OracleEnhancedConnection auto reconnection" do
|
@@ -284,9 +284,9 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
|
|
284
284
|
department_id NUMBER(4,0),
|
285
285
|
created_at DATE,
|
286
286
|
has_email CHAR(1),
|
287
|
-
has_phone VARCHAR2(1),
|
287
|
+
has_phone VARCHAR2(1) DEFAULT 'Y',
|
288
288
|
active_flag VARCHAR2(2),
|
289
|
-
manager_yn VARCHAR2(3),
|
289
|
+
manager_yn VARCHAR2(3) DEFAULT 'N',
|
290
290
|
test_boolean VARCHAR2(3)
|
291
291
|
)
|
292
292
|
SQL
|
@@ -358,6 +358,13 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
|
|
358
358
|
ActiveRecord::Base.connection.type_to_sql(
|
359
359
|
:boolean, nil, nil, nil).should == "NUMBER(1)"
|
360
360
|
end
|
361
|
+
|
362
|
+
it "should get default value from VARCHAR2 boolean column if emulate_booleans_from_strings is true" do
|
363
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
|
364
|
+
columns = @conn.columns('test3_employees')
|
365
|
+
columns.detect{|c| c.name == 'has_phone'}.default.should be_true
|
366
|
+
columns.detect{|c| c.name == 'manager_yn'}.default.should be_false
|
367
|
+
end
|
361
368
|
|
362
369
|
describe "/ VARCHAR2 boolean values from ActiveRecord model" do
|
363
370
|
before(:each) do
|
@@ -422,6 +429,12 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
|
|
422
429
|
create_employee3(:test_boolean => false)
|
423
430
|
@employee3.test_boolean.class.should == FalseClass
|
424
431
|
@employee3.test_boolean_before_type_cast.should == "N"
|
432
|
+
create_employee3(:test_boolean => nil)
|
433
|
+
@employee3.test_boolean.class.should == NilClass
|
434
|
+
@employee3.test_boolean_before_type_cast.should == nil
|
435
|
+
create_employee3(:test_boolean => "")
|
436
|
+
@employee3.test_boolean.class.should == NilClass
|
437
|
+
@employee3.test_boolean_before_type_cast.should == nil
|
425
438
|
end
|
426
439
|
|
427
440
|
end
|
@@ -493,18 +506,35 @@ describe "OracleEnhancedAdapter timestamp with timezone support" do
|
|
493
506
|
end
|
494
507
|
end
|
495
508
|
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
509
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
510
|
+
it "should return Time value with fractional seconds from TIMESTAMP columns" do
|
511
|
+
# currently fractional seconds are not retrieved from database
|
512
|
+
@now = Time.local(2008,5,26,23,11,11,10)
|
513
|
+
@employee = TestEmployee.create(
|
514
|
+
:created_at => @now,
|
515
|
+
:created_at_tz => @now,
|
516
|
+
:created_at_ltz => @now
|
517
|
+
)
|
518
|
+
@employee.reload
|
519
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
520
|
+
@employee.send(c).class.should == Time
|
521
|
+
@employee.send(c).to_f.should == @now.to_f
|
522
|
+
end
|
523
|
+
end
|
524
|
+
else
|
525
|
+
it "should return Time value without fractional seconds from TIMESTAMP columns" do
|
526
|
+
# currently fractional seconds are not retrieved from database
|
527
|
+
@now = Time.local(2008,5,26,23,11,11,10)
|
528
|
+
@employee = TestEmployee.create(
|
529
|
+
:created_at => @now,
|
530
|
+
:created_at_tz => @now,
|
531
|
+
:created_at_ltz => @now
|
532
|
+
)
|
533
|
+
@employee.reload
|
534
|
+
[:created_at, :created_at_tz, :created_at_ltz].each do |c|
|
535
|
+
@employee.send(c).class.should == Time
|
536
|
+
@employee.send(c).to_f.should == @now.to_f.to_i.to_f # remove fractional seconds
|
537
|
+
end
|
508
538
|
end
|
509
539
|
end
|
510
540
|
|
@@ -12,7 +12,7 @@ if ActiveRecord::Base.instance_methods.include?('changed?')
|
|
12
12
|
id NUMBER,
|
13
13
|
first_name VARCHAR2(20),
|
14
14
|
last_name VARCHAR2(25),
|
15
|
-
job_id NUMBER(6,0),
|
15
|
+
job_id NUMBER(6,0) NULL,
|
16
16
|
salary NUMBER(8,2),
|
17
17
|
comments CLOB,
|
18
18
|
hire_date DATE
|
@@ -77,6 +77,17 @@ if ActiveRecord::Base.instance_methods.include?('changed?')
|
|
77
77
|
@employee.should_not be_changed
|
78
78
|
end
|
79
79
|
|
80
|
+
it "should not mark integer as changed when reassigning it" do
|
81
|
+
@employee = TestEmployee.new
|
82
|
+
@employee.job_id = 0
|
83
|
+
@employee.save!.should be_true
|
84
|
+
|
85
|
+
@employee.should_not be_changed
|
86
|
+
|
87
|
+
@employee.job_id = '0'
|
88
|
+
@employee.should_not be_changed
|
89
|
+
end
|
90
|
+
|
80
91
|
end
|
81
92
|
|
82
93
|
end
|
@@ -6,6 +6,7 @@ describe "OracleEnhancedAdapter emulate OracleAdapter" do
|
|
6
6
|
|
7
7
|
before(:all) do
|
8
8
|
if defined?(ActiveRecord::ConnectionAdapters::OracleAdapter)
|
9
|
+
@old_oracle_adapter = ActiveRecord::ConnectionAdapters::OracleAdapter
|
9
10
|
ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
10
11
|
end
|
11
12
|
end
|
@@ -17,9 +18,10 @@ describe "OracleEnhancedAdapter emulate OracleAdapter" do
|
|
17
18
|
end
|
18
19
|
|
19
20
|
after(:all) do
|
20
|
-
if
|
21
|
+
if @old_oracle_adapter
|
21
22
|
ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
|
22
|
-
|
23
|
+
ActiveRecord::ConnectionAdapters::OracleAdapter = @old_oracle_adapter
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -14,16 +14,27 @@ elsif ENV['RAILS_GEM_VERSION'] =~ /^2.1/
|
|
14
14
|
gem 'actionpack', '=2.1.2'
|
15
15
|
gem 'activesupport', '=2.1.2'
|
16
16
|
gem 'composite_primary_keys', '=1.0.8'
|
17
|
-
|
17
|
+
elsif ENV['RAILS_GEM_VERSION'] =~ /^2.2/
|
18
18
|
gem 'activerecord', '=2.2.2'
|
19
19
|
gem 'actionpack', '=2.2.2'
|
20
20
|
gem 'activesupport', '=2.2.2'
|
21
|
-
gem 'composite_primary_keys', '=2.2.
|
21
|
+
gem 'composite_primary_keys', '=2.2.2'
|
22
|
+
else
|
23
|
+
ENV['RAILS_GEM_VERSION'] ||= '2.3.2'
|
24
|
+
gem 'activerecord', '=2.3.2'
|
25
|
+
gem 'actionpack', '=2.3.2'
|
26
|
+
gem 'activesupport', '=2.3.2'
|
27
|
+
gem 'composite_primary_keys', '=2.2.2'
|
22
28
|
end
|
23
29
|
|
24
30
|
require 'activerecord'
|
25
31
|
require 'actionpack'
|
26
|
-
|
32
|
+
if ENV['RAILS_GEM_VERSION'] >= '2.3'
|
33
|
+
require 'action_controller/session/abstract_store'
|
34
|
+
require 'active_record/session_store'
|
35
|
+
else
|
36
|
+
require 'action_controller/session/active_record_store'
|
37
|
+
end
|
27
38
|
if !defined?(RUBY_ENGINE)
|
28
39
|
gem "activerecord-oracle-adapter"
|
29
40
|
require 'active_record/connection_adapters/oracle_adapter'
|