pmacs-activerecord-oracle_enhanced-adapter 1.4.2.rc1 → 1.5.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +11 -40
  3. data/History.md +170 -0
  4. data/README.md +61 -5
  5. data/Rakefile +1 -0
  6. data/VERSION +1 -1
  7. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +330 -161
  8. data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +48 -8
  9. data/lib/active_record/connection_adapters/oracle_enhanced_column_dumper.rb +77 -0
  10. data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +8 -24
  11. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +4 -13
  12. data/lib/active_record/connection_adapters/oracle_enhanced_database_tasks.rb +61 -0
  13. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +13 -12
  14. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +42 -19
  15. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +28 -74
  16. data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +165 -231
  17. data/lib/active_record/connection_adapters/oracle_enhanced_schema_creation.rb +89 -0
  18. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +16 -24
  19. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +29 -38
  20. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +93 -42
  21. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +5 -3
  22. data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +7 -7
  23. data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -1
  24. data/lib/pmacs-activerecord-oracle_enhanced-adapter.rb +2 -2
  25. data/pmacs-activerecord-oracle_enhanced-adapter.gemspec +19 -17
  26. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +35 -99
  27. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +17 -3
  28. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +105 -98
  29. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +74 -44
  30. data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +89 -0
  31. data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +3 -3
  32. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +13 -2
  33. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +11 -12
  34. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +252 -60
  35. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +170 -40
  36. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +14 -8
  37. data/spec/spec_helper.rb +25 -54
  38. metadata +41 -72
  39. data/lib/active_record/connection_adapters/oracle_enhanced.rake +0 -105
  40. data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +0 -41
  41. data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +0 -118
  42. data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +0 -25
  43. data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +0 -17
  44. data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +0 -19
@@ -23,7 +23,9 @@ module ActiveRecord
23
23
  def initialize(config)
24
24
  @raw_connection = OCI8EnhancedAutoRecover.new(config, OracleEnhancedOCIFactory)
25
25
  # default schema owner
26
- @owner = config[:username].to_s.upcase
26
+ @owner = config[:schema]
27
+ @owner ||= config[:username]
28
+ @owner = @owner.to_s.upcase
27
29
  end
28
30
 
29
31
  def raw_oci_connection
@@ -113,11 +115,17 @@ module ActiveRecord
113
115
  @raw_cursor = raw_cursor
114
116
  end
115
117
 
116
- def bind_param(position, value, col_type = nil)
117
- if value.nil?
118
+ def bind_param(position, value, column = nil)
119
+ if column && column.object_type?
120
+ if @connection.raw_connection.respond_to? :get_tdo_by_typename
121
+ @raw_cursor.bind_param(position, value, :named_type, column.sql_type)
122
+ else
123
+ raise "Use ruby-oci8 2.1.6 or later to bind Oracle objects."
124
+ end
125
+ elsif value.nil?
118
126
  @raw_cursor.bind_param(position, nil, String)
119
127
  else
120
- case col_type
128
+ case col_type = column && column.type
121
129
  when :text, :binary
122
130
  # ruby-oci8 cannot create CLOB/BLOB from ''
123
131
  lob_value = value == '' ? ' ' : value
@@ -202,15 +210,19 @@ module ActiveRecord
202
210
  def write_lob(lob, value, is_binary = false)
203
211
  lob.write value
204
212
  end
205
-
213
+
206
214
  def describe(name)
207
215
  # fall back to SELECT based describe if using database link
208
216
  return super if name.to_s.include?('@')
209
217
  quoted_name = OracleEnhancedAdapter.valid_table_name?(name) ? name : "\"#{name}\""
210
218
  @raw_connection.describe(quoted_name)
211
219
  rescue OCIException => e
212
- # fall back to SELECT which can handle synonyms to database links
213
- super
220
+ if e.code == 4043
221
+ raise OracleEnhancedConnectionException, %Q{"DESC #{name}" failed; does it exist?}
222
+ else
223
+ # fall back to SELECT which can handle synonyms to database links
224
+ super
225
+ end
214
226
  end
215
227
 
216
228
  # Return OCIError error code
@@ -244,9 +256,7 @@ module ActiveRecord
244
256
  else
245
257
  value
246
258
  end
247
- # ruby-oci8 1.0 returns OraDate
248
- # ruby-oci8 2.0 returns Time or DateTime
249
- when OraDate, Time, DateTime
259
+ when Time, DateTime
250
260
  if OracleEnhancedAdapter.emulate_dates && date_without_time?(value)
251
261
  value.to_date
252
262
  else
@@ -296,6 +306,7 @@ module ActiveRecord
296
306
  username = config[:username] && config[:username].to_s
297
307
  password = config[:password] && config[:password].to_s
298
308
  database = config[:database] && config[:database].to_s
309
+ schema = config[:schema] && config[:schema].to_s
299
310
  host, port = config[:host], config[:port]
300
311
  privilege = config[:privilege] && config[:privilege].to_sym
301
312
  async = config[:allow_concurrency]
@@ -323,6 +334,7 @@ module ActiveRecord
323
334
  conn.prefetch_rows = prefetch_rows
324
335
  conn.exec "alter session set cursor_sharing = #{cursor_sharing}" rescue nil
325
336
  conn.exec "alter session set time_zone = '#{time_zone}'" unless time_zone.blank?
337
+ conn.exec "alter session set current_schema = #{schema}" unless schema.blank?
326
338
 
327
339
  # Initialize NLS parameters
328
340
  OracleEnhancedAdapter::DEFAULT_NLS_PARAMETERS.each do |key, default_value|
@@ -343,66 +355,15 @@ end
343
355
 
344
356
  class OCI8 #:nodoc:
345
357
 
346
- class Cursor #:nodoc:
347
- if method_defined? :define_a_column
348
- # This OCI8 patch is required with the ruby-oci8 1.0.x or lower.
349
- # Set OCI8::BindType::Mapping[] to change the column type
350
- # when using ruby-oci8 2.0.
351
-
352
- alias :enhanced_define_a_column_pre_ar :define_a_column
353
- def define_a_column(i)
354
- case do_ocicall(@ctx) { @parms[i - 1].attrGet(OCI_ATTR_DATA_TYPE) }
355
- when 8; @stmt.defineByPos(i, String, 65535) # Read LONG values
356
- when 187; @stmt.defineByPos(i, OraDate) # Read TIMESTAMP values
357
- when 108
358
- if @parms[i - 1].attrGet(OCI_ATTR_TYPE_NAME) == 'XMLTYPE'
359
- @stmt.defineByPos(i, String, 65535)
360
- else
361
- raise 'unsupported datatype'
362
- end
363
- else enhanced_define_a_column_pre_ar i
364
- end
365
- end
366
- end
367
- end
368
-
369
- if OCI8.public_method_defined?(:describe_table)
370
- # ruby-oci8 2.0 or upper
371
-
372
- def describe(name)
373
- info = describe_table(name.to_s)
374
- raise %Q{"DESC #{name}" failed} if info.nil?
358
+ def describe(name)
359
+ info = describe_table(name.to_s)
360
+ raise %Q{"DESC #{name}" failed} if info.nil?
361
+ if info.respond_to? :obj_link and info.obj_link
362
+ [info.obj_schema, info.obj_name, '@' + info.obj_link]
363
+ else
375
364
  [info.obj_schema, info.obj_name]
376
365
  end
377
- else
378
- # ruby-oci8 1.0.x or lower
379
-
380
- # missing constant from oci8 < 0.1.14
381
- OCI_PTYPE_UNK = 0 unless defined?(OCI_PTYPE_UNK)
382
-
383
- # Uses the describeAny OCI call to find the target owner and table_name
384
- # indicated by +name+, parsing through synonynms as necessary. Returns
385
- # an array of [owner, table_name].
386
- def describe(name)
387
- @desc ||= @@env.alloc(OCIDescribe)
388
- @desc.attrSet(OCI_ATTR_DESC_PUBLIC, -1) if VERSION >= '0.1.14'
389
- do_ocicall(@ctx) { @desc.describeAny(@svc, name.to_s, OCI_PTYPE_UNK) } rescue raise %Q{"DESC #{name}" failed; does it exist?}
390
- info = @desc.attrGet(OCI_ATTR_PARAM)
391
-
392
- case info.attrGet(OCI_ATTR_PTYPE)
393
- when OCI_PTYPE_TABLE, OCI_PTYPE_VIEW
394
- owner = info.attrGet(OCI_ATTR_OBJ_SCHEMA)
395
- table_name = info.attrGet(OCI_ATTR_OBJ_NAME)
396
- [owner, table_name]
397
- when OCI_PTYPE_SYN
398
- schema = info.attrGet(OCI_ATTR_SCHEMA_NAME)
399
- name = info.attrGet(OCI_ATTR_NAME)
400
- describe(schema + '.' + name)
401
- else raise %Q{"DESC #{name}" failed; not a table or view.}
402
- end
403
- end
404
366
  end
405
-
406
367
  end
407
368
 
408
369
  # The OCI8AutoRecover class enhances the OCI8 driver with auto-recover and
@@ -480,12 +441,5 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
480
441
  end
481
442
  end
482
443
 
483
- # otherwise not working in Ruby 1.9.1
484
- if RUBY_VERSION =~ /^1\.9/
485
- def describe(name) #:nodoc:
486
- @connection.describe(name)
487
- end
488
- end
489
-
490
444
  end
491
445
  #:startdoc:
@@ -1,260 +1,194 @@
1
- # define accessors before requiring ruby-plsql as these accessors are used in clob writing callback and should be
2
- # available also if ruby-plsql could not be loaded
3
- ActiveRecord::Base.class_eval do
4
- if respond_to? :class_attribute
5
- class_attribute :custom_create_method, :custom_update_method, :custom_delete_method
6
- elsif respond_to? :class_inheritable_accessor
7
- class_inheritable_accessor :custom_create_method, :custom_update_method, :custom_delete_method
8
- end
9
- end
10
-
11
1
  require 'active_support'
12
2
 
13
3
  module ActiveRecord #:nodoc:
14
- module ConnectionAdapters #:nodoc:
15
- module OracleEnhancedProcedures #:nodoc:
16
-
17
- module ClassMethods
18
- # Specify custom create method which should be used instead of Rails generated INSERT statement.
19
- # Provided block should return ID of new record.
20
- # Example:
21
- # set_create_method do
22
- # plsql.employees_pkg.create_employee(
23
- # :p_first_name => first_name,
24
- # :p_last_name => last_name,
25
- # :p_employee_id => nil
26
- # )[:p_employee_id]
27
- # end
28
- def set_create_method(&block)
29
- include_with_custom_methods
30
- self.custom_create_method = block
31
- end
32
-
33
- # Specify custom update method which should be used instead of Rails generated UPDATE statement.
34
- # Example:
35
- # set_update_method do
36
- # plsql.employees_pkg.update_employee(
37
- # :p_employee_id => id,
38
- # :p_first_name => first_name,
39
- # :p_last_name => last_name
40
- # )
41
- # end
42
- def set_update_method(&block)
43
- include_with_custom_methods
44
- self.custom_update_method = block
45
- end
46
-
47
- # Specify custom delete method which should be used instead of Rails generated DELETE statement.
48
- # Example:
49
- # set_delete_method do
50
- # plsql.employees_pkg.delete_employee(
51
- # :p_employee_id => id
52
- # )
53
- # end
54
- def set_delete_method(&block)
55
- include_with_custom_methods
56
- self.custom_delete_method = block
57
- end
58
-
59
- if ActiveRecord::VERSION::MAJOR < 3
60
- def create_method_name_before_custom_methods #:nodoc:
61
- if private_method_defined?(:create_without_timestamps) && defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::STRING.to_f >= 2.3
62
- :create_without_timestamps
63
- elsif private_method_defined?(:create_without_callbacks)
64
- :create_without_callbacks
65
- else
66
- :create
67
- end
68
- end
69
-
70
- def update_method_name_before_custom_methods #:nodoc:
71
- if private_method_defined?(:update_without_dirty)
72
- :update_without_dirty
73
- elsif private_method_defined?(:update_without_timestamps) && defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::STRING.to_f >= 2.3
74
- :update_without_timestamps
75
- elsif private_method_defined?(:update_without_callbacks)
76
- :update_without_callbacks
77
- else
78
- :update
79
- end
80
- end
4
+ # Custom create, update, delete methods functionality.
5
+ #
6
+ # Example:
7
+ #
8
+ # class Employee < ActiveRecord::Base
9
+ # include ActiveRecord::OracleEnhancedProcedures
10
+ #
11
+ # set_create_method do
12
+ # plsql.employees_pkg.create_employee(
13
+ # :p_first_name => first_name,
14
+ # :p_last_name => last_name,
15
+ # :p_employee_id => nil
16
+ # )[:p_employee_id]
17
+ # end
18
+ #
19
+ # set_update_method do
20
+ # plsql.employees_pkg.update_employee(
21
+ # :p_employee_id => id,
22
+ # :p_first_name => first_name,
23
+ # :p_last_name => last_name
24
+ # )
25
+ # end
26
+ #
27
+ # set_delete_method do
28
+ # plsql.employees_pkg.delete_employee(
29
+ # :p_employee_id => id
30
+ # )
31
+ # end
32
+ # end
33
+ #
34
+ module OracleEnhancedProcedures #:nodoc:
35
+ module ClassMethods
36
+ # Specify custom create method which should be used instead of Rails generated INSERT statement.
37
+ # Provided block should return ID of new record.
38
+ # Example:
39
+ # set_create_method do
40
+ # plsql.employees_pkg.create_employee(
41
+ # :p_first_name => first_name,
42
+ # :p_last_name => last_name,
43
+ # :p_employee_id => nil
44
+ # )[:p_employee_id]
45
+ # end
46
+ def set_create_method(&block)
47
+ self.custom_create_method = block
48
+ end
81
49
 
82
- def destroy_method_name_before_custom_methods #:nodoc:
83
- if public_method_defined?(:destroy_without_callbacks)
84
- :destroy_without_callbacks
85
- else
86
- :destroy
87
- end
88
- end
89
- end
50
+ # Specify custom update method which should be used instead of Rails generated UPDATE statement.
51
+ # Example:
52
+ # set_update_method do
53
+ # plsql.employees_pkg.update_employee(
54
+ # :p_employee_id => id,
55
+ # :p_first_name => first_name,
56
+ # :p_last_name => last_name
57
+ # )
58
+ # end
59
+ def set_update_method(&block)
60
+ self.custom_update_method = block
61
+ end
90
62
 
91
- private
63
+ # Specify custom delete method which should be used instead of Rails generated DELETE statement.
64
+ # Example:
65
+ # set_delete_method do
66
+ # plsql.employees_pkg.delete_employee(
67
+ # :p_employee_id => id
68
+ # )
69
+ # end
70
+ def set_delete_method(&block)
71
+ self.custom_delete_method = block
72
+ end
73
+ end
92
74
 
93
- def include_with_custom_methods
94
- unless included_modules.include? InstanceMethods
95
- include InstanceMethods
96
- end
97
- end
75
+ def self.included(base)
76
+ base.class_eval do
77
+ extend ClassMethods
78
+ class_attribute :custom_create_method
79
+ class_attribute :custom_update_method
80
+ class_attribute :custom_delete_method
98
81
  end
82
+ end
99
83
 
100
- module InstanceMethods #:nodoc:
101
- def self.included(base)
102
- # alias methods just for ActiveRecord 2.x
103
- # for ActiveRecord 3.0 will just redefine create, update, delete methods which call super
104
- if ActiveRecord::VERSION::MAJOR < 3
105
- base.instance_eval do
106
- alias_method :create_without_custom_method, create_method_name_before_custom_methods
107
- alias_method create_method_name_before_custom_methods, :create_with_custom_method
108
- alias_method :update_without_custom_method, update_method_name_before_custom_methods
109
- alias_method update_method_name_before_custom_methods, :update_with_custom_method
110
- alias_method :destroy_without_custom_method, destroy_method_name_before_custom_methods
111
- alias_method destroy_method_name_before_custom_methods, :destroy_with_custom_method
112
- private :create, :update
113
- public :destroy
114
- end
115
- end
84
+ def destroy #:nodoc:
85
+ # check if class has custom delete method
86
+ if self.class.custom_delete_method
87
+ # wrap destroy in transaction
88
+ with_transaction_returning_status do
89
+ # run before/after callbacks defined in model
90
+ run_callbacks(:destroy) { destroy_using_custom_method }
116
91
  end
92
+ else
93
+ super
94
+ end
95
+ end
117
96
 
118
- if ActiveRecord::VERSION::MAJOR >= 3
119
- def destroy #:nodoc:
120
- # check if class has custom delete method
121
- if self.class.custom_delete_method
122
- # wrap destroy in transaction
123
- with_transaction_returning_status do
124
- # run before/after callbacks defined in model
125
- _run_destroy_callbacks { destroy_using_custom_method }
97
+ private
98
+
99
+ # Creates a record with custom create method
100
+ # and returns its id.
101
+ def _create_record
102
+ # check if class has custom create method
103
+ if self.class.custom_create_method
104
+ # run before/after callbacks defined in model
105
+ run_callbacks(:create) do
106
+ # timestamp
107
+ if self.record_timestamps
108
+ current_time = current_time_from_proper_timezone
109
+
110
+ all_timestamp_attributes.each do |column|
111
+ if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
112
+ write_attribute(column.to_s, current_time)
126
113
  end
127
- else
128
- super
129
- end
130
- end
131
- end
132
-
133
- private
134
-
135
- # Creates a record with custom create method
136
- # and returns its id.
137
- if ActiveRecord::VERSION::MAJOR < 3
138
- def create_with_custom_method
139
- # check if class has custom create method
140
- self.class.custom_create_method ? create_using_custom_method : create_without_custom_method
141
- end
142
- else # ActiveRecord 3.x
143
- def create
144
- # check if class has custom create method
145
- if self.class.custom_create_method
146
- set_timestamps_before_custom_create_method
147
- # run before/after callbacks defined in model
148
- _run_create_callbacks { create_using_custom_method }
149
- else
150
- super
151
114
  end
152
115
  end
116
+ # run
117
+ create_using_custom_method
153
118
  end
119
+ else
120
+ super
121
+ end
122
+ end
154
123
 
155
- def create_using_custom_method
156
- self.class.connection.log_custom_method("custom create method", "#{self.class.name} Create") do
157
- self.id = instance_eval(&self.class.custom_create_method)
158
- end
159
- @new_record = false
160
- # Starting from ActiveRecord 3.0.3 @persisted is used instead of @new_record
161
- @persisted = true
162
- id
163
- end
124
+ def create_using_custom_method
125
+ log_custom_method("custom create method", "#{self.class.name} Create") do
126
+ self.id = instance_eval(&self.class.custom_create_method)
127
+ end
128
+ @new_record = false
129
+ # Starting from ActiveRecord 3.0.3 @persisted is used instead of @new_record
130
+ @persisted = true
131
+ id
132
+ end
164
133
 
165
- # Updates the associated record with custom update method
166
- # Returns the number of affected rows.
167
- if ActiveRecord::VERSION::MAJOR < 3
168
- def update_with_custom_method(attribute_names = @attributes.keys)
169
- # check if class has custom create method
170
- self.class.custom_update_method ? update_using_custom_method(attribute_names) : update_without_custom_method(attribute_names)
171
- end
172
- else # ActiveRecord 3.x
173
- def update(attribute_names = @attributes.keys)
174
- # check if class has custom update method
175
- if self.class.custom_update_method
176
- set_timestamps_before_custom_update_method
177
- # run before/after callbacks defined in model
178
- _run_update_callbacks do
179
- # update just dirty attributes
180
- if partial_updates?
181
- # Serialized attributes should always be written in case they've been
182
- # changed in place.
183
- update_using_custom_method(changed | (attributes.keys & self.class.serialized_attributes.keys))
184
- else
185
- update_using_custom_method(attribute_names)
186
- end
187
- end
188
- else
189
- super
134
+ # Updates the associated record with custom update method
135
+ # Returns the number of affected rows.
136
+ def _update_record(attribute_names = @attributes.keys)
137
+ # check if class has custom update method
138
+ if self.class.custom_update_method
139
+ # run before/after callbacks defined in model
140
+ run_callbacks(:update) do
141
+ # timestamp
142
+ if should_record_timestamps?
143
+ current_time = current_time_from_proper_timezone
144
+
145
+ timestamp_attributes_for_update_in_model.each do |column|
146
+ column = column.to_s
147
+ next if attribute_changed?(column)
148
+ write_attribute(column, current_time)
190
149
  end
191
150
  end
192
- end
193
-
194
- def update_using_custom_method(attribute_names)
195
- return 0 if attribute_names.empty?
196
- self.class.connection.log_custom_method("custom update method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Update") do
197
- instance_eval(&self.class.custom_update_method)
198
- end
199
- 1
200
- end
201
-
202
- # Deletes the record in the database with custom delete method
203
- # and freezes this instance to reflect that no changes should
204
- # be made (since they can't be persisted).
205
- if ActiveRecord::VERSION::MAJOR < 3
206
- def destroy_with_custom_method
207
- # check if class has custom delete method
208
- self.class.custom_delete_method ? destroy_using_custom_method : destroy_without_custom_method
151
+ # update just dirty attributes
152
+ if partial_writes?
153
+ # Serialized attributes should always be written in case they've been
154
+ # changed in place.
155
+ update_using_custom_method(changed | (attributes.keys & self.class.serialized_attributes.keys))
156
+ else
157
+ update_using_custom_method(attribute_names)
209
158
  end
210
159
  end
160
+ else
161
+ super
162
+ end
163
+ end
211
164
 
212
- def destroy_using_custom_method
213
- unless new_record? || @destroyed
214
- self.class.connection.log_custom_method("custom delete method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Destroy") do
215
- instance_eval(&self.class.custom_delete_method)
216
- end
217
- end
218
-
219
- @destroyed = true
220
- freeze
221
- end
222
-
223
- if ActiveRecord::VERSION::MAJOR >= 3
224
- def set_timestamps_before_custom_create_method
225
- if record_timestamps
226
- current_time = current_time_from_proper_timezone
227
-
228
- write_attribute('created_at', current_time) if respond_to?(:created_at) && created_at.nil?
229
- write_attribute('created_on', current_time) if respond_to?(:created_on) && created_on.nil?
230
-
231
- write_attribute('updated_at', current_time) if respond_to?(:updated_at) && updated_at.nil?
232
- write_attribute('updated_on', current_time) if respond_to?(:updated_on) && updated_on.nil?
233
- end
234
- end
235
-
236
- def set_timestamps_before_custom_update_method
237
- if record_timestamps && (!partial_updates? || changed?)
238
- current_time = current_time_from_proper_timezone
165
+ def update_using_custom_method(attribute_names)
166
+ return 0 if attribute_names.empty?
167
+ log_custom_method("custom update method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Update") do
168
+ instance_eval(&self.class.custom_update_method)
169
+ end
170
+ 1
171
+ end
239
172
 
240
- write_attribute('updated_at', current_time) if respond_to?(:updated_at)
241
- write_attribute('updated_on', current_time) if respond_to?(:updated_on)
242
- end
243
- end
173
+ # Deletes the record in the database with custom delete method
174
+ # and freezes this instance to reflect that no changes should
175
+ # be made (since they can't be persisted).
176
+ def destroy_using_custom_method
177
+ unless new_record? || @destroyed
178
+ log_custom_method("custom delete method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Destroy") do
179
+ instance_eval(&self.class.custom_delete_method)
244
180
  end
245
-
246
181
  end
247
182
 
183
+ @destroyed = true
184
+ freeze
248
185
  end
249
- end
250
- end
251
186
 
252
- ActiveRecord::Base.class_eval do
253
- extend ActiveRecord::ConnectionAdapters::OracleEnhancedProcedures::ClassMethods
254
- end
187
+ def log_custom_method(*args)
188
+ self.class.connection.send(:log, *args) { yield }
189
+ end
255
190
 
256
- ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
257
- # public alias to log method which could be used from other objects
258
- alias_method :log_custom_method, :log
259
- public :log_custom_method
191
+ alias_method :update_record, :_update_record if private_method_defined?(:_update_record)
192
+ alias_method :create_record, :_create_record if private_method_defined?(:_create_record)
193
+ end
260
194
  end