pmacs-activerecord-oracle_enhanced-adapter 1.5.6.1 → 1.6.2.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.
- checksums.yaml +4 -4
- data/Gemfile +7 -7
- data/History.md +126 -0
- data/README.md +285 -178
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/{oracle_enhanced_column.rb → oracle_enhanced/column.rb} +14 -63
- data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +65 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_connection.rb → oracle_enhanced/connection.rb} +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +347 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_cpk.rb → oracle_enhanced/cpk.rb} +0 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +257 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_database_tasks.rb → oracle_enhanced/database_tasks.rb} +0 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/dirty.rb +40 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_jdbc_connection.rb → oracle_enhanced/jdbc_connection.rb} +0 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_oci_connection.rb → oracle_enhanced/oci_connection.rb} +0 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_procedures.rb → oracle_enhanced/procedures.rb} +1 -3
- data/lib/active_record/connection_adapters/{oracle_enhanced_schema_creation.rb → oracle_enhanced/schema_creation.rb} +34 -35
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_schema_dumper.rb → oracle_enhanced/schema_dumper.rb} +4 -32
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +548 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +74 -0
- data/lib/active_record/connection_adapters/{oracle_enhanced_structure_dump.rb → oracle_enhanced/structure_dump.rb} +28 -6
- data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +161 -68
- data/lib/active_record/oracle_enhanced/type/integer.rb +13 -0
- data/lib/active_record/oracle_enhanced/type/raw.rb +13 -0
- data/lib/active_record/oracle_enhanced/type/timestamp.rb +11 -0
- data/lib/pmacs-activerecord-oracle_enhanced-adapter.rb +1 -1
- data/pmacs-activerecord-oracle_enhanced-adapter.gemspec +35 -31
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +6 -31
- data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +1 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +75 -63
- data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +1 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +7 -13
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +2 -1
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +25 -178
- data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +60 -5
- data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +1 -0
- data/spec/spec_helper.rb +21 -10
- metadata +32 -28
- data/lib/active_record/connection_adapters/oracle_enhanced_column_dumper.rb +0 -77
- data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +0 -350
- data/lib/active_record/connection_adapters/oracle_enhanced_database_statements.rb +0 -262
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +0 -45
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +0 -223
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +0 -450
- data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +0 -267
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +0 -1
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module OracleEnhancedSchemaStatementsExt
|
6
|
+
# Create primary key trigger (so that you can skip primary key value in INSERT statement).
|
7
|
+
# By default trigger name will be "table_name_pkt", you can override the name with
|
8
|
+
# :trigger_name option (but it is not recommended to override it as then this trigger will
|
9
|
+
# not be detected by ActiveRecord model and it will still do prefetching of sequence value).
|
10
|
+
#
|
11
|
+
# add_primary_key_trigger :users
|
12
|
+
#
|
13
|
+
# You can also create primary key trigger using +create_table+ with :primary_key_trigger
|
14
|
+
# option:
|
15
|
+
#
|
16
|
+
# create_table :users, :primary_key_trigger => true do |t|
|
17
|
+
# # ...
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
def add_primary_key_trigger(table_name, options={})
|
21
|
+
# call the same private method that is used for create_table :primary_key_trigger => true
|
22
|
+
create_primary_key_trigger(table_name, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def table_definition_tablespace
|
26
|
+
# TODO: Support specifying an :index_tablespace option in create_table?
|
27
|
+
tablespace_sql = ''
|
28
|
+
if tablespace = default_tablespace_for(:index)
|
29
|
+
tablespace_sql << " USING INDEX TABLESPACE #{tablespace}"
|
30
|
+
end
|
31
|
+
tablespace_sql
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add synonym to existing table or view or sequence. Can be used to create local synonym to
|
35
|
+
# remote table in other schema or in other database
|
36
|
+
# Examples:
|
37
|
+
#
|
38
|
+
# add_synonym :posts, "blog.posts"
|
39
|
+
# add_synonym :posts_seq, "blog.posts_seq"
|
40
|
+
# add_synonym :employees, "hr.employees@dblink", :force => true
|
41
|
+
#
|
42
|
+
def add_synonym(name, table_name, options = {})
|
43
|
+
sql = "CREATE"
|
44
|
+
if options[:force] == true
|
45
|
+
sql << " OR REPLACE"
|
46
|
+
end
|
47
|
+
sql << " SYNONYM #{quote_table_name(name)} FOR #{quote_table_name(table_name)}"
|
48
|
+
execute sql
|
49
|
+
end
|
50
|
+
|
51
|
+
# Remove existing synonym to table or view or sequence
|
52
|
+
# Example:
|
53
|
+
#
|
54
|
+
# remove_synonym :posts, "blog.posts"
|
55
|
+
#
|
56
|
+
def remove_synonym(name)
|
57
|
+
execute "DROP SYNONYM #{quote_table_name(name)}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# get synonyms for schema dump
|
61
|
+
def synonyms #:nodoc:
|
62
|
+
select_all("SELECT synonym_name, table_owner, table_name, db_link FROM all_synonyms WHERE owner = SYS_CONTEXT('userenv', 'current_schema')").collect do |row|
|
63
|
+
OracleEnhanced::SynonymDefinition.new(oracle_downcase(row['synonym_name']),
|
64
|
+
oracle_downcase(row['table_owner']), oracle_downcase(row['table_name']), oracle_downcase(row['db_link']))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
|
73
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaStatementsExt
|
74
|
+
end
|
@@ -127,19 +127,41 @@ module ActiveRecord #:nodoc:
|
|
127
127
|
if respond_to?(:foreign_keys) && (foreign_keys = foreign_keys(table["table_name"])).any?
|
128
128
|
foreign_keys.map do |fk|
|
129
129
|
sql = "ALTER TABLE #{quote_table_name(fk.from_table)} ADD CONSTRAINT #{quote_column_name(fk.options[:name])} "
|
130
|
-
sql << "#{foreign_key_definition(fk.to_table, fk.options)}"
|
130
|
+
sql << "#{foreign_key_definition(fk.to_table, fk.options) << table_definition_tablespace}"
|
131
131
|
end
|
132
132
|
end
|
133
133
|
end.flatten.compact
|
134
134
|
join_with_statement_token(fks)
|
135
135
|
end
|
136
136
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
|
137
|
+
def foreign_key_definition(to_table, options = {}) #:nodoc:
|
138
|
+
columns = Array(options[:column] || options[:columns])
|
139
|
+
|
140
|
+
if columns.size > 1
|
141
|
+
# composite foreign key
|
142
|
+
columns_sql = columns.map {|c| quote_column_name(c)}.join(',')
|
143
|
+
references = options[:references] || columns
|
144
|
+
references_sql = references.map {|c| quote_column_name(c)}.join(',')
|
145
|
+
else
|
146
|
+
columns_sql = quote_column_name(columns.first || "#{to_table.to_s.singularize}_id")
|
147
|
+
references = options[:references] ? options[:references].first : nil
|
148
|
+
references_sql = quote_column_name(options[:primary_key] || references || "id")
|
149
|
+
end
|
150
|
+
|
151
|
+
table_name = to_table
|
152
|
+
|
153
|
+
sql = "FOREIGN KEY (#{columns_sql}) REFERENCES #{quote_table_name(table_name)}(#{references_sql})"
|
154
|
+
|
155
|
+
case options[:dependent]
|
156
|
+
when :nullify
|
157
|
+
sql << " ON DELETE SET NULL"
|
158
|
+
when :delete
|
159
|
+
sql << " ON DELETE CASCADE"
|
160
|
+
end
|
161
|
+
sql
|
141
162
|
end
|
142
163
|
|
164
|
+
|
143
165
|
# Extract all stored procedures, packages, synonyms and views.
|
144
166
|
def structure_dump_db_stored_code #:nodoc:
|
145
167
|
structure = []
|
@@ -173,7 +195,7 @@ module ActiveRecord #:nodoc:
|
|
173
195
|
FROM all_synonyms
|
174
196
|
WHERE owner = SYS_CONTEXT('userenv', 'current_schema') ").each do |synonym|
|
175
197
|
structure << "CREATE OR REPLACE #{synonym['owner'] == 'PUBLIC' ? 'PUBLIC' : '' } SYNONYM #{synonym['synonym_name']}"
|
176
|
-
|
198
|
+
structure << " FOR #{synonym['table_owner']}.#{synonym['table_name']}"
|
177
199
|
end
|
178
200
|
|
179
201
|
join_with_statement_token(structure)
|
@@ -0,0 +1 @@
|
|
1
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter::VERSION = File.read(File.expand_path('../../../../../VERSION', __FILE__)).chomp
|
@@ -30,9 +30,13 @@
|
|
30
30
|
# portions Copyright 2005 Graham Jenkins
|
31
31
|
|
32
32
|
require 'active_record/connection_adapters/abstract_adapter'
|
33
|
-
require 'active_record/connection_adapters/
|
33
|
+
require 'active_record/connection_adapters/oracle_enhanced/connection'
|
34
|
+
require 'active_record/connection_adapters/oracle_enhanced/database_statements'
|
35
|
+
require 'active_record/connection_adapters/oracle_enhanced/schema_statements'
|
36
|
+
require 'active_record/connection_adapters/oracle_enhanced/column_dumper'
|
37
|
+
require 'active_record/connection_adapters/oracle_enhanced/context_index'
|
34
38
|
|
35
|
-
require 'active_record/connection_adapters/
|
39
|
+
require 'active_record/connection_adapters/oracle_enhanced/column'
|
36
40
|
|
37
41
|
require 'digest/sha1'
|
38
42
|
|
@@ -131,7 +135,7 @@ module ActiveRecord
|
|
131
135
|
|
132
136
|
def record_changed_lobs
|
133
137
|
@changed_lob_columns = self.class.lob_columns.select do |col|
|
134
|
-
|
138
|
+
self.attribute_changed?(col.name) && !self.class.readonly_attributes.to_a.include?(col.name)
|
135
139
|
end
|
136
140
|
end
|
137
141
|
end
|
@@ -218,6 +222,15 @@ module ActiveRecord
|
|
218
222
|
# * <tt>:nls_time_tz_format</tt>
|
219
223
|
#
|
220
224
|
class OracleEnhancedAdapter < AbstractAdapter
|
225
|
+
# TODO: Use relative
|
226
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhanced::DatabaseStatements
|
227
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhanced::SchemaStatements
|
228
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhanced::ColumnDumper
|
229
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhanced::ContextIndex
|
230
|
+
|
231
|
+
def schema_creation
|
232
|
+
OracleEnhanced::SchemaCreation.new self
|
233
|
+
end
|
221
234
|
|
222
235
|
##
|
223
236
|
# :singleton-method:
|
@@ -270,13 +283,6 @@ module ActiveRecord
|
|
270
283
|
cattr_accessor :emulate_dates_by_column_name
|
271
284
|
self.emulate_dates_by_column_name = false
|
272
285
|
|
273
|
-
##
|
274
|
-
# :singleton-method:
|
275
|
-
# Specify how `NUMBER` datatype columns, without precision and scale, are handled in Rails world.
|
276
|
-
# Default is :decimal and other valid option is :float. Be wary of setting it to other values.
|
277
|
-
cattr_accessor :number_datatype_coercion
|
278
|
-
self.number_datatype_coercion = :decimal
|
279
|
-
|
280
286
|
# Check column name to identify if it is Date (and not Time) column.
|
281
287
|
# Is used if +emulate_dates_by_column_name+ option is set to +true+.
|
282
288
|
# Override this method definition in initializer file if different Date column recognition is needed.
|
@@ -311,7 +317,7 @@ module ActiveRecord
|
|
311
317
|
# Is used if +emulate_integers_by_column_name+ option is set to +true+.
|
312
318
|
# Override this method definition in initializer file if different Integer column recognition is needed.
|
313
319
|
def self.is_integer_column?(name, table_name = nil)
|
314
|
-
|
320
|
+
name =~ /(^|_)id$/i
|
315
321
|
end
|
316
322
|
|
317
323
|
##
|
@@ -326,9 +332,9 @@ module ActiveRecord
|
|
326
332
|
# Check column name to identify if it is boolean (and not String) column.
|
327
333
|
# Is used if +emulate_booleans_from_strings+ option is set to +true+.
|
328
334
|
# Override this method definition in initializer file if different boolean column recognition is needed.
|
329
|
-
def self.is_boolean_column?(name,
|
330
|
-
return true if ["CHAR(1)","VARCHAR2(1)"].include?(
|
331
|
-
|
335
|
+
def self.is_boolean_column?(name, sql_type, table_name = nil)
|
336
|
+
return true if ["CHAR(1)","VARCHAR2(1)"].include?(sql_type)
|
337
|
+
sql_type =~ /^VARCHAR2/ && (name =~ /_flag$/i || name =~ /_yn$/i)
|
332
338
|
end
|
333
339
|
|
334
340
|
# How boolean value should be quoted to String.
|
@@ -383,21 +389,18 @@ module ActiveRecord
|
|
383
389
|
end
|
384
390
|
end
|
385
391
|
|
386
|
-
class BindSubstitution < Arel::Visitors::Oracle #:nodoc:
|
387
|
-
include Arel::Visitors::BindVisitor
|
388
|
-
end
|
389
|
-
|
390
392
|
def initialize(connection, logger, config) #:nodoc:
|
391
393
|
super(connection, logger)
|
392
394
|
@quoted_column_names, @quoted_table_names = {}, {}
|
393
395
|
@config = config
|
394
396
|
@statements = StatementPool.new(connection, config.fetch(:statement_limit) { 250 })
|
395
397
|
@enable_dbms_output = false
|
396
|
-
|
397
|
-
|
398
|
+
@visitor = Arel::Visitors::Oracle.new self
|
399
|
+
|
400
|
+
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
|
398
401
|
@prepared_statements = true
|
399
402
|
else
|
400
|
-
@
|
403
|
+
@prepared_statements = false
|
401
404
|
end
|
402
405
|
end
|
403
406
|
|
@@ -423,7 +426,13 @@ module ActiveRecord
|
|
423
426
|
true
|
424
427
|
end
|
425
428
|
|
426
|
-
|
429
|
+
def supports_foreign_keys?
|
430
|
+
true
|
431
|
+
end
|
432
|
+
|
433
|
+
def supports_views?
|
434
|
+
true
|
435
|
+
end
|
427
436
|
|
428
437
|
#:stopdoc:
|
429
438
|
DEFAULT_NLS_PARAMETERS = {
|
@@ -448,11 +457,11 @@ module ActiveRecord
|
|
448
457
|
|
449
458
|
#:stopdoc:
|
450
459
|
NATIVE_DATABASE_TYPES = {
|
451
|
-
:primary_key => "NUMBER(
|
460
|
+
:primary_key => "NUMBER(38) NOT NULL PRIMARY KEY",
|
452
461
|
:string => { :name => "VARCHAR2", :limit => 255 },
|
453
462
|
:text => { :name => "CLOB" },
|
454
|
-
:integer => { :name => "NUMBER", :limit =>
|
455
|
-
:float => { :name => "
|
463
|
+
:integer => { :name => "NUMBER", :limit => 38 },
|
464
|
+
:float => { :name => "BINARY_FLOAT" },
|
456
465
|
:decimal => { :name => "DECIMAL" },
|
457
466
|
:datetime => { :name => "DATE" },
|
458
467
|
# changed to native TIMESTAMP type
|
@@ -462,7 +471,8 @@ module ActiveRecord
|
|
462
471
|
:date => { :name => "DATE" },
|
463
472
|
:binary => { :name => "BLOB" },
|
464
473
|
:boolean => { :name => "NUMBER", :limit => 1 },
|
465
|
-
:raw => { :name => "RAW", :limit => 2000 }
|
474
|
+
:raw => { :name => "RAW", :limit => 2000 },
|
475
|
+
:bigint => { :name => "NUMBER", :limit => 19 }
|
466
476
|
}
|
467
477
|
# if emulate_booleans_from_strings then store booleans in VARCHAR2
|
468
478
|
NATIVE_DATABASE_TYPES_BOOLEAN_STRINGS = NATIVE_DATABASE_TYPES.dup.merge(
|
@@ -667,22 +677,26 @@ module ActiveRecord
|
|
667
677
|
|
668
678
|
# Cast a +value+ to a type that the database understands.
|
669
679
|
def type_cast(value, column)
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
680
|
+
if column && column.cast_type.is_a?(Type::Serialized)
|
681
|
+
super
|
682
|
+
else
|
683
|
+
case value
|
684
|
+
when true, false
|
685
|
+
if emulate_booleans_from_strings || column && column.type == :string
|
686
|
+
self.class.boolean_to_string(value)
|
687
|
+
else
|
688
|
+
value ? 1 : 0
|
689
|
+
end
|
690
|
+
when Date, Time
|
691
|
+
if value.acts_like?(:time)
|
692
|
+
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
693
|
+
value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
|
694
|
+
else
|
695
|
+
value
|
696
|
+
end
|
681
697
|
else
|
682
|
-
|
698
|
+
super
|
683
699
|
end
|
684
|
-
else
|
685
|
-
super
|
686
700
|
end
|
687
701
|
end
|
688
702
|
|
@@ -812,7 +826,7 @@ module ActiveRecord
|
|
812
826
|
value = attributes[col.name]
|
813
827
|
# changed sequence of next two lines - should check if value is nil before converting to yaml
|
814
828
|
next if value.nil? || (value == '')
|
815
|
-
value = value.to_yaml if col.
|
829
|
+
value = value.to_yaml if col.cast_type.is_a?(Type::Serialized) # klass.serialized_attributes[col.name]
|
816
830
|
uncached do
|
817
831
|
sql = is_with_cpk ? "SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)} WHERE #{klass.composite_where_clause(id)} FOR UPDATE" :
|
818
832
|
"SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)} WHERE #{quote_column_name(klass.primary_key)} = #{id} FOR UPDATE"
|
@@ -832,9 +846,9 @@ module ActiveRecord
|
|
832
846
|
|
833
847
|
# Current database session user
|
834
848
|
def current_user
|
835
|
-
select_value("SELECT SYS_CONTEXT('userenv', '
|
849
|
+
select_value("SELECT SYS_CONTEXT('userenv', 'current_schema') FROM dual")
|
836
850
|
end
|
837
|
-
|
851
|
+
|
838
852
|
# Current database session schema
|
839
853
|
def current_schema
|
840
854
|
select_value("SELECT SYS_CONTEXT('userenv', 'current_schema') FROM dual")
|
@@ -911,7 +925,7 @@ module ActiveRecord
|
|
911
925
|
statement_parameters = $1
|
912
926
|
end
|
913
927
|
end
|
914
|
-
all_schema_indexes <<
|
928
|
+
all_schema_indexes << OracleEnhanced::IndexDefinition.new(row['table_name'], row['index_name'],
|
915
929
|
row['uniqueness'] == "UNIQUE", row['index_type'] == 'DOMAIN' ? "#{row['ityp_owner']}.#{row['ityp_name']}" : nil,
|
916
930
|
row['parameters'], statement_parameters,
|
917
931
|
row['tablespace_name'] == default_tablespace_name ? nil : row['tablespace_name'], [])
|
@@ -1043,7 +1057,7 @@ module ActiveRecord
|
|
1043
1057
|
end.map do |row|
|
1044
1058
|
limit, scale = row['limit'], row['scale']
|
1045
1059
|
if limit || scale
|
1046
|
-
row['sql_type'] += "(#{(limit ||
|
1060
|
+
row['sql_type'] += "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
|
1047
1061
|
end
|
1048
1062
|
|
1049
1063
|
if row['sql_type_owner']
|
@@ -1060,19 +1074,61 @@ module ActiveRecord
|
|
1060
1074
|
# match newlines.
|
1061
1075
|
row['data_default'].sub!(/^'(.*)'$/m, '\1')
|
1062
1076
|
row['data_default'] = nil if row['data_default'] =~ /^(null|empty_[bc]lob\(\))$/i
|
1077
|
+
# TODO: Needs better fix to fallback "N" to false
|
1078
|
+
row['data_default'] = false if row['data_default'] == "N"
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
# TODO: Consider to extract another method such as `get_cast_type`
|
1082
|
+
case row['sql_type']
|
1083
|
+
when /decimal|numeric|number/i
|
1084
|
+
if get_type_for_column(table_name, oracle_downcase(row['name'])) == :integer
|
1085
|
+
cast_type = ActiveRecord::OracleEnhanced::Type::Integer.new
|
1086
|
+
elsif OracleEnhancedAdapter.emulate_booleans && row['sql_type'].upcase == "NUMBER(1)"
|
1087
|
+
cast_type = Type::Boolean.new
|
1088
|
+
elsif OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(row['name'], table_name)
|
1089
|
+
cast_type = ActiveRecord::OracleEnhanced::Type::Integer.new
|
1090
|
+
else
|
1091
|
+
cast_type = lookup_cast_type(row['sql_type'])
|
1092
|
+
end
|
1093
|
+
when /char/i
|
1094
|
+
if get_type_for_column(table_name, oracle_downcase(row['name'])) == :string
|
1095
|
+
cast_type = Type::String.new
|
1096
|
+
elsif get_type_for_column(table_name, oracle_downcase(row['name'])) == :boolean
|
1097
|
+
cast_type = Type::Boolean.new
|
1098
|
+
elsif OracleEnhancedAdapter.emulate_booleans_from_strings && OracleEnhancedAdapter.is_boolean_column?(row['name'], row['sql_type'], table_name)
|
1099
|
+
cast_type = Type::Boolean.new
|
1100
|
+
else
|
1101
|
+
cast_type = lookup_cast_type(row['sql_type'])
|
1102
|
+
end
|
1103
|
+
when /date/i
|
1104
|
+
if get_type_for_column(table_name, oracle_downcase(row['name'])) == :date
|
1105
|
+
cast_type = Type::Date.new
|
1106
|
+
elsif get_type_for_column(table_name, oracle_downcase(row['name'])) == :datetime
|
1107
|
+
cast_type = Type::DateTime.new
|
1108
|
+
elsif OracleEnhancedAdapter.emulate_dates_by_column_name && OracleEnhancedAdapter.is_date_column?(row['name'], table_name)
|
1109
|
+
cast_type = Type::Date.new
|
1110
|
+
else
|
1111
|
+
cast_type = lookup_cast_type(row['sql_type'])
|
1112
|
+
end
|
1113
|
+
else
|
1114
|
+
cast_type = lookup_cast_type(row['sql_type'])
|
1063
1115
|
end
|
1064
1116
|
|
1065
|
-
|
1117
|
+
new_column(oracle_downcase(row['name']),
|
1066
1118
|
row['data_default'],
|
1119
|
+
cast_type,
|
1067
1120
|
row['sql_type'],
|
1068
1121
|
row['nullable'] == 'Y',
|
1069
|
-
# pass table name for table specific column definitions
|
1070
1122
|
table_name,
|
1071
|
-
|
1072
|
-
|
1123
|
+
is_virtual,
|
1124
|
+
false )
|
1073
1125
|
end
|
1074
1126
|
end
|
1075
1127
|
|
1128
|
+
def new_column(name, default, cast_type, sql_type = nil, null = true, table_name = nil, virtual=false, returning_id=false)
|
1129
|
+
OracleEnhancedColumn.new(name, default, cast_type, sql_type, null, table_name, virtual, returning_id)
|
1130
|
+
end
|
1131
|
+
|
1076
1132
|
# used just in tests to clear column cache
|
1077
1133
|
def clear_columns_cache #:nodoc:
|
1078
1134
|
@@columns_cache = nil
|
@@ -1212,6 +1268,34 @@ module ActiveRecord
|
|
1212
1268
|
|
1213
1269
|
protected
|
1214
1270
|
|
1271
|
+
def initialize_type_map(m)
|
1272
|
+
super
|
1273
|
+
# oracle
|
1274
|
+
register_class_with_limit m, %r(date)i, Type::DateTime
|
1275
|
+
register_class_with_limit m, %r(raw)i, ActiveRecord::OracleEnhanced::Type::Raw
|
1276
|
+
register_class_with_limit m, %r(timestamp)i, ActiveRecord::OracleEnhanced::Type::Timestamp
|
1277
|
+
|
1278
|
+
m.register_type(%r(NUMBER)i) do |sql_type|
|
1279
|
+
scale = extract_scale(sql_type)
|
1280
|
+
precision = extract_precision(sql_type)
|
1281
|
+
limit = extract_limit(sql_type)
|
1282
|
+
if scale == 0
|
1283
|
+
ActiveRecord::OracleEnhanced::Type::Integer.new(precision: precision, limit: limit)
|
1284
|
+
else
|
1285
|
+
Type::Decimal.new(precision: precision, scale: scale)
|
1286
|
+
end
|
1287
|
+
end
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
def extract_limit(sql_type) #:nodoc:
|
1291
|
+
case sql_type
|
1292
|
+
when /^bigint/i
|
1293
|
+
19
|
1294
|
+
when /\((.*)\)/
|
1295
|
+
$1.to_i
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
|
1215
1299
|
def translate_exception(exception, message) #:nodoc:
|
1216
1300
|
case @connection.error_code(exception)
|
1217
1301
|
when 1
|
@@ -1225,6 +1309,10 @@ module ActiveRecord
|
|
1225
1309
|
|
1226
1310
|
private
|
1227
1311
|
|
1312
|
+
def select(sql, name = nil, binds = [])
|
1313
|
+
exec_query(sql, name, binds)
|
1314
|
+
end
|
1315
|
+
|
1228
1316
|
def oracle_downcase(column_name)
|
1229
1317
|
@connection.oracle_downcase(column_name)
|
1230
1318
|
end
|
@@ -1261,12 +1349,8 @@ module ActiveRecord
|
|
1261
1349
|
end
|
1262
1350
|
|
1263
1351
|
protected
|
1264
|
-
def log(sql, name, binds = nil) #:nodoc:
|
1265
|
-
|
1266
|
-
super sql, name, binds
|
1267
|
-
else
|
1268
|
-
super sql, name
|
1269
|
-
end
|
1352
|
+
def log(sql, name = "SQL", binds = [], statement_name = nil) #:nodoc:
|
1353
|
+
super
|
1270
1354
|
ensure
|
1271
1355
|
log_dbms_output if dbms_output_enabled?
|
1272
1356
|
end
|
@@ -1294,38 +1378,47 @@ module ActiveRecord
|
|
1294
1378
|
end
|
1295
1379
|
|
1296
1380
|
# Implementation of standard schema definition statements and extensions for schema definition
|
1297
|
-
require 'active_record/connection_adapters/
|
1298
|
-
require 'active_record/connection_adapters/
|
1381
|
+
require 'active_record/connection_adapters/oracle_enhanced/schema_statements'
|
1382
|
+
require 'active_record/connection_adapters/oracle_enhanced/schema_statements_ext'
|
1299
1383
|
|
1300
1384
|
# Extensions for schema definition
|
1301
|
-
require 'active_record/connection_adapters/
|
1385
|
+
require 'active_record/connection_adapters/oracle_enhanced/schema_definitions'
|
1302
1386
|
|
1303
1387
|
# Extensions for context index definition
|
1304
|
-
require 'active_record/connection_adapters/
|
1388
|
+
require 'active_record/connection_adapters/oracle_enhanced/context_index'
|
1305
1389
|
|
1306
1390
|
# Load additional methods for composite_primary_keys support
|
1307
|
-
require 'active_record/connection_adapters/
|
1391
|
+
require 'active_record/connection_adapters/oracle_enhanced/cpk'
|
1308
1392
|
|
1309
1393
|
# Load patch for dirty tracking methods
|
1310
|
-
require 'active_record/connection_adapters/
|
1394
|
+
require 'active_record/connection_adapters/oracle_enhanced/dirty'
|
1311
1395
|
|
1312
1396
|
# Patches and enhancements for schema dumper
|
1313
|
-
require 'active_record/connection_adapters/
|
1397
|
+
require 'active_record/connection_adapters/oracle_enhanced/schema_dumper'
|
1314
1398
|
|
1315
1399
|
# Implementation of structure dump
|
1316
|
-
require 'active_record/connection_adapters/
|
1400
|
+
require 'active_record/connection_adapters/oracle_enhanced/structure_dump'
|
1317
1401
|
|
1318
|
-
require 'active_record/connection_adapters/
|
1402
|
+
require 'active_record/connection_adapters/oracle_enhanced/version'
|
1319
1403
|
|
1320
1404
|
module ActiveRecord
|
1321
|
-
autoload :OracleEnhancedProcedures, 'active_record/connection_adapters/
|
1405
|
+
autoload :OracleEnhancedProcedures, 'active_record/connection_adapters/oracle_enhanced/procedures'
|
1322
1406
|
end
|
1323
1407
|
|
1324
1408
|
# Patches and enhancements for column dumper
|
1325
|
-
require 'active_record/connection_adapters/
|
1409
|
+
require 'active_record/connection_adapters/oracle_enhanced/column_dumper'
|
1326
1410
|
|
1327
1411
|
# Moved SchemaCreation class
|
1328
|
-
require 'active_record/connection_adapters/
|
1412
|
+
require 'active_record/connection_adapters/oracle_enhanced/schema_creation'
|
1329
1413
|
|
1330
1414
|
# Moved DatabaseStetements
|
1331
|
-
require 'active_record/connection_adapters/
|
1415
|
+
require 'active_record/connection_adapters/oracle_enhanced/database_statements'
|
1416
|
+
|
1417
|
+
# Add Type:Raw
|
1418
|
+
require 'active_record/oracle_enhanced/type/raw'
|
1419
|
+
|
1420
|
+
# Add Type:Timestamp
|
1421
|
+
require 'active_record/oracle_enhanced/type/timestamp'
|
1422
|
+
|
1423
|
+
# Add OracleEnhanced::Type::Integer
|
1424
|
+
require 'active_record/oracle_enhanced/type/integer'
|