From fc3d5f350739c74350f2d8779cec18f646b9b65d Mon Sep 17 00:00:00 2001 From: simonbrandhof Date: Mon, 14 Nov 2011 22:36:08 +0100 Subject: [PATCH] SONAR-2975 refactor the activerecord configuration --- .../java/org/sonar/persistence/Database.java | 2 + .../sonar/persistence/DefaultDatabase.java | 61 +++++++++------ .../persistence/DefaultDatabaseTest.java | 74 ++++++++++++++----- .../sonar/persistence/InMemoryDatabase.java | 4 + .../java/org/sonar/server/ui/JRubyFacade.java | 6 +- .../main/webapp/WEB-INF/app/models/server.rb | 2 +- .../main/webapp/WEB-INF/config/database.yml | 24 ++---- .../main/webapp/WEB-INF/config/environment.rb | 4 +- .../webapp/WEB-INF/lib/database_version.rb | 2 +- 9 files changed, 114 insertions(+), 65 deletions(-) diff --git a/sonar-core/src/main/java/org/sonar/persistence/Database.java b/sonar-core/src/main/java/org/sonar/persistence/Database.java index 4153c56d805..9fd31c7b652 100644 --- a/sonar-core/src/main/java/org/sonar/persistence/Database.java +++ b/sonar-core/src/main/java/org/sonar/persistence/Database.java @@ -42,5 +42,7 @@ public interface Database { */ Dialect getDialect(); + String getSchema(); + Properties getHibernateProperties(); } diff --git a/sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java b/sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java index d4dd8da80b0..c0bc4e6b2e6 100644 --- a/sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java +++ b/sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java @@ -28,10 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; -import org.sonar.jpa.dialect.Dialect; -import org.sonar.jpa.dialect.DialectRepository; -import org.sonar.jpa.dialect.Oracle; -import org.sonar.jpa.dialect.PostgreSql; +import org.sonar.jpa.dialect.*; import org.sonar.jpa.session.CustomHibernateConnectionProvider; import javax.sql.DataSource; @@ -50,6 +47,7 @@ public class DefaultDatabase implements Database { private Settings settings; private BasicDataSource datasource; private Dialect dialect; + private String schema; public DefaultDatabase(Settings settings) { this.settings = settings; @@ -61,7 +59,8 @@ public class DefaultDatabase implements Database { Properties properties = getProperties(); dialect = initDialect(properties); - datasource = initDatasource(properties, dialect); + schema = initSchema(properties, dialect); + datasource = initDatasource(properties, dialect, schema); return this; } catch (Exception e) { @@ -69,18 +68,29 @@ public class DefaultDatabase implements Database { } } - BasicDataSource initDatasource(Properties properties, Dialect dialect) throws Exception { - LOG.info("Create JDBC datasource"); - BasicDataSource result = (BasicDataSource) BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties)); - result.setConnectionInitSqls(getConnectionInitStatements(properties, dialect)); + static Dialect initDialect(Properties properties) { + Dialect result = DialectRepository.find(properties.getProperty("sonar.jdbc.dialect"), properties.getProperty("sonar.jdbc.url")); + if (result != null && Derby.ID.equals(result.getId())) { + LoggerFactory.getLogger(DefaultDatabase.class).warn("Derby database should be used for evaluation purpose only"); + } return result; } - Dialect initDialect(Properties properties) { - Dialect result = DialectRepository.find(properties.getProperty("sonar.jdbc.dialect"), properties.getProperty("sonar.jdbc.url")); - if (result != null && "derby".equals(result.getId())) { - LoggerFactory.getLogger(getClass()).warn("Derby database should be used for evaluation purpose only"); + static String initSchema(Properties properties, Dialect dialect) { + String result = null; + if (PostgreSql.ID.equals(dialect.getId())) { + result = getSchemaPropertyValue(properties, "sonar.jdbc.postgreSearchPath"); + + } else if (Oracle.ID.equals(dialect.getId())) { + result = getSchemaPropertyValue(properties, "sonar.hibernate.default_schema"); } + return StringUtils.isNotBlank(result) ? result : null; + } + + static BasicDataSource initDatasource(Properties properties, Dialect dialect, String schema) throws Exception { + LOG.info("Create JDBC datasource"); + BasicDataSource result = (BasicDataSource) BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties)); + result.setConnectionInitSqls(getConnectionInitStatements(dialect, schema)); return result; } @@ -107,6 +117,10 @@ public class DefaultDatabase implements Database { return dialect; } + public final String getSchema() { + return schema; + } + public Properties getHibernateProperties() { Properties props = new Properties(); @@ -118,6 +132,10 @@ public class DefaultDatabase implements Database { props.put("hibernate.generate_statistics", settings.getBoolean(DatabaseProperties.PROP_HIBERNATE_GENERATE_STATISTICS)); props.put("hibernate.hbm2ddl.auto", "validate"); props.put(Environment.CONNECTION_PROVIDER, CustomHibernateConnectionProvider.class.getName()); + + if (schema!=null) { + props.put("hibernate.default_schema", schema); + } return props; } @@ -161,23 +179,20 @@ public class DefaultDatabase implements Database { return result; } - static List getConnectionInitStatements(Properties properties, Dialect dialect) { + static List getConnectionInitStatements(Dialect dialect, String schema) { List result = Lists.newArrayList(); - if (PostgreSql.ID.equals(dialect.getId())) { - String searchPath = getSchema(properties, "sonar.jdbc.postgreSearchPath"); - if (StringUtils.isNotBlank(searchPath)) { - result.add("SET SEARCH_PATH TO " + searchPath); - } - } else if (Oracle.ID.equals(dialect.getId())) { - String schema = getSchema(properties, "sonar.hibernate.default_schema"); - if (StringUtils.isNotBlank(schema)) { + if (StringUtils.isNotBlank(schema)) { + if (PostgreSql.ID.equals(dialect.getId())) { + result.add("SET SEARCH_PATH TO " + schema); + + } else if (Oracle.ID.equals(dialect.getId())) { result.add("ALTER SESSION SET CURRENT SCHEMA = " + schema); } } return result; } - static String getSchema(Properties props, String deprecatedKey) { + static String getSchemaPropertyValue(Properties props, String deprecatedKey) { String value = props.getProperty("sonar.jdbc.schema"); if (StringUtils.isBlank(value) && deprecatedKey != null) { value = props.getProperty(deprecatedKey); diff --git a/sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java b/sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java index 45238a9bb8a..8bd4c9fe48d 100644 --- a/sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java +++ b/sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java @@ -23,6 +23,7 @@ import org.apache.commons.dbcp.BasicDataSource; import org.hamcrest.core.Is; import org.junit.Test; import org.sonar.api.config.Settings; +import org.sonar.jpa.dialect.MySql; import org.sonar.jpa.dialect.Oracle; import org.sonar.jpa.dialect.PostgreSql; @@ -30,6 +31,7 @@ import java.sql.SQLException; import java.util.List; import java.util.Properties; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; public class DefaultDatabaseTest { @@ -117,10 +119,7 @@ public class DefaultDatabaseTest { */ @Test public void shouldChangePostgreSearchPath() { - Properties props = new Properties(); - props.setProperty("sonar.jdbc.postgreSearchPath", "my_schema"); - - List statements = DefaultDatabase.getConnectionInitStatements(props, new PostgreSql()); + List statements = DefaultDatabase.getConnectionInitStatements(new PostgreSql(), "my_schema"); assertThat(statements.size(), Is.is(1)); assertThat(statements.get(0), Is.is("SET SEARCH_PATH TO my_schema")); @@ -128,7 +127,7 @@ public class DefaultDatabaseTest { @Test public void shouldNotChangePostgreSearchPathByDefault() { - List statements = DefaultDatabase.getConnectionInitStatements(new Properties(), new PostgreSql()); + List statements = DefaultDatabase.getConnectionInitStatements(new PostgreSql(), null); assertThat(statements.size(), Is.is(0)); } @@ -138,10 +137,7 @@ public class DefaultDatabaseTest { */ @Test public void shouldAlterOracleSession() { - Properties props = new Properties(); - props.setProperty("sonar.hibernate.default_schema", "my_schema"); - - List statements = DefaultDatabase.getConnectionInitStatements(props, new Oracle()); + List statements = DefaultDatabase.getConnectionInitStatements(new Oracle(), "my_schema"); assertThat(statements.size(), Is.is(1)); assertThat(statements.get(0), Is.is("ALTER SESSION SET CURRENT SCHEMA = my_schema")); @@ -149,30 +145,72 @@ public class DefaultDatabaseTest { @Test public void shouldNotAlterOracleSessionByDefault() { - List statements = DefaultDatabase.getConnectionInitStatements(new Properties(), new Oracle()); + List statements = DefaultDatabase.getConnectionInitStatements(new Oracle(), null); assertThat(statements.size(), Is.is(0)); } @Test - public void shouldSupportGenericSchemaPropertyForPostgreSQL() { + public void shouldInitPostgresqlSchema() { Properties props = new Properties(); props.setProperty("sonar.jdbc.schema", "my_schema"); - List statements = DefaultDatabase.getConnectionInitStatements(props, new PostgreSql()); + String schema = DefaultDatabase.initSchema(props, new PostgreSql()); - assertThat(statements.size(), Is.is(1)); - assertThat(statements.get(0), Is.is("SET SEARCH_PATH TO my_schema")); + assertThat(schema, Is.is("my_schema")); + } + + @Test + public void shouldInitPostgresqlSchemaWithDeprecatedProperty() { + Properties props = new Properties(); + props.setProperty("sonar.jdbc.postgreSearchPath", "my_schema"); + + String schema = DefaultDatabase.initSchema(props, new PostgreSql()); + + assertThat(schema, Is.is("my_schema")); } @Test - public void shouldSupportGenericSchemaPropertyForOracle() { + public void shouldNotInitPostgresqlSchemaByDefault() { + String schema = DefaultDatabase.initSchema(new Properties(), new PostgreSql()); + + assertThat(schema, nullValue()); + } + + @Test + public void shouldInitOracleSchema() { Properties props = new Properties(); props.setProperty("sonar.jdbc.schema", "my_schema"); - List statements = DefaultDatabase.getConnectionInitStatements(props, new Oracle()); + String schema = DefaultDatabase.initSchema(props, new Oracle()); - assertThat(statements.size(), Is.is(1)); - assertThat(statements.get(0), Is.is("ALTER SESSION SET CURRENT SCHEMA = my_schema")); + assertThat(schema, Is.is("my_schema")); + } + + @Test + public void shouldInitOracleSchemaWithDeprecatedProperty() { + Properties props = new Properties(); + props.setProperty("sonar.hibernate.default_schema", "my_schema"); + + String schema = DefaultDatabase.initSchema(props, new Oracle()); + + assertThat(schema, Is.is("my_schema")); + } + + @Test + public void shouldNotInitOracleSchemaByDefault() { + String schema = DefaultDatabase.initSchema(new Properties(), new Oracle()); + + assertThat(schema, nullValue()); + } + + @Test + public void shouldNotSchemaOnOtherDatabases() { + Properties props = new Properties(); + props.setProperty("sonar.jdbc.schema", "my_schema"); + + String schema = DefaultDatabase.initSchema(props, new MySql()); + + assertThat(schema, nullValue()); } } diff --git a/sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java b/sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java index 0a145afaaa6..f499b6a83d9 100644 --- a/sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java +++ b/sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java @@ -149,6 +149,10 @@ public class InMemoryDatabase implements Database { return new Derby(); } + public String getSchema() { + return null; + } + public Properties getHibernateProperties() { Properties properties = new Properties(); properties.put("hibernate.hbm2ddl.auto", "validate"); diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 0b80ed0cb5e..e4f9095cf4e 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -173,9 +173,9 @@ public final class JRubyFacade { public Collection getLanguages() { return getContainer().getComponentsByType(Language.class); } - - public Dialect getDialect() { - return getContainer().getComponentByType(Database.class).getDialect(); + + public Database getDatabase() { + return getContainer().getComponentByType(Database.class); } public boolean createDatabase() { diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb index 6ca38cb5fce..da8a5188e3c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/server.rb @@ -67,7 +67,7 @@ class Server add_property(sonar_info, 'Database Login') {sonar_property('sonar.jdbc.username')} add_property(sonar_info, 'Database Driver') {"#{jdbc_metadata.getDriverName()} #{jdbc_metadata.getDriverVersion()}"} add_property(sonar_info, 'Database Driver Class') {sonar_property('sonar.jdbc.driverClassName')} - add_property(sonar_info, 'Database Dialect (Hibernate)') {"#{Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getId()} (#{Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getHibernateDialectClass().getName()})"} + add_property(sonar_info, 'Database Dialect (Hibernate)') {"#{Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getId()} (#{Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getHibernateDialectClass().getName()})"} add_property(sonar_info, 'Database Validation Query') {sonar_property('sonar.jdbc.validationQuery')} add_property(sonar_info, 'Hibernate Default Schema') {sonar_property('sonar.hibernate.default_schema')} add_property(sonar_info, 'External User Authentication') {sonar_property(org.sonar.api.CoreProperties.CORE_AUTHENTICATOR_CLASS)} diff --git a/sonar-server/src/main/webapp/WEB-INF/config/database.yml b/sonar-server/src/main/webapp/WEB-INF/config/database.yml index fe16fdbd96e..38d382a903f 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/database.yml +++ b/sonar-server/src/main/webapp/WEB-INF/config/database.yml @@ -1,28 +1,18 @@ base: &base - adapter: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordJdbcAdapter() %> + adapter: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getActiveRecordJdbcAdapter() %> 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') %> - dialect: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordDialectCode() %> + dialect: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getActiveRecordDialectCode() %> driver: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.driverClassName') %> pool: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.maxActive') || 10 %> - # PostgreSQL -<% - search_path = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.jdbc.postgreSearchPath') - if search_path -%> - schema_search_path: <%= search_path %> -<% end %> + # postgreSQL + schema_search_path: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getSchema() %> + # Oracle -<% - schema = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getConfigurationValue('sonar.hibernate.default_schema') - if schema -%> - schema: <%= schema %> -<% - end -%> + schema: <%= ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getSchema() %> + development: <<: *base diff --git a/sonar-server/src/main/webapp/WEB-INF/config/environment.rb b/sonar-server/src/main/webapp/WEB-INF/config/environment.rb index ed28def4eae..5ee8f927a3b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/environment.rb +++ b/sonar-server/src/main/webapp/WEB-INF/config/environment.rb @@ -55,7 +55,7 @@ end class ActiveRecord::Migration def self.alter_to_big_primary_key(tablename) - dialect = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordDialectCode() + dialect = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getActiveRecordDialectCode() case dialect when "postgre" execute "ALTER TABLE #{tablename} ALTER COLUMN id TYPE bigint" @@ -74,7 +74,7 @@ class ActiveRecord::Migration end def self.alter_to_big_integer(tablename, columnname, indexname=nil) - dialect = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordDialectCode() + dialect = ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getActiveRecordDialectCode() case dialect when "sqlserver" execute "DROP INDEX #{indexname} on #{tablename}" if indexname diff --git a/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb b/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb index ee7f89f331a..5bf7e0761b6 100644 --- a/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb +++ b/sonar-server/src/main/webapp/WEB-INF/lib/database_version.rb @@ -101,7 +101,7 @@ class DatabaseVersion end def self.dialect - ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDialect().getActiveRecordDialectCode() + ::Java::OrgSonarServerUi::JRubyFacade.getInstance().getDatabase().getDialect().getActiveRecordDialectCode() end def self.use_structure_dump? -- 2.39.5