]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2587 SONAR-2549 Fix schema conflicts on Oracle and PostgreSQL
authorSimon Brandhof <simon.brandhof@gmail.com>
Tue, 6 Sep 2011 16:04:17 +0000 (18:04 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Tue, 6 Sep 2011 16:09:03 +0000 (18:09 +0200)
44 files changed:
sonar-application/src/main/assembly/conf/sonar.properties
sonar-core/src/main/java/org/sonar/jpa/dialect/Derby.java
sonar-core/src/main/java/org/sonar/jpa/dialect/Dialect.java
sonar-core/src/main/java/org/sonar/jpa/dialect/HsqlDb.java
sonar-core/src/main/java/org/sonar/jpa/dialect/MsSql.java
sonar-core/src/main/java/org/sonar/jpa/dialect/MySql.java
sonar-core/src/main/java/org/sonar/jpa/dialect/Oracle.java
sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSql.java
sonar-core/src/test/java/org/sonar/jpa/dialect/DialectRepositoryTest.java
sonar-server/src/dev/oracle/sonar.properties
sonar-server/src/main/webapp/WEB-INF/config/database.yml
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-jdbc-adapter-1.1.3/lib/arjdbc/oracle/adapter.rb
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/.rspec [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/.specification [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/Gemfile [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/History.txt [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/License.txt [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/README.md [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/RUNNING_TESTS.md [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/Rakefile [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/VERSION [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/activerecord-oracle_enhanced-adapter.gemspec [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/emulation/oracle_adapter.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced.rake [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_column.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_connection.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_version.rb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/activerecord-oracle_enhanced-adapter.rb [new file with mode: 0644]

index 0947968e054f24294d191fcfad0513e3f3086bee..a68b53670caaf36bb222bf2777c40d70de9b9cc8 100644 (file)
@@ -66,14 +66,19 @@ sonar.jdbc.driverClassName:                org.apache.derby.jdbc.ClientDriver
 
 #----- Oracle 10g/11g
 # To use Oracle database :
-# - Copy the JDBC driver to extensions/jdbc-driver/oracle.
+#
+# - Download the latest version of the JDBC driver (either ojdbc6.jar for Java 6 or ojdbc5.jar for Java 5) 
+#   from http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html
+# - Copy the driver to the directory extensions/jdbc-driver/oracle/
 # - Comment the embedded database and uncomment the following properties. The validation query is optional.
+#
 #sonar.jdbc.url:                            jdbc:oracle:thin:@localhost/XE
 #sonar.jdbc.driverClassName:                oracle.jdbc.driver.OracleDriver
 #sonar.jdbc.validationQuery:                select 1 from dual
 
-# Activate if more than one Sonar Oracle schemas on the data server (for example different versions installed).
-# In that case, use the same property during maven analysis (-Dsonar.hibernate.default_schema=xxx)
+# Uncomment the following property if multiple Sonar schemas are installed on the same server 
+# (for example with different versions).
+# In that case, use the same property during project analysis (-Dsonar.hibernate.default_schema=<schema>)
 #sonar.hibernate.default_schema:            sonar
 
 #----- PostgreSQL 8.x, 9.x
index b0c0ec5614de1c402369bf1e1a78a25f4779d611..5dd0bc6fee6e7d37ce9238f03b9c567232fb1dcb 100644 (file)
@@ -39,6 +39,10 @@ public class Derby implements Dialect {
     return "derby";
   }
 
+  public String getActiveRecordJdbcAdapter() {
+    return "jdbc";
+  }
+
   public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() {
     return DerbyWithDecimalDialect.class;
   }
index 8a265b594303b853ec00b4997c945e38e3e115da..c23698cb4439a96cf4084212a633af709a2bb321 100644 (file)
@@ -39,6 +39,11 @@ public interface Dialect {
    */
   String getActiveRecordDialectCode();
 
+  /**
+   * @return the activerecord-jdbc adapter. See the property 'adapter' in database.yml
+   */
+  String getActiveRecordJdbcAdapter();
+
   /**
    * Used to autodetect a dialect for a given driver URL
    *
index b8440a7efa3f5fd6eca3a8b4bdbe404e4414e194..4a7d2d2bc20d327e7e77df8b127cc57d14aaede8 100644 (file)
@@ -35,6 +35,10 @@ public class HsqlDb implements Dialect {
     return "hsqldb";
   }
 
+  public String getActiveRecordJdbcAdapter() {
+    return "jdbc";
+  }
+
   public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() {
     return HSQLDialect.class;
   }
index 8e480719c2ae837c1ae5fa3dcaf28f10067cebee..bd00d293c0c119c3cd3a13c5fd0ab168d1a318fe 100644 (file)
@@ -36,6 +36,10 @@ public class MsSql implements Dialect {
     return "sqlserver";
   }
 
+  public String getActiveRecordJdbcAdapter() {
+    return "jdbc";
+  }
+
   public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() {
     return MsSqlDialect.class;
   }
index 694e133579383f086fb858bcd49c6321907a7b38..142fa9fbff83d114d714b9fdb7baa84413a98a3b 100644 (file)
@@ -38,6 +38,10 @@ public class MySql implements Dialect {
     return "mysql";
   }
 
+  public String getActiveRecordJdbcAdapter() {
+    return "jdbc";
+  }
+
   public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() {
     return MySqlWithDecimalDialect.class;
   }
index 990e617e1d05e9bb7c408422c3f1bfc22143d0c0..a0417fb37210c635430b3301cadf92c5782bd1f6 100644 (file)
@@ -38,6 +38,10 @@ public class Oracle implements Dialect {
     return "oracle";
   }
 
+  public String getActiveRecordJdbcAdapter() {
+    return "oracle_enhanced";
+  }
+
   public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() {
     return Oracle10gWithDecimalDialect.class;
   }
index b7741722b9da7b5202dc0e77be0c8349782795f3..7f214a4aef0b4b9838667ee6f4562c0819d48121 100644 (file)
@@ -37,6 +37,10 @@ public class PostgreSql implements Dialect {
     return "postgre";
   }
 
+  public String getActiveRecordJdbcAdapter() {
+    return "jdbc";
+  }
+
   public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() {
     return PostgreSQLWithDecimalDialect.class;
   }
index 4a67f441d2fcbaf47fb5f19d4467d19707d57ba3..e1bad1fa3fe7bb644cc60e4880a40001948f130d 100644 (file)
@@ -63,8 +63,12 @@ public class DialectRepositoryTest {
     }
     
     public String getActiveRecordDialectCode() {
-      return null;
+      return "test";
     }
+
+    public String getActiveRecordJdbcAdapter() {
+    return "jdbc";
+  }
   }
 
 }
index 8ebce5e28e5c044ca2a6a14b9b435364c59d005f..b5125aa551f6fc13b0598bb8844be320c482ae27 100644 (file)
@@ -1,7 +1,7 @@
 # Oracle
 sonar.jdbc.url:                            jdbc:oracle:thin:@192.168.1.99/XE
 sonar.jdbc.driverClassName:                oracle.jdbc.driver.OracleDriver
-sonar.jdbc.username:                           sonar
+sonar.jdbc.username:                       sonar
 sonar.jdbc.password:                       sonar
 sonar.jdbc.maxActive:                      30
 sonar.jdbc.maxIdle:                        10
index 23d8913acd53cd1d9de72a2e49b37fe096f24e80..9773f48e7bb961f026959e4fa902b0b08bd217e4 100644 (file)
@@ -1,21 +1,31 @@
-# JDBC configured is loaded from Sonar
-development:
-  adapter: jdbc
-  
-production:
-  <% if ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.jndiName') %>
-  adapter: jndi
-  <% else %>
-  adapter: jdbc
+base: &base
+  adapter: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordJdbcAdapter() %>
+<% jndi_name = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.jndiName')
+   if jndi_name
+%>
+  # JNDI settings
+  jndi: <%= jndi_name %>
+<%
+  else
+%>
+  # JDBC settings
   username: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.username' ) || 'sonar' %>
   password: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.password') || 'sonar' %>
   url: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.url') %>
+  connection_alive_sql: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.validationQuery') %>
+<%
+  end
+%>
+  # Generic settings
+  dialect: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordDialectCode() %>
+  driver: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.driverClassName') %>
+  pool: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.maxActive') || 10 %>
 
   # PostgreSQL
   schema_search_path: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.postgreSearchPath') %>
-  connection_alive_sql: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.validationQuery') %>
-  <% end %>
 
-  dialect: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordDialectCode() %>
-  driver: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.driverClassName') %>
-  pool: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.maxActive') || 10 %>
\ No newline at end of file
+development:
+  <<: *base
+
+production:
+  <<: *base
\ No newline at end of file
index 6ed95b45aa0865a4af4e1caf1d20f5f285f22a7c..d0f08a2974b42625c2c7611299195378bdfa2e6b 100644 (file)
@@ -198,19 +198,8 @@ module ::ArJdbc
     def modify_types(tp)
       tp[:primary_key] = "NUMBER(38) NOT NULL PRIMARY KEY"
       tp[:integer] = { :name => "NUMBER", :limit => 38 }
-
-      # sonar
-      tp[:datetime] = { :name => "TIMESTAMP" }
-      tp[:timestamp] = { :name => "TIMESTAMP" }
-      # /sonar
-
       tp[:time] = { :name => "DATE" }
       tp[:date] = { :name => "DATE" }
-
-      # sonar
-      # New type
-      tp[:big_integer] = { :name => "NUMBER", :limit => 38 }
-      # /sonar
       tp
     end
 
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/.rspec b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/.rspec
new file mode 100644 (file)
index 0000000..a5faa1d
--- /dev/null
@@ -0,0 +1,2 @@
+--color
+--backtrace
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/.specification b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/.specification
new file mode 100644 (file)
index 0000000..df76146
--- /dev/null
@@ -0,0 +1,230 @@
+--- !ruby/object:Gem::Specification 
+name: activerecord-oracle_enhanced-adapter
+version: !ruby/object:Gem::Version 
+  prerelease: 
+  segments: 
+    - 1
+    - 4
+    - 0
+  version: 1.4.0
+platform: ruby
+authors: 
+  - Raimonds Simanovskis
+autorequire: 
+bindir: bin
+cert_chain: []
+
+date: 2011-08-08 00:00:00 +02:00
+default_executable: 
+dependencies: 
+  - !ruby/object:Gem::Dependency 
+    name: jeweler
+    prerelease: false
+    requirement: &id001 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ~>
+          - !ruby/object:Gem::Version 
+            version: 1.5.1
+    type: :development
+    version_requirements: *id001
+  - !ruby/object:Gem::Dependency 
+    name: rspec
+    prerelease: false
+    requirement: &id002 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ~>
+          - !ruby/object:Gem::Version 
+            version: "2.4"
+    type: :development
+    version_requirements: *id002
+  - !ruby/object:Gem::Dependency 
+    name: activerecord
+    prerelease: false
+    requirement: &id003 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: "0"
+    type: :development
+    version_requirements: *id003
+  - !ruby/object:Gem::Dependency 
+    name: activemodel
+    prerelease: false
+    requirement: &id004 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: "0"
+    type: :development
+    version_requirements: *id004
+  - !ruby/object:Gem::Dependency 
+    name: activesupport
+    prerelease: false
+    requirement: &id005 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: "0"
+    type: :development
+    version_requirements: *id005
+  - !ruby/object:Gem::Dependency 
+    name: actionpack
+    prerelease: false
+    requirement: &id006 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: "0"
+    type: :development
+    version_requirements: *id006
+  - !ruby/object:Gem::Dependency 
+    name: railties
+    prerelease: false
+    requirement: &id007 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: "0"
+    type: :development
+    version_requirements: *id007
+  - !ruby/object:Gem::Dependency 
+    name: arel
+    prerelease: false
+    requirement: &id008 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: "0"
+    type: :development
+    version_requirements: *id008
+  - !ruby/object:Gem::Dependency 
+    name: ruby-plsql
+    prerelease: false
+    requirement: &id009 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ">="
+          - !ruby/object:Gem::Version 
+            version: 0.4.4
+    type: :development
+    version_requirements: *id009
+  - !ruby/object:Gem::Dependency 
+    name: ruby-oci8
+    prerelease: false
+    requirement: &id010 !ruby/object:Gem::Requirement 
+      none: false
+      requirements: 
+        - - ~>
+          - !ruby/object:Gem::Version 
+            version: 2.0.4
+    type: :development
+    version_requirements: *id010
+description: |
+  Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases.
+  This adapter is superset of original ActiveRecord Oracle adapter.
+
+email: raimonds.simanovskis@gmail.com
+executables: []
+
+extensions: []
+
+extra_rdoc_files: 
+  - README.md
+files: 
+  - .rspec
+  - Gemfile
+  - History.txt
+  - License.txt
+  - README.md
+  - RUNNING_TESTS.md
+  - Rakefile
+  - VERSION
+  - activerecord-oracle_enhanced-adapter.gemspec
+  - lib/active_record/connection_adapters/emulation/oracle_adapter.rb
+  - lib/active_record/connection_adapters/oracle_enhanced.rake
+  - lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_column.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_connection.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_context_index.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_cpk.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_dirty.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_procedures.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_tasks.rb
+  - lib/active_record/connection_adapters/oracle_enhanced_version.rb
+  - lib/activerecord-oracle_enhanced-adapter.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb
+  - spec/spec_helper.rb
+has_rdoc: true
+homepage: http://github.com/rsim/oracle-enhanced
+licenses: []
+
+post_install_message: 
+rdoc_options: []
+
+require_paths: 
+  - lib
+required_ruby_version: !ruby/object:Gem::Requirement 
+  none: false
+  requirements: 
+    - - ">="
+      - !ruby/object:Gem::Version 
+        version: "0"
+required_rubygems_version: !ruby/object:Gem::Requirement 
+  none: false
+  requirements: 
+    - - ">="
+      - !ruby/object:Gem::Version 
+        version: "0"
+requirements: []
+
+rubyforge_project: 
+rubygems_version: 1.5.1
+signing_key: 
+specification_version: 3
+summary: Oracle enhanced adapter for ActiveRecord
+test_files: 
+  - spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb
+  - spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb
+  - spec/spec_helper.rb
+
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/Gemfile b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/Gemfile
new file mode 100644 (file)
index 0000000..0d9fe3c
--- /dev/null
@@ -0,0 +1,40 @@
+source 'http://rubygems.org'
+
+group :development do
+  gem 'jeweler', '~> 1.5.1'
+  gem 'rspec', '~> 2.4'
+
+  if ENV['RAILS_GEM_VERSION']
+    gem 'activerecord', "=#{ENV['RAILS_GEM_VERSION']}"
+    gem 'actionpack', "=#{ENV['RAILS_GEM_VERSION']}"
+    gem 'activesupport', "=#{ENV['RAILS_GEM_VERSION']}"
+    case ENV['RAILS_GEM_VERSION']
+    when /^2.0/
+      gem 'composite_primary_keys', '=0.9.93'
+    when /^2.1/
+      gem 'composite_primary_keys', '=1.0.8'
+    when /^2.2/
+      gem 'composite_primary_keys', '=2.2.2'
+    when /^2.3.3/
+      gem 'composite_primary_keys', '=2.3.2'
+    when /^3/
+      gem 'railties', "=#{ENV['RAILS_GEM_VERSION']}"
+    end
+  else
+    # uses local copy of Rails 3 and Arel gems
+    ENV['RAILS_GEM_PATH'] ||= File.expand_path('../../rails', __FILE__)
+    %w(activerecord activemodel activesupport actionpack railties).each do |gem_name|
+      gem gem_name, :path => File.join(ENV['RAILS_GEM_PATH'], gem_name)
+    end
+
+    ENV['AREL_GEM_PATH'] ||= File.expand_path('../../arel', __FILE__)
+    gem 'arel', :path => ENV['AREL_GEM_PATH']
+  end
+
+  gem 'ruby-plsql', '>=0.4.4'
+
+  platforms :ruby do
+    gem 'ruby-oci8', '~> 2.0.4'
+  end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/History.txt b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/History.txt
new file mode 100644 (file)
index 0000000..cddf45d
--- /dev/null
@@ -0,0 +1,252 @@
+== 1.4.0 2011-08-09
+
+* Enhancements:
+  * Support for Rails 3.1
+  * Bind parameter support for exec_insert, exec_update and exec_delete (in ActiveRecord 3.1)
+  * Purge recyclebin on rake db:test:purge
+  * Support transactional context index
+  * Require ojdbc6.jar (on Java 6) or ojdbc5.jar (on Java 5) JDBC drivers
+  * Support for RAW data type
+  * rake db:create and db:drop tasks
+  * Support virtual columns (in Oracle 11g) in schema dump
+  * It is possible to specify default tablespaces for tables, indexes, CLOBs and BLOBs
+  * rename_index migrations method
+  * Search for JDBC driver in ./lib directory of Rails application
+* Bug fixes:
+  * Fixed context index dump when definition is larger than 4000 bytes
+  * Fixed schema dump not to conflict with other database adapters that are used in the same application
+  * Allow $ in table name prefix or suffix
+
+== 1.3.2 2011-01-05
+
+* Enhancements:
+  * If no :host or :port is provided then connect with :database name (do not default :host to localhost)
+  * Database connection pool support for JRuby on Tomcat and JBoss application servers
+  * NLS connection parameters support via environment variables or database.yml
+  * Support for Arel 2.0 and latest Rails master branch
+  * Support for Rails 3.1 prepared statements (implemented in not yet released Rails master branch version)
+  * Eager loading of included association with more than 1000 records (implemented in not yet released Rails master branch version)
+* Bug fixes:
+  * Foreign keys are added after table definitions in schema dump to ensure correct order of schema statements
+  * Quote NCHAR and NVARCHAR2 type values with N'...'
+  * Numeric username and/or password in database.yml will be automatically converted to string
+
+== 1.3.1 2010-09-09
+
+* Enhancements:
+  * Tested with Rails 3.0.0 release
+  * Lexer options for context index creation
+  * Added Bundler for running adapter specs, added RUNNING_TESTS.rdoc with description how to run specs
+  * Connection to database using :host, :port and :database options
+  * Improved loading of adapter in Rails 3 using railtie
+* Bug fixes:
+  * Fix for custom context index procedure when indexing records with null values
+  * Quote table and column names in write_lobs callback
+  * Fix for incorrect column SQL types when two models use the same table and AR query cache is enabled
+  * Fixes for schema and scructure dump tasks
+  * Fix for handling of zero-length strings in BLOB and CLOB columns
+  * removed String.mb_chars upcase and downcase methods for Ruby 1.9 as Rails 3.0.0 already includes Unicode aware upcase and downcase methods for Ruby 1.9
+  * Fixes for latest ActiveRecord unit tests
+
+== 1.3.0 2010-06-21
+
+* Enhancements:
+  * Rails 3.0.0.beta4 and Rails 2.3.x compatible
+  * When used with Rails 3 then works together with Oracle SQL compiler included in Arel gem (http://github.com/rails/arel)
+  * Rails 3: Better support for limit and offset (when possible adds just ROWNUM condition in WHERE clause without using subqueries)
+  * Table and column names are always quoted and in uppercase to avoid the need for checking Oracle reserved words
+  * Full text search index creation (add_context_index and remove_context_index methods in migrations and #contains method in ActiveRecord models)
+  * add_index and remove_index give just warnings on wrong index names (new expected behavior in Rails 2.3.8 and 3.0.0)
+  * :tablespace and :options options for create_table and add_index
+* Workarounds:
+  * Rails 3: set ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true in initializer file for all environments
+    (to avoid too many data dictionary queries from Arel)
+  * Rails 2.3: patch several ActiveRecord methods to work correctly with quoted table names in uppercase (see oracle_enhanced_activerecord_patches.rb).
+    These patches are already included in Rails 3.0.0.beta4.
+* Bug fixes:
+  * Fixes for schema purge (drop correctly materialized views)
+  * Fixes for schema dump and structure dump (use correct statement separator)
+  * Only use Oracle specific schema dump for Oracle connections
+
+== 1.2.4 2010-02-23
+
+* Enhancements:
+  * rake db:test:purge will drop all schema objects from test schema (including views, synonyms, packages, functions, procedures) -
+    they should be always reloaded before tests run if necessary
+  * added views, synonyms, packages, functions, procedures, indexes, triggers, types, primary, unique and foreign key constraints to structure dump
+  * added :temporary option for create_table to create temporary tables
+  * added :tablespace option for add_index
+  * support function based indexes in schema dump
+  * support JNDI database connections in JRuby
+  * check ruby-oci8 minimum version 2.0.3
+  * added savepoints support (nested ActiveRecord transactions)
+* Bug fixes:
+  * typecast returned BigDecimal integer values to Fixnum or Bignum
+    (to avoid issues with _before_type_cast values for id attributes because _before_type_cast is used in form helpers)
+  * clear table columns cache after columns definition change in migrations
+
+== 1.2.3 2009-12-09
+
+* Enhancements
+  * support fractional seconds in TIMESTAMP values
+  * support for ActiveRecord 2.3.5
+  * use ENV['TZ'] to set database session time zone
+    (as a result DATE and TIMESTAMP values are retrieved with correct time zone)
+  * added cache_columns adapter option
+  * added current_user adapter method
+  * added set_integer_columns and set_string_columns ActiveRecord model class methods
+* Bug fixes:
+  * do not raise exception if ENV['PATH'] is nil
+  * do not add change_table behavior for ActiveRecord 2.0 (to avoid exception during loading)
+  * move foreign key definitions after definition of all tables in schema.rb
+    (to avoid definition of foreign keys before all tables are created)
+  * changed timestamp format mask to use ':' before fractional seconds
+    (workaround to avoid table detection in tables_in_string method in ActiveRecord associations.rb file)
+  * fixed custom create/update/delete methods with ActiveRecord 2.3+ and timestamps
+  * do not call oracle_enhanced specific schema dump methods when using other database adapters
+
+== 1.2.2 2009-09-28
+
+* Enhancements
+  * improved RDoc documentation of public methods
+  * structure dump optionally (database.yml environment has db_stored_code: yes) extracts
+    packages, procedures, functions, views, triggers and synonyms
+  * automatically generated too long index names are shortened down to 30 characters
+  * create tables with primary key triggers
+  * use 'set_sequence_name :autogenerated' for inserting into legacy tables with trigger populated primary keys
+  * access to tables over database link (need to define local synonym to remote table and use local synonym in set_table_name)
+  * [JRuby] support JDBC connection using TNS_ADMIN environment variable and TNS database alias
+  * changed cursor_sharing option default from 'similar' to 'force'
+  * optional dbms_output logging to ActiveRecord log file (requires ruby-plsql gem)
+  * use add_foreign_key and remove_foreign_key to define foreign key constraints
+    (the same syntax as in http://github.com/matthuhiggins/foreigner and similar
+    to http://github.com/eyestreet/active_record_oracle_extensions)
+  * raise RecordNotUnique and InvalidForeignKey exceptions if caused by corresponding ORA errors
+    (these new exceptions are supported just by current ActiveRecord master branch)
+  * implemented disable_referential_integrity
+    (enables safe loading of fixtures in schema with foreign key constraints)
+  * use add_synonym and remove_synonym to define database synonyms
+  * add_foreign_key and add_synonym are also exported to schema.rb
+* Bug fixes:
+  * [JRuby] do not raise LoadError if ojdbc14.jar cannot be required (rely on application server to add it to class path)
+  * [JRuby] 'execute' can be used to create triggers with :NEW reference
+  * support create_table without a block
+  * support create_table with Symbol table name
+  * use ActiveRecord functionality to do time zone conversion
+  * rake tasks such as db:test:clone are redefined only if oracle_enhanced is current adapter in use
+  * VARCHAR2 and CHAR column sizes are defined in characters and not in bytes (expected behavior from ActiveRecord)
+  * set_date_columns, set_datetime_columns, ignore_table_columns will work after reestablishing connection
+  * ignore :limit option for :text and :binary columns in migrations
+  * patches for ActiveRecord schema dumper to remove table prefixes and suffixes from schema.rb
+
+== 1.2.1 2009-06-07
+
+* Enhancements
+  * caching of table indexes query which makes schema dump much faster
+* Bug fixes:
+  * return Date (and not DateTime) values for :date column value before year 1970
+  * fixed after_create/update/destroy callbacks with plsql custom methods
+  * fixed creation of large integers in JRuby
+  * Made test tasks respect RAILS_ENV
+  * fixed support for composite primary keys for tables with LOBs
+
+== 1.2.0 2009-03-22
+
+* Enhancements
+  * support for JRuby and JDBC
+  * support for Ruby 1.9.1 and ruby-oci8 2.0
+  * support for Rails 2.3
+  * quoting of Oracle reserved words in table names and column names
+  * emulation of OracleAdapter (for ActiveRecord unit tests)
+* Bug fixes:
+  * several bug fixes that were identified during running of ActiveRecord unit tests
+
+== 1.1.9 2009-01-02
+
+* Enhancements
+  * Added support for table and column comments in migrations
+  * Added support for specifying sequence start values
+  * Added :privilege option (e.g. :SYSDBA) to ActiveRecord::Base.establish_connection
+* Bug fixes:
+  * Do not mark empty decimals, strings and texts (stored as NULL in database) as changed when reassigning them (starting from Rails 2.1)
+  * Create booleans as VARCHAR2(1) columns if emulate_booleans_from_strings is true
+
+== 1.1.8 2008-10-10
+
+* Bug fixes:
+  * Fixed storing of serialized LOB columns
+  * Prevent from SQL injection in :limit and :offset
+  * Order by LOB columns (by replacing column with function which returns first 100 characters of LOB)
+  * Sequence creation for tables with non-default primary key in create_table block
+  * Do count distinct workaround only when composite_primary_keys gem is used
+    (otherwise count distinct did not work with ActiveRecord 2.1.1)
+  * Fixed rake db:test:clone_structure task
+    (see http://rsim.lighthouseapp.com/projects/11468/tickets/11-rake-dbtestclone_structure-fails-in-117)
+  * Fixed bug when ActiveRecord::Base.allow_concurrency = true
+    (see http://dev.rubyonrails.org/ticket/11134)
+
+== 1.1.7 2008-08-20
+
+* Bug fixes:
+  * Fixed that adapter works without ruby-plsql gem (in this case just custom create/update/delete methods are not available)
+
+== 1.1.6 2008-08-19
+
+* Enhancements:
+  * Added support for set_date_columns and set_datetime_columns
+  * Added support for set_boolean_columns
+  * Added support for schema prefix in set_table_name (removed table name quoting)
+  * Added support for NVARCHAR2 column type
+* Bug fixes:
+  * Do not call write_lobs callback when custom create or update methods are defined
+    
+== 1.1.5 2008-07-27
+
+* Bug fixes:
+  * Fixed that write_lobs callback works with partial_updates enabled (added additional record lock before writing BLOB data to database)
+* Enhancements:
+  * Changed SQL SELECT in indexes method so that it will execute faster on some large data dictionaries
+  * Support for other date and time formats when assigning string to :date or :datetime column
+
+== 1.1.4 2008-07-14
+
+* Enhancements:
+  * Date/Time quoting changes to support composite_primary_keys
+  * Added additional methods that are used by composite_primary_keys
+
+== 1.1.3 2008-07-10
+
+* Enhancements:
+  * Added support for custom create, update and delete methods when working with legacy databases where
+    PL/SQL API should be used for create, update and delete operations
+
+== 1.1.2 2008-07-08
+
+* Bug fixes:
+  * Fixed after_save callback addition for session store in ActiveRecord version 2.0.2
+  * Changed date column name recognition - now should match regex /(^|_)date(_|$)/i
+    (previously "updated_at" was recognized as :date column and not as :datetime)
+
+== 1.1.1 2008-06-28
+
+* Enhancements:
+  * Added ignore_table_columns option
+  * Added support for TIMESTAMP columns (without fractional seconds)
+  * NLS_DATE_FORMAT and NLS_TIMESTAMP_FORMAT independent DATE and TIMESTAMP columns support
+* Bug fixes:
+  * Checks if CGI::Session::ActiveRecordStore::Session does not have enhanced_write_lobs callback before adding it
+    (Rails 2.0 does not add this callback, Rails 2.1 does)
+
+== 1.1.0 2008-05-05
+
+* Forked from original activerecord-oracle-adapter-1.0.0.9216
+* Renamed oracle adapter to oracle_enhanced adapter
+  * Added "enhanced" to method and class definitions so that oracle_enhanced and original oracle adapter
+    could be used simultaniously
+  * Added Rails rake tasks as a copy from original oracle tasks
+* Enhancements:
+  * Improved perfomance of schema dump methods when used on large data dictionaries
+  * Added LOB writing callback for sessions stored in database
+  * Added emulate_dates_by_column_name option
+  * Added emulate_integers_by_column_name option
+  * Added emulate_booleans_from_strings option
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/License.txt b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/License.txt
new file mode 100644 (file)
index 0000000..7b4cc05
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2008-2011 Graham Jenkins, Michael Schoen, Raimonds Simanovskis
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/README.md b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/README.md
new file mode 100644 (file)
index 0000000..794bf3b
--- /dev/null
@@ -0,0 +1,378 @@
+activerecord-oracle_enhanced-adapter
+====================================
+
+Oracle enhanced adapter for ActiveRecord
+
+DESCRIPTION
+-----------
+
+Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby on Rails applications. Oracle enhanced adapter can be used from Ruby on Rails versions 2.3.x and 3.x and it is working with Oracle database versions 10g and 11g.
+
+INSTALLATION
+------------
+
+### Rails 3
+
+When using Ruby on Rails version 3 then in Gemfile include
+
+    gem 'activerecord-oracle_enhanced-adapter', '~> 1.4.0'
+
+where instead of 1.4.0 you can specify any other desired version. It is recommended to specify version with `~>` which means that use specified version or later patch versions (in this example any later 1.4.x version but not 1.5.x version). Oracle enhanced adapter maintains API backwards compatibility during patch version upgrades and therefore it is safe to always upgrade to latest patch version.
+
+If you would like to use latest adapter version from github then specify
+
+    gem 'activerecord-oracle_enhanced-adapter', :git => 'git://github.com/rsim/oracle-enhanced.git'
+
+If you are using MRI 1.8 or 1.9 Ruby implementation then you need to install ruby-oci8 gem as well as Oracle client, e.g. [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html). Include in Gemfile also ruby-oci8:
+
+    gem 'ruby-oci8', '~> 2.0.6'
+
+If you are using JRuby then you need to download latest [Oracle JDBC driver](http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html) - either ojdbc6.jar for Java 6 or ojdbc5.jar for Java 5. And copy this file to one of these locations:
+
+  * in `./lib` directory of Rails application
+  * in some directory which is in `PATH`
+  * in `JRUBY_HOME/lib` directory
+  * or include path to JDBC driver jar file in Java `CLASSPATH`
+
+After specifying necessary gems in Gemfile run
+
+    bundle install
+
+to install the adapter (or later run `bundle update` to force updating to latest version).
+
+### Rails 2.3
+
+If you don't use Bundler in Rails 2 application then you need to specify gems in `config/environment.rb`, e.g.
+
+    Rails::Initializer.run do |config|
+      #...
+      config.gem 'activerecord-oracle_enhanced-adapter', :lib => "active_record/connection_adapters/oracle_enhanced_adapter"
+      config.gem 'ruby-oci8'
+      #...
+    end
+
+But it is recommended to use Bundler for gem version management also for Rails 2.3 applications (search for instructions in Google).
+
+### Without Rails and Bundler
+
+If you want to use ActiveRecord and Oracle enhanced adapter without Rails and Bundler then install it just as a gem:
+
+    gem install activerecord-oracle_enhanced-adapter
+
+USAGE
+-----
+
+### Database connection
+
+In Rails application `config/database.yml` use oracle_enhanced as adapter name, e.g.
+
+    development:
+      adapter: oracle_enhanced
+      database: xe
+      username: user
+      password: secret
+
+If `TNS_ADMIN` environment variable is pointing to directory where `tnsnames.ora` file is located then you can use TNS connection name in `database` parameter. Otherwise you can directly specify database host, port (defaults to 1521) and database name in the following way:
+
+    development:
+      adapter: oracle_enhanced
+      host: localhost
+      port: 1521
+      database: xe
+      username: user
+      password: secret
+
+or you can use Oracle specific format in `database` parameter:
+
+    development:
+      adapter: oracle_enhanced
+      database: //localhost:1521/xe
+      username: user
+      password: secret
+
+or you can even use Oracle specific TNS connection description:
+
+    development:
+      adapter: oracle_enhanced
+      database: "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=xe)))"
+      username: user
+      password: secret
+
+If you deploy JRuby on Rails application in Java application server that supports JNDI connections then you can specify JNDI connection as well:
+
+    development:
+      adapter: oracle_enhanced
+      jndi: "jdbc/jndi_connection_name"
+
+You can find other available database.yml connection parameters in [oracle_enhanced_adapter.rb](/rsim/oracle-enhanced/blob/master/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb). There are many NLS settings as well as some other Oracle session settings.
+
+### Adapter settings
+
+If you want to change Oracle enhanced adapter default settings then create initializer file e.g. `config/initializers/oracle.rb` specify there necessary defaults, e.g.:
+
+    # It is recommended to set time zone in TZ environment variable so that the same timezone will be used by Ruby and by Oracle session
+    ENV['TZ'] = 'UTC'
+
+    ActiveSupport.on_load(:active_record) do
+      ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+        # id columns and columns which end with _id will always be converted to integers
+        self.emulate_integers_by_column_name = true
+        # DATE columns which include "date" in name will be converted to Date, otherwise to Time
+        self.emulate_dates_by_column_name = true
+        # true and false will be stored as 'Y' and 'N'
+        self.emulate_booleans_from_strings = true
+        # start primary key sequences from 1 (and not 10000) and take just one next value in each session
+        self.default_sequence_start_value = "1 NOCACHE INCREMENT BY 1"
+        # other settings ...
+      end
+    end
+
+In case of Rails 2 application you do not need to use `ActiveSupport.on_load(:active_record) do ... end` around settings code block.
+
+See other adapter settings in [oracle_enhanced_adapter.rb](/rsim/oracle-enhanced/blob/master/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb).
+
+### Legacy schema support
+
+If you want to put Oracle enhanced adapter on top of existing schema tables then there are several methods how to override ActiveRecord defaults, see example:
+
+    class Employee < ActiveRecord::Base
+      # specify schema and table name
+      set_table_name "hr.hr_employees"
+      # specify primary key name
+      set_primary_key "employee_id"
+      # specify sequence name
+      set_sequence_name "hr.hr_employee_s"
+      # set which DATE columns should be converted to Ruby Date
+      set_date_columns :hired_on, :birth_date_on
+      # set which DATE columns should be converted to Ruby Time
+      set_datetime_columns :last_login_time
+      # set which VARCHAR2 columns should be converted to true and false
+      set_boolean_columns :manager, :active
+      # set which columns should be ignored in ActiveRecord
+      ignore_table_columns :attribute1, :attribute2
+    end
+
+You can also access remote tables over database link using
+
+    set_table_name "hr_employees@db_link"
+
+### Custom create, update and delete methods
+
+If you have legacy schema and you are not allowed to do direct INSERTs, UPDATEs and DELETEs in legacy schema tables and need to use existing PL/SQL procedures for create, updated, delete operations then you should add `ruby-plsql` gem to your application and then define custom create, update and delete methods, see example:
+
+    class Employee < ActiveRecord::Base
+      # when defining create method then return ID of new record that will be assigned to id attribute of new object
+      set_create_method do
+        plsql.employees_pkg.create_employee(
+          :p_first_name => first_name,
+          :p_last_name => last_name,
+          :p_employee_id => nil
+        )[:p_employee_id]
+      end
+      set_update_method do
+        plsql.employees_pkg.update_employee(
+          :p_employee_id => id,
+          :p_first_name => first_name,
+          :p_last_name => last_name
+        )
+      end
+      set_delete_method do
+        plsql.employees_pkg.delete_employee(
+          :p_employee_id => id
+        )
+      end
+    end
+
+In addition in `config/initializers/oracle.rb` initializer specify that ruby-plsql should use ActiveRecord database connection:
+
+    plsql.activerecord_class = ActiveRecord::Base
+
+### Oracle CONTEXT index support
+
+Every edition of Oracle database includes [Oracle Text](http://www.oracle.com/technology/products/text/index.html) option for free which provides several full text indexing capabilities. Therefore in Oracle database case you don’t need external full text indexing and searching engines which can simplify your application deployment architecture.
+
+To create simple single column index create migration with, e.g.
+
+    add_context_index :posts, :title
+
+and you can remove context index with
+
+    remove_context_index :posts, :title
+
+Include in class definition
+
+    has_context_index
+
+and then you can do full text search with
+
+    Post.contains(:title, 'word')
+
+You can create index on several columns (which will generate additional stored procedure for providing XML document with specified columns to indexer):
+
+    add_context_index :posts, [:title, :body]
+
+And you can search either in all columns or specify in which column you want to search (as first argument you need to specify first column name as this is the column which is referenced during index creation):
+
+    Post.contains(:title, 'word')
+    Post.contains(:title, 'word within title')
+    Post.contains(:title, 'word within body')
+
+See Oracle Text documentation for syntax that you can use in CONTAINS function in SELECT WHERE clause.
+
+You can also specify some dummy main column name when creating multiple column index as well as specify to update index automatically after each commit (as otherwise you need to synchronize index manually or schedule periodic update):
+
+    add_context_index :posts, [:title, :body], :index_column => :all_text, :sync => 'ON COMMIT'
+
+    Post.contains(:all_text, 'word')
+
+Or you can specify that index should be updated when specified columns are updated (e.g. in ActiveRecord you can specify to trigger index update when created_at or updated_at columns are updated). Otherwise index is updated only when main index column is updated.
+
+    add_context_index :posts, [:title, :body], :index_column => :all_text,
+      :sync => 'ON COMMIT', :index_column_trigger_on => [:created_at, :updated_at]
+
+And you can even create index on multiple tables by providing SELECT statements which should be used to fetch necessary columns from related tables:
+
+    add_context_index :posts,
+      [:title, :body,
+      # specify aliases always with AS keyword
+      "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"
+      ],
+      :name => 'post_and_comments_index',
+      :index_column => :all_text,
+      :index_column_trigger_on => [:updated_at, :comments_count],
+      :sync => 'ON COMMIT'
+
+    # search in any table columns
+    Post.contains(:all_text, 'word')
+    # search in specified column
+    Post.contains(:all_text, "aaa within title")
+    Post.contains(:all_text, "bbb within comment_author")
+
+### Oracle specific schema statements and data types
+
+There are several additional schema statements and data types available that you can use in database migrations:
+
+  * `add_foreign_key` and `remove_foreign_key` for foreign key definition (and they are also dumped in `db/schema.rb`)
+  * `add_synonym` and `remove_synonym` for synonym definition (and they are also dumped in `db/schema.rb`)
+  * You can create table with primary key trigger using `:primary_key_trigger => true` option for `create_table`
+  * You can define columns with `raw` type which maps to Oracle's `RAW` type
+  * You can add table and column comments with `:comment` option
+  * On Oracle 11g you can define `virtual` columns with calculation formula in `:default` option
+  * Default tablespaces can be specified for tables, indexes, clobs and blobs, for example:
+
+        ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces =
+          {:clob => 'TS_LOB', :blob => 'TS_LOB', :index => 'TS_INDEX', :table => 'TS_DATA'}
+
+TROUBLESHOOTING
+---------------
+
+### What to do if Oracle enhanced adapter is not working?
+
+Please verify that
+
+ 1. Oracle Instant Client is installed correctly
+    Can you connect to database using sqlnet?
+
+ 2. ruby-oci8 is installed correctly
+    Try something like:
+
+        ruby -rubygems -e "require 'oci8'; OCI8.new('username','password','database').exec('select * from dual') do |r| puts r.join(','); end"
+
+    to verify that ruby-oci8 is working
+
+ 3. Verify that activerecord-oracle_enhanced-adapter is working from irb
+
+        require 'rubygems'
+        gem 'activerecord'
+        gem 'activerecord-oracle_enhanced-adapter'
+        require 'activerecord'
+        ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced", :database => "database",:username => "user",:password => "password")
+
+    and see if it is successful (use your correct database, username and password)
+
+### What to do if Oracle enhanced adapter is not working with Phusion Passenger?
+
+Oracle Instant Client and ruby-oci8 requires that several environment variables are set:
+
+  * `LD_LIBRARY_PATH` (on Linux) or `DYLD_LIBRARY_PATH` (on Mac) should point to Oracle Instant Client directory (where Oracle client shared libraries are located)
+  * `TNS_ADMIN` should point to directory where `tnsnames.ora` file is located
+  * `NLS_LANG` should specify which territory and language NLS settings to use and which character set to use (e.g. `"AMERICAN_AMERICA.UTF8"`)
+
+If this continues to throw "OCI Library Initialization Error (OCIError)", you might also need
+
+  * `ORACLE_HOME` set to full Oracle client installation directory
+
+When Apache with Phusion Passenger (mod_passenger or previously mod_rails) is used for Rails application deployment then by default Ruby is launched without environment variables that you have set in shell profile scripts (e.g. .profile). Therefore it is necessary to set environment variables in one of the following ways:
+
+  * Create wrapper script as described in [Phusion blog](http://blog.phusion.nl/2008/12/16/passing-environment-variables-to-ruby-from-phusion-passenger) or [RayApps::Blog](http://blog.rayapps.com/2008/05/21/using-mod_rails-with-rails-applications-on-oracle)
+  * Set environment variables in the file which is used by Apache before launching Apache worker processes - on Linux it typically is envvars file (look in apachectl or apache2ctl script where it is looking for envvars file) or /System/Library/LaunchDaemons/org.apache.httpd.plist on Mac OS X. See the following [discussion thread](http://groups.google.com/group/oracle-enhanced/browse_thread/thread/c5f64106569fadd0) for more hints.
+
+RUNNING TESTS
+-------------
+
+See [RUNNING_TESTS.md](/rsim/oracle-enhanced/blob/master/RUNNING_TESTS.md) for information how to set up environment and run Oracle enhanced adapter unit tests.
+
+LINKS
+-----
+
+* Source code: http://github.com/rsim/oracle-enhanced
+* Bug reports / Feature requests / Pull requests: http://github.com/rsim/oracle-enhanced/issues
+* Discuss at Oracle enhanced adapter group: http://groups.google.com/group/oracle-enhanced
+* Blog posts about Oracle enhanced adapter can be found at http://blog.rayapps.com/category/oracle_enhanced
+
+CONTRIBUTORS
+------------
+
+* Raimonds Simanovskis
+* Jorge Dias
+* James Wylder
+* Rob Christie
+* Nate Wieger
+* Edgars Beigarts
+* Lachlan Laycock
+* toddwf
+* Anton Jenkins
+* Dave Smylie
+* Alex Rothenberg
+* Billy Reisinger
+* David Blain
+* Joe Khoobyar
+* Edvard Majakari
+* Beau Fabry
+* Simon Chiang
+* Peter Nyberg
+* Dwayne Litzenberger
+* Aaron Patterson
+* Darcy Schultz
+* Alexi Rahman
+* Joeri Samson
+* Luca Bernardo Ciddio
+* Sam Baskinger
+* Benjamin Ortega
+* Yasuo Honda
+
+LICENSE
+-------
+
+(The MIT License)
+
+Copyright (c) 2008-2011 Graham Jenkins, Michael Schoen, Raimonds Simanovskis
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/RUNNING_TESTS.md b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/RUNNING_TESTS.md
new file mode 100644 (file)
index 0000000..87655f8
--- /dev/null
@@ -0,0 +1,45 @@
+Creating the test database
+--------------------------
+
+You need Oracle database (version 10.2 or later) with SYS and SYSTEM user access.
+
+If you are on a Mac OS X 10.6 then use [these instructions](http://blog.rayapps.com/2009/09/14/how-to-install-oracle-database-10g-on-mac-os-x-snow-leopard) to install local Oracle DB 10.2.0.4. Other option is to use Linux VM and install Oracle DB on it.
+
+If you are on Linux (or will use Linux virtual machine) and need Oracle DB just for running tests then Oracle DB XE edition is enough. See [Oracle XE downloads page](http://www.oracle.com/technetwork/database/express-edition/downloads/index.html) for download links and instructions.
+
+If you are getting ORA-12520 errors when running tests then it means that Oracle cannot create enough processes to handle many connections (as during tests many connections are created and destroyed). In this case you need to log in as SYSTEM user and execute e.g.
+
+    alter system set processes=200 scope=spfile;
+
+to increase process limit and then restart the database (this will be necessary if Oracle XE will be used as default processes limit is 40).
+
+Ruby versions
+-------------
+
+It is recommended to use [RVM](http://rvm.beginrescueend.com) to run tests with different Ruby implementations. oracle_enhanced is mainly tested with MRI 1.8.7 (all Rails versions) and 1.9.2 (Rails 3) and JRuby 1.6.
+
+Running tests
+-------------
+
+* Create Oracle database schema for test purposes. Review `spec/spec_helper.rb` to see default schema/user names and database names (use environment variables to override defaults)
+
+        SQL> CREATE USER oracle_enhanced IDENTIFIED BY oracle_enhanced;
+        SQL> GRANT unlimited tablespace, create session, create table, create sequence, create procedure, create trigger, create view, create materialized view, create database link, create synonym, create type, ctxapp TO oracle_enhanced;
+
+* If you use RVM then switch to corresponding Ruby (1.8.7, 1.9.2 or JRuby) and it is recommended to create isolated gemset for test purposes (e.g. rvm create gemset oracle_enhanced)
+
+* Install bundler with
+
+        gem install bundler
+
+* Set RAILS_GEM_VERSION to Rails version that you would like to use in oracle_enhanced tests, e.g.
+
+        export RAILS_GEM_VERSION=3.0.3
+
+* Install necessary gems with
+
+        bundle install
+
+* Run tests with
+
+        rake spec
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/Rakefile b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/Rakefile
new file mode 100644 (file)
index 0000000..e757684
--- /dev/null
@@ -0,0 +1,46 @@
+require 'rubygems'
+require 'bundler'
+begin
+  Bundler.setup(:default, :development)
+rescue Bundler::BundlerError => e
+  $stderr.puts e.message
+  $stderr.puts "Run `bundle install` to install missing gems"
+  exit e.status_code
+end
+
+require 'rake'
+
+require 'jeweler'
+Jeweler::Tasks.new do |gem|
+  gem.name = "activerecord-oracle_enhanced-adapter"
+  gem.summary = "Oracle enhanced adapter for ActiveRecord"
+  gem.description = <<-EOS
+Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases.
+This adapter is superset of original ActiveRecord Oracle adapter.
+EOS
+  gem.email = "raimonds.simanovskis@gmail.com"
+  gem.homepage = "http://github.com/rsim/oracle-enhanced"
+  gem.authors = ["Raimonds Simanovskis"]
+  gem.extra_rdoc_files = ['README.md']
+end
+Jeweler::RubygemsDotOrgTasks.new
+
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:spec)
+
+RSpec::Core::RakeTask.new(:rcov) do |t|
+  t.rcov = true
+  t.rcov_opts =  ['--exclude', '/Library,spec/']
+end
+
+task :default => :spec
+
+require 'rake/rdoctask'
+Rake::RDocTask.new do |rdoc|
+  version = File.exist?('VERSION') ? File.read('VERSION') : ""
+
+  rdoc.rdoc_dir = 'doc'
+  rdoc.title = "activerecord-oracle_enhanced-adapter #{version}"
+  rdoc.rdoc_files.include('README*')
+  rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/VERSION b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/VERSION
new file mode 100644 (file)
index 0000000..88c5fb8
--- /dev/null
@@ -0,0 +1 @@
+1.4.0
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/activerecord-oracle_enhanced-adapter.gemspec b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/activerecord-oracle_enhanced-adapter.gemspec
new file mode 100644 (file)
index 0000000..9833bab
--- /dev/null
@@ -0,0 +1,127 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE DIRECTLY
+# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+  s.name = %q{activerecord-oracle_enhanced-adapter}
+  s.version = "1.4.0"
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+  s.authors = ["Raimonds Simanovskis"]
+  s.date = %q{2011-08-09}
+  s.description = %q{Oracle "enhanced" ActiveRecord adapter contains useful additional methods for working with new and legacy Oracle databases.
+This adapter is superset of original ActiveRecord Oracle adapter.
+}
+  s.email = %q{raimonds.simanovskis@gmail.com}
+  s.extra_rdoc_files = [
+    "README.md"
+  ]
+  s.files = [
+    ".rspec",
+    "Gemfile",
+    "History.txt",
+    "License.txt",
+    "README.md",
+    "RUNNING_TESTS.md",
+    "Rakefile",
+    "VERSION",
+    "activerecord-oracle_enhanced-adapter.gemspec",
+    "lib/active_record/connection_adapters/emulation/oracle_adapter.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced.rake",
+    "lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_adapter.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_column.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_connection.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_context_index.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_cpk.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_dirty.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_procedures.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_tasks.rb",
+    "lib/active_record/connection_adapters/oracle_enhanced_version.rb",
+    "lib/activerecord-oracle_enhanced-adapter.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb",
+    "spec/spec_helper.rb"
+  ]
+  s.homepage = %q{http://github.com/rsim/oracle-enhanced}
+  s.require_paths = ["lib"]
+  s.rubygems_version = %q{1.6.2}
+  s.summary = %q{Oracle enhanced adapter for ActiveRecord}
+  s.test_files = [
+    "spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_core_ext_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_dbms_output_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb",
+    "spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb",
+    "spec/spec_helper.rb"
+  ]
+
+  if s.respond_to? :specification_version then
+    s.specification_version = 3
+
+    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+      s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
+      s.add_development_dependency(%q<rspec>, ["~> 2.4"])
+      s.add_development_dependency(%q<activerecord>, [">= 0"])
+      s.add_development_dependency(%q<activemodel>, [">= 0"])
+      s.add_development_dependency(%q<activesupport>, [">= 0"])
+      s.add_development_dependency(%q<actionpack>, [">= 0"])
+      s.add_development_dependency(%q<railties>, [">= 0"])
+      s.add_development_dependency(%q<arel>, [">= 0"])
+      s.add_development_dependency(%q<ruby-plsql>, [">= 0.4.4"])
+      s.add_development_dependency(%q<ruby-oci8>, ["~> 2.0.4"])
+    else
+      s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
+      s.add_dependency(%q<rspec>, ["~> 2.4"])
+      s.add_dependency(%q<activerecord>, [">= 0"])
+      s.add_dependency(%q<activemodel>, [">= 0"])
+      s.add_dependency(%q<activesupport>, [">= 0"])
+      s.add_dependency(%q<actionpack>, [">= 0"])
+      s.add_dependency(%q<railties>, [">= 0"])
+      s.add_dependency(%q<arel>, [">= 0"])
+      s.add_dependency(%q<ruby-plsql>, [">= 0.4.4"])
+      s.add_dependency(%q<ruby-oci8>, ["~> 2.0.4"])
+    end
+  else
+    s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
+    s.add_dependency(%q<rspec>, ["~> 2.4"])
+    s.add_dependency(%q<activerecord>, [">= 0"])
+    s.add_dependency(%q<activemodel>, [">= 0"])
+    s.add_dependency(%q<activesupport>, [">= 0"])
+    s.add_dependency(%q<actionpack>, [">= 0"])
+    s.add_dependency(%q<railties>, [">= 0"])
+    s.add_dependency(%q<arel>, [">= 0"])
+    s.add_dependency(%q<ruby-plsql>, [">= 0.4.4"])
+    s.add_dependency(%q<ruby-oci8>, ["~> 2.0.4"])
+  end
+end
+
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/emulation/oracle_adapter.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/emulation/oracle_adapter.rb
new file mode 100644 (file)
index 0000000..94254dc
--- /dev/null
@@ -0,0 +1,5 @@
+class ActiveRecord::ConnectionAdapters::OracleAdapter < ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter #:nodoc:
+  def adapter_name
+    'Oracle'
+  end
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced.rake b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced.rake
new file mode 100644 (file)
index 0000000..38802a1
--- /dev/null
@@ -0,0 +1,96 @@
+# implementation idea taken from JDBC adapter
+# added possibility to execute previously defined task (passed as argument to task block)
+def redefine_task(*args, &block)
+  task_name = Hash === args.first ? args.first.keys[0] : args.first
+  existing_task = Rake.application.lookup task_name
+  existing_actions = nil
+  if existing_task
+    class << existing_task; public :instance_variable_set, :instance_variable_get; end
+    existing_task.instance_variable_set "@prerequisites", FileList[]
+    existing_actions = existing_task.instance_variable_get "@actions"
+    existing_task.instance_variable_set "@actions", []
+  end
+  task(*args) do
+    block.call(existing_actions)
+  end
+end
+
+# Creates database user with db:create
+def create_database_with_oracle_enhanced(config)
+  if config['adapter'] == 'oracle_enhanced'
+    print "Please provide the SYSTEM password for your oracle installation\n>"
+    system_password = $stdin.gets.strip
+    ActiveRecord::Base.establish_connection(config.merge('username' => 'SYSTEM', 'password' => system_password))
+    ActiveRecord::Base.connection.execute "DROP USER #{config['username']} CASCADE" rescue nil
+    ActiveRecord::Base.connection.execute "CREATE USER #{config['username']} IDENTIFIED BY #{config['password']}"
+    ActiveRecord::Base.connection.execute "GRANT unlimited tablespace TO #{config['username']}"
+    ActiveRecord::Base.connection.execute "GRANT create session TO #{config['username']}"
+    ActiveRecord::Base.connection.execute "GRANT create table TO #{config['username']}"
+    ActiveRecord::Base.connection.execute "GRANT create sequence TO #{config['username']}"
+  else
+    create_database_without_oracle_enhanced(config)
+  end
+end
+alias :create_database_without_oracle_enhanced :create_database
+alias :create_database :create_database_with_oracle_enhanced
+
+# Drops database user with db:drop
+def drop_database_with_oracle_enhanced(config)
+  if config['adapter'] == 'oracle_enhanced'
+    print "Please provide the SYSTEM password for your oracle installation\n>"
+    system_password = $stdin.gets.strip
+    ActiveRecord::Base.establish_connection(config.merge('username' => 'SYSTEM', 'password' => system_password))
+    ActiveRecord::Base.connection.execute "DROP USER #{config['username']} CASCADE"
+  else
+    drop_database_without_oracle_enhanced(config)
+  end
+end
+alias :drop_database_without_oracle_enhanced :drop_database
+alias :drop_database :drop_database_with_oracle_enhanced
+
+namespace :db do
+
+  namespace :structure do
+    redefine_task :dump => :environment do |existing_actions|
+      abcs = ActiveRecord::Base.configurations
+      rails_env = defined?(Rails.env) ? Rails.env : RAILS_ENV
+      if abcs[rails_env]['adapter'] == 'oracle_enhanced'
+        ActiveRecord::Base.establish_connection(abcs[rails_env])
+        File.open("db/#{rails_env}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
+        if ActiveRecord::Base.connection.supports_migrations?
+          File.open("db/#{rails_env}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
+        end
+        if abcs[rails_env]['structure_dump'] == "db_stored_code"
+           File.open("db/#{rails_env}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.structure_dump_db_stored_code }
+        end
+      else
+        Array(existing_actions).each{|action| action.call}
+      end
+    end
+  end
+
+  namespace :test do
+    redefine_task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do |existing_actions|
+      abcs = ActiveRecord::Base.configurations
+      rails_env = defined?(Rails.env) ? Rails.env : RAILS_ENV
+      if abcs[rails_env]['adapter'] == 'oracle_enhanced' && abcs['test']['adapter'] == 'oracle_enhanced'
+        ActiveRecord::Base.establish_connection(:test)
+        ActiveRecord::Base.connection.execute_structure_dump(File.read("db/#{rails_env}_structure.sql"))
+      else
+        Array(existing_actions).each{|action| action.call}
+      end
+    end
+
+    redefine_task :purge => :environment do |existing_actions|
+      abcs = ActiveRecord::Base.configurations
+      if abcs['test']['adapter'] == 'oracle_enhanced'
+        ActiveRecord::Base.establish_connection(:test)
+        ActiveRecord::Base.connection.execute_structure_dump(ActiveRecord::Base.connection.full_drop)
+        ActiveRecord::Base.connection.execute("PURGE RECYCLEBIN") rescue nil
+      else
+        Array(existing_actions).each{|action| action.call}
+      end
+    end
+
+  end
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_activerecord_patches.rb
new file mode 100644 (file)
index 0000000..ddce35c
--- /dev/null
@@ -0,0 +1,41 @@
+# ActiveRecord 2.3 patches
+if ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 3
+  require "active_record/associations"
+
+  ActiveRecord::Associations::ClassMethods.module_eval do
+    private
+    def tables_in_string(string)
+      return [] if string.blank?
+      if self.connection.adapter_name == "OracleEnhanced"
+        # always convert table names to downcase as in Oracle quoted table names are in uppercase
+        # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries
+        string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten.map(&:downcase).uniq - ['raw_sql_']
+      else
+        string.scan(/([\.a-zA-Z_]+).?\./).flatten
+      end
+    end
+  end
+
+  ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.class_eval do
+    protected
+    def aliased_table_name_for(name, suffix = nil)
+      # always downcase quoted table name as Oracle quoted table names are in uppercase
+      if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{active_record.connection.quote_table_name(name).downcase}\son}
+        @join_dependency.table_aliases[name] += 1
+      end
+
+      unless @join_dependency.table_aliases[name].zero?
+        # if the table name has been used, then use an alias
+        name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}"
+        table_index = @join_dependency.table_aliases[name]
+        @join_dependency.table_aliases[name] += 1
+        name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index+1}" if table_index > 0
+      else
+        @join_dependency.table_aliases[name] += 1
+      end
+
+      name
+    end
+  end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
new file mode 100644 (file)
index 0000000..22c94d6
--- /dev/null
@@ -0,0 +1,1309 @@
+# -*- coding: utf-8 -*-
+# oracle_enhanced_adapter.rb -- ActiveRecord adapter for Oracle 8i, 9i, 10g, 11g
+#
+# Authors or original oracle_adapter: Graham Jenkins, Michael Schoen
+#
+# Current maintainer: Raimonds Simanovskis (http://blog.rayapps.com)
+#
+#########################################################################
+#
+# See History.txt for changes added to original oracle_adapter.rb
+#
+#########################################################################
+#
+# From original oracle_adapter.rb:
+#
+# Implementation notes:
+# 1. Redefines (safely) a method in ActiveRecord to make it possible to
+#    implement an autonumbering solution for Oracle.
+# 2. The OCI8 driver is patched to properly handle values for LONG and
+#    TIMESTAMP columns. The driver-author has indicated that a future
+#    release of the driver will obviate this patch.
+# 3. LOB support is implemented through an after_save callback.
+# 4. Oracle does not offer native LIMIT and OFFSET options; this
+#    functionality is mimiced through the use of nested selects.
+#    See http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:127412348064
+#
+# Do what you want with this code, at your own peril, but if any
+# significant portion of my code remains then please acknowledge my
+# contribution.
+# portions Copyright 2005 Graham Jenkins
+
+# ActiveRecord 2.2 does not load version file automatically
+require 'active_record/version' unless defined?(ActiveRecord::VERSION)
+
+require 'active_record/connection_adapters/abstract_adapter'
+require 'active_record/connection_adapters/oracle_enhanced_connection'
+
+require 'active_record/connection_adapters/oracle_enhanced_base_ext'
+require 'active_record/connection_adapters/oracle_enhanced_column'
+
+require 'digest/sha1'
+
+module ActiveRecord
+  module ConnectionAdapters #:nodoc:
+
+    # Oracle enhanced adapter will work with both
+    # Ruby 1.8/1.9 ruby-oci8 gem (which provides interface to Oracle OCI client)
+    # or with JRuby and Oracle JDBC driver.
+    # 
+    # It should work with Oracle 9i, 10g and 11g databases.
+    # Limited set of functionality should work on Oracle 8i as well but several features
+    # rely on newer functionality in Oracle database.
+    #
+    # Usage notes:
+    # * Key generation assumes a "${table_name}_seq" sequence is available
+    #   for all tables; the sequence name can be changed using
+    #   ActiveRecord::Base.set_sequence_name. When using Migrations, these
+    #   sequences are created automatically.
+    #   Use set_sequence_name :autogenerated with legacy tables that have
+    #   triggers that populate primary keys automatically.
+    # * Oracle uses DATE or TIMESTAMP datatypes for both dates and times.
+    #   Consequently some hacks are employed to map data back to Date or Time
+    #   in Ruby. Timezones and sub-second precision on timestamps are
+    #   not supported.
+    # * Default values that are functions (such as "SYSDATE") are not
+    #   supported. This is a restriction of the way ActiveRecord supports
+    #   default values.
+    #
+    # Required parameters:
+    #
+    # * <tt>:username</tt>
+    # * <tt>:password</tt>
+    # * <tt>:database</tt> - either TNS alias or connection string for OCI client or database name in JDBC connection string
+    # 
+    # Optional parameters:
+    # 
+    # * <tt>:host</tt> - host name for JDBC connection, defaults to "localhost"
+    # * <tt>:port</tt> - port number for JDBC connection, defaults to 1521
+    # * <tt>:privilege</tt> - set "SYSDBA" if you want to connect with this privilege
+    # * <tt>:allow_concurrency</tt> - set to "true" if non-blocking mode should be enabled (just for OCI client)
+    # * <tt>:prefetch_rows</tt> - how many rows should be fetched at one time to increase performance, defaults to 100
+    # * <tt>:cursor_sharing</tt> - cursor sharing mode to minimize amount of unique statements, defaults to "force"
+    # * <tt>:time_zone</tt> - database session time zone
+    #   (it is recommended to set it using ENV['TZ'] which will be then also used for database session time zone)
+    # 
+    # Optionals NLS parameters:
+    # 
+    # * <tt>:nls_calendar</tt>
+    # * <tt>:nls_characterset</tt>
+    # * <tt>:nls_comp</tt>
+    # * <tt>:nls_currency</tt>
+    # * <tt>:nls_date_format</tt> - format for :date columns, defaults to <tt>YYYY-MM-DD HH24:MI:SS</tt>
+    # * <tt>:nls_date_language</tt>
+    # * <tt>:nls_dual_currency</tt>
+    # * <tt>:nls_iso_currency</tt>
+    # * <tt>:nls_language</tt>
+    # * <tt>:nls_length_semantics</tt> - semantics of size of VARCHAR2 and CHAR columns, defaults to <tt>CHAR</tt>
+    #   (meaning that size specifies number of characters and not bytes)
+    # * <tt>:nls_nchar_characterset</tt>
+    # * <tt>:nls_nchar_conv_excp</tt>
+    # * <tt>:nls_numeric_characters</tt>
+    # * <tt>:nls_sort</tt>
+    # * <tt>:nls_territory</tt>
+    # * <tt>:nls_timestamp_format</tt> - format for :timestamp columns, defaults to <tt>YYYY-MM-DD HH24:MI:SS:FF6</tt>
+    # * <tt>:nls_timestamp_tz_format</tt>
+    # * <tt>:nls_time_format</tt>
+    # * <tt>:nls_time_tz_format</tt>
+    # 
+    class OracleEnhancedAdapter < AbstractAdapter
+
+      ##
+      # :singleton-method:
+      # By default, the OracleEnhancedAdapter will consider all columns of type <tt>NUMBER(1)</tt>
+      # as boolean. If you wish to disable this emulation you can add the following line
+      # to your initializer file:
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans = false
+      cattr_accessor :emulate_booleans
+      self.emulate_booleans = true
+
+      ##
+      # :singleton-method:
+      # By default, the OracleEnhancedAdapter will typecast all columns of type <tt>DATE</tt>
+      # to Time or DateTime (if value is out of Time value range) value.
+      # If you wish that DATE values with hour, minutes and seconds equal to 0 are typecasted
+      # to Date then you can add the following line to your initializer file:
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = true
+      # 
+      # As this option can have side effects when unnecessary typecasting is done it is recommended
+      # that Date columns are explicily defined with +set_date_columns+ method.
+      cattr_accessor :emulate_dates
+      self.emulate_dates = false
+      
+       ##
+        # :singleton-method:
+        # OracleEnhancedAdapter will use the default tablespace, but if you want specific types of
+        # objects to go into specific tablespaces, specify them like this in an initializer:
+        #
+        #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces =
+        #  {:clob => 'TS_LOB', :blob => 'TS_LOB', :index => 'TS_INDEX', :table => 'TS_DATA'}
+        # 
+        # Using the :tablespace option where available (e.g create_table) will take precedence
+        # over these settings.
+      cattr_accessor :default_tablespaces
+      self.default_tablespaces={}
+
+      ##
+      # :singleton-method:
+      # By default, the OracleEnhancedAdapter will typecast all columns of type <tt>DATE</tt>
+      # to Time or DateTime (if value is out of Time value range) value.
+      # If you wish that DATE columns with "date" in their name (e.g. "creation_date") are typecasted
+      # to Date then you can add the following line to your initializer file:
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = true
+      # 
+      # As this option can have side effects when unnecessary typecasting is done it is recommended
+      # that Date columns are explicily defined with +set_date_columns+ method.
+      cattr_accessor :emulate_dates_by_column_name
+      self.emulate_dates_by_column_name = false
+
+      # Check column name to identify if it is Date (and not Time) column.
+      # Is used if +emulate_dates_by_column_name+ option is set to +true+.
+      # Override this method definition in initializer file if different Date column recognition is needed.
+      def self.is_date_column?(name, table_name = nil)
+        name =~ /(^|_)date(_|$)/i
+      end
+
+      # instance method uses at first check if column type defined at class level
+      def is_date_column?(name, table_name = nil) #:nodoc:
+        case get_type_for_column(table_name, name)
+        when nil
+          self.class.is_date_column?(name, table_name)
+        when :date
+          true
+        else
+          false
+        end
+      end
+
+      ##
+      # :singleton-method:
+      # By default, the OracleEnhancedAdapter will typecast all columns of type <tt>NUMBER</tt>
+      # (without precision or scale) to Float or BigDecimal value.
+      # If you wish that NUMBER columns with name "id" or that end with "_id" are typecasted
+      # to Integer then you can add the following line to your initializer file:
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
+      cattr_accessor :emulate_integers_by_column_name
+      self.emulate_integers_by_column_name = false
+
+      # Check column name to identify if it is Integer (and not Float or BigDecimal) column.
+      # Is used if +emulate_integers_by_column_name+ option is set to +true+.
+      # Override this method definition in initializer file if different Integer column recognition is needed.
+      def self.is_integer_column?(name, table_name = nil)
+        name =~ /(^|_)id$/i
+      end
+
+      ##
+      # :singleton-method:
+      # If you wish that CHAR(1), VARCHAR2(1) columns or VARCHAR2 columns with FLAG or YN at the end of their name
+      # are typecasted to booleans then you can add the following line to your initializer file:
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_booleans_from_strings = true
+      cattr_accessor :emulate_booleans_from_strings
+      self.emulate_booleans_from_strings = false
+
+      # Check column name to identify if it is boolean (and not String) column.
+      # Is used if +emulate_booleans_from_strings+ option is set to +true+.
+      # Override this method definition in initializer file if different boolean column recognition is needed.
+      def self.is_boolean_column?(name, field_type, table_name = nil)
+        return true if ["CHAR(1)","VARCHAR2(1)"].include?(field_type)
+        field_type =~ /^VARCHAR2/ && (name =~ /_flag$/i || name =~ /_yn$/i)
+      end
+      
+      # How boolean value should be quoted to String.
+      # Used if +emulate_booleans_from_strings+ option is set to +true+.
+      def self.boolean_to_string(bool)
+        bool ? "Y" : "N"
+      end
+
+      ##
+      # :singleton-method:
+      # Specify non-default date format that should be used when assigning string values to :date columns, e.g.:
+      # 
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_date_format = “%d.%m.%Y”
+      cattr_accessor :string_to_date_format
+      self.string_to_date_format = nil
+      
+      ##
+      # :singleton-method:
+      # Specify non-default time format that should be used when assigning string values to :datetime columns, e.g.:
+      # 
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.string_to_time_format = “%d.%m.%Y %H:%M:%S”
+      cattr_accessor :string_to_time_format
+      self.string_to_time_format = nil
+
+      def initialize(connection, logger = nil) #:nodoc:
+        super
+        @quoted_column_names, @quoted_table_names = {}, {}
+        @statements = {}
+        @enable_dbms_output = false
+      end
+
+      def self.visitor_for(pool) # :nodoc:
+        Arel::Visitors::Oracle.new(pool)
+      end
+
+      ADAPTER_NAME = 'OracleEnhanced'.freeze
+      
+      def adapter_name #:nodoc:
+        ADAPTER_NAME
+      end
+
+      def supports_migrations? #:nodoc:
+        true
+      end
+
+      def supports_primary_key? #:nodoc:
+        true
+      end
+
+      def supports_savepoints? #:nodoc:
+        true
+      end
+
+      #:stopdoc:
+      DEFAULT_NLS_PARAMETERS = {
+        :nls_calendar            => nil,
+        :nls_characterset        => nil,
+        :nls_comp                => nil,
+        :nls_currency            => nil,
+        :nls_date_format         => 'YYYY-MM-DD HH24:MI:SS',
+        :nls_date_language       => nil,
+        :nls_dual_currency       => nil,
+        :nls_iso_currency        => nil,
+        :nls_language            => nil,
+        :nls_length_semantics    => 'CHAR',
+        :nls_nchar_characterset  => nil,
+        :nls_nchar_conv_excp     => nil,
+        :nls_numeric_characters  => nil,
+        :nls_sort                => nil,
+        :nls_territory           => nil,
+        :nls_timestamp_format    => 'YYYY-MM-DD HH24:MI:SS:FF6',
+        :nls_timestamp_tz_format => nil,
+        :nls_time_format         => nil,
+        :nls_time_tz_format      => nil
+      }
+
+      #:stopdoc:
+      NATIVE_DATABASE_TYPES = {
+        :primary_key => "NUMBER(38) NOT NULL PRIMARY KEY",
+        :string      => { :name => "VARCHAR2", :limit => 255 },
+        :text        => { :name => "CLOB" },
+        :integer     => { :name => "NUMBER", :limit => 38 },
+        :float       => { :name => "NUMBER" },
+        :decimal     => { :name => "DECIMAL" },
+        :datetime    => { :name => "DATE" },
+        # changed to native TIMESTAMP type
+        # :timestamp   => { :name => "DATE" },
+        :timestamp   => { :name => "TIMESTAMP" },
+        :time        => { :name => "DATE" },
+        :date        => { :name => "DATE" },
+        :binary      => { :name => "BLOB" },
+        :boolean     => { :name => "NUMBER", :limit => 1 },
+        :raw         => { :name => "RAW", :limit => 2000 },
+
+        #sonar - big integers are exactly integers
+        :big_integer => { :name => "NUMBER", :limit => 38 }
+        #/sonar
+      }
+      # if emulate_booleans_from_strings then store booleans in VARCHAR2
+      NATIVE_DATABASE_TYPES_BOOLEAN_STRINGS = NATIVE_DATABASE_TYPES.dup.merge(
+        :boolean     => { :name => "VARCHAR2", :limit => 1 }
+      )
+      #:startdoc:
+
+      def native_database_types #:nodoc:
+        emulate_booleans_from_strings ? NATIVE_DATABASE_TYPES_BOOLEAN_STRINGS : NATIVE_DATABASE_TYPES
+      end
+
+      # maximum length of Oracle identifiers
+      IDENTIFIER_MAX_LENGTH = 30
+
+      def table_alias_length #:nodoc:
+        IDENTIFIER_MAX_LENGTH
+      end
+
+      # the maximum length of a table name
+      def table_name_length
+        IDENTIFIER_MAX_LENGTH
+      end
+
+      # the maximum length of a column name
+      def column_name_length
+        IDENTIFIER_MAX_LENGTH
+      end
+
+      # the maximum length of an index name
+      def index_name_length
+        IDENTIFIER_MAX_LENGTH
+      end
+
+      # To avoid ORA-01795: maximum number of expressions in a list is 1000
+      # tell ActiveRecord to limit us to 1000 ids at a time
+      def in_clause_length
+        1000
+      end
+      alias ids_in_list_limit in_clause_length
+
+      # QUOTING ==================================================
+      #
+      # see: abstract/quoting.rb
+
+      def quote_column_name(name) #:nodoc:
+        name = name.to_s
+        @quoted_column_names[name] ||= begin
+          # if only valid lowercase column characters in name
+          if name =~ /\A[a-z][a-z_0-9\$#]*\Z/
+            "\"#{name.upcase}\""
+          else
+            # remove double quotes which cannot be used inside quoted identifier
+            "\"#{name.gsub('"', '')}\""
+          end
+        end
+      end
+
+      # This method is used in add_index to identify either column name (which is quoted)
+      # or function based index (in which case function expression is not quoted)
+      def quote_column_name_or_expression(name) #:nodoc:
+        name = name.to_s
+        case name
+        # if only valid lowercase column characters in name
+        when /^[a-z][a-z_0-9\$#]*$/
+          "\"#{name.upcase}\""
+        when /^[a-z][a-z_0-9\$#\-]*$/i
+          "\"#{name}\""
+        # if other characters present then assume that it is expression
+        # which should not be quoted
+        else
+          name
+        end
+      end
+
+      # Names must be from 1 to 30 bytes long with these exceptions:
+      # * Names of databases are limited to 8 bytes.
+      # * Names of database links can be as long as 128 bytes.
+      #  
+      # Nonquoted identifiers cannot be Oracle Database reserved words
+      #  
+      # Nonquoted identifiers must begin with an alphabetic character from
+      # your database character set
+      #  
+      # Nonquoted identifiers can contain only alphanumeric characters from
+      # your database character set and the underscore (_), dollar sign ($),
+      # and pound sign (#). Database links can also contain periods (.) and
+      # "at" signs (@). Oracle strongly discourages you from using $ and # in
+      # nonquoted identifiers.
+      NONQUOTED_OBJECT_NAME   = /[A-Za-z][A-z0-9$#]{0,29}/
+      NONQUOTED_DATABASE_LINK = /[A-Za-z][A-z0-9$#\.@]{0,127}/
+      VALID_TABLE_NAME = /\A(?:#{NONQUOTED_OBJECT_NAME}\.)?#{NONQUOTED_OBJECT_NAME}(?:@#{NONQUOTED_DATABASE_LINK})?\Z/
+
+      # unescaped table name should start with letter and
+      # contain letters, digits, _, $ or #
+      # can be prefixed with schema name
+      # CamelCase table names should be quoted
+      def self.valid_table_name?(name) #:nodoc:
+        name = name.to_s 
+        name =~ VALID_TABLE_NAME && !(name =~ /[A-Z]/ && name =~ /[a-z]/) ? true : false
+      end
+
+      def quote_table_name(name) #:nodoc:
+        name = name.to_s
+        @quoted_table_names[name] ||= name.split('.').map{|n| n.split('@').map{|m| quote_column_name(m)}.join('@')}.join('.')
+      end
+      
+      def quote_string(s) #:nodoc:
+        s.gsub(/'/, "''")
+      end
+
+      def quote(value, column = nil) #:nodoc:
+        if value && column
+          case column.type
+          when :text, :binary
+            %Q{empty_#{ column.sql_type.downcase rescue 'blob' }()}
+          # NLS_DATE_FORMAT independent TIMESTAMP support
+          when :timestamp
+            quote_timestamp_with_to_timestamp(value)
+          # NLS_DATE_FORMAT independent DATE support
+          when :date, :time, :datetime
+            quote_date_with_to_date(value)
+          when :raw
+            quote_raw(value)
+          when :string
+            # NCHAR and NVARCHAR2 literals should be quoted with N'...'.
+            # Read directly instance variable as otherwise migrations with table column default values are failing
+            # as migrations pass ColumnDefinition object to this method.
+            # Check if instance variable is defined to avoid warnings about accessing undefined instance variable.
+            column.instance_variable_defined?('@nchar') && column.instance_variable_get('@nchar') ? 'N' << super : super
+          else
+            super
+          end
+        elsif value.acts_like?(:date)
+          quote_date_with_to_date(value)
+        elsif value.acts_like?(:time)
+          value.to_i == value.to_f ? quote_date_with_to_date(value) : quote_timestamp_with_to_timestamp(value)
+        else
+          super
+        end
+      end
+
+      def quoted_true #:nodoc:
+        return "'#{self.class.boolean_to_string(true)}'" if emulate_booleans_from_strings
+        "1"
+      end
+
+      def quoted_false #:nodoc:
+        return "'#{self.class.boolean_to_string(false)}'" if emulate_booleans_from_strings
+        "0"
+      end
+
+      def quote_date_with_to_date(value) #:nodoc:
+        # should support that composite_primary_keys gem will pass date as string
+        value = quoted_date(value) if value.acts_like?(:date) || value.acts_like?(:time)
+        "TO_DATE('#{value}','YYYY-MM-DD HH24:MI:SS')"
+      end
+
+      # Encode a string or byte array as string of hex codes
+      def self.encode_raw(value)
+        # When given a string, convert to a byte array.
+        value = value.unpack('C*') if value.is_a?(String)
+        value.map { |x| "%02X" % x }.join
+      end
+
+      # quote encoded raw value
+      def quote_raw(value) #:nodoc:
+        "'#{self.class.encode_raw(value)}'"
+      end
+
+      def quote_timestamp_with_to_timestamp(value) #:nodoc:
+        # add up to 9 digits of fractional seconds to inserted time
+        value = "#{quoted_date(value)}:#{("%.6f"%value.to_f).split('.')[1]}" if value.acts_like?(:time)
+        "TO_TIMESTAMP('#{value}','YYYY-MM-DD HH24:MI:SS:FF6')"
+      end
+
+      # Cast a +value+ to a type that the database understands.
+      def type_cast(value, column)
+        case value
+        when true, false
+          if emulate_booleans_from_strings || column && column.type == :string
+            self.class.boolean_to_string(value)
+          else
+            value ? 1 : 0
+          end
+        when Date, Time
+          if value.acts_like?(:time)
+            zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
+            value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
+          else
+            value
+          end
+        else
+          super
+        end
+      end
+
+      # CONNECTION MANAGEMENT ====================================
+      #
+
+      # If SQL statement fails due to lost connection then reconnect
+      # and retry SQL statement if autocommit mode is enabled.
+      # By default this functionality is disabled.
+      attr_reader :auto_retry #:nodoc:
+      @auto_retry = false
+
+      def auto_retry=(value) #:nodoc:
+        @auto_retry = value
+        @connection.auto_retry = value if @connection
+      end
+
+      # return raw OCI8 or JDBC connection
+      def raw_connection
+        @connection.raw_connection
+      end
+
+      # Returns true if the connection is active.
+      def active? #:nodoc:
+        # Pings the connection to check if it's still good. Note that an
+        # #active? method is also available, but that simply returns the
+        # last known state, which isn't good enough if the connection has
+        # gone stale since the last use.
+        @connection.ping
+      rescue OracleEnhancedConnectionException
+        false
+      end
+
+      # Reconnects to the database.
+      def reconnect! #:nodoc:
+        clear_cache!
+        @connection.reset!
+      rescue OracleEnhancedConnectionException => e
+        @logger.warn "#{adapter_name} automatic reconnection failed: #{e.message}" if @logger
+      end
+
+      def reset!
+        clear_cache!
+        super
+      end
+
+      # Disconnects from the database.
+      def disconnect! #:nodoc:
+        clear_cache!
+        @connection.logoff rescue nil
+      end
+
+      # DATABASE STATEMENTS ======================================
+      #
+      # see: abstract/database_statements.rb
+
+      # Executes a SQL statement
+      def execute(sql, name = nil)
+        log(sql, name) { @connection.exec(sql) }
+      end
+
+      def substitute_at(column, index)
+        Arel.sql(":a#{index + 1}")
+      end
+
+      def clear_cache!
+        @statements.each_value do |cursor|
+          cursor.close
+        end
+        @statements.clear
+      end
+
+      def exec_query(sql, name = 'SQL', binds = [])
+        log(sql, name, binds) do
+          cursor = nil
+          cached = false
+          if binds.empty?
+            cursor = @connection.prepare(sql)
+          else
+            unless @statements.key? sql
+              @statements[sql] = @connection.prepare(sql)
+            end
+
+            cursor = @statements[sql]
+
+            binds.each_with_index do |bind, i|
+              col, val = bind
+              cursor.bind_param(i + 1, type_cast(val, col), col && col.type)
+            end
+
+            cached = true
+          end
+
+          cursor.exec
+          columns = cursor.get_col_names.map do |col_name|
+            @connection.oracle_downcase(col_name)
+          end
+          rows = []
+          fetch_options = {:get_lob_value => (name != 'Writable Large Object')}
+          while row = cursor.fetch(fetch_options)
+            rows << row
+          end
+          res = ActiveRecord::Result.new(columns, rows)
+          cursor.close unless cached
+          res
+        end
+      end
+
+      def supports_statement_cache?
+        true
+      end
+
+      # Returns an array of arrays containing the field values.
+      # Order is the same as that returned by #columns.
+      def select_rows(sql, name = nil)
+        # last parameter indicates to return also column list
+        result = columns = nil
+        log(sql, name) do
+          result, columns = @connection.select(sql, name, true)
+        end
+        result.map{ |v| columns.map{|c| v[c]} }
+      end
+
+      # Executes an INSERT statement and returns the new record's ID
+      def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
+        # if primary key value is already prefetched from sequence
+        # or if there is no primary key
+        if id_value || pk.nil?
+          execute(sql, name)
+          return id_value
+        end
+
+        sql_with_returning = sql + @connection.returning_clause(quote_column_name(pk))
+        log(sql, name) do
+          @connection.exec_with_returning(sql_with_returning)
+        end
+      end
+      protected :insert_sql
+
+      # New method in ActiveRecord 3.1
+      # Will add RETURNING clause in case of trigger generated primary keys
+      def sql_for_insert(sql, pk, id_value, sequence_name, binds)
+        unless id_value || pk.nil?
+          sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO :returning_id"
+          (binds = binds.dup) << [:returning_id, nil]
+        end
+        [sql, binds]
+      end
+
+      EXEC_INSERT_RESULT_COLUMNS = %w(returning_id) #:nodoc:
+
+      # New method in ActiveRecord 3.1
+      def exec_insert(sql, name, binds)
+        log(sql, name, binds) do
+          returning_id_index = nil
+          cursor = if @statements.key?(sql)
+            @statements[sql]
+          else
+            @statements[sql] = @connection.prepare(sql)
+          end
+
+          binds.each_with_index do |bind, i|
+            col, val = bind
+            if col == :returning_id
+              returning_id_index = i + 1
+              cursor.bind_returning_param(returning_id_index, Integer)
+            else
+              cursor.bind_param(i + 1, type_cast(val, col), col && col.type)
+            end
+          end
+
+          cursor.exec_update
+
+          rows = []
+          if returning_id_index
+            returning_id = cursor.get_returning_param(returning_id_index, Integer)
+            rows << [returning_id]
+          end
+          ActiveRecord::Result.new(EXEC_INSERT_RESULT_COLUMNS, rows)
+        end
+      end
+
+      # New method in ActiveRecord 3.1
+      def exec_update(sql, name, binds)
+        log(sql, name, binds) do
+          cursor = if @statements.key?(sql)
+            @statements[sql]
+          else
+            @statements[sql] = @connection.prepare(sql)
+          end
+
+          binds.each_with_index do |bind, i|
+            col, val = bind
+            cursor.bind_param(i + 1, type_cast(val, col), col && col.type)
+          end
+
+          cursor.exec_update
+        end
+      end
+
+      alias :exec_delete :exec_update
+
+      # use in set_sequence_name to avoid fetching primary key value from sequence
+      AUTOGENERATED_SEQUENCE_NAME = 'autogenerated'.freeze
+
+      # Returns the next sequence value from a sequence generator. Not generally
+      # called directly; used by ActiveRecord to get the next primary key value
+      # when inserting a new database record (see #prefetch_primary_key?).
+      def next_sequence_value(sequence_name)
+        # if sequence_name is set to :autogenerated then it means that primary key will be populated by trigger
+        return nil if sequence_name == AUTOGENERATED_SEQUENCE_NAME
+        # call directly connection method to avoid prepared statement which causes fetching of next sequence value twice
+        @connection.select_value("SELECT #{quote_table_name(sequence_name)}.NEXTVAL FROM dual")
+      end
+
+      def begin_db_transaction #:nodoc:
+        @connection.autocommit = false
+      end
+
+      def commit_db_transaction #:nodoc:
+        @connection.commit
+      ensure
+        @connection.autocommit = true
+      end
+
+      def rollback_db_transaction #:nodoc:
+        @connection.rollback
+      ensure
+        @connection.autocommit = true
+      end
+
+      def create_savepoint #:nodoc:
+        execute("SAVEPOINT #{current_savepoint_name}")
+      end
+
+      def rollback_to_savepoint #:nodoc:
+        execute("ROLLBACK TO #{current_savepoint_name}")
+      end
+
+      def release_savepoint #:nodoc:
+        # there is no RELEASE SAVEPOINT statement in Oracle
+      end
+
+      def add_limit_offset!(sql, options) #:nodoc:
+        # added to_i for limit and offset to protect from SQL injection
+        offset = (options[:offset] || 0).to_i
+        limit = options[:limit]
+        limit = limit.is_a?(String) && limit.blank? ? nil : limit && limit.to_i
+        if limit && offset > 0
+          sql.replace "SELECT * FROM (SELECT raw_sql_.*, ROWNUM raw_rnum_ FROM (#{sql}) raw_sql_ WHERE ROWNUM <= #{offset+limit}) WHERE raw_rnum_ > #{offset}"
+        elsif limit
+          sql.replace "SELECT * FROM (#{sql}) WHERE ROWNUM <= #{limit}"
+        elsif offset > 0
+          sql.replace "SELECT * FROM (SELECT raw_sql_.*, ROWNUM raw_rnum_ FROM (#{sql}) raw_sql_) WHERE raw_rnum_ > #{offset}"
+        end
+      end
+
+      @@do_not_prefetch_primary_key = {}
+
+      # Returns true for Oracle adapter (since Oracle requires primary key
+      # values to be pre-fetched before insert). See also #next_sequence_value.
+      def prefetch_primary_key?(table_name = nil)
+        return true if table_name.nil?
+        table_name = table_name.to_s
+        do_not_prefetch = @@do_not_prefetch_primary_key[table_name]
+        if do_not_prefetch.nil?
+          owner, desc_table_name, db_link = @connection.describe(table_name)
+          @@do_not_prefetch_primary_key[table_name] = do_not_prefetch =
+            !has_primary_key?(table_name, owner, desc_table_name, db_link) ||
+            has_primary_key_trigger?(table_name, owner, desc_table_name, db_link)
+        end
+        !do_not_prefetch
+      end
+
+      # used just in tests to clear prefetch primary key flag for all tables
+      def clear_prefetch_primary_key #:nodoc:
+        @@do_not_prefetch_primary_key = {}
+      end
+
+      # Returns default sequence name for table.
+      # Will take all or first 26 characters of table name and append _seq suffix
+      def default_sequence_name(table_name, primary_key = nil)
+        # TODO: remove schema prefix if present before truncating
+        # truncate table name if necessary to fit in max length of identifier
+        "#{table_name.to_s[0,IDENTIFIER_MAX_LENGTH-4]}_seq"
+      end
+
+      # Inserts the given fixture into the table. Overridden to properly handle lobs.
+      def insert_fixture(fixture, table_name) #:nodoc:
+        super
+
+        if ActiveRecord::Base.pluralize_table_names
+          klass = table_name.singularize.camelize
+        else
+          klass = table_name.camelize
+        end
+
+        klass = klass.constantize rescue nil
+        if klass.respond_to?(:ancestors) && klass.ancestors.include?(ActiveRecord::Base)
+          write_lobs(table_name, klass, fixture)
+        end
+      end
+
+      # Writes LOB values from attributes, as indicated by the LOB columns of klass.
+      def write_lobs(table_name, klass, attributes) #:nodoc:
+        # is class with composite primary key>
+        is_with_cpk = klass.respond_to?(:composite?) && klass.composite?
+        if is_with_cpk
+          id = klass.primary_key.map {|pk| attributes[pk.to_s] }
+        else
+          id = quote(attributes[klass.primary_key])
+        end
+        klass.columns.select { |col| col.sql_type =~ /LOB$/i }.each do |col|
+          value = attributes[col.name]
+          # changed sequence of next two lines - should check if value is nil before converting to yaml
+          next if value.nil?  || (value == '')
+          value = value.to_yaml if col.text? && klass.serialized_attributes[col.name]
+          uncached do
+            sql = is_with_cpk ? "SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)} WHERE #{klass.composite_where_clause(id)} FOR UPDATE" :
+              "SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)} WHERE #{quote_column_name(klass.primary_key)} = #{id} FOR UPDATE"
+            unless lob_record = select_one(sql, 'Writable Large Object')
+              raise ActiveRecord::RecordNotFound, "statement #{sql} returned no rows"
+            end
+            lob = lob_record[col.name]
+            @connection.write_lob(lob, value.to_s, col.type == :binary)
+          end
+        end
+      end
+
+      # Current database name
+      def current_database
+        select_value("SELECT SYS_CONTEXT('userenv', 'db_name') FROM dual")
+      end
+
+      # Current database session user
+      def current_user
+        select_value("SELECT SYS_CONTEXT('userenv', 'session_user') FROM dual")
+      end
+
+      # Default tablespace name of current user
+      def default_tablespace
+        select_value("SELECT LOWER(default_tablespace) FROM user_users WHERE username = SYS_CONTEXT('userenv', 'session_user')")
+      end
+
+      def tables(name = nil) #:nodoc:
+        select_values(
+        "SELECT DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name) FROM all_tables WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N'",
+        name)
+      end
+
+      # Will return true if database object exists (to be able to use also views and synonyms for ActiveRecord models)
+      def table_exists?(table_name)
+        (owner, table_name, db_link) = @connection.describe(table_name)
+        true
+      rescue
+        false
+      end
+
+      def materialized_views #:nodoc:
+        select_values("SELECT LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'session_user')")
+      end
+
+      cattr_accessor :all_schema_indexes #:nodoc:
+
+      # This method selects all indexes at once, and caches them in a class variable.
+      # Subsequent index calls get them from the variable, without going to the DB.
+      def indexes(table_name, name = nil) #:nodoc:
+        (owner, table_name, db_link) = @connection.describe(table_name)
+        unless all_schema_indexes
+          default_tablespace_name = default_tablespace
+          result = select_all(<<-SQL.strip.gsub(/\s+/, ' '))
+            SELECT LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
+              i.index_type, i.ityp_owner, i.ityp_name, i.parameters,
+              LOWER(i.tablespace_name) AS tablespace_name,
+              LOWER(c.column_name) AS column_name, e.column_expression
+            FROM all_indexes#{db_link} i
+              JOIN all_ind_columns#{db_link} c ON c.index_name = i.index_name AND c.index_owner = i.owner
+              LEFT OUTER JOIN all_ind_expressions#{db_link} e ON e.index_name = i.index_name AND
+                e.index_owner = i.owner AND e.column_position = c.column_position
+            WHERE i.owner = '#{owner}'
+               AND i.table_owner = '#{owner}'
+               AND NOT EXISTS (SELECT uc.index_name FROM all_constraints uc
+                WHERE uc.index_name = i.index_name AND uc.owner = i.owner AND uc.constraint_type = 'P')
+            ORDER BY i.index_name, c.column_position
+          SQL
+
+          current_index = nil
+          self.all_schema_indexes = []
+
+          result.each do |row|
+            # have to keep track of indexes because above query returns dups
+            # there is probably a better query we could figure out
+            if current_index != row['index_name']
+              statement_parameters = nil
+              if row['index_type'] == 'DOMAIN' && row['ityp_owner'] == 'CTXSYS' && row['ityp_name'] == 'CONTEXT'
+                procedure_name = default_datastore_procedure(row['index_name'])
+                source = select_values(<<-SQL).join
+                  SELECT text
+                  FROM all_source#{db_link}
+                  WHERE owner = '#{owner}'
+                    AND name = '#{procedure_name.upcase}'
+                  ORDER BY line
+                SQL
+                if source =~ /-- add_context_index_parameters (.+)\n/
+                  statement_parameters = $1
+                end
+              end
+              all_schema_indexes << OracleEnhancedIndexDefinition.new(row['table_name'], row['index_name'],
+                row['uniqueness'] == "UNIQUE", row['index_type'] == 'DOMAIN' ? "#{row['ityp_owner']}.#{row['ityp_name']}" : nil,
+                row['parameters'], statement_parameters,
+                row['tablespace_name'] == default_tablespace_name ? nil : row['tablespace_name'], [])
+              current_index = row['index_name']
+            end
+            all_schema_indexes.last.columns << (row['column_expression'] || row['column_name'].downcase)
+          end
+        end
+
+        # Return the indexes just for the requested table, since AR is structured that way
+        table_name = table_name.downcase
+        all_schema_indexes.select{|i| i.table == table_name}
+      end
+
+      @@ignore_table_columns = nil #:nodoc:
+
+      # set ignored columns for table
+      def ignore_table_columns(table_name, *args) #:nodoc:
+        @@ignore_table_columns ||= {}
+        @@ignore_table_columns[table_name] ||= []
+        @@ignore_table_columns[table_name] += args.map{|a| a.to_s.downcase}
+        @@ignore_table_columns[table_name].uniq!
+      end
+      
+      def ignored_table_columns(table_name) #:nodoc:
+        @@ignore_table_columns ||= {}
+        @@ignore_table_columns[table_name]
+      end
+      
+      # used just in tests to clear ignored table columns
+      def clear_ignored_table_columns #:nodoc:
+        @@ignore_table_columns = nil
+      end
+
+      @@table_column_type = nil #:nodoc:
+
+      # set explicit type for specified table columns
+      def set_type_for_columns(table_name, column_type, *args) #:nodoc:
+        @@table_column_type ||= {}
+        @@table_column_type[table_name] ||= {}
+        args.each do |col|
+          @@table_column_type[table_name][col.to_s.downcase] = column_type
+        end
+      end
+      
+      def get_type_for_column(table_name, column_name) #:nodoc:
+        @@table_column_type && @@table_column_type[table_name] && @@table_column_type[table_name][column_name.to_s.downcase]
+      end
+
+      # used just in tests to clear column data type definitions
+      def clear_types_for_columns #:nodoc:
+        @@table_column_type = nil
+      end
+
+      # check if table has primary key trigger with _pkt suffix
+      def has_primary_key_trigger?(table_name, owner = nil, desc_table_name = nil, db_link = nil)
+        (owner, desc_table_name, db_link) = @connection.describe(table_name) unless owner
+
+        trigger_name = default_trigger_name(table_name).upcase
+        pkt_sql = <<-SQL
+          SELECT trigger_name
+          FROM all_triggers#{db_link}
+          WHERE owner = '#{owner}'
+            AND trigger_name = '#{trigger_name}'
+            AND table_owner = '#{owner}'
+            AND table_name = '#{desc_table_name}'
+            AND status = 'ENABLED'
+        SQL
+        select_value(pkt_sql, 'Primary Key Trigger') ? true : false
+      end
+
+      ##
+      # :singleton-method:
+      # Cache column description between requests.
+      # Could be used in development environment to avoid selecting table columns from data dictionary tables for each request.
+      # This can speed up request processing in development mode if development database is not on local computer.
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
+      cattr_accessor :cache_columns
+      self.cache_columns = false
+
+      def columns(table_name, name = nil) #:nodoc:
+        if @@cache_columns
+          @@columns_cache ||= {}
+          @@columns_cache[table_name] ||= columns_without_cache(table_name, name)
+        else
+          columns_without_cache(table_name, name)
+        end
+      end
+
+      def columns_without_cache(table_name, name = nil) #:nodoc:
+        table_name = table_name.to_s
+        # get ignored_columns by original table name
+        ignored_columns = ignored_table_columns(table_name)
+
+        (owner, desc_table_name, db_link) = @connection.describe(table_name)
+
+        # reset do_not_prefetch_primary_key cache for this table
+        @@do_not_prefetch_primary_key[table_name] = nil
+
+        table_cols = <<-SQL.strip.gsub(/\s+/, ' ')
+          SELECT column_name AS name, data_type AS sql_type, data_default, nullable, virtual_column, hidden_column,
+                 DECODE(data_type, 'NUMBER', data_precision,
+                                   'FLOAT', data_precision,
+                                   'VARCHAR2', DECODE(char_used, 'C', char_length, data_length),
+                                   'RAW', DECODE(char_used, 'C', char_length, data_length),
+                                   'CHAR', DECODE(char_used, 'C', char_length, data_length),
+                                    NULL) AS limit,
+                 DECODE(data_type, 'NUMBER', data_scale, NULL) AS scale
+            FROM all_tab_cols#{db_link}
+           WHERE owner      = '#{owner}'
+             AND table_name = '#{desc_table_name}'
+             AND hidden_column = 'NO'
+           ORDER BY column_id
+        SQL
+
+        # added deletion of ignored columns
+        select_all(table_cols, name).delete_if do |row|
+          ignored_columns && ignored_columns.include?(row['name'].downcase)
+        end.map do |row|
+          limit, scale = row['limit'], row['scale']
+          if limit || scale
+            row['sql_type'] += "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
+          end
+
+          # clean up odd default spacing from Oracle
+          if row['data_default']
+            row['data_default'].sub!(/^(.*?)\s*$/, '\1')
+
+            # If a default contains a newline these cleanup regexes need to 
+            # match newlines.
+            row['data_default'].sub!(/^'(.*)'$/m, '\1')
+            row['data_default'] = nil if row['data_default'] =~ /^(null|empty_[bc]lob\(\))$/i
+          end
+
+          OracleEnhancedColumn.new(oracle_downcase(row['name']),
+                           row['data_default'],
+                           row['sql_type'],
+                           row['nullable'] == 'Y',
+                           # pass table name for table specific column definitions
+                           table_name,
+                           # pass column type if specified in class definition
+                           get_type_for_column(table_name, oracle_downcase(row['name'])), row['virtual_column']=='YES')
+        end
+      end
+
+      # used just in tests to clear column cache
+      def clear_columns_cache #:nodoc:
+        @@columns_cache = nil
+        @@pk_and_sequence_for_cache = nil
+      end
+
+      # used in migrations to clear column cache for specified table
+      def clear_table_columns_cache(table_name)
+        if @@cache_columns
+          @@columns_cache ||= {}
+          @@columns_cache[table_name.to_s] = nil
+        end
+      end
+
+      ##
+      # :singleton-method:
+      # Specify default sequence start with value (by default 10000 if not explicitly set), e.g.:
+      #
+      #   ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value = 1
+      cattr_accessor :default_sequence_start_value
+      self.default_sequence_start_value = 10000
+
+      # Find a table's primary key and sequence. 
+      # *Note*: Only primary key is implemented - sequence will be nil.
+      def pk_and_sequence_for(table_name, owner=nil, desc_table_name=nil, db_link=nil) #:nodoc:
+        if @@cache_columns
+          @@pk_and_sequence_for_cache ||= {}
+          @@pk_and_sequence_for_cache[table_name] ||= pk_and_sequence_for_without_cache(table_name, owner, desc_table_name, db_link)
+        else
+          pk_and_sequence_for_without_cache(table_name, owner, desc_table_name, db_link)
+        end
+      end
+
+      def pk_and_sequence_for_without_cache(table_name, owner=nil, desc_table_name=nil, db_link=nil) #:nodoc:
+        (owner, desc_table_name, db_link) = @connection.describe(table_name) unless owner
+
+        # changed back from user_constraints to all_constraints for consistency
+        pks = select_values(<<-SQL.strip.gsub(/\s+/, ' '), 'Primary Key')
+          SELECT cc.column_name
+            FROM all_constraints#{db_link} c, all_cons_columns#{db_link} cc
+           WHERE c.owner = '#{owner}'
+             AND c.table_name = '#{desc_table_name}'
+             AND c.constraint_type = 'P'
+             AND cc.owner = c.owner
+             AND cc.constraint_name = c.constraint_name
+        SQL
+
+        # only support single column keys
+        pks.size == 1 ? [oracle_downcase(pks.first), nil] : nil
+      end
+
+      # Returns just a table's primary key
+      def primary_key(table_name)
+        pk_and_sequence = pk_and_sequence_for(table_name)
+        pk_and_sequence && pk_and_sequence.first
+      end
+
+      def has_primary_key?(table_name, owner=nil, desc_table_name=nil, db_link=nil) #:nodoc:
+        !pk_and_sequence_for(table_name, owner, desc_table_name, db_link).nil?
+      end
+
+      # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
+      #
+      # Oracle requires the ORDER BY columns to be in the SELECT list for DISTINCT
+      # queries. However, with those columns included in the SELECT DISTINCT list, you
+      # won't actually get a distinct list of the column you want (presuming the column
+      # has duplicates with multiple values for the ordered-by columns. So we use the 
+      # FIRST_VALUE function to get a single (first) value for each column, effectively
+      # making every row the same.
+      #
+      #   distinct("posts.id", "posts.created_at desc")
+      def distinct(columns, order_by) #:nodoc:
+        return "DISTINCT #{columns}" if order_by.blank?
+
+        # construct a valid DISTINCT clause, ie. one that includes the ORDER BY columns, using
+        # FIRST_VALUE such that the inclusion of these columns doesn't invalidate the DISTINCT
+        order_columns = if order_by.is_a?(String)
+          order_by.split(',').map { |s| s.strip }.reject(&:blank?)
+        else # in latest ActiveRecord versions order_by is already Array
+          order_by
+        end
+        order_columns = order_columns.zip((0...order_columns.size).to_a).map do |c, i|
+          # remove any ASC/DESC modifiers
+          value = c =~ /^(.+)\s+(ASC|DESC)\s*$/i ? $1 : c
+          "FIRST_VALUE(#{value}) OVER (PARTITION BY #{columns} ORDER BY #{c}) AS alias_#{i}__"
+        end
+        sql = "DISTINCT #{columns}, "
+        sql << order_columns * ", "
+      end
+
+      def temporary_table?(table_name) #:nodoc:
+        select_value("SELECT temporary FROM user_tables WHERE table_name = '#{table_name.upcase}'") == 'Y'
+      end
+
+      # ORDER BY clause for the passed order option.
+      #
+      # Uses column aliases as defined by #distinct.
+      #
+      # In Rails 3.x this method is moved to Arel
+      def add_order_by_for_association_limiting!(sql, options) #:nodoc:
+        return sql if options[:order].blank?
+
+        order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
+        order.map! {|s| $1 if s =~ / (.*)/}
+        order = order.zip((0...order.size).to_a).map { |s,i| "alias_#{i}__ #{s}" }.join(', ')
+
+        sql << " ORDER BY #{order}"
+      end
+
+      protected
+
+      def translate_exception(exception, message) #:nodoc:
+        case @connection.error_code(exception)
+        when 1
+          RecordNotUnique.new(message, exception)
+        when 2291
+          InvalidForeignKey.new(message, exception)
+        else
+          super
+        end
+      end
+
+      private
+
+      def select(sql, name = nil, binds = [])
+        if ActiveRecord.const_defined?(:Result)
+          exec_query(sql, name, binds).to_a
+        else
+          log(sql, name) do
+            @connection.select(sql, name, false)
+          end
+        end
+      end
+
+      def oracle_downcase(column_name)
+        @connection.oracle_downcase(column_name)
+      end
+
+      def compress_lines(string, join_with = "\n")
+        string.split($/).map { |line| line.strip }.join(join_with)
+      end
+
+      public
+      # DBMS_OUTPUT =============================================
+      #
+      # PL/SQL in Oracle uses dbms_output for logging print statements
+      # These methods stick that output into the Rails log so Ruby and PL/SQL
+      # code can can be debugged together in a single application 
+
+      # Maximum DBMS_OUTPUT buffer size
+      DBMS_OUTPUT_BUFFER_SIZE = 10000  # can be 1-1000000
+
+      # Turn DBMS_Output logging on
+      def enable_dbms_output
+        set_dbms_output_plsql_connection
+        @enable_dbms_output = true
+        plsql(:dbms_output).sys.dbms_output.enable(DBMS_OUTPUT_BUFFER_SIZE)
+      end
+      # Turn DBMS_Output logging off
+      def disable_dbms_output
+        set_dbms_output_plsql_connection
+        @enable_dbms_output = false
+        plsql(:dbms_output).sys.dbms_output.disable
+      end
+      # Is DBMS_Output logging enabled?
+      def dbms_output_enabled?
+        @enable_dbms_output
+      end
+
+      protected
+      def log(sql, name, binds = nil) #:nodoc:
+        if binds
+          super sql, name, binds
+        else
+          super sql, name
+        end
+      ensure
+        log_dbms_output if dbms_output_enabled?
+      end
+      
+      private
+
+      def set_dbms_output_plsql_connection
+        raise OracleEnhancedConnectionException, "ruby-plsql gem is required for logging DBMS output" unless self.respond_to?(:plsql)
+        # do not reset plsql connection if it is the same (as resetting will clear PL/SQL metadata cache)
+        unless plsql(:dbms_output).connection && plsql(:dbms_output).connection.raw_connection == raw_connection
+          plsql(:dbms_output).connection = raw_connection
+        end
+      end
+
+      def log_dbms_output
+        while true do
+          result = plsql(:dbms_output).sys.dbms_output.get_line(:line => '', :status => 0)
+          break unless result[:status] == 0
+          @logger.debug "DBMS_OUTPUT: #{result[:line]}" if @logger
+        end
+      end
+
+    end
+  end
+end
+
+# Added LOB writing callback for sessions stored in database
+# Otherwise it is not working as Session class is defined before OracleAdapter is loaded in Rails 2.0
+if defined?(CGI::Session::ActiveRecordStore::Session)
+  if !CGI::Session::ActiveRecordStore::Session.respond_to?(:after_save_callback_chain) ||
+      CGI::Session::ActiveRecordStore::Session.after_save_callback_chain.detect{|cb| cb.method == :enhanced_write_lobs}.nil?
+    #:stopdoc:
+    class CGI::Session::ActiveRecordStore::Session
+      after_save :enhanced_write_lobs
+    end
+    #:startdoc:
+  end
+end
+
+# Implementation of standard schema definition statements and extensions for schema definition
+require 'active_record/connection_adapters/oracle_enhanced_schema_statements'
+require 'active_record/connection_adapters/oracle_enhanced_schema_statements_ext'
+
+# Extensions for schema definition
+require 'active_record/connection_adapters/oracle_enhanced_schema_definitions'
+
+# Extensions for context index definition
+require 'active_record/connection_adapters/oracle_enhanced_context_index'
+
+# Load custom create, update, delete methods functionality
+require 'active_record/connection_adapters/oracle_enhanced_procedures'
+
+# Load additional methods for composite_primary_keys support
+require 'active_record/connection_adapters/oracle_enhanced_cpk'
+
+# Load patch for dirty tracking methods
+require 'active_record/connection_adapters/oracle_enhanced_dirty'
+
+# Load rake tasks definitions
+begin
+  require 'active_record/connection_adapters/oracle_enhanced_tasks'
+rescue LoadError
+end if defined?(Rails) || defined?(RAILS_ROOT)
+
+# Patches and enhancements for schema dumper
+require 'active_record/connection_adapters/oracle_enhanced_schema_dumper'
+
+# Implementation of structure dump
+require 'active_record/connection_adapters/oracle_enhanced_structure_dump'
+
+# Add BigDecimal#to_d, Fixnum#to_d and Bignum#to_d methods if not already present
+require 'active_record/connection_adapters/oracle_enhanced_core_ext'
+
+require 'active_record/connection_adapters/oracle_enhanced_activerecord_patches'
+
+require 'active_record/connection_adapters/oracle_enhanced_version'
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb
new file mode 100644 (file)
index 0000000..b9a2f53
--- /dev/null
@@ -0,0 +1,100 @@
+module ActiveRecord
+  class Base
+    # Establishes a connection to the database that's used by all Active Record objects.
+    def self.oracle_enhanced_connection(config) #:nodoc:
+      if config[:emulate_oracle_adapter] == true
+        # allows the enhanced adapter to look like the OracleAdapter. Useful to pick up
+        # conditionals in the rails activerecord test suite
+        require 'active_record/connection_adapters/emulation/oracle_adapter'
+        ConnectionAdapters::OracleAdapter.new(
+          ConnectionAdapters::OracleEnhancedConnection.create(config), logger)
+      else
+        ConnectionAdapters::OracleEnhancedAdapter.new(
+          ConnectionAdapters::OracleEnhancedConnection.create(config), logger)
+      end
+    end
+
+    # Specify table columns which should be ignored by ActiveRecord, e.g.:
+    # 
+    #   ignore_table_columns :attribute1, :attribute2
+    def self.ignore_table_columns(*args)
+      connection.ignore_table_columns(table_name,*args)
+    end
+
+    # Specify which table columns should be typecasted to Date (without time), e.g.:
+    # 
+    #   set_date_columns :created_on, :updated_on
+    def self.set_date_columns(*args)
+      connection.set_type_for_columns(table_name,:date,*args)
+    end
+
+    # Specify which table columns should be typecasted to Time (or DateTime), e.g.:
+    # 
+    #   set_datetime_columns :created_date, :updated_date
+    def self.set_datetime_columns(*args)
+      connection.set_type_for_columns(table_name,:datetime,*args)
+    end
+
+    # Specify which table columns should be typecasted to boolean values +true+ or +false+, e.g.:
+    # 
+    #   set_boolean_columns :is_valid, :is_completed
+    def self.set_boolean_columns(*args)
+      connection.set_type_for_columns(table_name,:boolean,*args)
+    end
+
+    # Specify which table columns should be typecasted to integer values.
+    # Might be useful to force NUMBER(1) column to be integer and not boolean, or force NUMBER column without
+    # scale to be retrieved as integer and not decimal. Example:
+    # 
+    #   set_integer_columns :version_number, :object_identifier
+    def self.set_integer_columns(*args)
+      connection.set_type_for_columns(table_name,:integer,*args)
+    end
+
+    # Specify which table columns should be typecasted to string values.
+    # Might be useful to specify that columns should be string even if its name matches boolean column criteria.
+    # 
+    #   set_string_columns :active_flag
+    def self.set_string_columns(*args)
+      connection.set_type_for_columns(table_name,:string,*args)
+    end
+
+    # After setting large objects to empty, select the OCI8::LOB
+    # and write back the data.
+    if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR >= 1
+      after_update :enhanced_write_lobs
+    else
+      after_save :enhanced_write_lobs
+    end
+    def enhanced_write_lobs #:nodoc:
+      if connection.is_a?(ConnectionAdapters::OracleEnhancedAdapter) &&
+          !(self.class.custom_create_method || self.class.custom_update_method)
+        connection.write_lobs(self.class.table_name, self.class, attributes)
+      end
+    end
+    private :enhanced_write_lobs
+
+    # Get table comment from schema definition.
+    def self.table_comment
+      connection.table_comment(self.table_name)
+    end
+    
+    if ActiveRecord::VERSION::MAJOR < 3
+      def attributes_with_quotes_with_virtual_columns(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
+        virtual_columns = self.class.columns.select(& :virtual?).map(&:name)
+        attributes_with_quotes_without_virtual_columns(include_primary_key, include_readonly_attributes, attribute_names - virtual_columns)
+      end
+
+      alias_method_chain :attributes_with_quotes, :virtual_columns
+    else
+      def arel_attributes_values_with_virtual_columns(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
+        virtual_columns = self.class.columns.select(& :virtual?).map(&:name)
+        arel_attributes_values_without_virtual_columns(include_primary_key, include_readonly_attributes, attribute_names - virtual_columns)
+      end
+
+      alias_method_chain :arel_attributes_values, :virtual_columns
+    end
+
+  end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_column.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_column.rb
new file mode 100644 (file)
index 0000000..0847139
--- /dev/null
@@ -0,0 +1,136 @@
+module ActiveRecord
+  module ConnectionAdapters #:nodoc:
+    class OracleEnhancedColumn < Column
+
+      attr_reader :table_name, :forced_column_type, :nchar, :virtual_column_data_default #:nodoc:
+      
+      def initialize(name, default, sql_type = nil, null = true, table_name = nil, forced_column_type = nil, virtual=false) #:nodoc:
+        @table_name = table_name
+        @forced_column_type = forced_column_type
+        @virtual = virtual
+        super(name, default, sql_type, null)
+        @virtual_column_data_default = default.inspect if virtual
+        # Is column NCHAR or NVARCHAR2 (will need to use N'...' value quoting for these data types)?
+        # Define only when needed as adapter "quote" method will check at first if instance variable is defined.
+        @nchar = true if @type == :string && sql_type[0,1] == 'N'
+      end
+
+      def type_cast(value) #:nodoc:
+        return OracleEnhancedColumn::string_to_raw(value) if type == :raw
+        return guess_date_or_time(value) if type == :datetime && OracleEnhancedAdapter.emulate_dates
+        super
+      end
+
+      def virtual?
+        @virtual
+      end
+
+      # convert something to a boolean
+      # added y as boolean value
+      def self.value_to_boolean(value) #:nodoc:
+        if value == true || value == false
+          value
+        elsif value.is_a?(String) && value.blank?
+          nil
+        else
+          %w(true t 1 y +).include?(value.to_s.downcase)
+        end
+      end
+
+      # convert Time or DateTime value to Date for :date columns
+      def self.string_to_date(string) #:nodoc:
+        return string.to_date if string.is_a?(Time) || string.is_a?(DateTime)
+        super
+      end
+
+      # convert Date value to Time for :datetime columns
+      def self.string_to_time(string) #:nodoc:
+        return string.to_time if string.is_a?(Date) && !OracleEnhancedAdapter.emulate_dates
+        super
+      end
+
+      # convert RAW column values back to byte strings.
+      def self.string_to_raw(string) #:nodoc:
+        string
+      end
+
+      # Get column comment from schema definition.
+      # Will work only if using default ActiveRecord connection.
+      def comment
+        ActiveRecord::Base.connection.column_comment(@table_name, name)
+      end
+      
+      private
+
+      def simplified_type(field_type)
+        forced_column_type ||
+        case field_type
+        when /decimal|numeric|number/i
+          if OracleEnhancedAdapter.emulate_booleans && field_type == 'NUMBER(1)'
+            :boolean
+          elsif extract_scale(field_type) == 0 ||
+                # if column name is ID or ends with _ID
+                OracleEnhancedAdapter.emulate_integers_by_column_name && OracleEnhancedAdapter.is_integer_column?(name, table_name)
+            :integer
+          else
+            :decimal
+          end
+        when /raw/i
+          :raw
+        when /char/i
+          if OracleEnhancedAdapter.emulate_booleans_from_strings &&
+             OracleEnhancedAdapter.is_boolean_column?(name, field_type, table_name)
+            :boolean
+          else
+            :string
+          end
+        when /date/i
+          if OracleEnhancedAdapter.emulate_dates_by_column_name && OracleEnhancedAdapter.is_date_column?(name, table_name)
+            :date
+          else
+            :datetime
+          end
+        when /timestamp/i
+          :timestamp
+        when /time/i
+          :datetime
+        else
+          super
+        end
+      end
+
+      def guess_date_or_time(value)
+        value.respond_to?(:hour) && (value.hour == 0 and value.min == 0 and value.sec == 0) ?
+          Date.new(value.year, value.month, value.day) : value
+      end
+      
+      class << self
+        protected
+
+        def fallback_string_to_date(string) #:nodoc:
+          if OracleEnhancedAdapter.string_to_date_format || OracleEnhancedAdapter.string_to_time_format
+            return (string_to_date_or_time_using_format(string).to_date rescue super)
+          end
+          super
+        end
+
+        def fallback_string_to_time(string) #:nodoc:
+          if OracleEnhancedAdapter.string_to_time_format || OracleEnhancedAdapter.string_to_date_format
+            return (string_to_date_or_time_using_format(string).to_time rescue super)
+          end
+          super
+        end
+
+        def string_to_date_or_time_using_format(string) #:nodoc:
+          if OracleEnhancedAdapter.string_to_time_format && dt=Date._strptime(string, OracleEnhancedAdapter.string_to_time_format)
+            return Time.parse("#{dt[:year]}-#{dt[:mon]}-#{dt[:mday]} #{dt[:hour]}:#{dt[:min]}:#{dt[:sec]}#{dt[:zone]}")
+          end
+          DateTime.strptime(string, OracleEnhancedAdapter.string_to_date_format).to_date
+        end
+        
+      end
+    end
+
+  end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_connection.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_connection.rb
new file mode 100644 (file)
index 0000000..22fe32d
--- /dev/null
@@ -0,0 +1,119 @@
+module ActiveRecord
+  module ConnectionAdapters
+    # interface independent methods
+    class OracleEnhancedConnection #:nodoc:
+
+      def self.create(config)
+        case ORACLE_ENHANCED_CONNECTION
+        when :oci
+          OracleEnhancedOCIConnection.new(config)
+        when :jdbc
+          OracleEnhancedJDBCConnection.new(config)
+        else
+          nil
+        end
+      end
+
+      attr_reader :raw_connection
+
+      # Oracle column names by default are case-insensitive, but treated as upcase;
+      # for neatness, we'll downcase within Rails. EXCEPT that folks CAN quote
+      # their column names when creating Oracle tables, which makes then case-sensitive.
+      # I don't know anybody who does this, but we'll handle the theoretical case of a
+      # camelCase column name. I imagine other dbs handle this different, since there's a
+      # unit test that's currently failing test_oci.
+      def oracle_downcase(column_name)
+        return nil if column_name.nil?
+        column_name =~ /[a-z]/ ? column_name : column_name.downcase
+      end
+
+      # Used always by JDBC connection as well by OCI connection when describing tables over database link
+      def describe(name)
+        name = name.to_s
+        if name.include?('@')
+          name, db_link = name.split('@')
+          default_owner = select_value("SELECT username FROM all_db_links WHERE db_link = '#{db_link.upcase}'")
+          db_link = "@#{db_link}"
+        else
+          db_link = nil
+          default_owner = @owner
+        end
+        real_name = OracleEnhancedAdapter.valid_table_name?(name) ? name.upcase : name
+        if real_name.include?('.')
+          table_owner, table_name = real_name.split('.')
+        else
+          table_owner, table_name = default_owner, real_name
+        end
+        sql = <<-SQL
+          SELECT owner, table_name, 'TABLE' name_type
+          FROM all_tables#{db_link}
+          WHERE owner = '#{table_owner}'
+            AND table_name = '#{table_name}'
+          UNION ALL
+          SELECT owner, view_name table_name, 'VIEW' name_type
+          FROM all_views#{db_link}
+          WHERE owner = '#{table_owner}'
+            AND view_name = '#{table_name}'
+          UNION ALL
+          SELECT table_owner, DECODE(db_link, NULL, table_name, table_name||'@'||db_link), 'SYNONYM' name_type
+          FROM all_synonyms#{db_link}
+          WHERE owner = '#{table_owner}'
+            AND synonym_name = '#{table_name}'
+          UNION ALL
+          SELECT table_owner, DECODE(db_link, NULL, table_name, table_name||'@'||db_link), 'SYNONYM' name_type
+          FROM all_synonyms#{db_link}
+          WHERE owner = 'PUBLIC'
+            AND synonym_name = '#{real_name}'
+        SQL
+        if result = select_one(sql)
+          case result['name_type']
+          when 'SYNONYM'
+            describe("#{result['owner'] && "#{result['owner']}."}#{result['table_name']}#{db_link}")
+          else
+            db_link ? [result['owner'], result['table_name'], db_link] : [result['owner'], result['table_name']]
+          end
+        else
+          raise OracleEnhancedConnectionException, %Q{"DESC #{name}" failed; does it exist?}
+        end
+      end
+
+      # Returns a record hash with the column names as keys and column values
+      # as values.
+      def select_one(sql)
+        result = select(sql)
+        result.first if result
+      end
+
+      # Returns a single value from a record
+      def select_value(sql)
+        if result = select_one(sql)
+          result.values.first
+        end
+      end
+
+      # Returns an array of the values of the first column in a select:
+      #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
+      def select_values(sql)
+        result = select(sql)
+        result.map { |r| r.values.first }
+      end
+
+    end
+    
+    class OracleEnhancedConnectionException < StandardError #:nodoc:
+    end
+
+  end
+end
+
+# if MRI or YARV
+if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
+  ORACLE_ENHANCED_CONNECTION = :oci
+  require 'active_record/connection_adapters/oracle_enhanced_oci_connection'
+# if JRuby
+elsif RUBY_ENGINE == 'jruby'
+  ORACLE_ENHANCED_CONNECTION = :jdbc
+  require 'active_record/connection_adapters/oracle_enhanced_jdbc_connection'
+else
+  raise "Unsupported Ruby engine #{RUBY_ENGINE}"
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb
new file mode 100644 (file)
index 0000000..ef296d2
--- /dev/null
@@ -0,0 +1,328 @@
+module ActiveRecord
+  module ConnectionAdapters
+    module OracleEnhancedContextIndex
+
+      # Define full text index with Oracle specific CONTEXT index type
+      #
+      # Oracle CONTEXT index by default supports full text indexing of one column.
+      # This method allows full text index creation also on several columns
+      # as well as indexing related table columns by generating stored procedure
+      # that concatenates all columns for indexing as well as generating trigger
+      # that will update main index column to trigger reindexing of record.
+      #
+      # Use +contains+ ActiveRecord model instance method to add CONTAINS where condition
+      # and order by score of matched results.
+      #
+      # Options:
+      #
+      # * <tt>:name</tt>
+      # * <tt>:index_column</tt>
+      # * <tt>:index_column_trigger_on</tt>
+      # * <tt>:tablespace</tt>
+      # * <tt>:sync</tt> - 'MANUAL', 'EVERY "interval-string"' or 'ON COMMIT' (defaults to 'MANUAL').
+      # * <tt>:lexer</tt> - Lexer options (e.g. <tt>:type => 'BASIC_LEXER', :base_letter => true</tt>).
+      # * <tt>:transactional</tt> - When +true+, the CONTAINS operator will process inserted and updated rows.
+      #
+      # ===== Examples
+      #
+      # ====== Creating single column index
+      #  add_context_index :posts, :title
+      # search with
+      #  Post.contains(:title, 'word')
+      #
+      # ====== Creating index on several columns
+      #  add_context_index :posts, [:title, :body]
+      # search with (use first column as argument for contains method but it will search in all index columns)
+      #  Post.contains(:title, 'word')
+      #
+      # ====== Creating index on several columns with dummy index column and commit option
+      #  add_context_index :posts, [:title, :body], :index_column => :all_text, :sync => 'ON COMMIT'
+      # search with
+      #  Post.contains(:all_text, 'word')
+      #
+      # ====== Creating index with trigger option (will reindex when specified columns are updated)
+      #  add_context_index :posts, [:title, :body], :index_column => :all_text, :sync => 'ON COMMIT',
+      #                     :index_column_trigger_on => [:created_at, :updated_at]
+      # search with
+      #  Post.contains(:all_text, 'word')
+      #
+      # ====== Creating index on multiple tables
+      #  add_context_index :posts,
+      #   [:title, :body,
+      #   # specify aliases always with AS keyword
+      #   "SELECT comments.author AS comment_author, comments.body AS comment_body FROM comments WHERE comments.post_id = :id"
+      #   ],
+      #   :name => 'post_and_comments_index',
+      #   :index_column => :all_text, :index_column_trigger_on => [:updated_at, :comments_count],
+      #   :sync => 'ON COMMIT'
+      # search in any table columns
+      #  Post.contains(:all_text, 'word')
+      # search in specified column
+      #  Post.contains(:all_text, "aaa within title")
+      #  Post.contains(:all_text, "bbb within comment_author")
+      #
+      # ====== Creating index using lexer
+      #  add_context_index :posts, :title, :lexer => { :type => 'BASIC_LEXER', :base_letter => true, ... }
+      #
+      # ====== Creating transactional index (will reindex changed rows when querying)
+      #  add_context_index :posts, :title, :transactional => true
+      #
+      def add_context_index(table_name, column_name, options = {})
+        self.all_schema_indexes = nil
+        column_names = Array(column_name)
+        index_name = options[:name] || index_name(table_name, :column => options[:index_column] || column_names,
+          # CONEXT index name max length is 25
+          :identifier_max_length => 25)
+
+        quoted_column_name = quote_column_name(options[:index_column] || column_names.first)
+        if options[:index_column_trigger_on]
+          raise ArgumentError, "Option :index_column should be specified together with :index_column_trigger_on option" \
+            unless options[:index_column]
+          create_index_column_trigger(table_name, index_name, options[:index_column], options[:index_column_trigger_on])
+        end
+
+        sql = "CREATE INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
+        sql << " (#{quoted_column_name})"
+        sql << " INDEXTYPE IS CTXSYS.CONTEXT"
+        parameters = []
+        if column_names.size > 1
+          procedure_name = default_datastore_procedure(index_name)
+          datastore_name = default_datastore_name(index_name)
+          create_datastore_procedure(table_name, procedure_name, column_names, options)
+          create_datastore_preference(datastore_name, procedure_name)
+          parameters << "DATASTORE #{datastore_name} SECTION GROUP CTXSYS.AUTO_SECTION_GROUP"
+        end
+        if options[:tablespace]
+          storage_name = default_storage_name(index_name)
+          create_storage_preference(storage_name, options[:tablespace])
+          parameters << "STORAGE #{storage_name}"
+        end
+        if options[:sync]
+          parameters << "SYNC(#{options[:sync]})"
+        end
+        if options[:lexer] && (lexer_type = options[:lexer][:type])
+          lexer_name = default_lexer_name(index_name)
+          (lexer_options = options[:lexer].dup).delete(:type)
+          create_lexer_preference(lexer_name, lexer_type, lexer_options)
+          parameters << "LEXER #{lexer_name}"
+        end
+        if options[:transactional]
+          parameters << "TRANSACTIONAL"
+        end
+        unless parameters.empty?
+          sql << " PARAMETERS ('#{parameters.join(' ')}')"
+        end
+        execute sql
+      end
+
+      # Drop full text index with Oracle specific CONTEXT index type
+      def remove_context_index(table_name, options = {})
+        self.all_schema_indexes = nil
+        unless Hash === options # if column names passed as argument
+          options = {:column => Array(options)}
+        end
+        index_name = options[:name] || index_name(table_name,
+          :column => options[:index_column] || options[:column], :identifier_max_length => 25)
+        execute "DROP INDEX #{index_name}"
+        drop_ctx_preference(default_datastore_name(index_name))
+        drop_ctx_preference(default_storage_name(index_name))
+        procedure_name = default_datastore_procedure(index_name)
+        execute "DROP PROCEDURE #{quote_table_name(procedure_name)}" rescue nil
+        drop_index_column_trigger(index_name)
+      end
+
+      private
+
+      def create_datastore_procedure(table_name, procedure_name, column_names, options)
+        quoted_table_name = quote_table_name(table_name)
+        select_queries, column_names = column_names.partition { |c| c.to_s =~ /^\s*SELECT\s+/i }
+        select_queries = select_queries.map { |s| s.strip.gsub(/\s+/, ' ') }
+        keys, selected_columns = parse_select_queries(select_queries)
+        quoted_column_names = (column_names+keys).map{|col| quote_column_name(col)}
+        execute compress_lines(<<-SQL)
+          CREATE OR REPLACE PROCEDURE #{quote_table_name(procedure_name)}
+            (p_rowid IN              ROWID,
+            p_clob     IN OUT NOCOPY CLOB) IS
+            -- add_context_index_parameters #{(column_names+select_queries).inspect}#{!options.empty? ? ', ' << options.inspect[1..-2] : ''}
+            #{
+            selected_columns.map do |cols|
+              cols.map do |col|
+                raise ArgumentError, "Alias #{col} too large, should be 28 or less characters long" unless col.length <= 28
+                "l_#{col} VARCHAR2(32767);\n"
+              end.join
+            end.join
+            } BEGIN
+            FOR r1 IN (
+              SELECT #{quoted_column_names.join(', ')}
+              FROM      #{quoted_table_name}
+              WHERE  #{quoted_table_name}.ROWID = p_rowid
+            ) LOOP
+              #{
+              (column_names.map do |col|
+                col = col.to_s
+                "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+2}, '<#{col}>');\n" <<
+                "IF LENGTH(r1.#{col}) > 0 THEN\n" <<
+                "DBMS_LOB.WRITEAPPEND(p_clob, LENGTH(r1.#{col}), r1.#{col});\n" <<
+                "END IF;\n" <<
+                "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+3}, '</#{col}>');\n"
+              end.join) <<
+              (selected_columns.zip(select_queries).map do |cols, query|
+                (cols.map do |col|
+                  "l_#{col} := '';\n"
+                end.join) <<
+                "FOR r2 IN (\n" <<
+                query.gsub(/:(\w+)/,"r1.\\1") << "\n) LOOP\n" <<
+                (cols.map do |col|
+                  "l_#{col} := l_#{col} || r2.#{col} || CHR(10);\n"
+                end.join) <<
+                "END LOOP;\n" <<
+                (cols.map do |col|
+                  col = col.to_s
+                  "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+2}, '<#{col}>');\n" <<
+                  "IF LENGTH(l_#{col}) > 0 THEN\n" <<
+                  "DBMS_LOB.WRITEAPPEND(p_clob, LENGTH(l_#{col}), l_#{col});\n" <<
+                  "END IF;\n" <<
+                  "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length+3}, '</#{col}>');\n"
+                end.join)
+              end.join)
+              }
+            END LOOP;
+          END;
+        SQL
+      end
+
+      def parse_select_queries(select_queries)
+        keys = []
+        selected_columns = []
+        select_queries.each do |query|
+          # get primary or foreign keys like :id or :something_id
+          keys << (query.scan(/:\w+/).map{|k| k[1..-1].downcase.to_sym})
+          select_part = query.scan(/^select\s.*\sfrom/i).first
+          selected_columns << select_part.scan(/\sas\s+(\w+)/i).map{|c| c.first}
+        end
+        [keys.flatten.uniq, selected_columns]
+      end
+
+      def create_datastore_preference(datastore_name, procedure_name)
+        drop_ctx_preference(datastore_name)
+        execute <<-SQL
+          BEGIN
+            CTX_DDL.CREATE_PREFERENCE('#{datastore_name}', 'USER_DATASTORE');
+            CTX_DDL.SET_ATTRIBUTE('#{datastore_name}', 'PROCEDURE', '#{procedure_name}');
+          END;
+        SQL
+      end
+
+      def create_storage_preference(storage_name, tablespace)
+        drop_ctx_preference(storage_name)
+        sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{storage_name}', 'BASIC_STORAGE');\n"
+        ['I_TABLE_CLAUSE', 'K_TABLE_CLAUSE', 'R_TABLE_CLAUSE',
+        'N_TABLE_CLAUSE', 'I_INDEX_CLAUSE', 'P_TABLE_CLAUSE'].each do |clause|
+          default_clause = case clause
+          when 'R_TABLE_CLAUSE'; 'LOB(DATA) STORE AS (CACHE) '
+          when 'I_INDEX_CLAUSE'; 'COMPRESS 2 '
+          else ''
+          end
+          sql << "CTX_DDL.SET_ATTRIBUTE('#{storage_name}', '#{clause}', '#{default_clause}TABLESPACE #{tablespace}');\n"
+        end
+        sql << "END;\n"
+        execute sql
+      end
+
+      def create_lexer_preference(lexer_name, lexer_type, options)
+        drop_ctx_preference(lexer_name)
+        sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{lexer_name}', '#{lexer_type}');\n"
+        options.each do |key, value|
+          plsql_value = case value
+          when String; "'#{value}'"
+          when true; "'YES'"
+          when false; "'NO'"
+          when nil; 'NULL'
+          else value
+          end
+          sql << "CTX_DDL.SET_ATTRIBUTE('#{lexer_name}', '#{key}', #{plsql_value});\n"
+        end
+        sql << "END;\n"
+        execute sql
+      end
+
+      def drop_ctx_preference(preference_name)
+        execute "BEGIN CTX_DDL.DROP_PREFERENCE('#{preference_name}'); END;" rescue nil
+      end
+
+      def create_index_column_trigger(table_name, index_name, index_column, index_column_source)
+        trigger_name = default_index_column_trigger_name(index_name)
+        columns = Array(index_column_source)
+        quoted_column_names = columns.map{|col| quote_column_name(col)}.join(', ')
+        execute compress_lines(<<-SQL)
+          CREATE OR REPLACE TRIGGER #{quote_table_name(trigger_name)}
+          BEFORE UPDATE OF #{quoted_column_names} ON #{quote_table_name(table_name)} FOR EACH ROW
+          BEGIN
+            :new.#{quote_column_name(index_column)} := '1';
+          END;
+        SQL
+      end
+
+      def drop_index_column_trigger(index_name)
+        trigger_name = default_index_column_trigger_name(index_name)
+        execute "DROP TRIGGER #{quote_table_name(trigger_name)}" rescue nil
+      end
+
+      def default_datastore_procedure(index_name)
+        "#{index_name}_prc"
+      end
+
+      def default_datastore_name(index_name)
+        "#{index_name}_dst"
+      end
+
+      def default_storage_name(index_name)
+        "#{index_name}_sto"
+      end
+
+      def default_index_column_trigger_name(index_name)
+        "#{index_name}_trg"
+      end
+
+      def default_lexer_name(index_name)
+        "#{index_name}_lex"
+      end
+
+      module BaseClassMethods
+        # Declare that model table has context index defined.
+        # As a result <tt>contains</tt> class scope method is defined.
+        def has_context_index
+          extend ContextIndexClassMethods
+        end
+      end
+
+      module ContextIndexClassMethods
+        # Add context index condition.
+        case ::ActiveRecord::VERSION::MAJOR
+        when 3
+          def contains(column, query, options ={})
+            score_label = options[:label].to_i || 1
+            where("CONTAINS(#{connection.quote_column_name(column)}, ?, #{score_label}) > 0", query).
+              order("SCORE(#{score_label}) DESC")
+          end
+        when 2
+          def contains(column, query, options ={})
+            score_label = options[:label].to_i || 1
+            scoped(:conditions => ["CONTAINS(#{connection.quote_column_name(column)}, ?, #{score_label}) > 0", query],
+              :order => "SCORE(#{score_label}) DESC")
+          end
+        end
+      end
+
+    end
+    
+  end
+end
+
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedContextIndex
+end
+
+ActiveRecord::Base.class_eval do
+  extend ActiveRecord::ConnectionAdapters::OracleEnhancedContextIndex::BaseClassMethods
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_core_ext.rb
new file mode 100644 (file)
index 0000000..0570c0e
--- /dev/null
@@ -0,0 +1,24 @@
+require "bigdecimal"
+if (BigDecimal.instance_methods & ["to_d", :to_d]).empty?
+  BigDecimal.class_eval do
+    def to_d #:nodoc:
+      self
+    end
+  end
+end
+
+if (Bignum.instance_methods & ["to_d", :to_d]).empty?
+  Bignum.class_eval do
+    def to_d #:nodoc:
+      BigDecimal.new(self.to_s)
+    end
+  end
+end
+
+if (Fixnum.instance_methods & ["to_d", :to_d]).empty?
+  Fixnum.class_eval do
+    def to_d #:nodoc:
+      BigDecimal.new(self.to_s)
+    end
+  end
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb
new file mode 100644 (file)
index 0000000..05cae11
--- /dev/null
@@ -0,0 +1,21 @@
+module ActiveRecord #:nodoc:
+  module ConnectionAdapters #:nodoc:
+    module OracleEnhancedCpk #:nodoc:
+
+      # This mightn't be in Core, but count(distinct x,y) doesn't work for me.
+      # Return that not supported if composite_primary_keys gem is required.
+      def supports_count_distinct? #:nodoc:
+        @supports_count_distinct ||= ! defined?(CompositePrimaryKeys)
+      end
+      
+      def concat(*columns) #:nodoc:
+        "(#{columns.join('||')})"
+      end
+      
+    end
+  end
+end
+
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedCpk
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb
new file mode 100644 (file)
index 0000000..9c9df30
--- /dev/null
@@ -0,0 +1,39 @@
+module ActiveRecord #:nodoc:
+  module ConnectionAdapters #:nodoc:
+    module OracleEnhancedDirty #:nodoc:
+
+      module InstanceMethods #:nodoc:
+        private
+        
+        def field_changed?(attr, old, value)
+          if column = column_for_attribute(attr)
+            # Added also :decimal type
+            if (column.type == :integer || column.type == :decimal) && column.null && (old.nil? || old == 0) && value.blank?
+              # For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
+              # Hence we don't record it as a change if the value changes from nil to ''.
+              # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
+              # be typecast back to 0 (''.to_i => 0)
+              value = nil
+            # Oracle stores empty string '' as NULL
+            # therefore need to convert empty string value to nil if old value is nil
+            elsif column.type == :string && column.null && old.nil?
+              value = nil if value == ''
+            else
+              value = column.type_cast(value)
+            end
+          end
+
+          old != value
+        end
+        
+      end
+
+    end
+  end
+end
+
+if ActiveRecord::Base.method_defined?(:changed?)
+  ActiveRecord::Base.class_eval do
+    include ActiveRecord::ConnectionAdapters::OracleEnhancedDirty::InstanceMethods
+  end
+end
\ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb
new file mode 100644 (file)
index 0000000..14c4ba3
--- /dev/null
@@ -0,0 +1,548 @@
+begin
+  require "java"
+  require "jruby"
+
+  # ojdbc6.jar or ojdbc5.jar file should be in JRUBY_HOME/lib or should be in ENV['PATH'] or load path
+
+  java_version = java.lang.System.getProperty("java.version")
+  ojdbc_jar = if java_version =~ /^1.5/
+    "ojdbc5.jar"
+  elsif java_version >= '1.6'
+    "ojdbc6.jar"
+  else
+    nil
+  end
+
+  unless ojdbc_jar.nil? || ENV_JAVA['java.class.path'] =~ Regexp.new(ojdbc_jar)
+    # On Unix environment variable should be PATH, on Windows it is sometimes Path
+    env_path = (ENV["PATH"] || ENV["Path"] || '').split(/[:;]/)
+    # Look for JDBC driver at first in lib subdirectory (application specific JDBC file version)
+    # then in Ruby load path and finally in environment PATH
+    if ojdbc_jar_path = ['./lib'].concat($LOAD_PATH).concat(env_path).find{|d| File.exists?(File.join(d,ojdbc_jar))}
+      require File.join(ojdbc_jar_path,ojdbc_jar)
+    end
+  end
+
+  java.sql.DriverManager.registerDriver Java::oracle.jdbc.OracleDriver.new
+
+  # set tns_admin property from TNS_ADMIN environment variable
+  if !java.lang.System.get_property("oracle.net.tns_admin") && ENV["TNS_ADMIN"]
+    java.lang.System.set_property("oracle.net.tns_admin", ENV["TNS_ADMIN"])
+  end
+
+rescue LoadError, NameError
+  # JDBC driver is unavailable.
+  raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load Oracle JDBC driver. Please install #{ojdbc_jar || "Oracle JDBC"} library."
+end
+
+
+module ActiveRecord
+  module ConnectionAdapters
+
+    # JDBC database interface for JRuby
+    class OracleEnhancedJDBCConnection < OracleEnhancedConnection #:nodoc:
+
+      attr_accessor :active
+      alias :active? :active
+
+      attr_accessor :auto_retry
+      alias :auto_retry? :auto_retry
+      @auto_retry = false
+
+      def initialize(config)
+        @active = true
+        @config = config
+        new_connection(@config)
+      end
+
+      # modified method to support JNDI connections
+      def new_connection(config)
+        username = nil
+
+        if config[:jndi]
+          jndi = config[:jndi].to_s
+          ctx = javax.naming.InitialContext.new
+          ds = nil
+
+          # tomcat needs first lookup method, oc4j (and maybe other application servers) need second method
+          begin
+            env = ctx.lookup('java:/comp/env')
+            ds = env.lookup(jndi)
+          rescue
+            ds = ctx.lookup(jndi)
+          end
+
+          # check if datasource supports pooled connections, otherwise use default
+          if ds.respond_to?(:pooled_connection)
+            @raw_connection = ds.pooled_connection
+          else
+            @raw_connection = ds.connection
+          end
+
+          # get Oracle JDBC connection when using DBCP in Tomcat or jBoss
+          if @raw_connection.respond_to?(:getInnermostDelegate)
+            @pooled_connection = @raw_connection
+            @raw_connection = @raw_connection.innermost_delegate
+          elsif @raw_connection.respond_to?(:getUnderlyingConnection)
+            @pooled_connection = @raw_connection
+            @raw_connection = @raw_connection.underlying_connection            
+          end
+
+          config[:driver] ||= @raw_connection.meta_data.connection.java_class.name
+          username = @raw_connection.meta_data.user_name
+        else
+          # to_s needed if username, password or database is specified as number in database.yml file
+          username = config[:username] && config[:username].to_s
+          password = config[:password] && config[:password].to_s
+          database = config[:database] && config[:database].to_s
+          host, port = config[:host], config[:port]
+          privilege = config[:privilege] && config[:privilege].to_s
+
+          # connection using TNS alias
+          if database && !host && !config[:url] && ENV['TNS_ADMIN']
+            url = "jdbc:oracle:thin:@#{database || 'XE'}"
+          else
+            url = config[:url] || "jdbc:oracle:thin:@#{host || 'localhost'}:#{port || 1521}:#{database || 'XE'}"
+          end
+
+          prefetch_rows = config[:prefetch_rows] || 100
+          # get session time_zone from configuration or from TZ environment variable
+          time_zone = config[:time_zone] || ENV['TZ'] || java.util.TimeZone.default.getID
+
+          properties = java.util.Properties.new
+          properties.put("user", username)
+          properties.put("password", password)
+          properties.put("defaultRowPrefetch", "#{prefetch_rows}") if prefetch_rows
+          properties.put("internal_logon", privilege) if privilege
+
+          @raw_connection = java.sql.DriverManager.getConnection(url, properties)
+
+          # Set session time zone to current time zone
+          @raw_connection.setSessionTimeZone(time_zone)
+
+          # Set default number of rows to prefetch
+          # @raw_connection.setDefaultRowPrefetch(prefetch_rows) if prefetch_rows
+        end
+
+        cursor_sharing = config[:cursor_sharing] || 'force'
+        exec "alter session set cursor_sharing = #{cursor_sharing}"
+
+        # Initialize NLS parameters
+        OracleEnhancedAdapter::DEFAULT_NLS_PARAMETERS.each do |key, default_value|
+          value = config[key] || ENV[key.to_s.upcase] || default_value
+          if value
+            exec "alter session set #{key} = '#{value}'"
+          end
+        end
+
+        self.autocommit = true
+
+        # default schema owner
+        @owner = username.upcase unless username.nil?
+
+        @raw_connection
+      end
+
+      def logoff
+        @active = false
+        if defined?(@pooled_connection)
+          @pooled_connection.close
+        else
+          @raw_connection.close
+        end
+        true
+      rescue
+        false
+      end
+
+      def commit
+        @raw_connection.commit
+      end
+
+      def rollback
+        @raw_connection.rollback
+      end
+
+      def autocommit?
+        @raw_connection.getAutoCommit
+      end
+
+      def autocommit=(value)
+        @raw_connection.setAutoCommit(value)
+      end
+
+      # Checks connection, returns true if active. Note that ping actively
+      # checks the connection, while #active? simply returns the last
+      # known state.
+      def ping
+        exec_no_retry("select 1 from dual")
+        @active = true
+      rescue NativeException => e
+        @active = false
+        if e.message =~ /^java\.sql\.SQL(Recoverable)?Exception/
+          raise OracleEnhancedConnectionException, e.message
+        else
+          raise
+        end
+      end
+
+      # Resets connection, by logging off and creating a new connection.
+      def reset!
+        logoff rescue nil
+        begin
+          new_connection(@config)
+          @active = true
+        rescue NativeException => e
+          @active = false
+          if e.message =~ /^java\.sql\.SQL(Recoverable)?Exception/
+            raise OracleEnhancedConnectionException, e.message
+          else
+            raise
+          end
+        end
+      end
+
+      # mark connection as dead if connection lost
+      def with_retry(&block)
+        should_retry = auto_retry? && autocommit?
+        begin
+          yield if block_given?
+        rescue NativeException => e
+          raise unless e.message =~ /^java\.sql\.SQL(Recoverable)?Exception: (Closed Connection|Io exception:|No more data to read from socket|IO Error:)/
+          @active = false
+          raise unless should_retry
+          should_retry = false
+          reset! rescue nil
+          retry
+        end
+      end
+
+      def exec(sql)
+        with_retry do
+          exec_no_retry(sql)
+        end
+      end
+
+      def exec_no_retry(sql)
+        case sql
+        when /\A\s*(UPDATE|INSERT|DELETE)/i
+          s = @raw_connection.prepareStatement(sql)
+          s.executeUpdate
+        # it is safer for CREATE and DROP statements not to use PreparedStatement
+        # as it does not allow creation of triggers with :NEW in their definition
+        when /\A\s*(CREATE|DROP)/i
+          s = @raw_connection.createStatement()
+          # this disables SQL92 syntax processing of {...} which can result in statement execution errors
+          # if sql contains {...} in strings or comments
+          s.setEscapeProcessing(false)
+          s.execute(sql)
+          true
+        else
+          s = @raw_connection.prepareStatement(sql)
+          s.execute
+          true
+        end
+      ensure
+        s.close rescue nil
+      end
+
+      def returning_clause(quoted_pk)
+        " RETURNING #{quoted_pk} INTO ?"
+      end
+
+      # execute sql with RETURNING ... INTO :insert_id
+      # and return :insert_id value
+      def exec_with_returning(sql)
+        with_retry do
+          begin
+            # it will always be INSERT statement
+
+            # TODO: need to investigate why PreparedStatement is giving strange exception "Protocol violation"
+            # s = @raw_connection.prepareStatement(sql)
+            # s.registerReturnParameter(1, ::Java::oracle.jdbc.OracleTypes::NUMBER)
+            # count = s.executeUpdate
+            # if count > 0
+            #   rs = s.getReturnResultSet
+            #   if rs.next
+            #     # Assuming that primary key will not be larger as long max value
+            #     insert_id = rs.getLong(1)
+            #     rs.wasNull ? nil : insert_id
+            #   else
+            #     nil
+            #   end
+            # else
+            #   nil
+            # end
+            
+            # Workaround with CallableStatement
+            s = @raw_connection.prepareCall("BEGIN #{sql}; END;")
+            s.registerOutParameter(1, java.sql.Types::BIGINT)
+            s.execute
+            insert_id = s.getLong(1)
+            s.wasNull ? nil : insert_id
+          ensure
+            # rs.close rescue nil
+            s.close rescue nil
+          end
+        end
+      end
+
+      def prepare(sql)
+        Cursor.new(self, @raw_connection.prepareStatement(sql))
+      end
+
+      class Cursor
+        def initialize(connection, raw_statement)
+          @connection = connection
+          @raw_statement = raw_statement
+        end
+
+        def bind_param(position, value, col_type = nil)
+          java_value = ruby_to_java_value(value, col_type)
+          case value
+          when Integer
+            @raw_statement.setLong(position, java_value)
+          when Float
+            @raw_statement.setFloat(position, java_value)
+          when BigDecimal
+            @raw_statement.setBigDecimal(position, java_value)
+          when String
+            case col_type
+            when :text
+              @raw_statement.setClob(position, java_value)
+            when :binary
+              @raw_statement.setBlob(position, java_value)
+            when :raw
+              @raw_statement.setString(position, OracleEnhancedAdapter.encode_raw(java_value))
+            else
+              @raw_statement.setString(position, java_value)
+            end
+          when Date, DateTime
+            @raw_statement.setDATE(position, java_value)
+          when Time
+            @raw_statement.setTimestamp(position, java_value)
+          when NilClass
+            # TODO: currently nil is always bound as NULL with VARCHAR type.
+            # When nils will actually be used by ActiveRecord as bound parameters
+            # then need to pass actual column type.
+            @raw_statement.setNull(position, java.sql.Types::VARCHAR)
+          else
+            raise ArgumentError, "Don't know how to bind variable with type #{value.class}"
+          end
+        end
+
+        def bind_returning_param(position, bind_type)
+          @returning_positions ||= []
+          @returning_positions << position
+          if bind_type == Integer
+            @raw_statement.registerReturnParameter(position, java.sql.Types::BIGINT)
+          end
+        end
+
+        def exec
+          @raw_result_set = @raw_statement.executeQuery
+          get_metadata
+          true
+        end
+
+        def exec_update
+          @raw_statement.executeUpdate
+        end
+
+        def get_metadata
+          metadata = @raw_result_set.getMetaData
+          column_count = metadata.getColumnCount
+          @column_names = (1..column_count).map{|i| metadata.getColumnName(i)}
+          @column_types = (1..column_count).map{|i| metadata.getColumnTypeName(i).to_sym}
+        end
+
+        def get_col_names
+          @column_names
+        end
+
+        def fetch(options={})
+          if @raw_result_set.next
+            get_lob_value = options[:get_lob_value]
+            row_values = []
+            @column_types.each_with_index do |column_type, i|
+              row_values <<
+                @connection.get_ruby_value_from_result_set(@raw_result_set, i+1, column_type, get_lob_value)
+            end
+            row_values
+          else
+            @raw_result_set.close
+            nil
+          end
+        end
+
+        def get_returning_param(position, type)
+          rs_position = @returning_positions.index(position) + 1
+          rs = @raw_statement.getReturnResultSet
+          if rs.next
+            # Assuming that primary key will not be larger as long max value
+            returning_id = rs.getLong(rs_position)
+            rs.wasNull ? nil : returning_id
+          else
+            nil
+          end
+        end
+
+        def close
+          @raw_statement.close
+        end
+
+        private
+
+        def ruby_to_java_value(value, col_type = nil)
+          case value
+          when Fixnum, Float
+            value
+          when String
+            case col_type
+            when :text
+              clob = Java::OracleSql::CLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::CLOB::DURATION_SESSION)
+              clob.setString(1, value)
+              clob
+            when :binary
+              blob = Java::OracleSql::BLOB.createTemporary(@connection.raw_connection, false, Java::OracleSql::BLOB::DURATION_SESSION)
+              blob.setBytes(1, value.to_java_bytes)
+              blob
+            else
+              value
+            end
+          when BigDecimal
+            java.math.BigDecimal.new(value.to_s)
+          when Date, DateTime
+            Java::oracle.sql.DATE.new(value.strftime("%Y-%m-%d %H:%M:%S"))
+          when Time
+            Java::java.sql.Timestamp.new(value.year-1900, value.month-1, value.day, value.hour, value.min, value.sec, value.usec * 1000)
+          else
+            value
+          end
+        end
+
+      end
+
+      def select(sql, name = nil, return_column_names = false)
+        with_retry do
+          select_no_retry(sql, name, return_column_names)
+        end
+      end
+
+      def select_no_retry(sql, name = nil, return_column_names = false)
+        stmt = @raw_connection.prepareStatement(sql)
+        rset = stmt.executeQuery
+
+        # Reuse the same hash for all rows
+        column_hash = {}
+
+        metadata = rset.getMetaData
+        column_count = metadata.getColumnCount
+
+        cols_types_index = (1..column_count).map do |i|
+          col_name = oracle_downcase(metadata.getColumnName(i))
+          next if col_name == 'raw_rnum_'
+          column_hash[col_name] = nil
+          [col_name, metadata.getColumnTypeName(i).to_sym, i]
+        end
+        cols_types_index.delete(nil)
+
+        rows = []
+        get_lob_value = !(name == 'Writable Large Object')
+
+        while rset.next
+          hash = column_hash.dup
+          cols_types_index.each do |col, column_type, i|
+            hash[col] = get_ruby_value_from_result_set(rset, i, column_type, get_lob_value)
+          end
+          rows << hash
+        end
+
+        return_column_names ? [rows, cols_types_index.map(&:first)] : rows
+      ensure
+        rset.close rescue nil
+        stmt.close rescue nil
+      end
+
+      def write_lob(lob, value, is_binary = false)
+        if is_binary
+          lob.setBytes(1, value.to_java_bytes)
+        else
+          lob.setString(1,value)
+        end
+      end
+
+      # Return NativeException / java.sql.SQLException error code
+      def error_code(exception)
+        case exception
+        when NativeException
+          exception.cause.getErrorCode
+        else
+          nil
+        end
+      end
+
+      def get_ruby_value_from_result_set(rset, i, type_name, get_lob_value = true)
+        case type_name
+        when :NUMBER
+          d = rset.getNUMBER(i)
+          if d.nil?
+            nil
+          elsif d.isInt
+            Integer(d.stringValue)
+          else
+            BigDecimal.new(d.stringValue)
+          end
+        when :VARCHAR2, :CHAR, :LONG, :NVARCHAR2, :NCHAR
+          rset.getString(i)
+        when :DATE
+          if dt = rset.getDATE(i)
+            d = dt.dateValue
+            t = dt.timeValue
+            if OracleEnhancedAdapter.emulate_dates && t.hours == 0 && t.minutes == 0 && t.seconds == 0
+              Date.new(d.year + 1900, d.month + 1, d.date)
+            else
+              Time.send(Base.default_timezone, d.year + 1900, d.month + 1, d.date, t.hours, t.minutes, t.seconds)
+            end
+          else
+            nil
+          end
+        when :TIMESTAMP, :TIMESTAMPTZ, :TIMESTAMPLTZ, :"TIMESTAMP WITH TIME ZONE", :"TIMESTAMP WITH LOCAL TIME ZONE"
+          ts = rset.getTimestamp(i)
+          ts && Time.send(Base.default_timezone, ts.year + 1900, ts.month + 1, ts.date, ts.hours, ts.minutes, ts.seconds,
+            ts.nanos / 1000)
+        when :CLOB
+          get_lob_value ? lob_to_ruby_value(rset.getClob(i)) : rset.getClob(i)
+        when :BLOB
+          get_lob_value ? lob_to_ruby_value(rset.getBlob(i)) : rset.getBlob(i)
+        when :RAW
+          raw_value = rset.getRAW(i)
+          raw_value && raw_value.getBytes.to_a.pack('C*')
+        else
+          nil
+        end
+      end
+
+      private
+
+      def lob_to_ruby_value(val)
+        case val
+        when ::Java::OracleSql::CLOB
+          if val.isEmptyLob
+            nil
+          else
+            val.getSubString(1, val.length)
+          end
+        when ::Java::OracleSql::BLOB
+          if val.isEmptyLob
+            nil
+          else
+            String.from_java_bytes(val.getBytes(1, val.length))
+          end
+        end
+      end
+
+    end
+
+  end
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb
new file mode 100644 (file)
index 0000000..8f56d70
--- /dev/null
@@ -0,0 +1,488 @@
+require 'delegate'
+
+begin
+  require "oci8"
+rescue LoadError
+  # OCI8 driver is unavailable.
+  raise LoadError, "ERROR: ActiveRecord oracle_enhanced adapter could not load ruby-oci8 library. Please install ruby-oci8 gem."
+end
+
+# check ruby-oci8 version
+required_oci8_version = [2, 0, 3]
+oci8_version_ints = OCI8::VERSION.scan(/\d+/).map{|s| s.to_i}
+if (oci8_version_ints <=> required_oci8_version) < 0
+  raise LoadError, "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
+end
+
+module ActiveRecord
+  module ConnectionAdapters
+
+    # OCI database interface for MRI
+    class OracleEnhancedOCIConnection < OracleEnhancedConnection #:nodoc:
+
+      def initialize(config)
+        @raw_connection = OCI8EnhancedAutoRecover.new(config, OracleEnhancedOCIFactory)
+        # default schema owner
+        @owner = config[:username].to_s.upcase
+      end
+
+      def raw_oci_connection
+        if @raw_connection.is_a? OCI8
+          @raw_connection
+        # ActiveRecord Oracle enhanced adapter puts OCI8EnhancedAutoRecover wrapper around OCI8
+        # in this case we need to pass original OCI8 connection
+        else
+          @raw_connection.instance_variable_get(:@connection)
+        end
+      end
+
+      def auto_retry
+        @raw_connection.auto_retry if @raw_connection
+      end
+
+      def auto_retry=(value)
+        @raw_connection.auto_retry = value if @raw_connection
+      end
+
+      def logoff
+        @raw_connection.logoff
+        @raw_connection.active = false
+      end
+
+      def commit
+        @raw_connection.commit
+      end
+
+      def rollback
+        @raw_connection.rollback
+      end
+
+      def autocommit?
+        @raw_connection.autocommit?
+      end
+
+      def autocommit=(value)
+        @raw_connection.autocommit = value
+      end
+
+      # Checks connection, returns true if active. Note that ping actively
+      # checks the connection, while #active? simply returns the last
+      # known state.
+      def ping
+        @raw_connection.ping
+      rescue OCIException => e
+        raise OracleEnhancedConnectionException, e.message
+      end
+
+      def active?
+        @raw_connection.active?
+      end
+
+      def reset!
+        @raw_connection.reset!
+      rescue OCIException => e
+        raise OracleEnhancedConnectionException, e.message
+      end
+
+      def exec(sql, *bindvars, &block)
+        @raw_connection.exec(sql, *bindvars, &block)
+      end
+
+      def returning_clause(quoted_pk)
+        " RETURNING #{quoted_pk} INTO :insert_id"
+      end
+
+      # execute sql with RETURNING ... INTO :insert_id
+      # and return :insert_id value
+      def exec_with_returning(sql)
+        cursor = @raw_connection.parse(sql)
+        cursor.bind_param(':insert_id', nil, Integer)
+        cursor.exec
+        cursor[':insert_id']
+      ensure
+        cursor.close rescue nil
+      end
+
+      def prepare(sql)
+        Cursor.new(self, @raw_connection.parse(sql))
+      end
+
+      class Cursor
+        def initialize(connection, raw_cursor)
+          @connection = connection
+          @raw_cursor = raw_cursor
+        end
+
+        def bind_param(position, value, col_type = nil)
+          if value.nil?
+            @raw_cursor.bind_param(position, nil, String)
+          else
+            case col_type
+            when :text, :binary
+              # ruby-oci8 cannot create CLOB/BLOB from ''
+              lob_value = value == '' ? ' ' : value
+              bind_type = col_type == :text ? OCI8::CLOB : OCI8::BLOB
+              ora_value = bind_type.new(@connection.raw_oci_connection, lob_value)
+              ora_value.size = 0 if value == ''
+              @raw_cursor.bind_param(position, ora_value)
+            when :raw
+              @raw_cursor.bind_param(position, OracleEnhancedAdapter.encode_raw(value))
+            else
+              @raw_cursor.bind_param(position, value)
+            end
+          end
+        end
+
+        def bind_returning_param(position, bind_type)
+          @raw_cursor.bind_param(position, nil, bind_type)
+        end
+
+        def exec
+          @raw_cursor.exec
+        end
+
+        def exec_update
+          @raw_cursor.exec
+        end
+
+        def get_col_names
+          @raw_cursor.get_col_names
+        end
+
+        def fetch(options={})
+          if row = @raw_cursor.fetch
+            get_lob_value = options[:get_lob_value]
+            row.map do |col|
+              @connection.typecast_result_value(col, get_lob_value)
+            end
+          end
+        end
+
+        def get_returning_param(position, type)
+          @raw_cursor[position]
+        end
+
+        def close
+          @raw_cursor.close
+        end
+
+      end
+
+      def select(sql, name = nil, return_column_names = false)
+        cursor = @raw_connection.exec(sql)
+        cols = []
+        # Ignore raw_rnum_ which is used to simulate LIMIT and OFFSET
+        cursor.get_col_names.each do |col_name|
+          col_name = oracle_downcase(col_name)
+          cols << col_name unless col_name == 'raw_rnum_'
+        end
+        # Reuse the same hash for all rows
+        column_hash = {}
+        cols.each {|c| column_hash[c] = nil}
+        rows = []
+        get_lob_value = !(name == 'Writable Large Object')
+
+        while row = cursor.fetch
+          hash = column_hash.dup
+
+          cols.each_with_index do |col, i|
+            hash[col] = typecast_result_value(row[i], get_lob_value)
+          end
+
+          rows << hash
+        end
+
+        return_column_names ? [rows, cols] : rows
+      ensure
+        cursor.close if cursor
+      end
+
+      def write_lob(lob, value, is_binary = false)
+        lob.write value
+      end
+      
+      def describe(name)
+        # fall back to SELECT based describe if using database link
+        return super if name.to_s.include?('@')
+        quoted_name = OracleEnhancedAdapter.valid_table_name?(name) ? name : "\"#{name}\""
+        @raw_connection.describe(quoted_name)
+      rescue OCIException => e
+        # fall back to SELECT which can handle synonyms to database links
+        super
+      end
+
+      # Return OCIError error code
+      def error_code(exception)
+        case exception
+        when OCIError
+          exception.code
+        else
+          nil
+        end
+      end
+
+      def typecast_result_value(value, get_lob_value)
+        case value
+        when Fixnum, Bignum
+          value
+        when String
+          value
+        when Float, BigDecimal
+          # return Fixnum or Bignum if value is integer (to avoid issues with _before_type_cast values for id attributes)
+          value == (v_to_i = value.to_i) ? v_to_i : value
+        when OraNumber
+          # change OraNumber value (returned in early versions of ruby-oci8 2.0.x) to BigDecimal
+          value == (v_to_i = value.to_i) ? v_to_i : BigDecimal.new(value.to_s)
+        when OCI8::LOB
+          if get_lob_value
+            data = value.read || ""     # if value.read returns nil, then we have an empty_clob() i.e. an empty string
+            # In Ruby 1.9.1 always change encoding to ASCII-8BIT for binaries
+            data.force_encoding('ASCII-8BIT') if data.respond_to?(:force_encoding) && value.is_a?(OCI8::BLOB)
+            data
+          else
+            value
+          end
+        # ruby-oci8 1.0 returns OraDate
+        # ruby-oci8 2.0 returns Time or DateTime
+        when OraDate, Time, DateTime
+          if OracleEnhancedAdapter.emulate_dates && date_without_time?(value)
+            value.to_date
+          else
+            create_time_with_default_timezone(value)
+          end
+        else
+          value
+        end
+      end
+
+      private
+
+      def date_without_time?(value)
+        case value
+        when OraDate
+          value.hour == 0 && value.minute == 0 && value.second == 0
+        else
+          value.hour == 0 && value.min == 0 && value.sec == 0
+        end
+      end
+      
+      def create_time_with_default_timezone(value)
+        year, month, day, hour, min, sec, usec = case value
+        when Time
+          [value.year, value.month, value.day, value.hour, value.min, value.sec, value.usec]
+        when OraDate
+          [value.year, value.month, value.day, value.hour, value.minute, value.second, 0]
+        else
+          [value.year, value.month, value.day, value.hour, value.min, value.sec, 0]
+        end
+        # code from Time.time_with_datetime_fallback
+        begin
+          Time.send(Base.default_timezone, year, month, day, hour, min, sec, usec)
+        rescue
+          offset = Base.default_timezone.to_sym == :local ? ::DateTime.local_offset : 0
+          ::DateTime.civil(year, month, day, hour, min, sec, offset)
+        end
+      end
+
+    end
+    
+    # The OracleEnhancedOCIFactory factors out the code necessary to connect and
+    # configure an Oracle/OCI connection.
+    class OracleEnhancedOCIFactory #:nodoc:
+      def self.new_connection(config)
+        # to_s needed if username, password or database is specified as number in database.yml file
+        username = config[:username] && config[:username].to_s
+        password = config[:password] && config[:password].to_s
+        database = config[:database] && config[:database].to_s
+        host, port = config[:host], config[:port]
+        privilege = config[:privilege] && config[:privilege].to_sym
+        async = config[:allow_concurrency]
+        prefetch_rows = config[:prefetch_rows] || 100
+        cursor_sharing = config[:cursor_sharing] || 'force'
+        # get session time_zone from configuration or from TZ environment variable
+        time_zone = config[:time_zone] || ENV['TZ']
+
+        # connection using host, port and database name
+        connection_string = if host || port
+          host ||= 'localhost'
+          host = "[#{host}]" if host =~ /^[^\[].*:/  # IPv6
+          port ||= 1521
+          "//#{host}:#{port}/#{database}"
+        # if no host is specified then assume that
+        # database parameter is TNS alias or TNS connection string
+        else
+          database
+        end
+
+        conn = OCI8.new username, password, connection_string, privilege
+        conn.autocommit = true
+        conn.non_blocking = true if async
+        conn.prefetch_rows = prefetch_rows
+        conn.exec "alter session set cursor_sharing = #{cursor_sharing}" rescue nil
+        conn.exec "alter session set time_zone = '#{time_zone}'" unless time_zone.blank?
+
+        # Initialize NLS parameters
+        OracleEnhancedAdapter::DEFAULT_NLS_PARAMETERS.each do |key, default_value|
+          value = config[key] || ENV[key.to_s.upcase] || default_value
+          if value
+            conn.exec "alter session set #{key} = '#{value}'"
+          end
+        end
+        conn
+      end
+    end
+    
+    
+  end
+end
+
+
+
+class OCI8 #:nodoc:
+
+  class Cursor #:nodoc:
+    if method_defined? :define_a_column
+      # This OCI8 patch is required with the ruby-oci8 1.0.x or lower.
+      # Set OCI8::BindType::Mapping[] to change the column type
+      # when using ruby-oci8 2.0.
+
+      alias :enhanced_define_a_column_pre_ar :define_a_column
+      def define_a_column(i)
+        case do_ocicall(@ctx) { @parms[i - 1].attrGet(OCI_ATTR_DATA_TYPE) }
+        when 8;   @stmt.defineByPos(i, String, 65535) # Read LONG values
+        when 187; @stmt.defineByPos(i, OraDate) # Read TIMESTAMP values
+        when 108
+          if @parms[i - 1].attrGet(OCI_ATTR_TYPE_NAME) == 'XMLTYPE'
+            @stmt.defineByPos(i, String, 65535)
+          else
+            raise 'unsupported datatype'
+          end
+        else enhanced_define_a_column_pre_ar i
+        end
+      end
+    end
+  end
+
+  if OCI8.public_method_defined?(:describe_table)
+    # ruby-oci8 2.0 or upper
+
+    def describe(name)
+      info = describe_table(name.to_s)
+      raise %Q{"DESC #{name}" failed} if info.nil?
+      [info.obj_schema, info.obj_name]
+    end
+  else
+    # ruby-oci8 1.0.x or lower
+
+    # missing constant from oci8 < 0.1.14
+    OCI_PTYPE_UNK = 0 unless defined?(OCI_PTYPE_UNK)
+
+    # Uses the describeAny OCI call to find the target owner and table_name
+    # indicated by +name+, parsing through synonynms as necessary. Returns
+    # an array of [owner, table_name].
+    def describe(name)
+      @desc ||= @@env.alloc(OCIDescribe)
+      @desc.attrSet(OCI_ATTR_DESC_PUBLIC, -1) if VERSION >= '0.1.14'
+      do_ocicall(@ctx) { @desc.describeAny(@svc, name.to_s, OCI_PTYPE_UNK) } rescue raise %Q{"DESC #{name}" failed; does it exist?}
+      info = @desc.attrGet(OCI_ATTR_PARAM)
+
+      case info.attrGet(OCI_ATTR_PTYPE)
+      when OCI_PTYPE_TABLE, OCI_PTYPE_VIEW
+        owner      = info.attrGet(OCI_ATTR_OBJ_SCHEMA)
+        table_name = info.attrGet(OCI_ATTR_OBJ_NAME)
+        [owner, table_name]
+      when OCI_PTYPE_SYN
+        schema = info.attrGet(OCI_ATTR_SCHEMA_NAME)
+        name   = info.attrGet(OCI_ATTR_NAME)
+        describe(schema + '.' + name)
+      else raise %Q{"DESC #{name}" failed; not a table or view.}
+      end
+    end
+  end
+
+end
+
+# The OCI8AutoRecover class enhances the OCI8 driver with auto-recover and
+# reset functionality. If a call to #exec fails, and autocommit is turned on
+# (ie., we're not in the middle of a longer transaction), it will
+# automatically reconnect and try again. If autocommit is turned off,
+# this would be dangerous (as the earlier part of the implied transaction
+# may have failed silently if the connection died) -- so instead the
+# connection is marked as dead, to be reconnected on it's next use.
+#:stopdoc:
+class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
+  attr_accessor :active #:nodoc:
+  alias :active? :active #:nodoc:
+
+  cattr_accessor :auto_retry
+  class << self
+    alias :auto_retry? :auto_retry #:nodoc:
+  end
+  @@auto_retry = false
+
+  def initialize(config, factory) #:nodoc:
+    @active = true
+    @config = config
+    @factory = factory
+    @connection  = @factory.new_connection @config
+    super @connection
+  end
+
+  # Checks connection, returns true if active. Note that ping actively
+  # checks the connection, while #active? simply returns the last
+  # known state.
+  def ping #:nodoc:
+    @connection.exec("select 1 from dual") { |r| nil }
+    @active = true
+  rescue
+    @active = false
+    raise
+  end
+
+  # Resets connection, by logging off and creating a new connection.
+  def reset! #:nodoc:
+    logoff rescue nil
+    begin
+      @connection = @factory.new_connection @config
+      __setobj__ @connection
+      @active = true
+    rescue
+      @active = false
+      raise
+    end
+  end
+
+  # ORA-00028: your session has been killed
+  # ORA-01012: not logged on
+  # ORA-03113: end-of-file on communication channel
+  # ORA-03114: not connected to ORACLE
+  # ORA-03135: connection lost contact
+  LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] #:nodoc:
+
+  # Adds auto-recovery functionality.
+  #
+  # See: http://www.jiubao.org/ruby-oci8/api.en.html#label-11
+  def exec(sql, *bindvars, &block) #:nodoc:
+    should_retry = self.class.auto_retry? && autocommit?
+
+    begin
+      @connection.exec(sql, *bindvars, &block)
+    rescue OCIException => e
+      raise unless e.is_a?(OCIError) && LOST_CONNECTION_ERROR_CODES.include?(e.code)
+      @active = false
+      raise unless should_retry
+      should_retry = false
+      reset! rescue nil
+      retry
+    end
+  end
+
+  # otherwise not working in Ruby 1.9.1
+  if RUBY_VERSION =~ /^1\.9/
+    def describe(name) #:nodoc:
+      @connection.describe(name)
+    end
+  end
+
+end
+#:startdoc:
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb
new file mode 100644 (file)
index 0000000..6c3c325
--- /dev/null
@@ -0,0 +1,260 @@
+# define accessors before requiring ruby-plsql as these accessors are used in clob writing callback and should be
+# available also if ruby-plsql could not be loaded
+ActiveRecord::Base.class_eval do
+  if respond_to? :class_attribute
+    class_attribute :custom_create_method, :custom_update_method, :custom_delete_method
+  elsif respond_to? :class_inheritable_accessor
+    class_inheritable_accessor :custom_create_method, :custom_update_method, :custom_delete_method
+  end
+end
+
+require 'active_support'
+
+module ActiveRecord #:nodoc:
+  module ConnectionAdapters #:nodoc:
+    module OracleEnhancedProcedures #:nodoc:
+
+      module ClassMethods
+        # Specify custom create method which should be used instead of Rails generated INSERT statement.
+        # Provided block should return ID of new record.
+        # Example:
+        #   set_create_method do
+        #     plsql.employees_pkg.create_employee(
+        #       :p_first_name => first_name,
+        #       :p_last_name => last_name,
+        #       :p_employee_id => nil
+        #     )[:p_employee_id]
+        #   end
+        def set_create_method(&block)
+          include_with_custom_methods
+          self.custom_create_method = block
+        end
+
+        # Specify custom update method which should be used instead of Rails generated UPDATE statement.
+        # Example:
+        #   set_update_method do
+        #     plsql.employees_pkg.update_employee(
+        #       :p_employee_id => id,
+        #       :p_first_name => first_name,
+        #       :p_last_name => last_name
+        #     )
+        #   end
+        def set_update_method(&block)
+          include_with_custom_methods
+          self.custom_update_method = block
+        end
+
+        # Specify custom delete method which should be used instead of Rails generated DELETE statement.
+        # Example:
+        #   set_delete_method do
+        #     plsql.employees_pkg.delete_employee(
+        #       :p_employee_id => id
+        #     )
+        #   end
+        def set_delete_method(&block)
+          include_with_custom_methods
+          self.custom_delete_method = block
+        end
+
+        if ActiveRecord::VERSION::MAJOR < 3
+          def create_method_name_before_custom_methods #:nodoc:
+            if private_method_defined?(:create_without_timestamps) && defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::STRING.to_f >= 2.3
+              :create_without_timestamps
+            elsif private_method_defined?(:create_without_callbacks)
+              :create_without_callbacks
+            else
+              :create
+            end
+          end
+
+          def update_method_name_before_custom_methods #:nodoc:
+            if private_method_defined?(:update_without_dirty)
+              :update_without_dirty
+            elsif private_method_defined?(:update_without_timestamps) && defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::STRING.to_f >= 2.3
+              :update_without_timestamps
+            elsif private_method_defined?(:update_without_callbacks)
+              :update_without_callbacks
+            else
+              :update
+            end
+          end
+
+          def destroy_method_name_before_custom_methods #:nodoc:
+            if public_method_defined?(:destroy_without_callbacks)
+              :destroy_without_callbacks
+            else
+              :destroy
+            end
+          end
+        end
+
+        private
+
+        def include_with_custom_methods
+          unless included_modules.include? InstanceMethods
+            include InstanceMethods
+          end
+        end
+      end
+
+      module InstanceMethods #:nodoc:
+        def self.included(base)
+          # alias methods just for ActiveRecord 2.x
+          # for ActiveRecord 3.0 will just redefine create, update, delete methods which call super
+          if ActiveRecord::VERSION::MAJOR < 3
+            base.instance_eval do
+              alias_method :create_without_custom_method, create_method_name_before_custom_methods
+              alias_method create_method_name_before_custom_methods, :create_with_custom_method
+              alias_method :update_without_custom_method, update_method_name_before_custom_methods
+              alias_method update_method_name_before_custom_methods, :update_with_custom_method
+              alias_method :destroy_without_custom_method, destroy_method_name_before_custom_methods
+              alias_method destroy_method_name_before_custom_methods, :destroy_with_custom_method
+              private :create, :update
+              public :destroy
+            end
+          end
+        end
+
+        if ActiveRecord::VERSION::MAJOR >= 3
+          def destroy #:nodoc:
+            # check if class has custom delete method
+            if self.class.custom_delete_method
+              # wrap destroy in transaction
+              with_transaction_returning_status do
+                # run before/after callbacks defined in model
+                _run_destroy_callbacks { destroy_using_custom_method }
+              end
+            else
+              super
+            end
+          end
+        end
+
+        private
+
+        # Creates a record with custom create method
+        # and returns its id.
+        if ActiveRecord::VERSION::MAJOR < 3
+          def create_with_custom_method
+            # check if class has custom create method
+            self.class.custom_create_method ? create_using_custom_method : create_without_custom_method
+          end
+        else # ActiveRecord 3.x
+          def create
+            # check if class has custom create method
+            if self.class.custom_create_method
+              set_timestamps_before_custom_create_method
+              # run before/after callbacks defined in model
+              _run_create_callbacks { create_using_custom_method }
+            else
+              super
+            end
+          end
+        end
+
+        def create_using_custom_method
+          self.class.connection.log_custom_method("custom create method", "#{self.class.name} Create") do
+            self.id = instance_eval(&self.class.custom_create_method)
+          end
+          @new_record = false
+          # Starting from ActiveRecord 3.0.3 @persisted is used instead of @new_record
+          @persisted = true
+          id
+        end
+
+        # Updates the associated record with custom update method
+        # Returns the number of affected rows.
+        if ActiveRecord::VERSION::MAJOR < 3
+          def update_with_custom_method(attribute_names = @attributes.keys)
+            # check if class has custom create method
+            self.class.custom_update_method ? update_using_custom_method(attribute_names) : update_without_custom_method(attribute_names)
+          end
+        else # ActiveRecord 3.x
+          def update(attribute_names = @attributes.keys)
+            # check if class has custom update method
+            if self.class.custom_update_method
+              set_timestamps_before_custom_update_method
+              # run before/after callbacks defined in model
+              _run_update_callbacks do
+                # update just dirty attributes
+                if partial_updates?
+                  # Serialized attributes should always be written in case they've been
+                  # changed in place.
+                  update_using_custom_method(changed | (attributes.keys & self.class.serialized_attributes.keys))
+                else
+                  update_using_custom_method(attribute_names)
+                end
+              end
+            else
+              super
+            end
+          end
+        end
+
+        def update_using_custom_method(attribute_names)
+          return 0 if attribute_names.empty?
+          self.class.connection.log_custom_method("custom update method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Update") do
+            instance_eval(&self.class.custom_update_method)
+          end
+          1
+        end
+
+        # Deletes the record in the database with custom delete method
+        # and freezes this instance to reflect that no changes should
+        # be made (since they can't be persisted).
+        if ActiveRecord::VERSION::MAJOR < 3
+          def destroy_with_custom_method
+            # check if class has custom delete method
+            self.class.custom_delete_method ? destroy_using_custom_method : destroy_without_custom_method
+          end
+        end
+
+        def destroy_using_custom_method
+          unless new_record? || @destroyed
+            self.class.connection.log_custom_method("custom delete method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Destroy") do
+              instance_eval(&self.class.custom_delete_method)
+            end
+          end
+
+          @destroyed = true
+          freeze
+        end
+
+        if ActiveRecord::VERSION::MAJOR >= 3
+          def set_timestamps_before_custom_create_method
+            if record_timestamps
+              current_time = current_time_from_proper_timezone
+
+              write_attribute('created_at', current_time) if respond_to?(:created_at) && created_at.nil?
+              write_attribute('created_on', current_time) if respond_to?(:created_on) && created_on.nil?
+
+              write_attribute('updated_at', current_time) if respond_to?(:updated_at) && updated_at.nil?
+              write_attribute('updated_on', current_time) if respond_to?(:updated_on) && updated_on.nil?
+            end
+          end
+
+          def set_timestamps_before_custom_update_method
+            if record_timestamps && (!partial_updates? || changed?)
+              current_time = current_time_from_proper_timezone
+
+              write_attribute('updated_at', current_time) if respond_to?(:updated_at)
+              write_attribute('updated_on', current_time) if respond_to?(:updated_on)
+            end
+          end
+        end
+
+      end
+
+    end
+  end
+end
+
+ActiveRecord::Base.class_eval do
+  extend ActiveRecord::ConnectionAdapters::OracleEnhancedProcedures::ClassMethods
+end
+
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+  # public alias to log method which could be used from other objects
+  alias_method :log_custom_method, :log
+  public :log_custom_method
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb
new file mode 100644 (file)
index 0000000..a2df729
--- /dev/null
@@ -0,0 +1,209 @@
+module ActiveRecord
+  module ConnectionAdapters
+    class OracleEnhancedForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
+    end
+
+    class OracleEnhancedSynonymDefinition < Struct.new(:name, :table_owner, :table_name, :db_link) #:nodoc:
+    end
+
+    class OracleEnhancedIndexDefinition < Struct.new(:table, :name, :unique, :type, :parameters, :statement_parameters,
+      :tablespace, :columns) #:nodoc:
+    end
+
+    module OracleEnhancedColumnDefinition
+       def self.included(base) #:nodoc:
+        base.class_eval do
+          alias_method_chain :to_sql, :virtual_columns
+          alias to_s :to_sql
+        end
+       end
+
+      def to_sql_with_virtual_columns
+        if type==:virtual
+          "#{base.quote_column_name(name)} AS (#{default})"
+        else
+          to_sql_without_virtual_columns
+        end
+      end
+
+      def lob?
+        ['CLOB', 'BLOB'].include?(sql_type)
+      end
+    end
+
+    module OracleEnhancedSchemaDefinitions #:nodoc:
+      def self.included(base)
+        base::TableDefinition.class_eval do
+          include OracleEnhancedTableDefinition
+        end
+
+        base::ColumnDefinition.class_eval do
+          include OracleEnhancedColumnDefinition
+        end
+        
+        # Available starting from ActiveRecord 2.1
+        base::Table.class_eval do
+          include OracleEnhancedTable
+        end if defined?(base::Table)
+      end
+    end
+  
+    module OracleEnhancedTableDefinition
+      class ForeignKey < Struct.new(:base, :to_table, :options) #:nodoc:
+        def to_sql
+          base.foreign_key_definition(to_table, options)
+        end
+        alias to_s :to_sql
+      end
+
+      def raw(name, options={})
+        column(name, :raw, options)
+      end
+
+      def self.included(base) #:nodoc:
+        base.class_eval do
+          alias_method_chain :references, :foreign_keys
+          alias_method_chain :to_sql, :foreign_keys
+
+          def virtual(* args)
+            options = args.extract_options!
+            column_names = args
+            column_names.each { |name| column(name, :virtual, options) }
+          end
+
+        end
+      end
+    
+      # Adds a :foreign_key option to TableDefinition.references.
+      # If :foreign_key is true, a foreign key constraint is added to the table.
+      # You can also specify a hash, which is passed as foreign key options.
+      # 
+      # ===== Examples
+      # ====== Add goat_id column and a foreign key to the goats table.
+      #  t.references(:goat, :foreign_key => true)
+      # ====== Add goat_id column and a cascading foreign key to the goats table.
+      #  t.references(:goat, :foreign_key => {:dependent => :delete})
+      # 
+      # Note: No foreign key is created if :polymorphic => true is used.
+      # Note: If no name is specified, the database driver creates one for you!
+      def references_with_foreign_keys(*args)
+        options = args.extract_options!
+        fk_options = options.delete(:foreign_key)
+
+        if fk_options && !options[:polymorphic]
+          fk_options = {} if fk_options == true
+          args.each { |to_table| foreign_key(to_table, fk_options) }
+        end
+
+        references_without_foreign_keys(*(args << options))
+      end
+  
+      # Defines a foreign key for the table. +to_table+ can be a single Symbol, or
+      # an Array of Symbols. See SchemaStatements#add_foreign_key
+      #
+      # ===== Examples
+      # ====== Creating a simple foreign key
+      #  t.foreign_key(:people)
+      # ====== Defining the column
+      #  t.foreign_key(:people, :column => :sender_id)
+      # ====== Creating a named foreign key
+      #  t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
+      # ====== Defining the column of the +to_table+.
+      #  t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
+      def foreign_key(to_table, options = {})
+        if @base.respond_to?(:supports_foreign_keys?) && @base.supports_foreign_keys?
+          to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
+          foreign_keys << ForeignKey.new(@base, to_table, options)
+        else
+          raise ArgumentError, "this ActiveRecord adapter is not supporting foreign_key definition"
+        end
+      end
+    
+      def to_sql_with_foreign_keys #:nodoc:
+        sql = to_sql_without_foreign_keys
+        sql << ', ' << (foreign_keys * ', ') unless foreign_keys.blank?
+        sql
+      end
+
+      def lob_columns
+        columns.select(&:lob?)
+      end
+    
+      private
+        def foreign_keys
+          @foreign_keys ||= []
+        end
+    end
+
+    module OracleEnhancedTable
+      def self.included(base) #:nodoc:
+        base.class_eval do
+          alias_method_chain :references, :foreign_keys
+        end
+      end
+
+      # Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
+      # an Array of Symbols. See SchemaStatements#add_foreign_key
+      #
+      # ===== Examples
+      # ====== Creating a simple foreign key
+      #  t.foreign_key(:people)
+      # ====== Defining the column
+      #  t.foreign_key(:people, :column => :sender_id)
+      # ====== Creating a named foreign key
+      #  t.foreign_key(:people, :column => :sender_id, :name => 'sender_foreign_key')
+      # ====== Defining the column of the +to_table+.
+      #  t.foreign_key(:people, :column => :sender_id, :primary_key => :person_id)
+      def foreign_key(to_table, options = {})
+        if @base.respond_to?(:supports_foreign_keys?) && @base.supports_foreign_keys?
+          to_table = to_table.to_s.pluralize if ActiveRecord::Base.pluralize_table_names
+          @base.add_foreign_key(@table_name, to_table, options)
+        else
+          raise ArgumentError, "this ActiveRecord adapter is not supporting foreign_key definition"
+        end
+      end
+  
+      # Remove the given foreign key from the table.
+      #
+      # ===== Examples
+      # ====== Remove the suppliers_company_id_fk in the suppliers table.
+      #   t.remove_foreign_key :companies
+      # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
+      #   remove_foreign_key :column => :branch_id
+      # ====== Remove the foreign key named party_foreign_key in the accounts table.
+      #   remove_index :name => :party_foreign_key
+      def remove_foreign_key(options = {})
+        @base.remove_foreign_key(@table_name, options)
+      end
+    
+      # Adds a :foreign_key option to TableDefinition.references.
+      # If :foreign_key is true, a foreign key constraint is added to the table.
+      # You can also specify a hash, which is passed as foreign key options.
+      # 
+      # ===== Examples
+      # ====== Add goat_id column and a foreign key to the goats table.
+      #  t.references(:goat, :foreign_key => true)
+      # ====== Add goat_id column and a cascading foreign key to the goats table.
+      #  t.references(:goat, :foreign_key => {:dependent => :delete})
+      # 
+      # Note: No foreign key is created if :polymorphic => true is used.
+      def references_with_foreign_keys(*args)
+        options = args.extract_options!
+        polymorphic = options[:polymorphic]
+        fk_options = options.delete(:foreign_key)
+
+        references_without_foreign_keys(*(args << options))
+        # references_without_foreign_keys adds {:type => :integer}
+        args.extract_options!
+        if fk_options && !polymorphic
+          fk_options = {} if fk_options == true
+          args.each { |to_table| foreign_key(to_table, fk_options) }
+        end
+      end
+    end
+  end
+end
+
+ActiveRecord::ConnectionAdapters.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaDefinitions
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb
new file mode 100644 (file)
index 0000000..fff2454
--- /dev/null
@@ -0,0 +1,252 @@
+module ActiveRecord #:nodoc:
+  module ConnectionAdapters #:nodoc:
+    module OracleEnhancedSchemaDumper #:nodoc:
+
+      def self.included(base) #:nodoc:
+        base.class_eval do
+          private
+          alias_method_chain :tables, :oracle_enhanced
+          alias_method_chain :indexes, :oracle_enhanced
+        end
+      end
+
+      private
+
+      def ignore_table?(table)
+        [ActiveRecord::Migrator.proper_table_name('schema_migrations'), ignore_tables].flatten.any? do |ignored|
+          case ignored
+          when String; table == ignored
+          when Regexp; table =~ ignored
+          else
+            raise StandardError, 'ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values.'
+          end
+        end
+      end
+
+      def tables_with_oracle_enhanced(stream)
+        return tables_without_oracle_enhanced(stream) unless @connection.respond_to?(:materialized_views)
+        # do not include materialized views in schema dump - they should be created separately after schema creation
+        sorted_tables = (@connection.tables - @connection.materialized_views).sort
+        sorted_tables.each do |tbl|
+          # add table prefix or suffix for schema_migrations
+          next if ignore_table? tbl
+          # change table name inspect method
+          tbl.extend TableInspect
+          oracle_enhanced_table(tbl, stream)
+          # add primary key trigger if table has it
+          primary_key_trigger(tbl, stream)
+        end
+        # following table definitions
+        # add foreign keys if table has them
+        sorted_tables.each do |tbl|
+          next if ignore_table? tbl
+          foreign_keys(tbl, stream)
+        end
+
+        # add synonyms in local schema
+        synonyms(stream)
+      end
+
+      def primary_key_trigger(table_name, stream)
+        if @connection.respond_to?(:has_primary_key_trigger?) && @connection.has_primary_key_trigger?(table_name)
+          pk, pk_seq = @connection.pk_and_sequence_for(table_name)
+          stream.print "  add_primary_key_trigger #{table_name.inspect}"
+          stream.print ", :primary_key => \"#{pk}\"" if pk != 'id'
+          stream.print "\n\n"
+        end
+      end
+
+      def foreign_keys(table_name, stream)
+        if @connection.respond_to?(:foreign_keys) && (foreign_keys = @connection.foreign_keys(table_name)).any?
+          add_foreign_key_statements = foreign_keys.map do |foreign_key|
+            statement_parts = [ ('add_foreign_key ' + foreign_key.from_table.inspect) ]
+            statement_parts << foreign_key.to_table.inspect
+            
+            if foreign_key.options[:columns].size == 1
+              column = foreign_key.options[:columns].first
+              if column != "#{foreign_key.to_table.singularize}_id"
+                statement_parts << (':column => ' + column.inspect)
+              end
+              
+              if foreign_key.options[:references].first != 'id'
+                statement_parts << (':primary_key => ' + foreign_key.options[:primary_key].inspect)
+              end
+            else
+              statement_parts << (':columns => ' + foreign_key.options[:columns].inspect)
+            end
+
+            statement_parts << (':name => ' + foreign_key.options[:name].inspect)
+            
+            unless foreign_key.options[:dependent].blank?
+              statement_parts << (':dependent => ' + foreign_key.options[:dependent].inspect)
+            end
+
+            '  ' + statement_parts.join(', ')
+          end
+
+          stream.puts add_foreign_key_statements.sort.join("\n")
+          stream.puts
+        end
+      end
+
+      def synonyms(stream)
+        if @connection.respond_to?(:synonyms)
+          syns = @connection.synonyms
+          syns.each do |syn|
+                       next if ignore_table? syn.name
+            table_name = syn.table_name
+            table_name = "#{syn.table_owner}.#{table_name}" if syn.table_owner
+            table_name = "#{table_name}@#{syn.db_link}" if syn.db_link
+            stream.print "  add_synonym #{syn.name.inspect}, #{table_name.inspect}, :force => true"
+            stream.puts
+          end
+          stream.puts unless syns.empty?
+        end
+      end
+
+      def indexes_with_oracle_enhanced(table, stream)
+        # return original method if not using oracle_enhanced
+        if (rails_env = defined?(Rails.env) ? Rails.env : (defined?(RAILS_ENV) ? RAILS_ENV : nil)) &&
+              ActiveRecord::Base.configurations[rails_env] &&
+              ActiveRecord::Base.configurations[rails_env]['adapter'] != 'oracle_enhanced'
+          return indexes_without_oracle_enhanced(table, stream)
+        end
+        if (indexes = @connection.indexes(table)).any?
+          add_index_statements = indexes.map do |index|
+            case index.type
+            when nil
+              # use table.inspect as it will remove prefix and suffix
+              statement_parts = [ ('add_index ' + table.inspect) ]
+              statement_parts << index.columns.inspect
+              statement_parts << (':name => ' + index.name.inspect)
+              statement_parts << ':unique => true' if index.unique
+              statement_parts << ':tablespace => ' + index.tablespace.inspect if index.tablespace
+            when 'CTXSYS.CONTEXT'
+              if index.statement_parameters
+                statement_parts = [ ('add_context_index ' + table.inspect) ]
+                statement_parts << index.statement_parameters
+              else
+                statement_parts = [ ('add_context_index ' + table.inspect) ]
+                statement_parts << index.columns.inspect
+                statement_parts << (':name => ' + index.name.inspect)
+              end
+            else
+              # unrecognized index type
+              statement_parts = ["# unrecognized index #{index.name.inspect} with type #{index.type.inspect}"]
+            end
+            '  ' + statement_parts.join(', ')
+          end
+
+          stream.puts add_index_statements.sort.join("\n")
+          stream.puts
+        end
+      end
+
+      def oracle_enhanced_table(table, stream)
+        columns = @connection.columns(table)
+        begin
+          tbl = StringIO.new
+
+          # first dump primary key column
+          if @connection.respond_to?(:pk_and_sequence_for)
+            pk, pk_seq = @connection.pk_and_sequence_for(table)
+          elsif @connection.respond_to?(:primary_key)
+            pk = @connection.primary_key(table)
+          end
+          
+          tbl.print "  create_table #{table.inspect}"
+          
+          # addition to make temporary option work
+          tbl.print ", :temporary => true" if @connection.temporary_table?(table)
+          
+          if columns.detect { |c| c.name == pk }
+            if pk != 'id'
+              tbl.print %Q(, :primary_key => "#{pk}")
+            end
+          else
+            tbl.print ", :id => false"
+          end
+          tbl.print ", :force => true"
+          tbl.puts " do |t|"
+
+          # then dump all non-primary key columns
+          column_specs = columns.map do |column|
+            raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
+            next if column.name == pk
+            spec = {}
+            spec[:name]      = column.name.inspect
+            spec[:type]      = column.virtual? ? 'virtual' : column.type.to_s
+            spec[:limit]     = column.limit.inspect if column.limit != @types[column.type][:limit] && column.type != :decimal
+            spec[:precision] = column.precision.inspect if !column.precision.nil?
+            spec[:scale]     = column.scale.inspect if !column.scale.nil?
+            spec[:null]      = 'false' if !column.null
+            spec[:default]   = column.virtual_column_data_default if column.virtual?
+            spec[:default] ||= default_string(column.default) if column.has_default?
+            (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
+            spec
+          end.compact
+
+          # find all migration keys used in this table
+          keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map(&:keys).flatten
+
+          # figure out the lengths for each column based on above keys
+          lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max }
+
+          # the string we're going to sprintf our values against, with standardized column widths
+          format_string = lengths.map{ |len| "%-#{len}s" }
+
+          # find the max length for the 'type' column, which is special
+          type_length = column_specs.map{ |column| column[:type].length }.max
+
+          # add column type definition to our format string
+          format_string.unshift "    t.%-#{type_length}s "
+
+          format_string *= ''
+
+          column_specs.each do |colspec|
+            values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
+            values.unshift colspec[:type]
+            tbl.print((format_string % values).gsub(/,\s*$/, ''))
+            tbl.puts
+          end
+
+          tbl.puts "  end"
+          tbl.puts
+          
+          indexes(table, tbl)
+
+          tbl.rewind
+          stream.print tbl.read
+        rescue => e
+          stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
+          stream.puts "#   #{e.message}"
+          stream.puts
+        end
+        
+        stream
+      end
+      
+      
+      # remove table name prefix and suffix when doing #inspect (which is used in tables method)
+      module TableInspect #:nodoc:
+        def inspect
+          remove_prefix_and_suffix(self)
+        end
+        
+        private
+        def remove_prefix_and_suffix(table_name)
+          if table_name =~ /\A#{ActiveRecord::Base.table_name_prefix.to_s.gsub('$','\$')}(.*)#{ActiveRecord::Base.table_name_suffix.to_s.gsub('$','\$')}\Z/
+            "\"#{$1}\""
+          else
+            "\"#{table_name}\""
+          end
+        end
+      end
+
+    end
+  end
+end
+
+ActiveRecord::SchemaDumper.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaDumper
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb
new file mode 100644 (file)
index 0000000..ca9040f
--- /dev/null
@@ -0,0 +1,367 @@
+require 'digest/sha1'
+
+module ActiveRecord
+  module ConnectionAdapters
+    module OracleEnhancedSchemaStatements
+      # SCHEMA STATEMENTS ========================================
+      #
+      # see: abstract/schema_statements.rb
+
+      # Additional options for +create_table+ method in migration files.
+      #
+      # You can specify individual starting value in table creation migration file, e.g.:
+      #
+      #   create_table :users, :sequence_start_value => 100 do |t|
+      #     # ...
+      #   end
+      #
+      # You can also specify other sequence definition additional parameters, e.g.:
+      #
+      #   create_table :users, :sequence_start_value => “100 NOCACHE INCREMENT BY 10” do |t|
+      #     # ...
+      #   end
+      #
+      # Create primary key trigger (so that you can skip primary key value in INSERT statement).
+      # By default trigger name will be "table_name_pkt", you can override the name with 
+      # :trigger_name option (but it is not recommended to override it as then this trigger will
+      # not be detected by ActiveRecord model and it will still do prefetching of sequence value).
+      # Example:
+      # 
+      #   create_table :users, :primary_key_trigger => true do |t|
+      #     # ...
+      #   end
+      #
+      # It is possible to add table and column comments in table creation migration files:
+      #
+      #   create_table :employees, :comment => “Employees and contractors” do |t|
+      #     t.string      :first_name, :comment => “Given name”
+      #     t.string      :last_name, :comment => “Surname”
+      #   end
+      
+      def create_table(name, options = {}, &block)
+        create_sequence = options[:id] != false
+        column_comments = {}
+        
+        table_definition = TableDefinition.new(self)
+        table_definition.primary_key(options[:primary_key] || Base.get_primary_key(name.to_s.singularize)) unless options[:id] == false
+
+        # store that primary key was defined in create_table block
+        unless create_sequence
+          class << table_definition
+            attr_accessor :create_sequence
+            def primary_key(*args)
+              self.create_sequence = true
+              super(*args)
+            end
+          end
+        end
+
+        # store column comments
+        class << table_definition
+          attr_accessor :column_comments
+          def column(name, type, options = {})
+            if options[:comment]
+              self.column_comments ||= {}
+              self.column_comments[name] = options[:comment]
+            end
+            super(name, type, options)
+          end
+        end
+
+        result = block.call(table_definition) if block
+        create_sequence = create_sequence || table_definition.create_sequence
+        column_comments = table_definition.column_comments if table_definition.column_comments
+        tablespace = tablespace_for(:table, options[:tablespace])
+
+        if options[:force] && table_exists?(name)
+          drop_table(name, options)
+        end
+
+        create_sql = "CREATE#{' GLOBAL TEMPORARY' if options[:temporary]} TABLE "
+        create_sql << quote_table_name(name)
+        create_sql << " (#{table_definition.to_sql})"
+        unless options[:temporary]
+          create_sql << " ORGANIZATION #{options[:organization]}" if options[:organization]
+          create_sql << tablespace
+          table_definition.lob_columns.each{|cd| create_sql << tablespace_for(cd.sql_type.downcase.to_sym, nil, name, cd.name)}
+        end
+        create_sql << " #{options[:options]}"
+        execute create_sql
+        
+        create_sequence_and_trigger(name, options) if create_sequence
+        
+        add_table_comment name, options[:comment]
+        column_comments.each do |column_name, comment|
+          add_comment name, column_name, comment
+        end
+        
+      end
+
+      def rename_table(name, new_name) #:nodoc:
+        execute "RENAME #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
+        execute "RENAME #{quote_table_name("#{name}_seq")} TO #{quote_table_name("#{new_name}_seq")}" rescue nil
+      end
+
+      def drop_table(name, options = {}) #:nodoc:
+        super(name)
+        seq_name = options[:sequence_name] || default_sequence_name(name)
+        execute "DROP SEQUENCE #{quote_table_name(seq_name)}" rescue nil
+      ensure
+        clear_table_columns_cache(name)
+      end
+
+      # clear cached indexes when adding new index
+      def add_index(table_name, column_name, options = {}) #:nodoc:
+        column_names = Array(column_name)
+        index_name   = index_name(table_name, :column => column_names)
+
+        if Hash === options # legacy support, since this param was a string
+          index_type = options[:unique] ? "UNIQUE" : ""
+          index_name = options[:name].to_s if options.key?(:name)
+          tablespace = tablespace_for(:index, options[:tablespace])
+        else
+          index_type = options
+        end
+
+        if index_name.to_s.length > index_name_length
+          raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters"
+        end
+        if index_name_exists?(table_name, index_name, false)
+          raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
+        end
+        quoted_column_names = column_names.map { |e| quote_column_name_or_expression(e) }.join(", ")
+
+        execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{options[:options]}"
+      ensure
+        self.all_schema_indexes = nil
+      end
+
+      # Remove the given index from the table.
+      # Gives warning if index does not exist
+      def remove_index(table_name, options = {}) #:nodoc:
+        index_name = index_name(table_name, options)
+        unless index_name_exists?(table_name, index_name, true)
+          raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
+        end
+        remove_index!(table_name, index_name)
+      end
+
+      # clear cached indexes when removing index
+      def remove_index!(table_name, index_name) #:nodoc:
+        execute "DROP INDEX #{quote_column_name(index_name)}"
+      ensure
+        self.all_schema_indexes = nil
+      end
+
+      # returned shortened index name if default is too large
+      def index_name(table_name, options) #:nodoc:
+        default_name = super(table_name, options).to_s
+        # sometimes options can be String or Array with column names
+        options = {} unless options.is_a?(Hash)
+        identifier_max_length = options[:identifier_max_length] || index_name_length
+        return default_name if default_name.length <= identifier_max_length
+        
+        # remove 'index', 'on' and 'and' keywords
+        shortened_name = "i_#{table_name}_#{Array(options[:column]) * '_'}"
+        
+        # leave just first three letters from each word
+        if shortened_name.length > identifier_max_length
+          shortened_name = shortened_name.split('_').map{|w| w[0,3]}.join('_')
+        end
+        # generate unique name using hash function
+        if shortened_name.length > identifier_max_length
+          shortened_name = 'i'+Digest::SHA1.hexdigest(default_name)[0,identifier_max_length-1]
+        end
+        @logger.warn "#{adapter_name} shortened default index name #{default_name} to #{shortened_name}" if @logger
+        shortened_name
+      end
+
+      # Verify the existence of an index with a given name.
+      #
+      # The default argument is returned if the underlying implementation does not define the indexes method,
+      # as there's no way to determine the correct answer in that case.
+      #
+      # Will always query database and not index cache.
+      def index_name_exists?(table_name, index_name, default)
+        (owner, table_name, db_link) = @connection.describe(table_name)
+        result = select_value(<<-SQL)
+          SELECT 1 FROM all_indexes#{db_link} i
+          WHERE i.owner = '#{owner}'
+             AND i.table_owner = '#{owner}'
+             AND i.table_name = '#{table_name}'
+             AND i.index_name = '#{index_name.to_s.upcase}'
+        SQL
+        result == 1
+      end
+
+      def rename_index(table_name, index_name, new_index_name) #:nodoc:
+        unless index_name_exists?(table_name, index_name, true)
+          raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
+        end
+        execute "ALTER INDEX #{quote_column_name(index_name)} rename to #{quote_column_name(new_index_name)}"
+      ensure
+        self.all_schema_indexes = nil
+      end
+
+      def add_column(table_name, column_name, type, options = {}) #:nodoc:
+        add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
+        add_column_options!(add_column_sql, options.merge(:type=>type, :column_name=>column_name, :table_name=>table_name))
+        add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name)
+        execute(add_column_sql)
+      ensure
+        clear_table_columns_cache(table_name)
+      end
+
+      def change_column_default(table_name, column_name, default) #:nodoc:
+        execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
+      ensure
+        clear_table_columns_cache(table_name)
+      end
+
+      def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
+        column = column_for(table_name, column_name)
+
+        unless null || default.nil?
+          execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
+        end
+
+        change_column table_name, column_name, column.sql_type, :null => null
+      end
+
+      def change_column(table_name, column_name, type, options = {}) #:nodoc:
+        column = column_for(table_name, column_name)
+
+        # remove :null option if its value is the same as current column definition
+        # otherwise Oracle will raise error
+        if options.has_key?(:null) && options[:null] == column.null
+          options[:null] = nil
+        end
+
+        change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
+        add_column_options!(change_column_sql, options.merge(:type=>type, :column_name=>column_name, :table_name=>table_name))
+        change_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, options[:table_name], options[:column_name])
+        execute(change_column_sql)
+      ensure
+        clear_table_columns_cache(table_name)
+      end
+
+      def rename_column(table_name, column_name, new_column_name) #:nodoc:
+        execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}"
+      ensure
+        clear_table_columns_cache(table_name)
+      end
+
+      def remove_column(table_name, column_name) #:nodoc:
+        execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
+      ensure
+        clear_table_columns_cache(table_name)
+      end
+
+      def add_comment(table_name, column_name, comment) #:nodoc:
+        return if comment.blank?
+        execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{column_name} IS '#{comment}'"
+      end
+
+      def add_table_comment(table_name, comment) #:nodoc:
+        return if comment.blank?
+        execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS '#{comment}'"
+      end
+
+      def table_comment(table_name) #:nodoc:
+        (owner, table_name, db_link) = @connection.describe(table_name)
+        select_value <<-SQL
+          SELECT comments FROM all_tab_comments#{db_link}
+          WHERE owner = '#{owner}'
+            AND table_name = '#{table_name}'
+        SQL
+      end
+
+      def column_comment(table_name, column_name) #:nodoc:
+        (owner, table_name, db_link) = @connection.describe(table_name)
+        select_value <<-SQL
+          SELECT comments FROM all_col_comments#{db_link}
+          WHERE owner = '#{owner}'
+            AND table_name = '#{table_name}'
+            AND column_name = '#{column_name.upcase}'
+        SQL
+      end
+
+      # Maps logical Rails types to Oracle-specific data types.
+      def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
+        # Ignore options for :text and :binary columns
+        return super(type, nil, nil, nil) if ['text', 'binary'].include?(type.to_s)
+
+        super
+      end
+
+      def tablespace(table_name)
+        select_value <<-SQL
+          SELECT tablespace_name
+          FROM user_tables
+          WHERE table_name='#{table_name.to_s.upcase}'
+        SQL
+      end
+
+      private
+
+      def tablespace_for(obj_type, tablespace_option, table_name=nil, column_name=nil)
+        tablespace_sql = ''
+        if tablespace = (tablespace_option || default_tablespace_for(obj_type))
+          tablespace_sql << if [:blob, :clob].include?(obj_type.to_sym)
+           " LOB (#{column_name}) STORE AS #{column_name.to_s[0..10]}_#{table_name.to_s[0..14]}_ls (TABLESPACE #{tablespace})"
+          else
+           " TABLESPACE #{tablespace}"
+          end
+        end
+        tablespace_sql
+      end
+
+      def default_tablespace_for(type)
+        (default_tablespaces[type] || default_tablespaces[native_database_types[type][:name]]) rescue nil
+      end
+
+
+      def column_for(table_name, column_name)
+        unless column = columns(table_name).find { |c| c.name == column_name.to_s }
+          raise "No such column: #{table_name}.#{column_name}"
+        end
+        column
+      end
+
+      def create_sequence_and_trigger(table_name, options)
+        seq_name = options[:sequence_name] || default_sequence_name(table_name)
+        seq_start_value = options[:sequence_start_value] || default_sequence_start_value
+        execute "CREATE SEQUENCE #{quote_table_name(seq_name)} START WITH #{seq_start_value}"
+
+        create_primary_key_trigger(table_name, options) if options[:primary_key_trigger]
+      end
+      
+      def create_primary_key_trigger(table_name, options)
+        seq_name = options[:sequence_name] || default_sequence_name(table_name)
+        trigger_name = options[:trigger_name] || default_trigger_name(table_name)
+        primary_key = options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)
+        execute compress_lines(<<-SQL)
+          CREATE OR REPLACE TRIGGER #{quote_table_name(trigger_name)}
+          BEFORE INSERT ON #{quote_table_name(table_name)} FOR EACH ROW
+          BEGIN
+            IF inserting THEN
+              IF :new.#{quote_column_name(primary_key)} IS NULL THEN
+                SELECT #{quote_table_name(seq_name)}.NEXTVAL INTO :new.#{quote_column_name(primary_key)} FROM dual;
+              END IF;
+            END IF;
+          END;
+        SQL
+      end
+
+      def default_trigger_name(table_name)
+        # truncate table name if necessary to fit in max length of identifier
+        "#{table_name.to_s[0,table_name_length-4]}_pkt"
+      end
+
+    end
+  end
+end
+
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaStatements
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_schema_statements_ext.rb
new file mode 100644 (file)
index 0000000..39b7b18
--- /dev/null
@@ -0,0 +1,256 @@
+require 'digest/sha1'
+
+module ActiveRecord
+  module ConnectionAdapters
+    module OracleEnhancedSchemaStatementsExt
+      def supports_foreign_keys? #:nodoc:
+        true
+      end
+
+      # Create primary key trigger (so that you can skip primary key value in INSERT statement).
+      # By default trigger name will be "table_name_pkt", you can override the name with 
+      # :trigger_name option (but it is not recommended to override it as then this trigger will
+      # not be detected by ActiveRecord model and it will still do prefetching of sequence value).
+      #
+      #   add_primary_key_trigger :users
+      #
+      # You can also create primary key trigger using +create_table+ with :primary_key_trigger
+      # option:
+      #
+      #   create_table :users, :primary_key_trigger => true do |t|
+      #     # ...
+      #   end
+      #
+      def add_primary_key_trigger(table_name, options={})
+        # call the same private method that is used for create_table :primary_key_trigger => true
+        create_primary_key_trigger(table_name, options)
+      end
+
+      # Adds a new foreign key to the +from_table+, referencing the primary key of +to_table+
+      # (syntax and partial implementation taken from http://github.com/matthuhiggins/foreigner)
+      #
+      # The foreign key will be named after the from and to tables unless you pass
+      # <tt>:name</tt> as an option.
+      #
+      # === Examples
+      # ==== Creating a foreign key
+      #  add_foreign_key(:comments, :posts)
+      # generates
+      #  ALTER TABLE comments ADD CONSTRAINT
+      #     comments_post_id_fk FOREIGN KEY (post_id) REFERENCES posts (id)
+      # 
+      # ==== Creating a named foreign key
+      #  add_foreign_key(:comments, :posts, :name => 'comments_belongs_to_posts')
+      # generates
+      #  ALTER TABLE comments ADD CONSTRAINT
+      #     comments_belongs_to_posts FOREIGN KEY (post_id) REFERENCES posts (id)
+      # 
+      # ==== Creating a cascading foreign_key on a custom column
+      #  add_foreign_key(:people, :people, :column => 'best_friend_id', :dependent => :nullify)
+      # generates
+      #  ALTER TABLE people ADD CONSTRAINT
+      #     people_best_friend_id_fk FOREIGN KEY (best_friend_id) REFERENCES people (id)
+      #     ON DELETE SET NULL
+      # 
+      # ==== Creating a composite foreign key
+      #  add_foreign_key(:comments, :posts, :columns => ['post_id', 'author_id'], :name => 'comments_post_fk')
+      # generates
+      #  ALTER TABLE comments ADD CONSTRAINT
+      #     comments_post_fk FOREIGN KEY (post_id, author_id) REFERENCES posts (post_id, author_id)
+      #       
+      # === Supported options
+      # [:column]
+      #   Specify the column name on the from_table that references the to_table. By default this is guessed
+      #   to be the singular name of the to_table with "_id" suffixed. So a to_table of :posts will use "post_id"
+      #   as the default <tt>:column</tt>.
+      # [:columns]
+      #   An array of column names when defining composite foreign keys. An alias of <tt>:column</tt> provided for improved readability.
+      # [:primary_key]
+      #   Specify the column name on the to_table that is referenced by this foreign key. By default this is
+      #   assumed to be "id". Ignored when defining composite foreign keys.
+      # [:name]
+      #   Specify the name of the foreign key constraint. This defaults to use from_table and foreign key column.
+      # [:dependent]
+      #   If set to <tt>:delete</tt>, the associated records in from_table are deleted when records in to_table table are deleted.
+      #   If set to <tt>:nullify</tt>, the foreign key column is set to +NULL+.
+      def add_foreign_key(from_table, to_table, options = {})
+        columns = options[:column] || options[:columns] || "#{to_table.to_s.singularize}_id"
+        constraint_name = foreign_key_constraint_name(from_table, columns, options)
+        sql = "ALTER TABLE #{quote_table_name(from_table)} ADD CONSTRAINT #{quote_column_name(constraint_name)} "
+        sql << foreign_key_definition(to_table, options)
+        execute sql
+      end
+
+      def foreign_key_definition(to_table, options = {}) #:nodoc:
+        columns = Array(options[:column] || options[:columns])
+        
+        if columns.size > 1
+          # composite foreign key
+          columns_sql = columns.map {|c| quote_column_name(c)}.join(',')
+          references = options[:references] || columns
+          references_sql = references.map {|c| quote_column_name(c)}.join(',')
+        else
+          columns_sql = quote_column_name(columns.first || "#{to_table.to_s.singularize}_id")
+          references = options[:references] ? options[:references].first : nil
+          references_sql = quote_column_name(options[:primary_key] || references || "id")
+        end
+        
+        sql = "FOREIGN KEY (#{columns_sql}) REFERENCES #{quote_table_name(to_table)}(#{references_sql})"
+        
+        case options[:dependent]
+        when :nullify
+          sql << " ON DELETE SET NULL"
+        when :delete
+          sql << " ON DELETE CASCADE"
+        end
+        sql
+      end
+
+      # Remove the given foreign key from the table.
+      #
+      # ===== Examples
+      # ====== Remove the suppliers_company_id_fk in the suppliers table.
+      #   remove_foreign_key :suppliers, :companies
+      # ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
+      #   remove_foreign_key :accounts, :column => :branch_id
+      # ====== Remove the foreign key named party_foreign_key in the accounts table.
+      #   remove_foreign_key :accounts, :name => :party_foreign_key
+      def remove_foreign_key(from_table, options)
+        if Hash === options
+          constraint_name = foreign_key_constraint_name(from_table, options[:column], options)
+        else
+          constraint_name = foreign_key_constraint_name(from_table, "#{options.to_s.singularize}_id")
+        end
+        execute "ALTER TABLE #{quote_table_name(from_table)} DROP CONSTRAINT #{quote_column_name(constraint_name)}"
+      end
+
+      private
+
+      def foreign_key_constraint_name(table_name, columns, options = {})
+        columns = Array(columns)
+        constraint_name = original_name = options[:name] || "#{table_name}_#{columns.join('_')}_fk"
+        
+        return constraint_name if constraint_name.length <= OracleEnhancedAdapter::IDENTIFIER_MAX_LENGTH
+        
+        # leave just first three letters from each word
+        constraint_name = constraint_name.split('_').map{|w| w[0,3]}.join('_')
+        # generate unique name using hash function
+        if constraint_name.length > OracleEnhancedAdapter::IDENTIFIER_MAX_LENGTH
+          constraint_name = 'c'+Digest::SHA1.hexdigest(original_name)[0,OracleEnhancedAdapter::IDENTIFIER_MAX_LENGTH-1]
+        end
+        @logger.warn "#{adapter_name} shortened foreign key constraint name #{original_name} to #{constraint_name}" if @logger
+        constraint_name
+      end
+      
+
+      public
+
+      # get table foreign keys for schema dump
+      def foreign_keys(table_name) #:nodoc:
+        (owner, desc_table_name, db_link) = @connection.describe(table_name)
+
+        fk_info = select_all(<<-SQL, 'Foreign Keys')
+          SELECT r.table_name to_table
+                ,rc.column_name references_column
+                ,cc.column_name
+                ,c.constraint_name name
+                ,c.delete_rule
+            FROM user_constraints#{db_link} c, user_cons_columns#{db_link} cc,
+                 user_constraints#{db_link} r, user_cons_columns#{db_link} rc
+           WHERE c.owner = '#{owner}'
+             AND c.table_name = '#{desc_table_name}'
+             AND c.constraint_type = 'R'
+             AND cc.owner = c.owner
+             AND cc.constraint_name = c.constraint_name
+             AND r.constraint_name = c.r_constraint_name
+             AND r.owner = c.owner
+             AND rc.owner = r.owner
+             AND rc.constraint_name = r.constraint_name
+             AND rc.position = cc.position
+          ORDER BY name, to_table, column_name, references_column
+        SQL
+
+        fks = {}
+
+        fk_info.map do |row|
+          name = oracle_downcase(row['name'])
+          fks[name] ||= { :columns => [], :to_table => oracle_downcase(row['to_table']), :references => [] }
+          fks[name][:columns] << oracle_downcase(row['column_name'])
+          fks[name][:references] << oracle_downcase(row['references_column'])
+          case row['delete_rule']
+          when 'CASCADE'
+            fks[name][:dependent] = :delete
+          when 'SET NULL'
+            fks[name][:dependent] = :nullify
+          end
+        end
+        
+        fks.map do |k, v|
+          options = {:name => k, :columns => v[:columns], :references => v[:references], :dependent => v[:dependent]}
+          OracleEnhancedForeignKeyDefinition.new(table_name, v[:to_table], options)
+        end
+      end
+
+      # REFERENTIAL INTEGRITY ====================================
+
+      def disable_referential_integrity(&block) #:nodoc:
+        sql_constraints = <<-SQL
+        SELECT constraint_name, owner, table_name
+          FROM user_constraints
+          WHERE constraint_type = 'R'
+          AND status = 'ENABLED'
+        SQL
+        old_constraints = select_all(sql_constraints)
+        begin
+          old_constraints.each do |constraint|
+            execute "ALTER TABLE #{constraint["table_name"]} DISABLE CONSTRAINT #{constraint["constraint_name"]}"
+          end
+          yield
+        ensure
+          old_constraints.each do |constraint|
+            execute "ALTER TABLE #{constraint["table_name"]} ENABLE CONSTRAINT #{constraint["constraint_name"]}"
+          end
+        end
+      end
+
+      # Add synonym to existing table or view or sequence. Can be used to create local synonym to
+      # remote table in other schema or in other database
+      # Examples:
+      #
+      #   add_synonym :posts, "blog.posts"
+      #   add_synonym :posts_seq, "blog.posts_seq"
+      #   add_synonym :employees, "hr.employees@dblink", :force => true
+      #
+      def add_synonym(name, table_name, options = {})
+        sql = "CREATE"
+        if options[:force] == true
+          sql << " OR REPLACE"
+        end
+        sql << " SYNONYM #{quote_table_name(name)} FOR #{quote_table_name(table_name)}"
+        execute sql
+      end
+
+      # Remove existing synonym to table or view or sequence
+      # Example:
+      #
+      #   remove_synonym :posts, "blog.posts"
+      #
+      def remove_synonym(name)
+        execute "DROP SYNONYM #{quote_table_name(name)}"
+      end
+
+      # get synonyms for schema dump
+      def synonyms #:nodoc:
+        select_all("SELECT synonym_name, table_owner, table_name, db_link FROM user_synonyms").collect do |row|
+          OracleEnhancedSynonymDefinition.new(oracle_downcase(row['synonym_name']),
+            oracle_downcase(row['table_owner']), oracle_downcase(row['table_name']), oracle_downcase(row['db_link']))
+        end
+      end
+
+    end
+  end
+end
+
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaStatementsExt
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb
new file mode 100644 (file)
index 0000000..f4507e7
--- /dev/null
@@ -0,0 +1,290 @@
+module ActiveRecord #:nodoc:
+  module ConnectionAdapters #:nodoc:
+    module OracleEnhancedStructureDump #:nodoc:
+
+      # Statements separator used in structure dump to allow loading of structure dump also with SQL*Plus
+      STATEMENT_TOKEN = "\n\n/\n\n"
+
+      def structure_dump #:nodoc:
+        structure = select_values("SELECT sequence_name FROM user_sequences ORDER BY 1").map do |seq|
+          "CREATE SEQUENCE \"#{seq}\""
+        end
+        select_values("SELECT table_name FROM all_tables t
+                    WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N'
+                      AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
+                      AND NOT EXISTS (SELECT mvl.log_table FROM all_mview_logs mvl WHERE mvl.log_owner = t.owner AND mvl.log_table = t.table_name)
+                    ORDER BY 1").each do |table_name|
+          virtual_columns = virtual_columns_for(table_name)
+          ddl = "CREATE#{ ' GLOBAL TEMPORARY' if temporary_table?(table_name)} TABLE \"#{table_name}\" (\n"
+          cols = select_all(%Q{
+            SELECT column_name, data_type, data_length, char_used, char_length, data_precision, data_scale, data_default, nullable
+            FROM user_tab_columns
+            WHERE table_name = '#{table_name}'
+            ORDER BY column_id
+          }).map do |row|
+            if(v = virtual_columns.find {|col| col['column_name'] == row['column_name']})
+              structure_dump_virtual_column(row, v['data_default'])
+            else
+              structure_dump_column(row)
+            end
+          end
+          ddl << cols.join(",\n ")
+          ddl << structure_dump_primary_key(table_name)
+          ddl << "\n)"
+          structure << ddl
+          structure << structure_dump_indexes(table_name)
+          structure << structure_dump_unique_keys(table_name)
+        end
+
+        join_with_statement_token(structure) << structure_dump_fk_constraints
+      end
+
+      def structure_dump_column(column) #:nodoc:
+        col = "\"#{column['column_name']}\" #{column['data_type']}"
+        if column['data_type'] =='NUMBER' and !column['data_precision'].nil?
+          col << "(#{column['data_precision'].to_i}"
+          col << ",#{column['data_scale'].to_i}" if !column['data_scale'].nil?
+          col << ')'
+        elsif column['data_type'].include?('CHAR')
+          length = column['char_used'] == 'C' ? column['char_length'].to_i : column['data_length'].to_i
+          col <<  "(#{length})"
+        end
+        col << " DEFAULT #{column['data_default']}" if !column['data_default'].nil?
+        col << ' NOT NULL' if column['nullable'] == 'N'
+        col
+      end
+
+      def structure_dump_virtual_column(column, data_default) #:nodoc:
+        data_default = data_default.gsub(/"/, '')
+        col = "\"#{column['column_name']}\" #{column['data_type']}"
+        if column['data_type'] =='NUMBER' and !column['data_precision'].nil?
+          col << "(#{column['data_precision'].to_i}"
+          col << ",#{column['data_scale'].to_i}" if !column['data_scale'].nil?
+          col << ')'
+        elsif column['data_type'].include?('CHAR')
+          length = column['char_used'] == 'C' ? column['char_length'].to_i : column['data_length'].to_i
+          col <<  "(#{length})"
+        end
+        col << " GENERATED ALWAYS AS (#{data_default}) VIRTUAL"
+      end
+
+      def structure_dump_primary_key(table) #:nodoc:
+        opts = {:name => '', :cols => []}
+        pks = select_all(<<-SQL, "Primary Keys") 
+          SELECT a.constraint_name, a.column_name, a.position
+            FROM user_cons_columns a
+            JOIN user_constraints c
+              ON a.constraint_name = c.constraint_name
+           WHERE c.table_name = '#{table.upcase}'
+             AND c.constraint_type = 'P'
+             AND c.owner = SYS_CONTEXT('userenv', 'session_user')
+        SQL
+        pks.each do |row|
+          opts[:name] = row['constraint_name']
+          opts[:cols][row['position']-1] = row['column_name']
+        end
+        opts[:cols].length > 0 ? ",\n CONSTRAINT #{opts[:name]} PRIMARY KEY (#{opts[:cols].join(',')})" : ''
+      end
+
+      def structure_dump_unique_keys(table) #:nodoc:
+        keys = {}
+        uks = select_all(<<-SQL, "Primary Keys") 
+          SELECT a.constraint_name, a.column_name, a.position
+            FROM user_cons_columns a
+            JOIN user_constraints c
+              ON a.constraint_name = c.constraint_name
+           WHERE c.table_name = '#{table.upcase}'
+             AND c.constraint_type = 'U'
+             AND c.owner = SYS_CONTEXT('userenv', 'session_user')
+        SQL
+        uks.each do |uk|
+          keys[uk['constraint_name']] ||= []
+          keys[uk['constraint_name']][uk['position']-1] = uk['column_name']
+        end
+        keys.map do |k,v|
+          "ALTER TABLE #{table.upcase} ADD CONSTRAINT #{k} UNIQUE (#{v.join(',')})"
+        end
+      end
+
+      def structure_dump_indexes(table_name) #:nodoc:
+        indexes(table_name).map do |options|
+          column_names = options[:columns]
+          options = {:name => options[:name], :unique => options[:unique]}
+          index_name   = index_name(table_name, :column => column_names)
+          if Hash === options # legacy support, since this param was a string
+            index_type = options[:unique] ? "UNIQUE" : ""
+            index_name = options[:name] || index_name
+          else
+            index_type = options
+          end
+          quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
+          "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
+        end
+      end
+
+      def structure_dump_fk_constraints #:nodoc:
+        fks = select_all("SELECT table_name FROM all_tables WHERE owner = SYS_CONTEXT('userenv', 'session_user') ORDER BY 1").map do |table|
+          if respond_to?(:foreign_keys) && (foreign_keys = foreign_keys(table["table_name"])).any?
+            foreign_keys.map do |fk|
+              sql = "ALTER TABLE #{quote_table_name(fk.from_table)} ADD CONSTRAINT #{quote_column_name(fk.options[:name])} "
+              sql << "#{foreign_key_definition(fk.to_table, fk.options)}"
+            end
+          end
+        end.flatten.compact
+        join_with_statement_token(fks)
+      end
+
+      def dump_schema_information #:nodoc:
+        sm_table = ActiveRecord::Migrator.schema_migrations_table_name
+        migrated = select_values("SELECT version FROM #{sm_table}")
+        join_with_statement_token(migrated.map{|v| "INSERT INTO #{sm_table} (version) VALUES ('#{v}')" })
+      end
+
+      # Extract all stored procedures, packages, synonyms and views.
+      def structure_dump_db_stored_code #:nodoc:
+        structure = []
+        select_all("SELECT DISTINCT name, type
+                     FROM all_source
+                    WHERE type IN ('PROCEDURE', 'PACKAGE', 'PACKAGE BODY', 'FUNCTION', 'TRIGGER', 'TYPE')
+                      AND name NOT LIKE 'BIN$%'
+                      AND owner = SYS_CONTEXT('userenv', 'session_user') ORDER BY type").each do |source|
+          ddl = "CREATE OR REPLACE   \n"
+          lines = select_all(%Q{
+                  SELECT text
+                    FROM all_source
+                   WHERE name = '#{source['name']}'
+                     AND type = '#{source['type']}'
+                     AND owner = SYS_CONTEXT('userenv', 'session_user')
+                   ORDER BY line
+                }).map do |row|
+            ddl << row['text']
+          end
+          ddl << ";" unless ddl.strip[-1,1] == ";"
+          structure << ddl
+        end
+
+        # export views 
+        select_all("SELECT view_name, text FROM user_views").each do |view|
+          structure << "CREATE OR REPLACE VIEW #{view['view_name']} AS\n #{view['text']}"
+        end
+
+        # export synonyms
+        select_all("SELECT owner, synonym_name, table_name, table_owner
+                      FROM all_synonyms
+                     WHERE owner = SYS_CONTEXT('userenv', 'session_user') ").each do |synonym|
+          structure << "CREATE OR REPLACE #{synonym['owner'] == 'PUBLIC' ? 'PUBLIC' : '' } SYNONYM #{synonym['synonym_name']}"
+          structure << " FOR #{synonym['table_owner']}.#{synonym['table_name']}"
+        end
+
+        join_with_statement_token(structure)
+      end
+
+      def structure_drop #:nodoc:
+        statements = select_values("SELECT sequence_name FROM user_sequences ORDER BY 1").map do |seq|
+          "DROP SEQUENCE \"#{seq}\""
+        end
+        select_values("SELECT table_name from all_tables t
+                    WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N'
+                      AND NOT EXISTS (SELECT mv.mview_name FROM all_mviews mv WHERE mv.owner = t.owner AND mv.mview_name = t.table_name)
+                      AND NOT EXISTS (SELECT mvl.log_table FROM all_mview_logs mvl WHERE mvl.log_owner = t.owner AND mvl.log_table = t.table_name)
+                    ORDER BY 1").each do |table|
+          statements << "DROP TABLE \"#{table}\" CASCADE CONSTRAINTS"
+        end
+        join_with_statement_token(statements)
+      end
+
+      def temp_table_drop #:nodoc:
+        join_with_statement_token(select_values(
+                  "SELECT table_name FROM all_tables
+                    WHERE owner = SYS_CONTEXT('userenv', 'session_user') AND secondary = 'N' AND temporary = 'Y' ORDER BY 1").map do |table|
+          "DROP TABLE \"#{table}\" CASCADE CONSTRAINTS"
+        end)
+      end
+
+      def full_drop(preserve_tables=false) #:nodoc:
+        s = preserve_tables ? [] : [structure_drop]
+        s << temp_table_drop if preserve_tables
+        s << drop_sql_for_feature("view")
+        s << drop_sql_for_feature("materialized view")
+        s << drop_sql_for_feature("synonym")
+        s << drop_sql_for_feature("type")
+        s << drop_sql_for_object("package")
+        s << drop_sql_for_object("function")
+        s << drop_sql_for_object("procedure")
+        s.join
+      end
+
+      def add_column_options!(sql, options) #:nodoc:
+        type = options[:type] || ((column = options[:column]) && column.type)
+        type = type && type.to_sym
+        # handle case of defaults for CLOB columns, which would otherwise get "quoted" incorrectly
+        if options_include_default?(options)
+          if type == :text
+            sql << " DEFAULT #{quote(options[:default])}"
+          else
+            # from abstract adapter
+            sql << " DEFAULT #{quote(options[:default], options[:column])}"
+          end
+        end
+        # must explicitly add NULL or NOT NULL to allow change_column to work on migrations
+        if options[:null] == false
+          sql << " NOT NULL"
+        elsif options[:null] == true
+          sql << " NULL" unless type == :primary_key
+        end
+      end
+
+      def execute_structure_dump(string)
+        string.split(STATEMENT_TOKEN).each do |ddl|
+          ddl.chop! if ddl.last == ";"
+          execute(ddl) unless ddl.blank?
+        end
+      end
+
+      private
+
+      # virtual columns are an 11g feature.  This returns [] if feature is not 
+      # present or none are found.
+      # return [{'column_name' => 'FOOS', 'data_default' => '...'}, ...]
+      def virtual_columns_for(table)
+        begin
+          select_all <<-SQL
+            SELECT column_name, data_default
+              FROM user_tab_cols
+             WHERE virtual_column = 'YES'
+               AND table_name = '#{table.upcase}'
+          SQL
+        # feature not supported previous to 11g
+        rescue ActiveRecord::StatementInvalid => e
+          []
+        end
+      end
+
+      def drop_sql_for_feature(type)
+        short_type = type == 'materialized view' ? 'mview' : type
+        join_with_statement_token(
+        select_values("SELECT #{short_type}_name FROM user_#{short_type.tableize}").map do |name|
+          "DROP #{type.upcase} \"#{name}\""
+        end)
+      end
+
+      def drop_sql_for_object(type)
+        join_with_statement_token(
+        select_values("SELECT object_name FROM user_objects WHERE object_type = '#{type.upcase}'").map do |name|
+          "DROP #{type.upcase} \"#{name}\""
+        end)
+      end
+
+      def join_with_statement_token(array)
+        string = array.join(STATEMENT_TOKEN)
+        string << STATEMENT_TOKEN unless string.blank?
+        string
+      end
+
+    end
+  end
+end
+
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
+  include ActiveRecord::ConnectionAdapters::OracleEnhancedStructureDump
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb
new file mode 100644 (file)
index 0000000..2b16cf6
--- /dev/null
@@ -0,0 +1,17 @@
+# Used just for Rails 2.x
+# In Rails 3.x rake tasks are loaded using railtie
+if ActiveRecord::VERSION::MAJOR == 2
+
+  if defined?(Rake.application) && Rake.application &&
+      ActiveRecord::Base.configurations[defined?(Rails.env) ? Rails.env : RAILS_ENV]['adapter'] == 'oracle_enhanced'
+    oracle_enhanced_rakefile = File.dirname(__FILE__) + "/oracle_enhanced.rake"
+    if Rake.application.lookup("environment")
+      # rails tasks already defined; load the override tasks now
+      load oracle_enhanced_rakefile
+    else
+      # rails tasks not loaded yet; load as an import
+      Rake.application.add_import(oracle_enhanced_rakefile)
+    end
+  end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_version.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/active_record/connection_adapters/oracle_enhanced_version.rb
new file mode 100644 (file)
index 0000000..6439ce7
--- /dev/null
@@ -0,0 +1 @@
+ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter::VERSION = File.read(File.dirname(__FILE__)+'/../../../VERSION').chomp
diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/activerecord-oracle_enhanced-adapter.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/activerecord-oracle_enhanced-adapter-1.4.0/lib/activerecord-oracle_enhanced-adapter.rb
new file mode 100644 (file)
index 0000000..69e13b5
--- /dev/null
@@ -0,0 +1,25 @@
+# define railtie which will be executed in Rails 3
+if defined?(::Rails::Railtie)
+
+  module ActiveRecord
+    module ConnectionAdapters
+      class OracleEnhancedRailtie < ::Rails::Railtie
+        rake_tasks do
+          load 'active_record/connection_adapters/oracle_enhanced.rake'
+        end
+
+        ActiveSupport.on_load(:active_record) do
+          require 'active_record/connection_adapters/oracle_enhanced_adapter'
+
+          # Cache column descriptions between requests in test and production environments
+          if Rails.env.test? || Rails.env.production?
+            ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
+          end
+
+        end
+
+      end
+    end
+  end
+
+end
\ No newline at end of file