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

Ticket #1798: oci_omnibus.2.patch

File oci_omnibus.2.patch, 18.7 kB (added by anonymous, 3 years ago)

Now includes the code from ticket 1807

  • test/base_test.rb

    old new  
    571571 
    572572  def test_multiparameter_mass_assignment_protector 
    573573    task = Task.new 
    574     time = Time.mktime(0
     574    time = Time.mktime(2000, 1, 1, 1
    575575    task.starting = time  
    576576    attributes = { "starting(1i)" => "2004", "starting(2i)" => "6", "starting(3i)" => "24" } 
    577577    task.attributes = attributes 
  • test/fixtures/db_definitions/oci2.sql

    old new  
    1 create sequence rails_sequence minvalue 10000; 
    2  
    31create table courses ( 
    42  id int not null primary key, 
    53  name varchar(255) not null 
    64); 
     5 
     6create sequence courses_seq minvalue 10000; 
  • test/fixtures/db_definitions/oci2.drop.sql

    old new  
    11drop table courses; 
    2 drop sequence rails_sequence
     2drop sequence courses_seq
  • test/fixtures/db_definitions/oci.sql

    old new  
    1 create sequence rails_sequence minvalue 10000; 
    2  
    31create table companies ( 
    42    id integer not null, 
    53    type varchar(50) default null, 
     
    1210    primary key (id) 
    1311); 
    1412 
     13-- non-standard sequence name used to test set_sequence_name 
     14-- 
     15create sequence companies_nonstd_seq minvalue 10000; 
     16 
    1517create table accounts ( 
    1618    id integer not null, 
    1719    firm_id integer default null references companies initially deferred disable, 
    1820    credit_limit integer default null, 
    1921    primary key (id) 
    2022); 
     23create sequence accounts_seq minvalue 10000; 
    2124 
    2225create table topics ( 
    2326    id integer not null, 
     
    5053    type varchar(50) default null, 
    5154    primary key (id) 
    5255); 
     56create sequence topics_seq minvalue 10000; 
    5357 
     58create synonym subjects for topics; 
     59 
    5460create table developers ( 
    5561    id integer not null, 
    5662    name varchar(100) default null, 
     
    5965    updated_at timestamp default null, 
    6066    primary key (id) 
    6167); 
     68create sequence developers_seq minvalue 10000; 
    6269 
    6370create table projects ( 
    6471    id integer not null, 
     
    6673    type varchar(255) default null, 
    6774    primary key (id) 
    6875); 
     76create sequence projects_seq minvalue 10000; 
    6977 
    7078create table developers_projects ( 
    7179    developer_id integer not null references developers initially deferred disable, 
     
    7886    project_id integer not null references projects initially deferred disable, 
    7987    joined_on date default null 
    8088); 
     89create sequence developers_projects_seq minvalue 10000; 
    8190 
    8291create table customers ( 
    8392    id integer not null, 
     
    8998    gps_location varchar(100) default null, 
    9099    primary key (id) 
    91100); 
     101create sequence customers_seq minvalue 10000; 
    92102 
    93103create table movies ( 
    94104    movieid integer not null, 
    95105    name varchar(100) default null, 
    96106    primary key (movieid) 
    97107); 
     108create sequence movies_seq minvalue 10000; 
    98109 
    99110create table subscribers ( 
    100111    nick varchar(100) not null, 
    101112    name varchar(100) default null, 
    102113    primary key (nick) 
    103114); 
     115create sequence subscribers_seq minvalue 10000; 
    104116 
    105117create table booleantests ( 
    106118    id integer not null, 
    107119    value integer default null, 
    108120    primary key (id) 
    109121); 
     122create sequence booleantests_seq minvalue 10000; 
    110123 
    111124create table auto_id_tests ( 
    112125    auto_id integer not null, 
    113126    value integer default null, 
    114127    primary key (auto_id) 
    115128); 
     129create sequence auto_id_tests_seq minvalue 10000; 
    116130 
    117131create table entrants ( 
    118132    id integer not null primary key, 
    119133    name varchar(255) not null, 
    120134    course_id integer not null 
    121135); 
     136create sequence entrants_seq minvalue 10000; 
    122137 
    123138create table colnametests ( 
    124139    id integer not null, 
    125140    references integer not null, 
    126141    primary key (id) 
    127142); 
     143create sequence colnametests_seq minvalue 10000; 
    128144 
    129145create table mixins ( 
    130146    id integer not null, 
     
    151167    updated_at date default null, 
    152168    primary key (id) 
    153169); 
     170create sequence mixins_seq minvalue 10000; 
    154171 
    155172create table people ( 
    156173    id integer not null, 
     
    158175    lock_version integer default 0, 
    159176    primary key (id) 
    160177); 
     178create sequence people_seq minvalue 10000; 
    161179 
    162180create table binaries ( 
    163181    id integer not null, 
    164182    data blob null, 
    165183    primary key (id) 
    166184); 
     185create sequence binaries_seq minvalue 10000; 
    167186 
    168187create table computers ( 
    169188  id integer not null primary key, 
    170189  developer integer not null references developers initially deferred disable, 
    171   extendedWarranty integer not null 
     190  "extendedWarranty" integer not null 
    172191); 
     192create sequence computers_seq minvalue 10000; 
    173193 
    174194create table posts ( 
    175195  id integer not null primary key, 
     
    178198  type varchar(255) default null, 
    179199  body varchar(3000) default null 
    180200); 
     201create sequence posts_seq minvalue 10000; 
    181202 
    182203create table comments ( 
    183204  id integer not null primary key, 
     
    185206  type varchar(255) default null, 
    186207  body varchar(3000) default null 
    187208); 
     209create sequence comments_seq minvalue 10000; 
    188210 
    189211create table authors ( 
    190212  id integer not null primary key, 
    191213  name varchar(255) default null 
    192214); 
     215create sequence authors_seq minvalue 10000; 
    193216 
    194217create table tasks ( 
    195218  id integer not null primary key, 
    196219  starting date default null, 
    197220  ending date default null 
    198221); 
     222create sequence tasks_seq minvalue 10000; 
    199223 
    200224create table categories ( 
    201225  id integer not null primary key, 
    202226  name varchar(255) default null, 
    203227  type varchar(255) default null 
    204228); 
     229create sequence categories_seq minvalue 10000; 
    205230 
    206231create table categories_posts ( 
    207232  category_id integer not null references categories initially deferred disable, 
    208233  post_id integer not null references posts initially deferred disable 
    209234); 
     235create sequence categories_posts_seq minvalue 10000; 
    210236 
    211237create table fk_test_has_pk ( 
    212238  id integer not null primary key 
    213239); 
     240create sequence fk_test_has_pk_seq minvalue 10000; 
    214241 
    215242create table fk_test_has_fk ( 
    216243  id integer not null primary key, 
    217244  fk_id integer not null references fk_test_has_fk initially deferred disable 
    218245); 
     246create sequence fk_test_has_fk_seq minvalue 10000; 
  • test/fixtures/db_definitions/oci.drop.sql

    old new  
    11drop table accounts; 
    22drop table companies; 
    33drop table topics; 
     4drop synonym subjects; 
     5drop table developers_projects; 
     6drop table computers; 
    47drop table developers; 
    58drop table projects; 
    6 drop table developers_projects; 
    79drop table customers; 
    810drop table movies; 
    911drop table subscribers; 
     
    1416drop table mixins; 
    1517drop table people; 
    1618drop table binaries; 
    17 drop table posts; 
    1819drop table comments; 
    1920drop table authors; 
    20 drop table computers; 
     21drop table tasks; 
     22drop table categories_posts; 
    2123drop table categories; 
    22 drop table categories_posts; 
    23 drop sequence rails_sequence; 
     24drop table posts; 
     25drop table fk_test_has_pk; 
     26drop table fk_test_has_fk; 
     27drop sequence accounts_seq; 
     28drop sequence companies_nonstd_seq; 
     29drop sequence topics_seq; 
     30drop sequence developers_seq; 
     31drop sequence projects_seq; 
     32drop sequence developers_projects_seq; 
     33drop sequence customers_seq; 
     34drop sequence movies_seq; 
     35drop sequence subscribers_seq; 
     36drop sequence booleantests_seq; 
     37drop sequence auto_id_tests_seq; 
     38drop sequence entrants_seq; 
     39drop sequence colnametests_seq; 
     40drop sequence mixins_seq; 
     41drop sequence people_seq; 
     42drop sequence binaries_seq; 
     43drop sequence posts_seq; 
     44drop sequence comments_seq; 
     45drop sequence authors_seq; 
     46drop sequence tasks_seq; 
     47drop sequence computers_seq; 
     48drop sequence categories_seq; 
     49drop sequence categories_posts_seq; 
     50drop sequence fk_test_has_pk_seq; 
     51drop sequence fk_test_has_fk_seq; 
  • test/fixtures/company.rb

    old new  
    11class Company < ActiveRecord::Base 
    22  attr_protected :rating 
     3  set_sequence_name :companies_nonstd_seq 
    34 
    45  validates_presence_of :name 
    56end 
  • lib/active_record/connection_adapters/sqlite_adapter.rb

    old new  
    119119        @connection.changes 
    120120      end 
    121121 
    122       def insert(sql, name = nil, pk = nil, id_value = nil
     122      def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
    123123        execute(sql, name = nil) 
    124124        id_value || @connection.last_insert_row_id 
    125125      end 
  • lib/active_record/connection_adapters/abstract_adapter.rb

    old new  
    279279      def columns(table_name, name = nil) end 
    280280 
    281281      # Returns the last auto-generated ID from the affected table. 
    282       def insert(sql, name = nil, pk = nil, id_value = nil) end 
     282      def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) end 
    283283 
    284284      # Executes the update statement and returns the number of rows affected. 
    285285      def update(sql, name = nil) end 
  • lib/active_record/connection_adapters/postgresql_adapter.rb

    old new  
    9595        end 
    9696      end 
    9797 
    98       def insert(sql, name = nil, pk = nil, id_value = nil
     98      def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
    9999        execute(sql, name) 
    100100        table = sql.split(" ", 4)[2] 
    101101        return id_value || last_insert_id(table, pk) 
  • lib/active_record/connection_adapters/mysql_adapter.rb

    old new  
    109109        columns 
    110110      end 
    111111 
    112       def insert(sql, name = nil, pk = nil, id_value = nil
     112      def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
    113113        execute(sql, name = nil) 
    114114        id_value || @connection.insert_id 
    115115      end 
  • lib/active_record/connection_adapters/sqlserver_adapter.rb

    old new  
    204204        columns 
    205205      end 
    206206 
    207       def insert(sql, name = nil, pk = nil, id_value = nil
     207      def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
    208208        begin 
    209209          table_name = get_table_name(sql) 
    210210          col = get_identity_column(table_name) 
  • lib/active_record/connection_adapters/db2_adapter.rb

    old new  
    4444          select(sql, name).first 
    4545        end 
    4646 
    47         def insert(sql, name = nil, pk = nil, id_value = nil
     47        def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
    4848          execute(sql, name = nil) 
    4949          id_value || last_insert_id 
    5050        end 
  • lib/active_record/connection_adapters/oci_adapter.rb

    old new  
    1515# Do what you want with this code, at your own peril, but if any significant portion of my code 
    1616# remains then please acknowledge my contribution. 
    1717# Copyright 2005 Graham Jenkins 
    18 # $Revision: 1.2 $ 
     18 
    1919require 'active_record/connection_adapters/abstract_adapter' 
    2020 
    2121begin 
    2222  require_library_or_gem 'oci8' unless self.class.const_defined? :OCI8 
    2323 
     24  class String 
     25 
     26        # Oracle column names by default are case-insensitive, but treated as upcase; 
     27        # for neatness, we'll downcase within Rails. EXCEPT that folks CAN quote 
     28        # their column names when creating Oracle tables, which makes then case-sensitive. 
     29        # I don't know anybody who does this, but we'll handle the theoretical case of a 
     30        # camelCase column name. I imagine other dbs handle this different, since there's a 
     31        # unit test that's currently failing test_oci. 
     32        def oci_downcase 
     33          self =~ /[a-z]/ ? self : self.downcase 
     34        end 
     35  end 
     36 
    2437  module ActiveRecord 
    2538    module ConnectionAdapters #:nodoc: 
    2639      class OCIColumn < Column #:nodoc: 
     
    7790      # It has also been tested against a 9i database. 
    7891      # 
    7992      # Usage notes: 
    80       # * Key generation uses a sequence "rails_sequence" for all tables. (I couldn't find a simple 
    81       #   and safe way of passing table-specific sequence information to the adapter.) 
     93      # * Key generation assumes a "${table_name}_seq" sequence is available for all tables. 
    8294      # * Oracle uses DATE or TIMESTAMP datatypes for both dates and times. Consequently I have had to 
    8395      #   resort to some hacks to get data converted to Date or Time in Ruby. 
    8496      #   If the column_name ends in _time it's created as a Ruby Time. Else if the 
     
    117129          end 
    118130        end 
    119131 
     132        # camelCase column names need to be quoted; not that anyone using Oracle 
     133        # would really do this, but handling this case means we pass the test... 
     134        def quote_column_name(name) 
     135          name =~ /[A-Z]/ ? "\"#{name}\"" : name 
     136        end 
     137 
    120138        def select_all(sql, name = nil) 
    121139          offset = sql =~ /OFFSET (\d+)$/ ? $1.to_i : 0 
    122140          sql, limit = $1, $2.to_i if sql =~ /(.*)(?: LIMIT[= ](\d+))(\s*OFFSET \d+)?$/ 
     
    126144            sql = "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_) where raw_rnum_ > #{offset}" 
    127145          end 
    128146          cursor = log(sql, name) { @connection.exec sql } 
    129           cols = cursor.get_col_names.map { |x| x.downcase } 
     147          cols = cursor.get_col_names.map { |x| x.oci_downcase } 
    130148          rows = [] 
    131149          while row = cursor.fetch 
    132150            hash = Hash.new 
     
    155173        def columns(table_name, name = nil) 
    156174          cols = select_all(%Q{ 
    157175              select column_name, data_type, data_default, data_length, data_scale 
    158               from user_tab_columns where table_name = '#{table_name.upcase}'} 
     176              from user_catalog cat, user_synonyms syn, all_tab_columns col 
     177              where cat.table_name = '#{table_name.upcase}' 
     178              and syn.synonym_name (+)= cat.table_name 
     179              and col.owner = nvl(syn.table_owner, user) 
     180              and col.table_name = nvl(syn.table_name, cat.table_name)} 
    159181          ).map { |row| 
    160             OCIColumn.new row['column_name'].downcase, row['data_default'], 
     182            OCIColumn.new row['column_name'].oci_downcase, row['data_default'], 
    161183              row['data_length'], row['data_type'], row['data_scale'] 
    162184          } 
    163185          cols 
    164186        end 
    165187 
    166         def insert(sql, name = nil, pk = nil, id_value = nil
     188        def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
    167189          if pk.nil? # Who called us? What does the sql look like? No idea! 
    168190            execute sql, name 
    169191          elsif id_value # Pre-assigned id 
    170192            log(sql, name) { @connection.exec sql } 
    171193          else # Assume the sql contains a bind-variable for the id 
    172             id_value = select_one("select rails_sequence.nextval id from dual")['id'] 
     194            id_value = select_one("select #{sequence_name}.nextval id from dual")['id'] 
    173195            log(sql, name) { @connection.exec sql, id_value } 
    174196          end 
    175197          id_value 
     
    233255      def write_lobs() #:nodoc: 
    234256        if connection.class == ConnectionAdapters::OCIAdapter 
    235257          self.class.columns.select { |c| c.type == :binary }.each { |c| 
    236             break unless value = self[c.name] 
     258            #break unless value = self[c.name] 
     259                                                value = self[c.name] 
     260                                                next if value.nil?  || (value == '') 
    237261            lob = connection.select_one( 
    238262              "select #{ c.name} from #{ self.class.table_name } WHERE #{ self.class.primary_key} = #{quote(id)}", 
    239263              'Writable Large Object' 
  • lib/active_record/base.rb

    old new  
    561561        end 
    562562      end 
    563563 
     564      # Defines the sequence_name (for Oracle) -- can be overridden in subclasses. 
     565      def sequence_name 
     566        "#{table_name}_seq" 
     567      end 
     568 
    564569      # Defines the column name for use with single table inheritance -- can be overridden in subclasses. 
    565570      def inheritance_column 
    566571        "type" 
     
    593598      end 
    594599      alias :primary_key= :set_primary_key 
    595600 
     601      # Sets the name of the sequence to use when generating ids to the given 
     602      # value, or (if the value is nil or false) to the value returned by the 
     603      # given block. Currently useful only when using Oracle, which requires 
     604      # explicit sequences. 
     605      # 
     606      # Setting the sequence name when using other dbs will have no effect. 
     607      # If a sequence name is not explicitly set when using Oracle, it will 
     608      # default to the commonly used pattern of: #{table_name}_seq 
     609      # 
     610      # Example: 
     611      # 
     612      #   class Project < ActiveRecord::Base 
     613      #     set_sequence_name "projectseq"   # default would have been "project_seq" 
     614      #   end 
     615      def set_sequence_name( value=nil, &block ) 
     616        define_attr_method :sequence_name, value, &block 
     617      end 
     618      alias :sequence_name= :set_sequence_name 
     619 
    596620      # Sets the name of the inheritance column to use to the given value, 
    597621      # or (if the value # is nil or false) to the value returned by the 
    598622      # given block. 
     
    11571181          "(#{quoted_column_names.join(', ')}) " + 
    11581182          "VALUES(#{attributes_with_quotes.values.join(', ')})", 
    11591183          "#{self.class.name} Create", 
    1160           self.class.primary_key, self.id 
     1184          self.class.primary_key, self.id, self.class.sequence_name 
    11611185        ) 
    11621186 
    11631187        @new_record = false