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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -7
  3. data/History.md +126 -0
  4. data/README.md +285 -178
  5. data/Rakefile +1 -1
  6. data/VERSION +1 -1
  7. data/lib/active_record/connection_adapters/{oracle_enhanced_column.rb → oracle_enhanced/column.rb} +14 -63
  8. data/lib/active_record/connection_adapters/oracle_enhanced/column_dumper.rb +65 -0
  9. data/lib/active_record/connection_adapters/{oracle_enhanced_connection.rb → oracle_enhanced/connection.rb} +2 -2
  10. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +347 -0
  11. data/lib/active_record/connection_adapters/{oracle_enhanced_cpk.rb → oracle_enhanced/cpk.rb} +0 -0
  12. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +257 -0
  13. data/lib/active_record/connection_adapters/{oracle_enhanced_database_tasks.rb → oracle_enhanced/database_tasks.rb} +0 -0
  14. data/lib/active_record/connection_adapters/oracle_enhanced/dirty.rb +40 -0
  15. data/lib/active_record/connection_adapters/{oracle_enhanced_jdbc_connection.rb → oracle_enhanced/jdbc_connection.rb} +0 -0
  16. data/lib/active_record/connection_adapters/{oracle_enhanced_oci_connection.rb → oracle_enhanced/oci_connection.rb} +0 -0
  17. data/lib/active_record/connection_adapters/{oracle_enhanced_procedures.rb → oracle_enhanced/procedures.rb} +1 -3
  18. data/lib/active_record/connection_adapters/{oracle_enhanced_schema_creation.rb → oracle_enhanced/schema_creation.rb} +34 -35
  19. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +95 -0
  20. data/lib/active_record/connection_adapters/{oracle_enhanced_schema_dumper.rb → oracle_enhanced/schema_dumper.rb} +4 -32
  21. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +548 -0
  22. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +74 -0
  23. data/lib/active_record/connection_adapters/{oracle_enhanced_structure_dump.rb → oracle_enhanced/structure_dump.rb} +28 -6
  24. data/lib/active_record/connection_adapters/oracle_enhanced/version.rb +1 -0
  25. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +161 -68
  26. data/lib/active_record/oracle_enhanced/type/integer.rb +13 -0
  27. data/lib/active_record/oracle_enhanced/type/raw.rb +13 -0
  28. data/lib/active_record/oracle_enhanced/type/timestamp.rb +11 -0
  29. data/lib/pmacs-activerecord-oracle_enhanced-adapter.rb +1 -1
  30. data/pmacs-activerecord-oracle_enhanced-adapter.gemspec +35 -31
  31. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +6 -31
  32. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +1 -1
  33. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +2 -2
  34. data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +2 -2
  35. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +75 -63
  36. data/spec/active_record/connection_adapters/oracle_enhanced_database_tasks_spec.rb +1 -1
  37. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +7 -13
  38. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +2 -1
  39. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +25 -178
  40. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +60 -5
  41. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +1 -0
  42. data/spec/spec_helper.rb +21 -10
  43. metadata +32 -28
  44. data/lib/active_record/connection_adapters/oracle_enhanced_column_dumper.rb +0 -77
  45. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +0 -350
  46. data/lib/active_record/connection_adapters/oracle_enhanced_database_statements.rb +0 -262
  47. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +0 -45
  48. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +0 -223
  49. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +0 -450
  50. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb +0 -267
  51. 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 dump_schema_information #:nodoc:
138
- sm_table = ActiveRecord::Migrator.schema_migrations_table_name
139
- migrated = select_values("SELECT version FROM #{sm_table} ORDER BY version")
140
- join_with_statement_token(migrated.map{|v| "INSERT INTO #{sm_table} (version) VALUES ('#{v}')" })
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
- structure << " FOR #{synonym['table_owner']}.#{synonym['table_name']}"
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/oracle_enhanced_connection'
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/oracle_enhanced_column'
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
- (self.class.serialized_attributes.keys.include?(col.name) || self.send(:"#{col.name}_changed?")) && !self.class.readonly_attributes.to_a.include?(col.name)
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
- !!(name =~ /(^|_)id$/i)
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, field_type, table_name = nil)
330
- return true if ["CHAR(1)","VARCHAR2(1)"].include?(field_type)
331
- field_type =~ /^VARCHAR2/ && (name =~ /_flag$/i || name =~ /_yn$/i)
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
- if config.fetch(:prepared_statements) { true }
397
- @visitor = Arel::Visitors::Oracle.new self
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
- @visitor = unprepared_visitor
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
- NUMBER_MAX_PRECISION = 38
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(#{NUMBER_MAX_PRECISION}) NOT NULL PRIMARY KEY",
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 => NUMBER_MAX_PRECISION },
455
- :float => { :name => "NUMBER" },
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
- case value
671
- when true, false
672
- if emulate_booleans_from_strings || column && column.type == :string
673
- self.class.boolean_to_string(value)
674
- else
675
- value ? 1 : 0
676
- end
677
- when Date, Time
678
- if value.acts_like?(:time)
679
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
680
- value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
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
- value
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.text? && klass.serialized_attributes[col.name]
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', 'session_user') FROM dual")
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 << OracleEnhancedIndexDefinition.new(row['table_name'], row['index_name'],
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 || NUMBER_MAX_PRECISION).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
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
- OracleEnhancedColumn.new(oracle_downcase(row['name']),
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
- # pass column type if specified in class definition
1072
- get_type_for_column(table_name, oracle_downcase(row['name'])), is_virtual)
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
- if binds
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/oracle_enhanced_schema_statements'
1298
- require 'active_record/connection_adapters/oracle_enhanced_schema_statements_ext'
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/oracle_enhanced_schema_definitions'
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/oracle_enhanced_context_index'
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/oracle_enhanced_cpk'
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/oracle_enhanced_dirty'
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/oracle_enhanced_schema_dumper'
1397
+ require 'active_record/connection_adapters/oracle_enhanced/schema_dumper'
1314
1398
 
1315
1399
  # Implementation of structure dump
1316
- require 'active_record/connection_adapters/oracle_enhanced_structure_dump'
1400
+ require 'active_record/connection_adapters/oracle_enhanced/structure_dump'
1317
1401
 
1318
- require 'active_record/connection_adapters/oracle_enhanced_version'
1402
+ require 'active_record/connection_adapters/oracle_enhanced/version'
1319
1403
 
1320
1404
  module ActiveRecord
1321
- autoload :OracleEnhancedProcedures, 'active_record/connection_adapters/oracle_enhanced_procedures'
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/oracle_enhanced_column_dumper'
1409
+ require 'active_record/connection_adapters/oracle_enhanced/column_dumper'
1326
1410
 
1327
1411
  # Moved SchemaCreation class
1328
- require 'active_record/connection_adapters/oracle_enhanced_schema_creation'
1412
+ require 'active_record/connection_adapters/oracle_enhanced/schema_creation'
1329
1413
 
1330
1414
  # Moved DatabaseStetements
1331
- require 'active_record/connection_adapters/oracle_enhanced_database_statements'
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'