Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #4017: oracle_adapter.patch

File oracle_adapter.patch, 21.0 kB (added by anonymous, 3 years ago)
  • activerecord/test/connections/native_oracle/connection.rb

    old new  
     1print "Using Oracle\n" 
     2require_dependency 'fixtures/course' 
     3require 'logger' 
     4 
     5ActiveRecord::Base.logger = Logger.new STDOUT 
     6ActiveRecord::Base.logger.level = Logger::WARN 
     7 
     8# Set these to your database connection strings 
     9db = 'activerecord_unit_tests' 
     10 
     11ActiveRecord::Base.establish_connection( 
     12  :adapter  => 'oracle', 
     13  :username => 'arunit', 
     14  :password => 'arunit', 
     15  :database => db 
     16) 
     17 
     18Course.establish_connection( 
     19  :adapter  => 'oracle', 
     20  :username => 'arunit2', 
     21  :password => 'arunit2', 
     22  :database => db 
     23) 
  • activerecord/test/column_alias_test.rb

    old new  
    44class TestColumnAlias < Test::Unit::TestCase 
    55  fixtures :topics 
    66 
    7   QUERY = if 'OCI' == ActiveRecord::Base.connection.adapter_name 
     7  QUERY = if 'Oracle' == ActiveRecord::Base.connection.adapter_name 
    88            'SELECT id AS pk FROM topics WHERE ROWNUM < 2' 
    99          else 
    1010            'SELECT id AS pk FROM topics' 
  • activerecord/test/fixtures_test.rb

    old new  
    6161        t.column :written_on, :datetime 
    6262        t.column :bonus_time, :time 
    6363        t.column :last_read, :date 
    64         t.column :content, :text 
     64        t.column :content, :string 
    6565        t.column :approved, :boolean, :default => true 
    6666        t.column :replies_count, :integer, :default => 0 
    6767        t.column :parent_id, :integer 
     
    7878 
    7979      topics = create_fixtures("topics") 
    8080 
    81       # Restore prefix/suffix to its previous values 
    82       ActiveRecord::Base.table_name_prefix = old_prefix  
    83       ActiveRecord::Base.table_name_suffix = old_suffix  
    84  
    8581      firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'David'") 
    8682      assert_equal("The First Topic", firstRow["title"]) 
    8783 
    8884      secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'Mary'") 
    8985      assert_nil(secondRow["author_email_address"])         
    9086    ensure 
     87      # Restore prefix/suffix to its previous values 
     88      ActiveRecord::Base.table_name_prefix = old_prefix  
     89      ActiveRecord::Base.table_name_suffix = old_suffix  
     90 
    9191      ActiveRecord::Base.connection.drop_table :prefix_topics_suffix rescue nil 
    9292    end 
    9393  end 
  • activerecord/test/base_test.rb

    old new  
    1717class Post < ActiveRecord::Base; end 
    1818class Computer < ActiveRecord::Base; end 
    1919class NonExistentTable < ActiveRecord::Base; end 
    20 class TestOCIDefault < ActiveRecord::Base; end 
     20class TestOracleDefault < ActiveRecord::Base; end 
    2121 
    2222class LoosePerson < ActiveRecord::Base 
    2323  attr_protected :credit_rating, :administrator 
     
    526526 
    527527    # Oracle has some funky default handling, so it requires a bit of  
    528528    # extra testing. See ticket #2788. 
    529     if current_adapter?(:OCIAdapter) 
    530       test = TestOCIDefault.new 
     529    if current_adapter?(:OracleAdapter) 
     530      test = TestOracleDefault.new 
    531531      assert_equal "X", test.test_char 
    532532      assert_equal "hello", test.test_string 
    533533      assert_equal 3, test.test_int 
     
    536536 
    537537  def test_utc_as_time_zone 
    538538    # Oracle and SQLServer do not have a TIME datatype. 
    539     return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OCIAdapter) 
     539    return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OracleAdapter) 
    540540 
    541541    Topic.default_timezone = :utc 
    542542    attributes = { "bonus_time" => "5:42:00AM" } 
     
    704704 
    705705  def test_attributes_on_dummy_time 
    706706    # Oracle and SQL Server do not have a TIME datatype. 
    707     return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OCIAdapter) 
     707    return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OracleAdapter) 
    708708 
    709709    attributes = { 
    710710      "bonus_time" => "5:42:00AM" 
  • activerecord/test/binary_test.rb

    old new  
    2020  # Without using prepared statements, it makes no sense to test 
    2121  # BLOB data with DB2 or Firebird, because the length of a statement 
    2222  # is limited to 32KB. 
    23   unless %w(SQLServer DB2 OCI Firebird).include? ActiveRecord::Base.connection.adapter_name 
     23  unless %w(SQLServer DB2 Oracle Firebird).include? ActiveRecord::Base.connection.adapter_name 
    2424    def test_load_save 
    2525      bin = Binary.new 
    2626      bin.data = @data 
  • activerecord/test/migration_test.rb

    old new  
    8484      four = columns.detect { |c| c.name == "four" } 
    8585 
    8686      assert_equal "hello", one.default 
    87       if current_adapter?(:OCIAdapter) 
     87      if current_adapter?(:OracleAdapter) 
    8888        # Oracle doesn't support native booleans 
    8989        assert_equal true, two.default == 1 
    9090        assert_equal false, three.default != 0 
     
    153153      assert_equal Fixnum, bob.age.class 
    154154      assert_equal Time, bob.birthday.class 
    155155 
    156       if current_adapter?(:SQLServerAdapter) or current_adapter?(:OCIAdapter) 
     156      if current_adapter?(:SQLServerAdapter) or current_adapter?(:OracleAdapter) 
    157157        # SQL Server and Oracle don't differentiate between date/time 
    158158        assert_equal Time, bob.favorite_day.class 
    159159      else 
     
    241241        ActiveRecord::Base.connection.rename_table :octopuses, :octopi 
    242242 
    243243        assert_nothing_raised do 
    244           if current_adapter?(:OCIAdapter) 
     244          if current_adapter?(:OracleAdapter) 
    245245            # Oracle requires the explicit sequence for the pk 
    246246            ActiveRecord::Base.connection.execute "INSERT INTO octopi (id, url) VALUES (octopi_seq.nextval, 'http://www.foreverflying.com/octopus-black7.jpg')" 
    247247          else 
  • activerecord/test/fixtures/db_definitions/oracle.sql

    old new  
    275275); 
    276276create sequence keyboards_seq minvalue 10000; 
    277277 
    278 create table test_oci_defaults ( 
     278create table test_oracle_defaults ( 
    279279  id integer not null primary key, 
    280280  test_char char(1) default 'X' not null, 
    281281  test_string varchar2(20) default 'hello' not null, 
    282282  test_int integer default 3 not null 
    283283); 
    284 create sequence test_oci_defaults_seq minvalue 10000; 
     284create sequence test_oracle_defaults_seq minvalue 10000; 
    285285 
    286286--This table has an altered lock_version column name. 
    287287create table legacy_things ( 
  • activerecord/test/readonly_test.rb

    old new  
    7979 
    8080    # Oracle barfs on this because the join includes unqualified and 
    8181    # conflicting column names 
    82     unless current_adapter?(:OCIAdapter) 
     82    unless current_adapter?(:OracleAdapter) 
    8383      Post.with_scope(:find => { :joins => ', developers' }) do  
    8484        assert Post.find(1).readonly? 
    8585        assert Post.find(1, :readonly => true).readonly? 
  • activerecord/Rakefile

    old new  
    2727 
    2828# Run the unit tests 
    2929 
    30 for adapter in %w( mysql postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oci
     30for adapter in %w( mysql postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oracle
    3131  Rake::TestTask.new("test_#{adapter}") { |t| 
    3232    t.libs << "test" << "test/connections/native_#{adapter}" 
    3333    t.pattern = "test/*_test{,_#{adapter}}.rb" 
  • activerecord/lib/active_record/connection_adapters/oracle_adapter.rb

    old new  
    1 # oci_adapter.rb -- ActiveRecord adapter for Oracle 8i, 9i, 10g 
     1# oracle_adapter.rb -- ActiveRecord adapter for Oracle 8i, 9i, 10g 
    22# 
    33# Original author: Graham Jenkins 
    44# 
     
    3030 
    3131  module ActiveRecord 
    3232    class Base 
    33       def self.oci_connection(config) #:nodoc: 
     33      def self.oracle_connection(config) #:nodoc: 
    3434        # Use OCI8AutoRecover instead of normal OCI8 driver. 
    35         ConnectionAdapters::OCIAdapter.new OCI8AutoRecover.new(config), logger 
     35        ConnectionAdapters::OracleAdapter.new OCI8AutoRecover.new(config), logger 
    3636      end 
    3737 
     38      # for backwards-compatibility 
     39      def self.oci_connection(config) #:nodoc: 
     40        config[:database] = config[:host] 
     41        self.oracle_connection(config) 
     42      end 
     43 
    3844      # Enable the id column to be bound into the sql later, by the adapter's insert method. 
    3945      # This is preferable to inserting the hard-coded value here, because the insert method 
    4046      # needs to know the id value explicitly. 
    41       alias :attributes_with_quotes_pre_oci :attributes_with_quotes #:nodoc: 
     47      alias :attributes_with_quotes_pre_oracle :attributes_with_quotes #:nodoc: 
    4248      def attributes_with_quotes(creating = true) #:nodoc: 
    43         aq = attributes_with_quotes_pre_oci creating 
    44         if connection.class == ConnectionAdapters::OCIAdapter 
     49        aq = attributes_with_quotes_pre_oracle creating 
     50        if connection.class == ConnectionAdapters::OracleAdapter 
    4551          aq[self.class.primary_key] = ":id" if creating && aq[self.class.primary_key].nil? 
    4652        end 
    4753        aq 
     
    5157      # and write back the data. 
    5258      after_save :write_lobs  
    5359      def write_lobs() #:nodoc: 
    54         if connection.is_a?(ConnectionAdapters::OCIAdapter) 
     60        if connection.is_a?(ConnectionAdapters::OracleAdapter) 
    5561          self.class.columns.select { |c| c.type == :binary }.each { |c| 
    5662            value = self[c.name] 
    5763            next if value.nil?  || (value == '') 
     
    6874 
    6975 
    7076    module ConnectionAdapters #:nodoc: 
    71       class OCIColumn < Column #:nodoc: 
     77      class OracleColumn < Column #:nodoc: 
    7278        attr_reader :sql_type 
    7379 
    7480        # overridden to add the concept of scale, required to differentiate 
     
    153159      #   is supported in Oracle9i and later. You will need to use #finder_sql for 
    154160      #   has_and_belongs_to_many associations to run against Oracle8. 
    155161      # 
    156       # Options: 
     162      # Required parameters: 
    157163      # 
    158       # * <tt>:username</tt> -- Defaults to root 
    159       # * <tt>:password</tt> -- Defaults to nothing 
    160       # * <tt>:host</tt> -- Defaults to localhost 
    161       class OCIAdapter < AbstractAdapter 
     164      # * <tt>:username</tt> 
     165      # * <tt>:password</tt> 
     166      # * <tt>:database</tt> 
     167      class OracleAdapter < AbstractAdapter 
    162168 
    163169        def adapter_name #:nodoc: 
    164           'OCI
     170          'Oracle
    165171        end 
    166172 
    167173        def supports_migrations? #:nodoc: 
     
    172178          { 
    173179            :primary_key => "NUMBER(38) NOT NULL PRIMARY KEY", 
    174180            :string      => { :name => "VARCHAR2", :limit => 255 }, 
    175             :text        => { :name => "LONG" }, 
     181            :text        => { :name => "BLOB" }, 
    176182            :integer     => { :name => "NUMBER", :limit => 38 }, 
    177183            :float       => { :name => "NUMBER" }, 
    178184            :datetime    => { :name => "DATE" }, 
     
    214220        end 
    215221 
    216222 
    217         # CONNECTION MANAGEMENT ====================================# 
     223        # CONNECTION MANAGEMENT ==================================== 
     224        # 
    218225 
    219226        # Returns true if the connection is active. 
    220227        def active? 
     
    223230          # last known state, which isn't good enough if the connection has 
    224231          # gone stale since the last use. 
    225232          @connection.ping 
    226         rescue OCIError 
     233        rescue OCIException 
    227234          false 
    228235        end 
    229236 
    230237        # Reconnects to the database. 
    231238        def reconnect! 
    232239          @connection.reset! 
    233         rescue OCIError => e 
     240        rescue OCIException => e 
    234241          @logger.warn "#{adapter_name} automatic reconnection failed: #{e.message}" 
    235242        end 
    236243 
     244        # Disconnects from the database. 
     245        def disconnect! 
     246          @connection.logoff rescue nil 
     247          @connection.active = false 
     248        end 
    237249 
     250 
    238251        # DATABASE STATEMENTS ====================================== 
    239252        # 
    240253        # see: abstract/database_statements.rb 
     
    346359              from all_tab_columns 
    347360             where owner      = '#{table_info.schema}' 
    348361               and table_name = '#{table_info.name}' 
     362             order by column_id 
    349363          } 
    350364 
    351365          select_all(table_cols, name).map do |row| 
    352366            row['data_default'].sub!(/^'(.*)'\s*$/, '\1') if row['data_default'] 
    353             OCIColumn.new( 
    354               oci_downcase(row['column_name']), 
     367            OracleColumn.new( 
     368              oracle_downcase(row['column_name']), 
    355369              row['data_default'], 
    356370              row['data_type'], 
    357               row['length']
    358               row['scale']
     371              row['length'].to_i
     372              row['scale'].to_i
    359373              row['nullable'] == 'Y' 
    360374            ) 
    361375          end 
     
    444458 
    445459        def select(sql, name = nil) 
    446460          cursor = log(sql, name) { @connection.exec sql } 
    447           cols = cursor.get_col_names.map { |x| oci_downcase(x) } 
     461          cols = cursor.get_col_names.map { |x| oracle_downcase(x) } 
    448462          rows = [] 
    449463 
    450464          while row = cursor.fetch 
     
    476490        # I don't know anybody who does this, but we'll handle the theoretical case of a 
    477491        # camelCase column name. I imagine other dbs handle this different, since there's a 
    478492        # unit test that's currently failing test_oci. 
    479         def oci_downcase(column_name) 
     493        def oracle_downcase(column_name) 
    480494          column_name =~ /[a-z]/ ? column_name : column_name.downcase 
    481495        end 
    482496 
     
    500514      end 
    501515    end 
    502516 
    503     # missing constant from oci8 
    504     OCI_PTYPE_UNK = 0 
     517    # missing constant from oci8 < 0.1.14 
     518    OCI_PTYPE_UNK = 0 unless defined?(OCI_PTYPE_UNK) 
    505519 
    506520    def object_info(name) 
    507521      OraObject.new describe(name.to_s, OCI_PTYPE_UNK) 
     
    529543  end 
    530544 
    531545 
    532   # The OCIConnectionFactory factors out the code necessary to connect and 
    533   # configure an OCI connection. 
    534   class OCIConnectionFactory #:nodoc: 
    535     def new_connection(username, password, host
    536       conn = OCI8.new username, password, host 
     546  # The OracleConnectionFactory factors out the code necessary to connect and 
     547  # configure an Oracle/OCI connection. 
     548  class OracleConnectionFactory #:nodoc: 
     549    def new_connection(username, password, database
     550      conn = OCI8.new username, password, database 
    537551      conn.exec %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'} 
    538552      conn.exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'} rescue nil 
    539553      conn.autocommit = true 
     
    559573    end 
    560574    @@auto_retry = false 
    561575 
    562     def initialize(config, factory = OCIConnectionFactory.new) 
     576    def initialize(config, factory = OracleConnectionFactory.new) 
    563577      @active = true 
    564       @username, @password, @host = config[:username], config[:password], config[:host
     578      @username, @password, @database = config[:username], config[:password], config[:database
    565579      @factory = factory 
    566       @connection  = @factory.new_connection @username, @password, @host 
     580      @connection  = @factory.new_connection @username, @password, @database 
    567581      super @connection 
    568582    end 
    569583 
     
    582596    def reset! 
    583597      logoff rescue nil 
    584598      begin 
    585         @connection = @factory.new_connection @username, @password, @host 
     599        @connection = @factory.new_connection @username, @password, @database 
    586600        __setobj__ @connection 
    587601        @active = true 
    588602      rescue 
     
    605619 
    606620      begin 
    607621        @connection.exec(sql, *bindvars) 
    608       rescue OCIError => e 
     622      rescue OCIException => e 
    609623        raise unless LOST_CONNECTION_ERROR_CODES.include?(e.code) 
    610624        @active = false 
    611625        raise unless should_retry 
     
    621635  # OCI8 driver is unavailable. 
    622636  module ActiveRecord # :nodoc: 
    623637    class Base 
     638      def self.oracle_connection(config) # :nodoc: 
     639        # Set up a reasonable error message 
     640        raise LoadError, "Oracle/OCI libraries could not be loaded." 
     641      end 
    624642      def self.oci_connection(config) # :nodoc: 
    625643        # Set up a reasonable error message 
    626644        raise LoadError, "Oracle/OCI libraries could not be loaded." 
  • activerecord/lib/active_record.rb

    old new  
    6868end 
    6969 
    7070unless defined?(RAILS_CONNECTION_ADAPTERS) 
    71   RAILS_CONNECTION_ADAPTERS = %w(mysql postgresql sqlite firebird sqlserver db2 oci
     71  RAILS_CONNECTION_ADAPTERS = %w(mysql postgresql sqlite firebird sqlserver db2 oracle
    7272end 
    7373 
    7474RAILS_CONNECTION_ADAPTERS.each do |adapter| 
  • railties/configs/databases/oracle.yml

    old new  
     1# Oracle/OCI 8i, 9, 10g 
     2# 
     3# Requires Ruby/OCI8: 
     4#  http://rubyforge.org/projects/ruby-oci8/ 
     5# 
     6# Specify your database using any valid connection syntax, such as a 
     7# tnsnames.ora service name, or a sql connect url string of the form: 
     8# 
     9#   //host:[port][/service name]  
     10 
     11development: 
     12  adapter: oracle 
     13  database: <%= app_name %>_development 
     14  username: <%= app_name %> 
     15  password: 
     16 
     17# Warning: The database defined as 'test' will be erased and 
     18# re-generated from your development database when you run 'rake'. 
     19# Do not set this db to the same as development or production. 
     20test: 
     21  adapter: oracle 
     22  database: <%= app_name %>_test 
     23  username: <%= app_name %> 
     24  password: 
     25 
     26production: 
     27  adapter: oracle 
     28  database: <%= app_name %>_production 
     29  username: <%= app_name %> 
     30  password:  
  • railties/lib/rails_generator/generators/applications/app/app_generator.rb

    old new  
    44  DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], 
    55                              Config::CONFIG['ruby_install_name']) 
    66   
    7   DATABASES = %w( mysql sqlite2 sqlite3 postgresql
     7  DATABASES = %w( mysql oracle postgresql sqlite2 sqlite3
    88   
    99  default_options   :db => "mysql", :shebang => DEFAULT_SHEBANG 
    1010  mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.." 
     
    9797             "Default: #{DEFAULT_SHEBANG}") { |options[:shebang]| } 
    9898 
    9999      opt.on("-d", "--database=name", String, 
    100              "Preconfigure for selected database (options: mysql/postgresql/sqlite2/sqlite3).", 
     100             "Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite2/sqlite3).", 
    101101             "Default: mysql") { |options[:db]| } 
    102102    end 
    103103