activerecord-oracle_enhanced-adapter-with-schema 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/Gemfile +52 -0
- data/History.md +301 -0
- data/License.txt +20 -0
- data/README.md +123 -0
- data/RUNNING_TESTS.md +45 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/activerecord-oracle_enhanced-adapter-with-schema.gemspec +130 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced.rake +105 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb +41 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +1399 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +121 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +146 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_connection.rb +119 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +359 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb +25 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +21 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +46 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +565 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +494 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +260 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +227 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +260 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +428 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +258 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +294 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +17 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +1 -0
- data/lib/activerecord-oracle_enhanced-adapter-with-schema.rb +25 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +778 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +332 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +427 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb +19 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +113 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +1388 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb +69 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +141 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +25 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +378 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +440 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +1385 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +339 -0
- data/spec/spec_helper.rb +189 -0
- metadata +260 -0
@@ -0,0 +1,260 @@
|
|
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
|
+
require 'active_support'
|
12
|
+
|
13
|
+
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
|
81
|
+
|
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
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def include_with_custom_methods
|
94
|
+
unless included_modules.include? InstanceMethods
|
95
|
+
include InstanceMethods
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
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
|
116
|
+
end
|
117
|
+
|
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 }
|
126
|
+
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
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
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
|
164
|
+
|
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
|
190
|
+
end
|
191
|
+
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
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
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
|
239
|
+
|
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
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
ActiveRecord::Base.class_eval do
|
253
|
+
extend ActiveRecord::ConnectionAdapters::OracleEnhancedProcedures::ClassMethods
|
254
|
+
end
|
255
|
+
|
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
|
260
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
class OracleEnhancedForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
class OracleEnhancedSynonymDefinition < Struct.new(:name, :table_owner, :table_name, :db_link) #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
class OracleEnhancedIndexDefinition < Struct.new(:table, :name, :unique, :type, :parameters, :statement_parameters,
|
10
|
+
:tablespace, :columns) #:nodoc:
|
11
|
+
end
|
12
|
+
|
13
|
+
module OracleEnhancedColumnDefinition
|
14
|
+
def self.included(base) #:nodoc:
|
15
|
+
base.class_eval do
|
16
|
+
alias_method_chain :to_sql, :virtual_columns
|
17
|
+
alias to_s :to_sql
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_sql_with_virtual_columns
|
22
|
+
if type == :virtual
|
23
|
+
sql_type = base.type_to_sql(default[:type], limit, precision, scale) if default[:type]
|
24
|
+
"#{base.quote_column_name(name)} #{sql_type} AS (#{default[:as]})"
|
25
|
+
else
|
26
|
+
to_sql_without_virtual_columns
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def lob?
|
31
|
+
['CLOB', 'BLOB'].include?(sql_type)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module OracleEnhancedSchemaDefinitions #:nodoc:
|
36
|
+
def self.included(base)
|
37
|
+
base::TableDefinition.class_eval do
|
38
|
+
include OracleEnhancedTableDefinition
|
39
|
+
end
|
40
|
+
|
41
|
+
base::ColumnDefinition.class_eval do
|
42
|
+
include OracleEnhancedColumnDefinition
|
43
|
+
end
|
44
|
+
|
45
|
+
# Available starting from ActiveRecord 2.1
|
46
|
+
base::Table.class_eval do
|
47
|
+
include OracleEnhancedTable
|
48
|
+
end if defined?(base::Table)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module OracleEnhancedTableDefinition
|
53
|
+
class ForeignKey < Struct.new(:base, :to_table, :options) #:nodoc:
|
54
|
+
def to_sql
|
55
|
+
base.foreign_key_definition(to_table, options)
|
56
|
+
end
|
57
|
+
alias to_s :to_sql
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.included(base) #:nodoc:
|
61
|
+
base.class_eval do
|
62
|
+
alias_method_chain :references, :foreign_keys
|
63
|
+
alias_method_chain :to_sql, :foreign_keys
|
64
|
+
|
65
|
+
alias_method_chain :column, :virtual_columns
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def raw(name, options={})
|
70
|
+
column(name, :raw, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def virtual(* args)
|
74
|
+
options = args.extract_options!
|
75
|
+
column_names = args
|
76
|
+
column_names.each { |name| column(name, :virtual, options) }
|
77
|
+
end
|
78
|
+
|
79
|
+
def column_with_virtual_columns(name, type, options = {})
|
80
|
+
if type == :virtual
|
81
|
+
default = {:type => options[:type]}
|
82
|
+
if options[:as]
|
83
|
+
default[:as] = options[:as]
|
84
|
+
elsif options[:default]
|
85
|
+
warn "[DEPRECATION] virtual column `:default` option is deprecated. Please use `:as` instead."
|
86
|
+
default[:as] = options[:default]
|
87
|
+
else
|
88
|
+
raise "No virtual column definition found."
|
89
|
+
end
|
90
|
+
options[:default] = default
|
91
|
+
end
|
92
|
+
column_without_virtual_columns(name, type, options)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Adds a :foreign_key option to TableDefinition.references.
|
96
|
+
# If :foreign_key is true, a foreign key constraint is added to the table.
|
97
|
+
# You can also specify a hash, which is passed as foreign key options.
|
98
|
+
#
|
99
|
+
# ===== Examples
|
100
|
+
# ====== Add goat_id column and a foreign key to the goats table.
|
101
|
+
# t.references(:goat, :foreign_key => true)
|
102
|
+
# ====== Add goat_id column and a cascading foreign key to the goats table.
|
103
|
+
# t.references(:goat, :foreign_key => {:dependent => :delete})
|
104
|
+
#
|
105
|
+
# Note: No foreign key is created if :polymorphic => true is used.
|
106
|
+
# Note: If no name is specified, the database driver creates one for you!
|
107
|
+
def references_with_foreign_keys(*args)
|
108
|
+
options = args.extract_options!
|
109
|
+
fk_options = options.delete(:foreign_key)
|
110
|
+
|
111
|
+
if fk_options && !options[:polymorphic]
|
112
|
+
fk_options = {} if fk_options == true
|
113
|
+
args.each { |to_table| foreign_key(to_table, fk_options) }
|
114
|
+
end
|
115
|
+
|
116
|
+
references_without_foreign_keys(*(args << options))
|
117
|
+
end
|
118
|
+
|
119
|
+
# Defines a foreign key for the table. +to_table+ can be a single Symbol, or
|
120
|
+
# an Array of Symbols. See SchemaStatements#add_foreign_key
|
121
|
+
#
|
122
|
+
# ===== Examples
|
123
|
+
# ====== Creating a simple foreign key
|
124
|
+
# t.foreign_key(:people)
|
125
|
+
# ====== Defining the column
|
126
|
+
# t.foreign_key(:people, :column => :sender_id)
|
127
|
+
# ====== Creating a named foreign key
|
128
|
+
# t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
|
129
|
+
# ====== Defining the column of the +to_table+.
|
130
|
+
# t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
|
131
|
+
def foreign_key(to_table, options = {})
|
132
|
+
if @base.respond_to?(:supports_foreign_keys?) && @base.supports_foreign_keys?
|
133
|
+
to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
|
134
|
+
foreign_keys << ForeignKey.new(@base, to_table, options)
|
135
|
+
else
|
136
|
+
raise ArgumentError, "this ActiveRecord adapter is not supporting foreign_key definition"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_sql_with_foreign_keys #:nodoc:
|
141
|
+
sql = to_sql_without_foreign_keys
|
142
|
+
sql << ', ' << (foreign_keys * ', ') unless foreign_keys.blank?
|
143
|
+
sql
|
144
|
+
end
|
145
|
+
|
146
|
+
def lob_columns
|
147
|
+
columns.select(&:lob?)
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
def foreign_keys
|
152
|
+
@foreign_keys ||= []
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
module OracleEnhancedTable
|
157
|
+
def self.included(base) #:nodoc:
|
158
|
+
base.class_eval do
|
159
|
+
alias_method_chain :references, :foreign_keys
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
|
164
|
+
# an Array of Symbols. See SchemaStatements#add_foreign_key
|
165
|
+
#
|
166
|
+
# ===== Examples
|
167
|
+
# ====== Creating a simple foreign key
|
168
|
+
# t.foreign_key(:people)
|
169
|
+
# ====== Defining the column
|
170
|
+
# t.foreign_key(:people, :column => :sender_id)
|
171
|
+
# ====== Creating a named foreign key
|
172
|
+
# t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
|
173
|
+
# ====== Defining the column of the +to_table+.
|
174
|
+
# t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
|
175
|
+
def foreign_key(to_table, options = {})
|
176
|
+
if @base.respond_to?(:supports_foreign_keys?) && @base.supports_foreign_keys?
|
177
|
+
to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
|
178
|
+
@base.add_foreign_key(@table_name, to_table, options)
|
179
|
+
else
|
180
|
+
raise ArgumentError, "this ActiveRecord adapter is not supporting foreign_key definition"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Remove the given foreign key from the table.
|
185
|
+
#
|
186
|
+
# ===== Examples
|
187
|
+
# ====== Remove the suppliers_company_id_fk in the suppliers table.
|
188
|
+
# t.remove_foreign_key :companies
|
189
|
+
# ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
|
190
|
+
# remove_foreign_key :column => :branch_id
|
191
|
+
# ====== Remove the foreign key named party_foreign_key in the accounts table.
|
192
|
+
# remove_index :name => :party_foreign_key
|
193
|
+
def remove_foreign_key(options = {})
|
194
|
+
@base.remove_foreign_key(@table_name, options)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Adds a :foreign_key option to TableDefinition.references.
|
198
|
+
# If :foreign_key is true, a foreign key constraint is added to the table.
|
199
|
+
# You can also specify a hash, which is passed as foreign key options.
|
200
|
+
#
|
201
|
+
# ===== Examples
|
202
|
+
# ====== Add goat_id column and a foreign key to the goats table.
|
203
|
+
# t.references(:goat, :foreign_key => true)
|
204
|
+
# ====== Add goat_id column and a cascading foreign key to the goats table.
|
205
|
+
# t.references(:goat, :foreign_key => {:dependent => :delete})
|
206
|
+
#
|
207
|
+
# Note: No foreign key is created if :polymorphic => true is used.
|
208
|
+
def references_with_foreign_keys(*args)
|
209
|
+
options = args.extract_options!
|
210
|
+
polymorphic = options[:polymorphic]
|
211
|
+
fk_options = options.delete(:foreign_key)
|
212
|
+
|
213
|
+
references_without_foreign_keys(*(args << options))
|
214
|
+
# references_without_foreign_keys adds {:type => :integer}
|
215
|
+
args.extract_options!
|
216
|
+
if fk_options && !polymorphic
|
217
|
+
fk_options = {} if fk_options == true
|
218
|
+
args.each { |to_table| foreign_key(to_table, fk_options) }
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
ActiveRecord::ConnectionAdapters.class_eval do
|
226
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaDefinitions
|
227
|
+
end
|