aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-application/src/main/assembly/conf/sonar.properties16
-rw-r--r--sonar-core/src/main/java/org/sonar/persistence/Database.java5
-rw-r--r--sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java49
-rw-r--r--sonar-core/src/main/java/org/sonar/persistence/MyBatis.java9
-rw-r--r--sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-mssql.xml4
-rw-r--r--sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-oracle.xml4
-rw-r--r--sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper.xml4
-rw-r--r--sonar-core/src/main/resources/org/sonar/persistence/model/RuleMapper.xml4
-rw-r--r--sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java67
-rw-r--r--sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java4
10 files changed, 115 insertions, 51 deletions
diff --git a/sonar-application/src/main/assembly/conf/sonar.properties b/sonar-application/src/main/assembly/conf/sonar.properties
index d9735de8cf3..560fab5c1a4 100644
--- a/sonar-application/src/main/assembly/conf/sonar.properties
+++ b/sonar-application/src/main/assembly/conf/sonar.properties
@@ -57,6 +57,7 @@ sonar.jdbc.driverClassName: org.apache.derby.jdbc.ClientDriver
# uncomment to accept connections from remote hosts. Ba default it only accepts localhost connections.
#sonar.derby.drda.host: 0.0.0.0
+
#----- MySQL 5.x/6.x
# Comment the embedded database and uncomment the following properties to use MySQL. The validation query is optional.
#sonar.jdbc.url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8
@@ -76,10 +77,11 @@ sonar.jdbc.driverClassName: org.apache.derby.jdbc.ClientDriver
#sonar.jdbc.driverClassName: oracle.jdbc.OracleDriver
#sonar.jdbc.validationQuery: select 1 from dual
-# 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
+# Uncomment the following property if the Oracle account has permissions to access multiple schemas,
+# for example sonar schemas with different versions. In that case, use the same property during project analysis
+# (-Dsonar.jdbc.schema=<schema>)
+#sonar.jdbc.schema: sonar
+
#----- PostgreSQL 8.x, 9.x
# Uncomment the following properties to use PostgreSQL. The validation query is optional.
@@ -87,8 +89,10 @@ sonar.jdbc.driverClassName: org.apache.derby.jdbc.ClientDriver
#sonar.jdbc.driverClassName: org.postgresql.Driver
#sonar.jdbc.validationQuery: select 1
-# If the PostgreSql database contains several schemas, the following property must define the schema to be used
-#sonar.jdbc.postgreSearchPath: public
+# Uncomment the following property if the PostgreSQL account has permissions to access multiple schemas,
+# for example sonar schemas with different versions. In that case, use the same property during project analysis
+# (-Dsonar.jdbc.schema=<schema>)
+#sonar.jdbc.schema: public
#----- Microsoft SQLServer
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 1f030afb3ab..4153c56d805 100644
--- a/sonar-core/src/main/java/org/sonar/persistence/Database.java
+++ b/sonar-core/src/main/java/org/sonar/persistence/Database.java
@@ -42,10 +42,5 @@ public interface Database {
*/
Dialect getDialect();
- /**
- * @return the schema or null if not defined or if start() has not been executed
- */
- 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 0eb87719c26..d4dd8da80b0 100644
--- a/sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java
+++ b/sonar-core/src/main/java/org/sonar/persistence/DefaultDatabase.java
@@ -19,6 +19,7 @@
*/
package org.sonar.persistence;
+import com.google.common.collect.Lists;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.commons.lang.StringUtils;
@@ -49,7 +50,6 @@ 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,8 +61,7 @@ public class DefaultDatabase implements Database {
Properties properties = getProperties();
dialect = initDialect(properties);
- schema = initSchema(properties, dialect);
- datasource = initDatasource(properties);
+ datasource = initDatasource(properties, dialect);
return this;
} catch (Exception e) {
@@ -70,19 +69,11 @@ public class DefaultDatabase implements Database {
}
}
- private String initSchema(Properties properties, Dialect dialect) {
- if (dialect.getId().equals(PostgreSql.ID)) {
- return properties.getProperty("sonar.jdbc.postgreSearchPath", "public");
- }
- if (dialect.getId().equals(Oracle.ID)) {
- return properties.getProperty("sonar.hibernate.default_schema", "sonar");
- }
- return null;
- }
-
- BasicDataSource initDatasource(Properties properties) throws Exception {
+ BasicDataSource initDatasource(Properties properties, Dialect dialect) throws Exception {
LOG.info("Create JDBC datasource");
- return (BasicDataSource) BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties));
+ BasicDataSource result = (BasicDataSource) BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties));
+ result.setConnectionInitSqls(getConnectionInitStatements(properties, dialect));
+ return result;
}
Dialect initDialect(Properties properties) {
@@ -116,10 +107,6 @@ public class DefaultDatabase implements Database {
return dialect;
}
- public String getSchema() {
- return schema;
- }
-
public Properties getHibernateProperties() {
Properties props = new Properties();
@@ -174,6 +161,30 @@ public class DefaultDatabase implements Database {
return result;
}
+ static List<String> getConnectionInitStatements(Properties properties, Dialect dialect) {
+ List<String> 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)) {
+ result.add("ALTER SESSION SET CURRENT SCHEMA = " + schema);
+ }
+ }
+ return result;
+ }
+
+ static String getSchema(Properties props, String deprecatedKey) {
+ String value = props.getProperty("sonar.jdbc.schema");
+ if (StringUtils.isBlank(value) && deprecatedKey != null) {
+ value = props.getProperty(deprecatedKey);
+ }
+ return StringUtils.isNotBlank(value) ? value : null;
+ }
+
private static void completeDefaultProperties(Properties props) {
completeDefaultProperty(props, DatabaseProperties.PROP_DRIVER, props.getProperty(DatabaseProperties.PROP_DRIVER_DEPRECATED, DatabaseProperties.PROP_DRIVER_DEFAULT_VALUE));
completeDefaultProperty(props, DatabaseProperties.PROP_URL, DatabaseProperties.PROP_URL_DEFAULT_VALUE);
diff --git a/sonar-core/src/main/java/org/sonar/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/persistence/MyBatis.java
index 6ba20d19236..f0978cdb248 100644
--- a/sonar-core/src/main/java/org/sonar/persistence/MyBatis.java
+++ b/sonar-core/src/main/java/org/sonar/persistence/MyBatis.java
@@ -49,7 +49,6 @@ public class MyBatis implements BatchComponent, ServerComponent {
conf.setEnvironment(new Environment("production", createTransactionFactory(), database.getDataSource()));
conf.setUseGeneratedKeys(true);
conf.setLazyLoadingEnabled(false);
- loadSchemaVariable(conf);
loadAlias(conf, "DuplicationUnit", DuplicationUnit.class);
loadAlias(conf, "Rule", Rule.class);
@@ -60,14 +59,6 @@ public class MyBatis implements BatchComponent, ServerComponent {
return this;
}
- private void loadSchemaVariable(Configuration conf) {
- String schema = database.getSchema();
- if (StringUtils.isNotBlank(schema)) {
- conf.getVariables().setProperty("_schema", schema + ".");
- } else {
- conf.getVariables().setProperty("_schema", "");
- }
- }
public SqlSessionFactory getSessionFactory() {
return sessionFactory;
diff --git a/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-mssql.xml b/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-mssql.xml
index fb495eeb7e3..bc1837a35fa 100644
--- a/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-mssql.xml
+++ b/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-mssql.xml
@@ -5,7 +5,7 @@
<select id="selectCandidates" parameterType="map" resultType="DuplicationUnit">
SELECT DISTINCT to_blocks.hash hash, res.kee resourceKey, to_blocks.index_in_file indexInFile, to_blocks.start_line startLine, to_blocks.end_line endLine
- FROM ${_schema}duplications_index to_blocks, ${_schema}duplications_index from_blocks, ${_schema}snapshots snapshot, ${_schema}projects res
+ FROM duplications_index to_blocks, duplications_index from_blocks, snapshots snapshot, projects res
WHERE from_blocks.snapshot_id = #{resource_snapshot_id}
AND to_blocks.hash = from_blocks.hash
AND to_blocks.snapshot_id = snapshot.id
@@ -17,7 +17,7 @@
</select>
<insert id="batchInsert" parameterType="DuplicationUnit" keyColumn="id" useGeneratedKeys="false">
- INSERT INTO ${_schema}duplications_index (snapshot_id, project_snapshot_id, hash, index_in_file, start_line, end_line)
+ INSERT INTO duplications_index (snapshot_id, project_snapshot_id, hash, index_in_file, start_line, end_line)
VALUES (#{snapshotId}, #{projectSnapshotId}, #{hash}, #{indexInFile}, #{startLine}, #{endLine})
</insert>
diff --git a/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-oracle.xml b/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-oracle.xml
index ff06ab3f95e..92a6bedc2fe 100644
--- a/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-oracle.xml
+++ b/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper-oracle.xml
@@ -5,7 +5,7 @@
<select id="selectCandidates" parameterType="map" resultType="DuplicationUnit">
SELECT DISTINCT to_blocks.hash hash, res.kee resourceKey, to_blocks.index_in_file indexInFile, to_blocks.start_line startLine, to_blocks.end_line endLine
- FROM ${_schema}duplications_index to_blocks, ${_schema}duplications_index from_blocks, ${_schema}snapshots snapshot, ${_schema}projects res
+ FROM duplications_index to_blocks, duplications_index from_blocks, snapshots snapshot, projects res
WHERE from_blocks.snapshot_id = #{resource_snapshot_id}
AND to_blocks.hash = from_blocks.hash
AND to_blocks.snapshot_id = snapshot.id
@@ -17,7 +17,7 @@
</select>
<insert id="batchInsert" parameterType="DuplicationUnit" keyColumn="id" useGeneratedKeys="false">
- INSERT INTO ${_schema}duplications_index (id, snapshot_id, project_snapshot_id, hash, index_in_file, start_line, end_line)
+ INSERT INTO duplications_index (id, snapshot_id, project_snapshot_id, hash, index_in_file, start_line, end_line)
VALUES (duplications_index_seq.NEXTVAL, #{snapshotId}, #{projectSnapshotId}, #{hash}, #{indexInFile}, #{startLine}, #{endLine})
</insert>
diff --git a/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper.xml b/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper.xml
index b6a6bcee564..5f39d7dea7c 100644
--- a/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/persistence/model/DuplicationMapper.xml
@@ -5,7 +5,7 @@
<select id="selectCandidates" parameterType="map" resultType="DuplicationUnit">
SELECT DISTINCT to_blocks.hash hash, res.kee resourceKey, to_blocks.index_in_file indexInFile, to_blocks.start_line startLine, to_blocks.end_line endLine
- FROM ${_schema}duplications_index to_blocks, ${_schema}duplications_index from_blocks, ${_schema}snapshots snapshot, ${_schema}projects res
+ FROM duplications_index to_blocks, duplications_index from_blocks, snapshots snapshot, projects res
WHERE from_blocks.snapshot_id = #{resource_snapshot_id}
AND to_blocks.hash = from_blocks.hash
AND to_blocks.snapshot_id = snapshot.id
@@ -17,7 +17,7 @@
</select>
<insert id="batchInsert" parameterType="DuplicationUnit" useGeneratedKeys="false">
- INSERT INTO ${_schema}duplications_index (snapshot_id, project_snapshot_id, hash, index_in_file, start_line, end_line)
+ INSERT INTO duplications_index (snapshot_id, project_snapshot_id, hash, index_in_file, start_line, end_line)
VALUES (#{snapshotId}, #{projectSnapshotId}, #{hash}, #{indexInFile}, #{startLine}, #{endLine})
</insert>
diff --git a/sonar-core/src/main/resources/org/sonar/persistence/model/RuleMapper.xml b/sonar-core/src/main/resources/org/sonar/persistence/model/RuleMapper.xml
index 7d0614dea2b..7cb565596dc 100644
--- a/sonar-core/src/main/resources/org/sonar/persistence/model/RuleMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/persistence/model/RuleMapper.xml
@@ -4,11 +4,11 @@
<mapper namespace="org.sonar.persistence.model.RuleMapper">
<select id="selectAll" resultType="Rule">
- select id, plugin_rule_key as "ruleKey", plugin_name as "repositoryKey", description, enabled, name from ${_schema}RULES
+ select id, plugin_rule_key as "ruleKey", plugin_name as "repositoryKey", description, enabled, name from RULES
</select>
<select id="selectById" parameterType="long" resultType="Rule">
- select id, plugin_rule_key as "ruleKey", plugin_name as "repositoryKey", description, enabled, name from ${_schema}RULES WHERE id=#{id}
+ select id, plugin_rule_key as "ruleKey", plugin_name as "repositoryKey", description, enabled, name from RULES WHERE id=#{id}
</select>
</mapper>
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 2f11a05c619..45238a9bb8a 100644
--- a/sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java
+++ b/sonar-core/src/test/java/org/sonar/persistence/DefaultDatabaseTest.java
@@ -23,8 +23,11 @@ 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.Oracle;
+import org.sonar.jpa.dialect.PostgreSql;
import java.sql.SQLException;
+import java.util.List;
import java.util.Properties;
import static org.junit.Assert.assertThat;
@@ -108,4 +111,68 @@ public class DefaultDatabaseTest {
DerbyUtils.dropInMemoryDatabase();
}
}
+
+ /**
+ * Avoid conflicts with other schemas
+ */
+ @Test
+ public void shouldChangePostgreSearchPath() {
+ Properties props = new Properties();
+ props.setProperty("sonar.jdbc.postgreSearchPath", "my_schema");
+
+ List<String> statements = DefaultDatabase.getConnectionInitStatements(props, new PostgreSql());
+
+ assertThat(statements.size(), Is.is(1));
+ assertThat(statements.get(0), Is.is("SET SEARCH_PATH TO my_schema"));
+ }
+
+ @Test
+ public void shouldNotChangePostgreSearchPathByDefault() {
+ List<String> statements = DefaultDatabase.getConnectionInitStatements(new Properties(), new PostgreSql());
+
+ assertThat(statements.size(), Is.is(0));
+ }
+
+ /**
+ * Avoid conflicts with other schemas
+ */
+ @Test
+ public void shouldAlterOracleSession() {
+ Properties props = new Properties();
+ props.setProperty("sonar.hibernate.default_schema", "my_schema");
+
+ List<String> statements = DefaultDatabase.getConnectionInitStatements(props, new Oracle());
+
+ assertThat(statements.size(), Is.is(1));
+ assertThat(statements.get(0), Is.is("ALTER SESSION SET CURRENT SCHEMA = my_schema"));
+ }
+
+ @Test
+ public void shouldNotAlterOracleSessionByDefault() {
+ List<String> statements = DefaultDatabase.getConnectionInitStatements(new Properties(), new Oracle());
+
+ assertThat(statements.size(), Is.is(0));
+ }
+
+ @Test
+ public void shouldSupportGenericSchemaPropertyForPostgreSQL() {
+ Properties props = new Properties();
+ props.setProperty("sonar.jdbc.schema", "my_schema");
+
+ List<String> statements = DefaultDatabase.getConnectionInitStatements(props, new PostgreSql());
+
+ assertThat(statements.size(), Is.is(1));
+ assertThat(statements.get(0), Is.is("SET SEARCH_PATH TO my_schema"));
+ }
+
+ @Test
+ public void shouldSupportGenericSchemaPropertyForOracle() {
+ Properties props = new Properties();
+ props.setProperty("sonar.jdbc.schema", "my_schema");
+
+ List<String> statements = DefaultDatabase.getConnectionInitStatements(props, new Oracle());
+
+ assertThat(statements.size(), Is.is(1));
+ assertThat(statements.get(0), Is.is("ALTER SESSION SET CURRENT SCHEMA = my_schema"));
+ }
}
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 f499b6a83d9..0a145afaaa6 100644
--- a/sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java
+++ b/sonar-core/src/test/java/org/sonar/persistence/InMemoryDatabase.java
@@ -149,10 +149,6 @@ 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");