activerecord-oracle_enhanced-adapter 1.2.2 → 1.2.3

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/.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