]> source.dussan.org Git - sonarqube.git/blob
22fe32dcc331526d6d3afdeb23e679b74aade7f4
[sonarqube.git] /
1 module ActiveRecord
2   module ConnectionAdapters
3     # interface independent methods
4     class OracleEnhancedConnection #:nodoc:
5
6       def self.create(config)
7         case ORACLE_ENHANCED_CONNECTION
8         when :oci
9           OracleEnhancedOCIConnection.new(config)
10         when :jdbc
11           OracleEnhancedJDBCConnection.new(config)
12         else
13           nil
14         end
15       end
16
17       attr_reader :raw_connection
18
19       # Oracle column names by default are case-insensitive, but treated as upcase;
20       # for neatness, we'll downcase within Rails. EXCEPT that folks CAN quote
21       # their column names when creating Oracle tables, which makes then case-sensitive.
22       # I don't know anybody who does this, but we'll handle the theoretical case of a
23       # camelCase column name. I imagine other dbs handle this different, since there's a
24       # unit test that's currently failing test_oci.
25       def oracle_downcase(column_name)
26         return nil if column_name.nil?
27         column_name =~ /[a-z]/ ? column_name : column_name.downcase
28       end
29
30       # Used always by JDBC connection as well by OCI connection when describing tables over database link
31       def describe(name)
32         name = name.to_s
33         if name.include?('@')
34           name, db_link = name.split('@')
35           default_owner = select_value("SELECT username FROM all_db_links WHERE db_link = '#{db_link.upcase}'")
36           db_link = "@#{db_link}"
37         else
38           db_link = nil
39           default_owner = @owner
40         end
41         real_name = OracleEnhancedAdapter.valid_table_name?(name) ? name.upcase : name
42         if real_name.include?('.')
43           table_owner, table_name = real_name.split('.')
44         else
45           table_owner, table_name = default_owner, real_name
46         end
47         sql = <<-SQL
48           SELECT owner, table_name, 'TABLE' name_type
49           FROM all_tables#{db_link}
50           WHERE owner = '#{table_owner}'
51             AND table_name = '#{table_name}'
52           UNION ALL
53           SELECT owner, view_name table_name, 'VIEW' name_type
54           FROM all_views#{db_link}
55           WHERE owner = '#{table_owner}'
56             AND view_name = '#{table_name}'
57           UNION ALL
58           SELECT table_owner, DECODE(db_link, NULL, table_name, table_name||'@'||db_link), 'SYNONYM' name_type
59           FROM all_synonyms#{db_link}
60           WHERE owner = '#{table_owner}'
61             AND synonym_name = '#{table_name}'
62           UNION ALL
63           SELECT table_owner, DECODE(db_link, NULL, table_name, table_name||'@'||db_link), 'SYNONYM' name_type
64           FROM all_synonyms#{db_link}
65           WHERE owner = 'PUBLIC'
66             AND synonym_name = '#{real_name}'
67         SQL
68         if result = select_one(sql)
69           case result['name_type']
70           when 'SYNONYM'
71             describe("#{result['owner'] && "#{result['owner']}."}#{result['table_name']}#{db_link}")
72           else
73             db_link ? [result['owner'], result['table_name'], db_link] : [result['owner'], result['table_name']]
74           end
75         else
76           raise OracleEnhancedConnectionException, %Q{"DESC #{name}" failed; does it exist?}
77         end
78       end
79
80       # Returns a record hash with the column names as keys and column values
81       # as values.
82       def select_one(sql)
83         result = select(sql)
84         result.first if result
85       end
86
87       # Returns a single value from a record
88       def select_value(sql)
89         if result = select_one(sql)
90           result.values.first
91         end
92       end
93
94       # Returns an array of the values of the first column in a select:
95       #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
96       def select_values(sql)
97         result = select(sql)
98         result.map { |r| r.values.first }
99       end
100
101     end
102     
103     class OracleEnhancedConnectionException < StandardError #:nodoc:
104     end
105
106   end
107 end
108
109 # if MRI or YARV
110 if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
111   ORACLE_ENHANCED_CONNECTION = :oci
112   require 'active_record/connection_adapters/oracle_enhanced_oci_connection'
113 # if JRuby
114 elsif RUBY_ENGINE == 'jruby'
115   ORACLE_ENHANCED_CONNECTION = :jdbc
116   require 'active_record/connection_adapters/oracle_enhanced_jdbc_connection'
117 else
118   raise "Unsupported Ruby engine #{RUBY_ENGINE}"
119 end