activerecord-oracle_enhanced-adapter 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .svn
2
+ .DS_Store
3
+ coverage
4
+ doc
5
+ pkg
6
+ log
7
+ tmp
8
+ sqlnet.log
9
+ activerecord-oracle_enhanced-adapter.gemspec
10
+
data/History.txt CHANGED
@@ -1,3 +1,23 @@
1
+ == 1.2.3 2009-12-09
2
+
3
+ * Enhancements
4
+ * support fractional seconds in TIMESTAMP values
5
+ * support for ActiveRecord 2.3.5
6
+ * use ENV['TZ'] to set database session time zone
7
+ (as a result DATE and TIMESTAMP values are retrieved with correct time zone)
8
+ * added cache_columns adapter option
9
+ * added current_user adapter method
10
+ * added set_integer_columns and set_string_columns ActiveRecord model class methods
11
+ * Bug fixes:
12
+ * do not raise exception if ENV['PATH'] is nil
13
+ * do not add change_table behavior for ActiveRecord 2.0 (to avoid exception during loading)
14
+ * move foreign key definitions after definition of all tables in schema.rb
15
+ (to avoid definition of foreign keys before all tables are created)
16
+ * changed timestamp format mask to use ':' before fractional seconds
17
+ (workaround to avoid table detection in tables_in_string method in ActiveRecord associations.rb file)
18
+ * fixed custom create/update/delete methods with ActiveRecord 2.3+ and timestamps
19
+ * do not call oracle_enhanced specific schema dump methods when using other database adapters
20
+
1
21
  == 1.2.2 2009-09-28
2
22
 
3
23
  * Enhancements
data/Manifest.txt ADDED
@@ -0,0 +1,32 @@
1
+ History.txt
2
+ License.txt
3
+ README.rdoc
4
+ lib/active_record/connection_adapters/emulation/oracle_adapter.rb
5
+ lib/active_record/connection_adapters/oracle_enhanced.rake
6
+ lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
7
+ lib/active_record/connection_adapters/oracle_enhanced_connection.rb
8
+ lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb
9
+ lib/active_record/connection_adapters/oracle_enhanced_cpk.rb
10
+ lib/active_record/connection_adapters/oracle_enhanced_dirty.rb
11
+ lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb
12
+ lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb
13
+ lib/active_record/connection_adapters/oracle_enhanced_procedures.rb
14
+ lib/active_record/connection_adapters/oracle_enhanced_reserved_words.rb
15
+ lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb
16
+ lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb
17
+ lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb
18
+ lib/active_record/connection_adapters/oracle_enhanced_tasks.rb
19
+ lib/active_record/connection_adapters/oracle_enhanced_version.rb
20
+ spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb
21
+ spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb
22
+ spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb
23
+ spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb
24
+ spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
25
+ spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb
26
+ spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb
27
+ spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb
28
+ spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb
29
+ spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb
30
+ spec/active_record/connection_adapters/oracle_enhanced_schema_spec.rb
31
+ spec/spec.opts
32
+ spec/spec_helper.rb
data/README.rdoc CHANGED
@@ -1,27 +1,23 @@
1
- = Activerecord Oracle enhanced adapter
1
+ = activerecord-oracle_enhanced-adapter
2
2
 
3
- * http://github.com/rsim/oracle-enhanced
3
+ Oracle enhanced adapter for ActiveRecord
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
7
  Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases
8
8
  from Rails which are extracted from current real projects' monkey patches of original Oracle adapter.
9
9
 
10
- See http://github.com/rsim/oracle-enhanced/wikis for usage information.
11
-
12
- See http://oracle-enhanced.rubyforge.org/rdoc for detailed API documentation.
10
+ See http://wiki.github.com/rsim/oracle-enhanced for usage information.
13
11
 
14
12
  For questions and feature discussion please use http://groups.google.com/group/oracle-enhanced
15
13
 
16
14
  Blog posts about oracle-enahnced can be found at http://blog.rayapps.com/category/oracle-enhanced
17
15
 
18
- Bugs and enhancement requests can be reported at http://rsim.lighthouseapp.com/projects/11468-oracle-enhanced
19
-
20
16
  == REQUIREMENTS:
21
17
 
22
18
  * Works (has been tested) with ActiveRecord version 2.0, 2.1, 2.2 and 2.3 (these are the same as Rails versions)
23
19
  * Can be used on the following Ruby platforms:
24
- * MRI - requires ruby-oci8 1.x or 2.x library to connect to Oracle
20
+ * MRI - requires ruby-oci8 1.x or 2.x gem to connect to Oracle (2.0.3 or later recommended)
25
21
  * Ruby/YARV 1.9.1 - requires ruby-oci8 2.x library to connect to Oracle
26
22
  unicode_utils gem is recommended for Unicode aware string upcase and downcase
27
23
  * JRuby - uses JDBC driver ojdbc14.jar to connect to Oracle (should be in JRUBY_HOME/lib or in Java class path)
@@ -31,6 +27,14 @@ Bugs and enhancement requests can be reported at http://rsim.lighthouseapp.com/p
31
27
 
32
28
  * [sudo] gem install activerecord-oracle_enhanced-adapter
33
29
 
30
+ In addition install either ruby-oci8 (for MRI/YARV) or copy Oracle JDBC driver to $JRUBY_HOME/lib (for JRuby).
31
+
32
+ == LINKS
33
+
34
+ * Source code: http://github.com/rsim/oracle-enhanced
35
+ * Bug reports / Feature requests: http://github.com/rsim/oracle-enhanced/issues
36
+ * Discuss at oracle_enhanced adapter group: http://groups.google.com/group/oracle-enhanced
37
+
34
38
  == CONTRIBUTORS:
35
39
 
36
40
  * Raimonds Simanovskis
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "activerecord-oracle_enhanced-adapter"
8
+ gem.summary = "Oracle enhanced adapter for ActiveRecord"
9
+ gem.description = <<-EOS
10
+ Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases.
11
+ This adapter is superset of original ActiveRecord Oracle adapter.
12
+ EOS
13
+ gem.email = "raimonds.simanovskis@gmail.com"
14
+ gem.homepage = "http://github.com/rsim/oracle-enhanced"
15
+ gem.authors = ["Raimonds Simanovskis"]
16
+ gem.add_dependency "activerecord", ">= 2.0.0"
17
+ gem.add_development_dependency "rspec", ">= 1.2.9"
18
+ gem.extra_rdoc_files = ['README.rdoc']
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ require 'spec/rake/spectask'
26
+ Spec::Rake::SpecTask.new(:spec) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.spec_files = FileList['spec/**/*_spec.rb']
29
+ end
30
+
31
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
32
+ spec.libs << 'lib' << 'spec'
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.rcov = true
35
+ end
36
+
37
+ task :spec => :check_dependencies
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'doc'
46
+ rdoc.title = "activerecord-oracle_enhanced-adapter #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.2.3
@@ -78,6 +78,23 @@ module ActiveRecord
78
78
  connection.set_type_for_columns(table_name,:boolean,*args)
79
79
  end
80
80
 
81
+ # Specify which table columns should be typecasted to integer values.
82
+ # Might be useful to force NUMBER(1) column to be integer and not boolean, or force NUMBER column without
83
+ # scale to be retrieved as integer and not decimal. Example:
84
+ #
85
+ # set_integer_columns :version_number, :object_identifier
86
+ def self.set_integer_columns(*args)
87
+ connection.set_type_for_columns(table_name,:integer,*args)
88
+ end
89
+
90
+ # Specify which table columns should be typecasted to string values.
91
+ # Might be useful to specify that columns should be string even if its name matches boolean column criteria.
92
+ #
93
+ # set_integer_columns :active_flag
94
+ def self.set_string_columns(*args)
95
+ connection.set_type_for_columns(table_name,:string,*args)
96
+ end
97
+
81
98
  # After setting large objects to empty, select the OCI8::LOB
82
99
  # and write back the data.
83
100
  after_save :enhanced_write_lobs
@@ -170,23 +187,24 @@ module ActiveRecord
170
187
 
171
188
  private
172
189
  def simplified_type(field_type)
173
- return :boolean if OracleEnhancedAdapter.emulate_booleans && field_type == 'NUMBER(1)'
174
- return :boolean if OracleEnhancedAdapter.emulate_booleans_from_strings &&
175
- (forced_column_type == :boolean ||
176
- OracleEnhancedAdapter.is_boolean_column?(name, field_type, table_name))
177
-
190
+ forced_column_type ||
178
191
  case field_type
192
+ when /decimal|numeric|number/i
193
+ return :boolean if OracleEnhancedAdapter.emulate_booleans && field_type == 'NUMBER(1)'
194
+ return :integer if extract_scale(field_type) == 0
195
+ # if column name is ID or ends with _ID
196
+ return :integer if OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(name, table_name)
197
+ :decimal
198
+ when /char/i
199
+ return :boolean if OracleEnhancedAdapter.emulate_booleans_from_strings &&
200
+ OracleEnhancedAdapter.is_boolean_column?(name, field_type, table_name)
201
+ :string
179
202
  when /date/i
180
203
  forced_column_type ||
181
204
  (:date if OracleEnhancedAdapter.emulate_dates_by_column_name && OracleEnhancedAdapter.is_date_column?(name, table_name)) ||
182
205
  :datetime
183
206
  when /timestamp/i then :timestamp
184
207
  when /time/i then :datetime
185
- when /decimal|numeric|number/i
186
- return :integer if extract_scale(field_type) == 0
187
- # if column name is ID or ends with _ID
188
- return :integer if OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(name, table_name)
189
- :decimal
190
208
  else super
191
209
  end
192
210
  end
@@ -263,6 +281,8 @@ module ActiveRecord
263
281
  # * <tt>:cursor_sharing</tt> - cursor sharing mode to minimize amount of unique statements, defaults to "force"
264
282
  # * <tt>:nls_length_semantics</tt> - semantics of size of VARCHAR2 and CHAR columns, defaults to "CHAR"
265
283
  # (meaning that size specifies number of characters and not bytes)
284
+ # * <tt>:time_zone</tt> - database session time zone
285
+ # (it is recommended to set it using ENV['TZ'] which will be then also used for database session time zone)
266
286
  class OracleEnhancedAdapter < AbstractAdapter
267
287
 
268
288
  ##
@@ -363,12 +383,16 @@ module ActiveRecord
363
383
  bool ? "Y" : "N"
364
384
  end
365
385
 
386
+ ##
387
+ # :singleton-method:
366
388
  # Specify non-default date format that should be used when assigning string values to :date columns, e.g.:
367
389
  #
368
390
  # ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = “%d.%m.%Y”
369
391
  cattr_accessor :string_to_date_format
370
392
  self.string_to_date_format = nil
371
393
 
394
+ ##
395
+ # :singleton-method:
372
396
  # Specify non-default time format that should be used when assigning string values to :datetime columns, e.g.:
373
397
  #
374
398
  # ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = “%d.%m.%Y %H:%M:%S”
@@ -490,8 +514,8 @@ module ActiveRecord
490
514
 
491
515
  def quote_timestamp_with_to_timestamp(value) #:nodoc:
492
516
  # add up to 9 digits of fractional seconds to inserted time
493
- value = "#{quoted_date(value)}.#{("%.6f"%value.to_f).split('.')[1]}" if value.acts_like?(:time)
494
- "TO_TIMESTAMP('#{value}','YYYY-MM-DD HH24:MI:SS.FF6')"
517
+ value = "#{quoted_date(value)}:#{("%.6f"%value.to_f).split('.')[1]}" if value.acts_like?(:time)
518
+ "TO_TIMESTAMP('#{value}','YYYY-MM-DD HH24:MI:SS:FF6')"
495
519
  end
496
520
 
497
521
  # CONNECTION MANAGEMENT ====================================
@@ -689,10 +713,16 @@ module ActiveRecord
689
713
  #
690
714
  # see: abstract/schema_statements.rb
691
715
 
692
- def current_database #:nodoc:
716
+ # current database name
717
+ def current_database
693
718
  select_one("select sys_context('userenv','db_name') db from dual")["db"]
694
719
  end
695
720
 
721
+ # current database session user
722
+ def current_user
723
+ select_one("select sys_context('userenv','session_user') u from dual")['u']
724
+ end
725
+
696
726
  def tables(name = nil) #:nodoc:
697
727
  # changed select from user_tables to all_tables - much faster in large data dictionaries
698
728
  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']}
@@ -793,7 +823,27 @@ module ActiveRecord
793
823
  select_value(pkt_sql) ? true : false
794
824
  end
795
825
 
826
+ ##
827
+ # :singleton-method:
828
+ # Cache column description between requests.
829
+ # Could be used in development environment to avoid selecting table columns from data dictionary tables for each request.
830
+ # This can speed up request processing in development mode if development database is not on local computer.
831
+ #
832
+ # ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
833
+ cattr_accessor :cache_columns
834
+ self.cache_columns = false
835
+
796
836
  def columns(table_name, name = nil) #:nodoc:
837
+ # Don't double cache if config.cache_classes is turned on
838
+ if @@cache_columns && !(defined?(Rails) && Rails.configuration.cache_classes)
839
+ @@columns_cache ||= {}
840
+ @@columns_cache[table_name] ||= columns_without_cache(table_name, name)
841
+ else
842
+ columns_without_cache(table_name, name)
843
+ end
844
+ end
845
+
846
+ def columns_without_cache(table_name, name = nil) #:nodoc:
797
847
  # get ignored_columns by original table name
798
848
  ignored_columns = ignored_table_columns(table_name)
799
849
 
@@ -844,6 +894,11 @@ module ActiveRecord
844
894
  end
845
895
  end
846
896
 
897
+ # used just in tests to clear column cache
898
+ def clear_columns_cache #:nodoc:
899
+ @@columns_cache = nil
900
+ end
901
+
847
902
  ##
848
903
  # :singleton-method:
849
904
  # Specify default sequence start with value (by default 10000 if not explicitly set), e.g.:
@@ -1379,3 +1434,4 @@ require 'active_record/connection_adapters/oracle_enhanced_schema_definitions'
1379
1434
  # Add BigDecimal#to_d, Fixnum#to_d and Bignum#to_d methods if not already present
1380
1435
  require 'active_record/connection_adapters/oracle_enhanced_core_ext'
1381
1436
 
1437
+ require 'active_record/connection_adapters/oracle_enhanced_version'
@@ -7,11 +7,9 @@ begin
7
7
  ojdbc_jar = "ojdbc14.jar"
8
8
 
9
9
  unless ENV_JAVA['java.class.path'] =~ Regexp.new(ojdbc_jar)
10
- # Adds JRuby classloader to current thread classloader - as a result ojdbc14.jar should not be in $JRUBY_HOME/lib
11
- # not necessary anymore for JRuby 1.3
12
- # java.lang.Thread.currentThread.setContextClassLoader(JRuby.runtime.jruby_class_loader)
13
-
14
- if ojdbc_jar_path = ENV["PATH"].split(/[:;]/).concat($LOAD_PATH).find{|d| File.exists?(File.join(d,ojdbc_jar))}
10
+ # On Unix environment variable should be PATH, on Windows it is sometimes Path
11
+ env_path = ENV["PATH"] || ENV["Path"] || ''
12
+ if ojdbc_jar_path = env_path.split(/[:;]/).concat($LOAD_PATH).find{|d| File.exists?(File.join(d,ojdbc_jar))}
15
13
  require File.join(ojdbc_jar_path,ojdbc_jar)
16
14
  end
17
15
  end
@@ -71,6 +69,8 @@ module ActiveRecord
71
69
  cursor_sharing = config[:cursor_sharing] || 'force'
72
70
  # by default VARCHAR2 column size will be interpreted as max number of characters (and not bytes)
73
71
  nls_length_semantics = config[:nls_length_semantics] || 'CHAR'
72
+ # get session time_zone from configuration or from TZ environment variable
73
+ time_zone = config[:time_zone] || ENV['TZ'] || java.util.TimeZone.default.getID
74
74
 
75
75
  properties = java.util.Properties.new
76
76
  properties.put("user", username)
@@ -80,13 +80,13 @@ module ActiveRecord
80
80
 
81
81
  @raw_connection = java.sql.DriverManager.getConnection(url, properties)
82
82
  exec %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'}
83
- exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'}
83
+ exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS:FF6'}
84
84
  exec "alter session set cursor_sharing = #{cursor_sharing}"
85
85
  exec "alter session set nls_length_semantics = '#{nls_length_semantics}'"
86
86
  self.autocommit = true
87
87
 
88
88
  # Set session time zone to current time zone
89
- @raw_connection.setSessionTimeZone(java.util.TimeZone.default.getID)
89
+ @raw_connection.setSessionTimeZone(time_zone)
90
90
 
91
91
  # Set default number of rows to prefetch
92
92
  # @raw_connection.setDefaultRowPrefetch(prefetch_rows) if prefetch_rows
@@ -4,10 +4,11 @@ begin
4
4
  require 'oci8' unless self.class.const_defined? :OCI8
5
5
 
6
6
  # added mapping for TIMESTAMP / WITH TIME ZONE / LOCAL TIME ZONE types
7
- # currently Ruby-OCI8 does not support fractional seconds for timestamps
8
- OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP] = OCI8::BindType::OraDate
9
- OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_TZ] = OCI8::BindType::OraDate
10
- OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_LTZ] = OCI8::BindType::OraDate
7
+ # latest version of Ruby-OCI8 supports fractional seconds for timestamps
8
+ # therefore default binding to Time class should be used
9
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP] = OCI8::BindType::OraDate
10
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_TZ] = OCI8::BindType::OraDate
11
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_LTZ] = OCI8::BindType::OraDate
11
12
  rescue LoadError
12
13
  # OCI8 driver is unavailable.
13
14
  error_message = "ERROR: ActiveRecord oracle_enhanced adapter could not load ruby-oci8 library. "+
@@ -192,15 +193,17 @@ module ActiveRecord
192
193
  end
193
194
 
194
195
  def create_time_with_default_timezone(value)
195
- year, month, day, hour, min, sec = case value
196
+ year, month, day, hour, min, sec, usec = case value
197
+ when Time
198
+ [value.year, value.month, value.day, value.hour, value.min, value.sec, value.usec]
196
199
  when OraDate
197
- [value.year, value.month, value.day, value.hour, value.minute, value.second]
200
+ [value.year, value.month, value.day, value.hour, value.minute, value.second, 0]
198
201
  else
199
- [value.year, value.month, value.day, value.hour, value.min, value.sec]
202
+ [value.year, value.month, value.day, value.hour, value.min, value.sec, 0]
200
203
  end
201
204
  # code from Time.time_with_datetime_fallback
202
205
  begin
203
- Time.send(Base.default_timezone, year, month, day, hour, min, sec)
206
+ Time.send(Base.default_timezone, year, month, day, hour, min, sec, usec)
204
207
  rescue
205
208
  offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
206
209
  ::DateTime.civil(year, month, day, hour, min, sec, offset)
@@ -219,15 +222,18 @@ module ActiveRecord
219
222
  cursor_sharing = config[:cursor_sharing] || 'force'
220
223
  # by default VARCHAR2 column size will be interpreted as max number of characters (and not bytes)
221
224
  nls_length_semantics = config[:nls_length_semantics] || 'CHAR'
225
+ # get session time_zone from configuration or from TZ environment variable
226
+ time_zone = config[:time_zone] || ENV['TZ']
222
227
 
223
228
  conn = OCI8.new username, password, database, privilege
224
229
  conn.exec %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'}
225
- conn.exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'} rescue nil
230
+ conn.exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS:FF6'} rescue nil
226
231
  conn.autocommit = true
227
232
  conn.non_blocking = true if async
228
233
  conn.prefetch_rows = prefetch_rows
229
234
  conn.exec "alter session set cursor_sharing = #{cursor_sharing}" rescue nil
230
235
  conn.exec "alter session set nls_length_semantics = '#{nls_length_semantics}'"
236
+ conn.exec "alter session set time_zone = '#{time_zone}'" unless time_zone.blank?
231
237
  conn
232
238
  end
233
239
  end
@@ -5,7 +5,7 @@ ActiveRecord::Base.class_eval do
5
5
  end
6
6
 
7
7
  require 'ruby_plsql'
8
- require 'activesupport'
8
+ require 'active_support'
9
9
 
10
10
  module ActiveRecord #:nodoc:
11
11
  module ConnectionAdapters #:nodoc:
@@ -53,6 +53,36 @@ module ActiveRecord #:nodoc:
53
53
  self.custom_delete_method = block
54
54
  end
55
55
 
56
+ def create_method_name_before_custom_methods
57
+ if private_method_defined?(:create_without_timestamps) && defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::STRING.to_f >= 2.3
58
+ :create_without_timestamps
59
+ elsif private_method_defined?(:create_without_callbacks)
60
+ :create_without_callbacks
61
+ else
62
+ :create
63
+ end
64
+ end
65
+
66
+ def update_method_name_before_custom_methods
67
+ if private_method_defined?(:update_without_dirty)
68
+ :update_without_dirty
69
+ elsif private_method_defined?(:update_without_timestamps) && defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::STRING.to_f >= 2.3
70
+ :update_without_timestamps
71
+ elsif private_method_defined?(:update_without_callbacks)
72
+ :update_without_callbacks
73
+ else
74
+ :update
75
+ end
76
+ end
77
+
78
+ def destroy_method_name_before_custom_methods
79
+ if public_method_defined?(:destroy_without_callbacks)
80
+ :destroy_without_callbacks
81
+ else
82
+ :destroy
83
+ end
84
+ end
85
+
56
86
  private
57
87
  def include_with_custom_methods
58
88
  unless included_modules.include? InstanceMethods
@@ -64,30 +94,13 @@ module ActiveRecord #:nodoc:
64
94
  module InstanceMethods #:nodoc:
65
95
  def self.included(base)
66
96
  base.instance_eval do
67
- if private_instance_methods.include?('create_without_callbacks') || private_instance_methods.include?(:create_without_callbacks)
68
- alias_method :create_without_custom_method, :create_without_callbacks
69
- alias_method :create_without_callbacks, :create_with_custom_method
70
- else
71
- alias_method_chain :create, :custom_method
72
- end
73
- # insert after dirty checking in Rails 2.1
74
- # in Ruby 1.9 methods names are returned as symbols
75
- if private_instance_methods.include?('update_without_dirty') || private_instance_methods.include?(:update_without_dirty)
76
- alias_method :update_without_custom_method, :update_without_dirty
77
- alias_method :update_without_dirty, :update_with_custom_method
78
- elsif private_instance_methods.include?('update_without_callbacks') || private_instance_methods.include?(:update_without_callbacks)
79
- alias_method :update_without_custom_method, :update_without_callbacks
80
- alias_method :update_without_callbacks, :update_with_custom_method
81
- else
82
- alias_method_chain :update, :custom_method
83
- end
97
+ alias_method :create_without_custom_method, create_method_name_before_custom_methods
98
+ alias_method create_method_name_before_custom_methods, :create_with_custom_method
99
+ alias_method :update_without_custom_method, update_method_name_before_custom_methods
100
+ alias_method update_method_name_before_custom_methods, :update_with_custom_method
101
+ alias_method :destroy_without_custom_method, destroy_method_name_before_custom_methods
102
+ alias_method destroy_method_name_before_custom_methods, :destroy_with_custom_method
84
103
  private :create, :update
85
- if public_instance_methods.include?('destroy_without_callbacks') || public_instance_methods.include?(:destroy_without_callbacks)
86
- alias_method :destroy_without_custom_method, :destroy_without_callbacks
87
- alias_method :destroy_without_callbacks, :destroy_with_custom_method
88
- else
89
- alias_method_chain :destroy, :custom_method
90
- end
91
104
  public :destroy
92
105
  end
93
106
  end
@@ -130,6 +143,7 @@ module ActiveRecord #:nodoc:
130
143
  end
131
144
  end
132
145
 
146
+ @destroyed = true
133
147
  freeze
134
148
  end
135
149
 
@@ -12,9 +12,10 @@ module ActiveRecord
12
12
  include OracleEnhancedTableDefinition
13
13
  end
14
14
 
15
+ # Available starting from ActiveRecord 2.1
15
16
  base::Table.class_eval do
16
17
  include OracleEnhancedTable
17
- end
18
+ end if defined?(base::Table)
18
19
  end
19
20
  end
20
21
 
@@ -80,7 +81,7 @@ module ActiveRecord
80
81
 
81
82
  def to_sql_with_foreign_keys #:nodoc:
82
83
  sql = to_sql_without_foreign_keys
83
- sql << ', ' << (foreign_keys * ', ') if foreign_keys.present?
84
+ sql << ', ' << (foreign_keys * ', ') unless foreign_keys.blank?
84
85
  sql
85
86
  end
86
87
 
@@ -13,7 +13,8 @@ module ActiveRecord #:nodoc:
13
13
  private
14
14
 
15
15
  def tables_with_oracle_enhanced(stream)
16
- @connection.tables.sort.each do |tbl|
16
+ sorted_tables = @connection.tables.sort
17
+ sorted_tables.each do |tbl|
17
18
  # add table prefix or suffix for schema_migrations
18
19
  next if [ActiveRecord::Migrator.proper_table_name('schema_migrations'), ignore_tables].flatten.any? do |ignored|
19
20
  case ignored
@@ -28,9 +29,12 @@ module ActiveRecord #:nodoc:
28
29
  table(tbl, stream)
29
30
  # add primary key trigger if table has it
30
31
  primary_key_trigger(tbl, stream)
32
+ end
33
+ sorted_tables.each do |tbl|
31
34
  # add foreign keys if table has them
32
35
  foreign_keys(tbl, stream)
33
36
  end
37
+ # add synonyms in local schema
34
38
  synonyms(stream)
35
39
  end
36
40
 
@@ -44,7 +48,7 @@ module ActiveRecord #:nodoc:
44
48
  end
45
49
 
46
50
  def foreign_keys(table_name, stream)
47
- if (foreign_keys = @connection.foreign_keys(table_name)).any?
51
+ if @connection.respond_to?(:foreign_keys) && (foreign_keys = @connection.foreign_keys(table_name)).any?
48
52
  add_foreign_key_statements = foreign_keys.map do |foreign_key|
49
53
  statement_parts = [ ('add_foreign_key ' + foreign_key.from_table.inspect) ]
50
54
  statement_parts << foreign_key.to_table.inspect
@@ -56,7 +60,7 @@ module ActiveRecord #:nodoc:
56
60
  if foreign_key.options[:primary_key] != 'id'
57
61
  statement_parts << (':primary_key => ' + foreign_key.options[:primary_key].inspect)
58
62
  end
59
- if foreign_key.options[:dependent].present?
63
+ unless foreign_key.options[:dependent].blank?
60
64
  statement_parts << (':dependent => ' + foreign_key.options[:dependent].inspect)
61
65
  end
62
66
 
@@ -69,15 +73,17 @@ module ActiveRecord #:nodoc:
69
73
  end
70
74
 
71
75
  def synonyms(stream)
72
- syns = @connection.synonyms
73
- syns.each do |syn|
74
- table_name = syn.table_name
75
- table_name = "#{syn.table_owner}.#{table_name}" if syn.table_owner
76
- table_name = "#{table_name}@#{syn.db_link}" if syn.db_link
77
- stream.print " add_synonym #{syn.name.inspect}, #{table_name.inspect}, :force => true"
78
- stream.puts
76
+ if @connection.respond_to?(:synonyms)
77
+ syns = @connection.synonyms
78
+ syns.each do |syn|
79
+ table_name = syn.table_name
80
+ table_name = "#{syn.table_owner}.#{table_name}" if syn.table_owner
81
+ table_name = "#{table_name}@#{syn.db_link}" if syn.db_link
82
+ stream.print " add_synonym #{syn.name.inspect}, #{table_name.inspect}, :force => true"
83
+ stream.puts
84
+ end
85
+ stream.puts unless syns.empty?
79
86
  end
80
- stream.puts unless syns.empty?
81
87
  end
82
88
 
83
89
  def indexes_with_oracle_enhanced(table, stream)
@@ -1,7 +1 @@
1
- module ActiveRecord #:nodoc:
2
- module ConnectionAdapters #:nodoc:
3
- module OracleEnhancedVersion #:nodoc:
4
- VERSION = '1.2.2'
5
- end
6
- end
7
- end
1
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter::VERSION = '1.2.3'
@@ -34,6 +34,8 @@ describe "OracleEnhancedAdapter establish connection" do
34
34
  end
35
35
 
36
36
  describe "OracleEnhancedAdapter" do
37
+ include LoggerSpecHelper
38
+
37
39
  before(:all) do
38
40
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
39
41
  @conn = ActiveRecord::Base.connection
@@ -173,6 +175,77 @@ describe "OracleEnhancedAdapter" do
173
175
 
174
176
  end
175
177
 
178
+ describe "cache table columns" do
179
+ before(:all) do
180
+ @conn.execute "DROP TABLE test_employees" rescue nil
181
+ @conn.execute <<-SQL
182
+ CREATE TABLE test_employees (
183
+ id NUMBER,
184
+ first_name VARCHAR2(20),
185
+ last_name VARCHAR2(25),
186
+ hire_date DATE
187
+ )
188
+ SQL
189
+ @column_names = ['id', 'first_name', 'last_name', 'hire_date']
190
+ class ::TestEmployee < ActiveRecord::Base
191
+ end
192
+ end
193
+
194
+ after(:all) do
195
+ Object.send(:remove_const, "TestEmployee")
196
+ @conn.execute "DROP TABLE test_employees"
197
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = nil
198
+ end
199
+
200
+ before(:each) do
201
+ @buffer = StringIO.new
202
+ log_to @buffer
203
+ @conn = ActiveRecord::Base.connection
204
+ @conn.clear_columns_cache
205
+ end
206
+
207
+ describe "without column caching" do
208
+
209
+ before(:each) do
210
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = false
211
+ end
212
+
213
+ it "should get columns from database at first time" do
214
+ TestEmployee.connection.columns('test_employees').map(&:name).should == @column_names
215
+ @buffer.string.should =~ /select .* from all_tab_columns/im
216
+ end
217
+
218
+ it "should get columns from database at second time" do
219
+ TestEmployee.connection.columns('test_employees')
220
+ @buffer.truncate(0)
221
+ TestEmployee.connection.columns('test_employees').map(&:name).should == @column_names
222
+ @buffer.string.should =~ /select .* from all_tab_columns/im
223
+ end
224
+
225
+ end
226
+
227
+ describe "with column caching" do
228
+
229
+ before(:each) do
230
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
231
+ end
232
+
233
+ it "should get columns from database at first time" do
234
+ TestEmployee.connection.columns('test_employees').map(&:name).should == @column_names
235
+ @buffer.string.should =~ /select .* from all_tab_columns/im
236
+ end
237
+
238
+ it "should get columns from cache at second time" do
239
+ TestEmployee.connection.columns('test_employees')
240
+ @buffer.truncate(0)
241
+ TestEmployee.connection.columns('test_employees').map(&:name).should == @column_names
242
+ @buffer.string.should be_blank
243
+ end
244
+
245
+ end
246
+
247
+ end
248
+
176
249
  describe "without composite_primary_keys" do
177
250
 
178
251
  before(:all) do
@@ -362,4 +435,14 @@ describe "OracleEnhancedAdapter" do
362
435
 
363
436
  end
364
437
 
438
+ describe "session information" do
439
+ it "should get current database name" do
440
+ @conn.current_database.should == CONNECTION_PARAMS[:database]
441
+ end
442
+
443
+ it "should get current database session user" do
444
+ @conn.current_user.should == CONNECTION_PARAMS[:username].upcase
445
+ end
446
+ end
447
+
365
448
  end
@@ -105,7 +105,7 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
105
105
  after(:each) do
106
106
  # @employee.destroy if @employee
107
107
  Object.send(:remove_const, "TestEmployee")
108
- ActiveRecord::Base.connection.clear_types_for_columns
108
+ @conn.clear_types_for_columns
109
109
  end
110
110
 
111
111
  it "should return Time value from DATE column if emulate_dates_by_column_name is false" do
@@ -202,6 +202,7 @@ describe "OracleEnhancedAdapter integer type detection based on column names" do
202
202
  salary NUMBER,
203
203
  commission_pct NUMBER(2,2),
204
204
  manager_id NUMBER(6),
205
+ is_manager NUMBER(1),
205
206
  department_id NUMBER(4,0),
206
207
  created_at DATE
207
208
  )
@@ -262,6 +263,8 @@ describe "OracleEnhancedAdapter integer type detection based on column names" do
262
263
 
263
264
  after(:each) do
264
265
  Object.send(:remove_const, "Test2Employee")
266
+ @conn.clear_types_for_columns
267
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = true
265
268
  end
266
269
 
267
270
  def create_employee2
@@ -269,6 +272,7 @@ describe "OracleEnhancedAdapter integer type detection based on column names" do
269
272
  :first_name => "First",
270
273
  :last_name => "Last",
271
274
  :job_id => 1,
275
+ :is_manager => 1,
272
276
  :salary => 1000
273
277
  )
274
278
  @employee2.reload
@@ -292,6 +296,32 @@ describe "OracleEnhancedAdapter integer type detection based on column names" do
292
296
  @employee2.salary.class.should == BigDecimal
293
297
  end
294
298
 
299
+ it "should return Fixnum value from NUMBER column if column specified in set_integer_columns" do
300
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = false
301
+ Test2Employee.set_integer_columns :job_id
302
+ create_employee2
303
+ @employee2.job_id.class.should == Fixnum
304
+ end
305
+
306
+ it "should return Boolean value from NUMBER(1) column if emulate booleans is used" do
307
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = true
308
+ create_employee2
309
+ @employee2.is_manager.class.should == TrueClass
310
+ end
311
+
312
+ it "should return Fixnum value from NUMBER(1) column if emulate booleans is not used" do
313
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = false
314
+ create_employee2
315
+ @employee2.is_manager.class.should == Fixnum
316
+ end
317
+
318
+ it "should return Fixnum value from NUMBER(1) column if column specified in set_integer_columns" do
319
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = true
320
+ Test2Employee.set_integer_columns :is_manager
321
+ create_employee2
322
+ @employee2.is_manager.class.should == Fixnum
323
+ end
324
+
295
325
  end
296
326
 
297
327
  end
@@ -330,6 +360,7 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
330
360
  after(:all) do
331
361
  @conn.execute "DROP TABLE test3_employees"
332
362
  @conn.execute "DROP SEQUENCE test3_employees_seq"
363
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
333
364
  end
334
365
 
335
366
  it "should set CHAR/VARCHAR2 column type as string if emulate_booleans_from_strings is false" do
@@ -384,7 +415,7 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
384
415
  :boolean, nil, nil, nil).should == "VARCHAR2(1)"
385
416
  end
386
417
 
387
- it "should translate boolean type to NUMBER(1) if emulate_booleans_from_strings is true" do
418
+ it "should translate boolean type to NUMBER(1) if emulate_booleans_from_strings is false" do
388
419
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = false
389
420
  ActiveRecord::Base.connection.type_to_sql(
390
421
  :boolean, nil, nil, nil).should == "NUMBER(1)"
@@ -406,6 +437,7 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
406
437
 
407
438
  after(:each) do
408
439
  Object.send(:remove_const, "Test3Employee")
440
+ @conn.clear_types_for_columns
409
441
  end
410
442
 
411
443
  def create_employee3(params={})
@@ -451,9 +483,7 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
451
483
 
452
484
  it "should return boolean value from VARCHAR2 boolean column if column specified in set_boolean_columns" do
453
485
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
454
- class ::Test3Employee < ActiveRecord::Base
455
- set_boolean_columns :test_boolean
456
- end
486
+ Test3Employee.set_boolean_columns :test_boolean
457
487
  create_employee3(:test_boolean => true)
458
488
  @employee3.test_boolean.class.should == TrueClass
459
489
  @employee3.test_boolean_before_type_cast.should == "Y"
@@ -467,7 +497,14 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
467
497
  @employee3.test_boolean.class.should == NilClass
468
498
  @employee3.test_boolean_before_type_cast.should == nil
469
499
  end
470
-
500
+
501
+ it "should return string value from VARCHAR2 column with boolean column name but is specified in set_string_columns" do
502
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
503
+ Test3Employee.set_string_columns :active_flag
504
+ create_employee3
505
+ @employee3.active_flag.class.should == String
506
+ end
507
+
471
508
  end
472
509
 
473
510
  end
@@ -523,7 +560,6 @@ describe "OracleEnhancedAdapter timestamp with timezone support" do
523
560
  end
524
561
 
525
562
  it "should return Time value from TIMESTAMP columns" do
526
- # currently fractional seconds are not retrieved from database
527
563
  @now = Time.local(2008,5,26,23,11,11,0)
528
564
  @employee = TestEmployee.create(
529
565
  :created_at => @now,
@@ -537,35 +573,17 @@ describe "OracleEnhancedAdapter timestamp with timezone support" do
537
573
  end
538
574
  end
539
575
 
540
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
541
- it "should return Time value with fractional seconds from TIMESTAMP columns" do
542
- # currently fractional seconds are not retrieved from database
543
- @now = Time.local(2008,5,26,23,11,11,10)
544
- @employee = TestEmployee.create(
545
- :created_at => @now,
546
- :created_at_tz => @now,
547
- :created_at_ltz => @now
548
- )
549
- @employee.reload
550
- [:created_at, :created_at_tz, :created_at_ltz].each do |c|
551
- @employee.send(c).class.should == Time
552
- @employee.send(c).to_f.should == @now.to_f
553
- end
554
- end
555
- else
556
- it "should return Time value without fractional seconds from TIMESTAMP columns" do
557
- # currently fractional seconds are not retrieved from database
558
- @now = Time.local(2008,5,26,23,11,11,10)
559
- @employee = TestEmployee.create(
560
- :created_at => @now,
561
- :created_at_tz => @now,
562
- :created_at_ltz => @now
563
- )
564
- @employee.reload
565
- [:created_at, :created_at_tz, :created_at_ltz].each do |c|
566
- @employee.send(c).class.should == Time
567
- @employee.send(c).to_f.should == @now.to_f.to_i.to_f # remove fractional seconds
568
- end
576
+ it "should return Time value with fractional seconds from TIMESTAMP columns" do
577
+ @now = Time.local(2008,5,26,23,11,11,10)
578
+ @employee = TestEmployee.create(
579
+ :created_at => @now,
580
+ :created_at_tz => @now,
581
+ :created_at_ltz => @now
582
+ )
583
+ @employee.reload
584
+ [:created_at, :created_at_tz, :created_at_ltz].each do |c|
585
+ @employee.send(c).class.should == Time
586
+ @employee.send(c).to_f.should == @now.to_f
569
587
  end
570
588
  end
571
589
 
@@ -674,7 +692,7 @@ describe "OracleEnhancedAdapter date and timestamp with different NLS date forma
674
692
  it "should quote Time values with TO_TIMESTAMP" do
675
693
  @ts = @now + 0.1
676
694
  @conn.quote(@ts).should == "TO_TIMESTAMP('#{@ts.year}-#{"%02d" % @ts.month}-#{"%02d" % @ts.day} "+
677
- "#{"%02d" % @ts.hour}:#{"%02d" % @ts.min}:#{"%02d" % @ts.sec}.100000','YYYY-MM-DD HH24:MI:SS.FF6')"
695
+ "#{"%02d" % @ts.hour}:#{"%02d" % @ts.min}:#{"%02d" % @ts.sec}:100000','YYYY-MM-DD HH24:MI:SS:FF6')"
678
696
  end
679
697
 
680
698
  end
@@ -26,6 +26,10 @@ describe "OracleEnhancedAdapter logging dbms_output from plsql" do
26
26
  SQL
27
27
  end
28
28
 
29
+ after(:all) do
30
+ ActiveRecord::Base.connection.execute "DROP FUNCTION MORE_THAN_FIVE_CHARACTERS_LONG"
31
+ end
32
+
29
33
  before(:each) do
30
34
  @buffer = StringIO.new
31
35
  log_to @buffer
@@ -6,7 +6,7 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
6
6
  before(:all) do
7
7
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
8
8
  @conn = ActiveRecord::Base.connection
9
- plsql.connection = ActiveRecord::Base.connection.raw_connection
9
+ plsql.activerecord_class = ActiveRecord::Base
10
10
  @conn.execute("DROP TABLE test_employees") rescue nil
11
11
  @conn.execute <<-SQL
12
12
  CREATE TABLE test_employees (
@@ -18,7 +18,9 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
18
18
  description CLOB,
19
19
  version NUMBER(15,0),
20
20
  create_time DATE,
21
- update_time DATE
21
+ update_time DATE,
22
+ created_at DATE,
23
+ updated_at DATE
22
24
  )
23
25
  SQL
24
26
  @conn.execute("DROP SEQUENCE test_employees_s") rescue nil
@@ -168,10 +170,9 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
168
170
  TestEmployee.class_eval { def after_create() raise "Make the transaction rollback" end }
169
171
  begin
170
172
  employees_count = TestEmployee.count
171
- @employee.save
172
- fail "Did not raise exception"
173
- rescue => e
174
- e.message.should == "Make the transaction rollback"
173
+ lambda {
174
+ @employee.save
175
+ }.should raise_error("Make the transaction rollback")
175
176
  @employee.id.should == nil
176
177
  TestEmployee.count.should == employees_count
177
178
  ensure
@@ -205,10 +206,9 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
205
206
  empl_id = @employee.id
206
207
  @employee.reload
207
208
  @employee.first_name = "Second"
208
- @employee.save!
209
- fail "Did not raise exception"
210
- rescue => e
211
- e.message.should == "Make the transaction rollback"
209
+ lambda {
210
+ @employee.save
211
+ }.should raise_error("Make the transaction rollback")
212
212
  @employee.reload
213
213
  @employee.first_name.should == "First"
214
214
  ensure
@@ -257,20 +257,31 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
257
257
  TestEmployee.find_by_employee_id(empl_id).should be_nil
258
258
  end
259
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 }
260
+ it "should delete record and set destroyed flag" do
261
+ return pending("Not in this ActiveRecord version (requires >= 2.3.5)") unless TestEmployee.method_defined?(:destroyed?)
262
262
  @employee = TestEmployee.create(
263
263
  :first_name => "First",
264
264
  :last_name => "Last",
265
265
  :hire_date => @today
266
266
  )
267
267
  @employee.reload
268
- empl_id = @employee.id
268
+ @employee.destroy
269
+ @employee.should be_destroyed
270
+ end
271
+
272
+ it "should rollback record when exception is raised in after_desotry callback" do
273
+ TestEmployee.class_eval { def after_destroy() raise "Make the transaction rollback" end }
269
274
  begin
270
- @employee.destroy
271
- fail "Did not raise exception"
272
- rescue => e
273
- e.message.should == "Make the transaction rollback"
275
+ @employee = TestEmployee.create(
276
+ :first_name => "First",
277
+ :last_name => "Last",
278
+ :hire_date => @today
279
+ )
280
+ @employee.reload
281
+ empl_id = @employee.id
282
+ lambda {
283
+ @employee.destroy
284
+ }.should raise_error("Make the transaction rollback")
274
285
  @employee.id.should == empl_id
275
286
  TestEmployee.find_by_employee_id(empl_id).should_not be_nil
276
287
  ensure
@@ -278,10 +289,33 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
278
289
  end
279
290
  end
280
291
 
292
+ it "should set timestamps when creating record" do
293
+ @employee = TestEmployee.create(
294
+ :first_name => "First",
295
+ :last_name => "Last",
296
+ :hire_date => @today
297
+ )
298
+ @employee.created_at.should_not be_nil
299
+ @employee.updated_at.should_not be_nil
300
+ end
301
+
302
+ it "should set timestamps when updating record" do
303
+ @employee = TestEmployee.create(
304
+ :first_name => "First",
305
+ :last_name => "Last",
306
+ :hire_date => @today
307
+ )
308
+ @employee.reload
309
+ @employee.created_at.should be_nil
310
+ @employee.updated_at.should be_nil
311
+ @employee.first_name = "Second"
312
+ @employee.save!
313
+ @employee.created_at.should be_nil
314
+ @employee.updated_at.should_not be_nil
315
+ end
316
+
281
317
  it "should log create record" do
282
318
  log_to @buffer
283
- # reestablish plsql.connection as log_to might reset existing connection
284
- plsql.connection = ActiveRecord::Base.connection.raw_connection
285
319
  @employee = TestEmployee.create(
286
320
  :first_name => "First",
287
321
  :last_name => "Last",
@@ -298,8 +332,6 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
298
332
  :hire_date => @today
299
333
  )
300
334
  log_to @buffer
301
- # reestablish plsql.connection as log_to might reset existing connection
302
- plsql.connection = ActiveRecord::Base.connection.raw_connection
303
335
  @employee.save!
304
336
  @buffer.string.should match(/^TestEmployee Update \(\d+\.\d+(ms)?\) custom update method with employee_id=#{@employee.id}$/)
305
337
  end
@@ -311,8 +343,6 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
311
343
  :hire_date => @today
312
344
  )
313
345
  log_to @buffer
314
- # reestablish plsql.connection as log_to might reset existing connection
315
- plsql.connection = ActiveRecord::Base.connection.raw_connection
316
346
  @employee.destroy
317
347
  @buffer.string.should match(/^TestEmployee Destroy \(\d+\.\d+(ms)?\) custom delete method with employee_id=#{@employee.id}$/)
318
348
  end
@@ -139,6 +139,7 @@ describe "OracleEnhancedAdapter schema dump" do
139
139
 
140
140
  after(:each) do
141
141
  drop_test_posts_table
142
+ @conn.clear_prefetch_primary_key
142
143
  end
143
144
 
144
145
  it "should include primary key trigger in schema dump" do
@@ -572,6 +572,7 @@ describe "OracleEnhancedAdapter schema definition" do
572
572
  end
573
573
 
574
574
  it "should add foreign key in change_table" do
575
+ return pending("Not in this ActiveRecord version") unless ENV['RAILS_GEM_VERSION'] >= '2.1'
575
576
  schema_define do
576
577
  create_table :test_comments, :force => true do |t|
577
578
  t.string :body, :limit => 4000
@@ -587,6 +588,7 @@ describe "OracleEnhancedAdapter schema definition" do
587
588
  end
588
589
 
589
590
  it "should add foreign key in change_table references" do
591
+ return pending("Not in this ActiveRecord version") unless ENV['RAILS_GEM_VERSION'] >= '2.1'
590
592
  schema_define do
591
593
  create_table :test_comments, :force => true do |t|
592
594
  t.string :body, :limit => 4000
@@ -601,6 +603,7 @@ describe "OracleEnhancedAdapter schema definition" do
601
603
  end
602
604
 
603
605
  it "should remove foreign key by table name" do
606
+ return pending("Not in this ActiveRecord version") unless ENV['RAILS_GEM_VERSION'] >= '2.1'
604
607
  schema_define do
605
608
  create_table :test_comments, :force => true do |t|
606
609
  t.string :body, :limit => 4000
data/spec/spec_helper.rb CHANGED
@@ -25,15 +25,15 @@ elsif ENV['RAILS_GEM_VERSION'] =~ /^2.3.3/
25
25
  gem 'activesupport', '=2.3.3'
26
26
  gem 'composite_primary_keys', '=2.3.2'
27
27
  else
28
- ENV['RAILS_GEM_VERSION'] ||= '2.3.4'
29
- gem 'activerecord', '=2.3.4'
30
- gem 'actionpack', '=2.3.4'
31
- gem 'activesupport', '=2.3.4'
28
+ ENV['RAILS_GEM_VERSION'] ||= '2.3.5'
29
+ gem 'activerecord', '=2.3.5'
30
+ gem 'actionpack', '=2.3.5'
31
+ gem 'activesupport', '=2.3.5'
32
32
  NO_COMPOSITE_PRIMARY_KEYS = true
33
33
  end
34
34
 
35
- require 'activerecord'
36
- require 'actionpack'
35
+ require 'active_record'
36
+ require 'action_pack'
37
37
  if ENV['RAILS_GEM_VERSION'] >= '2.3'
38
38
  require 'action_controller/session/abstract_store'
39
39
  require 'active_record/session_store'
@@ -42,14 +42,14 @@ else
42
42
  end
43
43
  if !defined?(RUBY_ENGINE)
44
44
  # change version to 1.0.6 to test with old oracle_adapter
45
- gem 'ruby-oci8', '>=2.0.2'
45
+ gem 'ruby-oci8', '=2.0.3'
46
46
  require 'oci8'
47
47
  if OCI8::VERSION =~ /^1\./
48
48
  gem "activerecord-oracle-adapter"
49
49
  require 'active_record/connection_adapters/oracle_adapter'
50
50
  end
51
51
  elsif RUBY_ENGINE == 'ruby'
52
- gem 'ruby-oci8', '>=2.0.2'
52
+ gem 'ruby-oci8', '=2.0.3'
53
53
  require 'oci8'
54
54
  elsif RUBY_ENGINE == 'jruby'
55
55
  gem "activerecord-jdbc-adapter"
@@ -123,3 +123,7 @@ SYSTEM_CONNECTION_PARAMS = {
123
123
 
124
124
  # For JRuby Set default $KCODE to UTF8
125
125
  $KCODE = "UTF8" if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
126
+
127
+ # set default time zone in TZ environment variable
128
+ # which will be used to set session time zone
129
+ ENV['TZ'] ||= 'Europe/Riga'
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.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raimonds Simanovskis
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-28 00:00:00 +03:00
12
+ date: 2009-12-09 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -23,42 +23,34 @@ dependencies:
23
23
  version: 2.0.0
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
- name: hoe
26
+ name: rspec
27
27
  type: :development
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 2.3.3
33
+ version: 1.2.9
34
34
  version:
35
- description: |-
36
- Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases
37
- from Rails which are extracted from current real projects' monkey patches of original Oracle adapter.
38
-
39
- See http://github.com/rsim/oracle-enhanced/wikis for usage information.
40
-
41
- See http://oracle-enhanced.rubyforge.org/rdoc for detailed API documentation.
42
-
43
- For questions and feature discussion please use http://groups.google.com/group/oracle-enhanced
44
-
45
- Blog posts about oracle-enahnced can be found at http://blog.rayapps.com/category/oracle-enhanced
46
-
47
- Bugs and enhancement requests can be reported at http://rsim.lighthouseapp.com/projects/11468-oracle-enhanced
48
- email:
49
- - raimonds.simanovskis@gmail.com
35
+ description: |
36
+ Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases.
37
+ This adapter is superset of original ActiveRecord Oracle adapter.
38
+
39
+ email: raimonds.simanovskis@gmail.com
50
40
  executables: []
51
41
 
52
42
  extensions: []
53
43
 
54
44
  extra_rdoc_files:
55
- - History.txt
56
- - License.txt
57
45
  - README.rdoc
58
46
  files:
47
+ - .gitignore
59
48
  - History.txt
60
49
  - License.txt
50
+ - Manifest.txt
61
51
  - README.rdoc
52
+ - Rakefile
53
+ - VERSION
62
54
  - lib/active_record/connection_adapters/emulation/oracle_adapter.rb
63
55
  - lib/active_record/connection_adapters/oracle_enhanced.rake
64
56
  - lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
@@ -94,8 +86,7 @@ licenses: []
94
86
 
95
87
  post_install_message:
96
88
  rdoc_options:
97
- - --main
98
- - README.rdoc
89
+ - --charset=UTF-8
99
90
  require_paths:
100
91
  - lib
101
92
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -112,10 +103,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
103
  version:
113
104
  requirements: []
114
105
 
115
- rubyforge_project: oracle-enhanced
116
- rubygems_version: 1.3.3
106
+ rubyforge_project:
107
+ rubygems_version: 1.3.5
117
108
  signing_key:
118
109
  specification_version: 3
119
- summary: Oracle enhaced adapter for Active Record
120
- test_files: []
121
-
110
+ summary: Oracle enhanced adapter for ActiveRecord
111
+ test_files:
112
+ - spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb
113
+ - spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb
114
+ - spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb
115
+ - spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb
116
+ - spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
117
+ - spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb
118
+ - spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb
119
+ - spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb
120
+ - spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb
121
+ - spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb
122
+ - spec/active_record/connection_adapters/oracle_enhanced_schema_spec.rb
123
+ - spec/spec_helper.rb