@@ -81,13 +81,7 @@ | |||
</prerequisites> | |||
<properties> | |||
<!-- | |||
Warning before upgrading Derby to 10.8 : new conversion from BOOLEAN to CHAR. | |||
"If you use setBoolean() or setObject() with a CHAR(1) datatype you must change your code and use setInt() or Derby will try to store "true" or | |||
"false" strings." | |||
--> | |||
<derby.version>10.7.1.1</derby.version> | |||
<h2.version>1.3.167</h2.version> | |||
<jetty.version>6.1.25</jetty.version> | |||
<sonar.skippedModules>sonar-gwt-api,sonar-core-gwt</sonar.skippedModules> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
@@ -792,19 +786,9 @@ | |||
<version>0.9.30</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbyclient</artifactId> | |||
<version>${derby.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derby</artifactId> | |||
<version>${derby.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbynet</artifactId> | |||
<version>${derby.version}</version> | |||
<groupId>com.h2database</groupId> | |||
<artifactId>h2</artifactId> | |||
<version>${h2.version}</version> | |||
</dependency> | |||
<dependency> | |||
<!-- |
@@ -13,7 +13,7 @@ | |||
<excludes> | |||
<exclude>org.codehaus.sonar:sonar-server</exclude> | |||
<exclude>mysql:mysql-connector-java</exclude> | |||
<exclude>org.apache.derby:derbyclient</exclude> | |||
<exclude>com.h2database:h2</exclude> | |||
<exclude>postgresql:postgresql</exclude> | |||
<exclude>net.sourceforge.jtds:jtds</exclude> | |||
<exclude>org.codehaus.sonar.plugins:*</exclude> | |||
@@ -45,9 +45,9 @@ | |||
<scope>runtime</scope> | |||
</dependencySet> | |||
<dependencySet> | |||
<outputDirectory>extensions/jdbc-driver/derby/</outputDirectory> | |||
<outputDirectory>extensions/jdbc-driver/h2/</outputDirectory> | |||
<includes> | |||
<include>org.apache.derby:derbyclient</include> | |||
<include>com.h2database:h2</include> | |||
</includes> | |||
<unpack>false</unpack> | |||
<scope>runtime</scope> |
@@ -93,8 +93,8 @@ | |||
<scope>runtime</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbyclient</artifactId> | |||
<groupId>com.h2database</groupId> | |||
<artifactId>h2</artifactId> | |||
<scope>runtime</scope> | |||
</dependency> | |||
<dependency> |
@@ -26,7 +26,7 @@ | |||
#----------------------------------------------------------------------- | |||
# DATABASE | |||
# | |||
# IMPORTANT : the embedded database Derby is used by default. | |||
# IMPORTANT : the embedded database H2 is used by default. | |||
# It is recommended for tests only. Please use an external database | |||
# for production environment (MySQL, Oracle, Postgresql, SQLServer) | |||
# | |||
@@ -38,22 +38,19 @@ | |||
sonar.jdbc.username: sonar | |||
sonar.jdbc.password: sonar | |||
#----- Embedded database Derby | |||
#----- Embedded database H2 | |||
# Note : it does not accept connections from remote hosts, so the | |||
# sonar server and the maven plugin must be executed on the same host. | |||
# Comment the following line to deactivate the default embedded database. | |||
sonar.jdbc.url: jdbc:derby://localhost:1527/sonar;create=true | |||
#sonar.jdbc.driverClassName: org.apache.derby.jdbc.ClientDriver | |||
sonar.jdbc.url: jdbc:h2:tcp://localhost:9092/sonar | |||
#sonar.jdbc.driverClassName: org.h2.Driver | |||
#sonar.jdbc.validationQuery: values(1) | |||
# directory containing Derby database files. By default it's the /data directory in the sonar installation. | |||
# directory containing H2 database files. By default it's the /data directory in the sonar installation. | |||
#sonar.embeddedDatabase.dataDir: | |||
# derby embedded database server listening port, defaults to 1527 | |||
#sonar.derby.drda.portNumber: 1527 | |||
# uncomment to accept connections from remote hosts. Ba default it only accepts localhost connections. | |||
#sonar.derby.drda.host: 0.0.0.0 | |||
# H2 embedded database server listening port, defaults to 9092 | |||
#sonar.embeddedDatabase.port: 9092 | |||
#----- MySQL 5.x/6.x |
@@ -41,18 +41,6 @@ | |||
<groupId>org.mybatis</groupId> | |||
<artifactId>mybatis</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derby</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbyclient</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbynet</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-update-center-common</artifactId> | |||
@@ -160,6 +148,11 @@ | |||
<artifactId>jtds</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.h2database</groupId> | |||
<artifactId>h2</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<profiles> |
@@ -26,7 +26,7 @@ import org.sonar.api.ServerComponent; | |||
import java.sql.Connection; | |||
/** | |||
* Restore schema by executing DDL scripts. Only Derby database is supported. | |||
* Restore schema by executing DDL scripts. Only H2 database is supported. | |||
* Other databases are created by Ruby on Rails migrations. | |||
* | |||
* @since 2.12 |
@@ -37,7 +37,7 @@ public final class DdlUtils { | |||
} | |||
public static boolean supportsDialect(String dialect) { | |||
return "derby".equals(dialect); | |||
return "h2".equals(dialect); | |||
} | |||
/** |
@@ -27,10 +27,15 @@ import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.core.persistence.dialect.*; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
import org.sonar.core.persistence.dialect.DialectUtils; | |||
import org.sonar.core.persistence.dialect.H2; | |||
import org.sonar.core.persistence.dialect.Oracle; | |||
import org.sonar.core.persistence.dialect.PostgreSql; | |||
import org.sonar.jpa.session.CustomHibernateConnectionProvider; | |||
import javax.sql.DataSource; | |||
import java.sql.SQLException; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
@@ -84,8 +89,8 @@ public class DefaultDatabase implements Database { | |||
if (dialect == null) { | |||
throw new IllegalStateException("Can not guess the JDBC dialect. Please check the property sonar.jdbc.url."); | |||
} | |||
if (Derby.ID.equals(dialect.getId())) { | |||
LoggerFactory.getLogger(DefaultDatabase.class).warn("Derby database should be used for evaluation purpose only"); | |||
if (H2.ID.equals(dialect.getId())) { | |||
LoggerFactory.getLogger(DefaultDatabase.class).warn("H2 database should be used for evaluation purpose only"); | |||
} | |||
if (!properties.containsKey("sonar.jdbc.driverClassName")) { | |||
properties.setProperty("sonar.jdbc.driverClassName", dialect.getDefaultDriverClassName()); | |||
@@ -107,7 +112,7 @@ public class DefaultDatabase implements Database { | |||
} | |||
} | |||
private void initDatasource() throws Exception {//NOSONAR this exception is thrown by BasicDataSourceFactory | |||
private void initDatasource() throws Exception {// NOSONAR this exception is thrown by BasicDataSourceFactory | |||
// but it's correctly caught by start() | |||
LOG.info("Create JDBC datasource"); |
@@ -32,7 +32,7 @@ public final class DialectUtils { | |||
private DialectUtils() { | |||
} | |||
private static final Dialect[] DIALECTS = new Dialect[]{new Derby(), new MySql(), new Oracle(), new PostgreSql(), new MsSql()}; | |||
private static final Dialect[] DIALECTS = new Dialect[] {new H2(), new MySql(), new Oracle(), new PostgreSql(), new MsSql()}; | |||
public static Dialect find(final String dialectId, final String jdbcConnectionUrl) { | |||
Dialect match = StringUtils.isNotBlank(dialectId) ? findById(dialectId) : findByJdbcUrl(jdbcConnectionUrl); |
@@ -20,25 +20,21 @@ | |||
package org.sonar.core.persistence.dialect; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.DerbyDialect; | |||
import org.hibernate.id.IdentityGenerator; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import java.sql.Types; | |||
import org.hibernate.dialect.H2Dialect; | |||
/** | |||
* @since 1.12 | |||
*/ | |||
public class Derby implements Dialect { | |||
public class H2 implements Dialect { | |||
public static final String ID = "derby"; | |||
public static final String ID = "h2"; | |||
public String getId() { | |||
return ID; | |||
} | |||
public String getActiveRecordDialectCode() { | |||
return "derby"; | |||
return "h2"; | |||
} | |||
public String getActiveRecordJdbcAdapter() { | |||
@@ -46,51 +42,21 @@ public class Derby implements Dialect { | |||
} | |||
public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { | |||
return DerbyWithDecimalDialect.class; | |||
return H2Dialect.class; | |||
} | |||
public boolean matchesJdbcURL(String jdbcConnectionURL) { | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:derby:"); | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:h2:"); | |||
} | |||
public String getDefaultDriverClassName() { | |||
return "org.apache.derby.jdbc.ClientDriver"; | |||
return "org.h2.Driver"; | |||
} | |||
public String getConnectionInitStatement(String schema) { | |||
return null; | |||
} | |||
public static class DerbyWithDecimalDialect extends DerbyDialect { | |||
public DerbyWithDecimalDialect() { | |||
super(); | |||
registerColumnType(Types.DOUBLE, "decimal"); | |||
registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "clob"); | |||
registerColumnType(Types.VARBINARY, "blob"); | |||
// Not possible to do alter column types in Derby | |||
registerColumnType(Types.BIGINT, "integer"); | |||
registerColumnType(Types.BIT, "boolean"); | |||
} | |||
@Override | |||
public String toBooleanValueString(boolean bool) { | |||
return bool ? "true" : "false"; | |||
} | |||
/** | |||
* To be compliant with Oracle, we define on each model (ch.hortis.sonar.model classes) | |||
* a sequence generator. It works on mySQL because strategy = GenerationType.AUTO, so | |||
* it equals GenerationType.IDENTITY. | |||
* But on derby, AUTO becomes TABLE instead of IDENTITY. So we explicitly change this behavior. | |||
*/ | |||
@Override | |||
public Class getNativeIdentifierGeneratorClass() { | |||
return IdentityGenerator.class; | |||
} | |||
} | |||
public String getTrueSqlValue() { | |||
return "true"; | |||
} |
@@ -1,6 +1,6 @@ | |||
-- Structure of Sonar Database | |||
-- Initially this file has been generated from existing H2 DB | |||
-- Should be updated manually, during addition of new migrations | |||
CREATE TABLE "QUALITY_MODELS" ( | |||
@@ -24,13 +24,13 @@ CREATE TABLE "CRITERIA" ( | |||
"FAMILY" VARCHAR(100), | |||
"KEE" VARCHAR(100), | |||
"OPERATOR" VARCHAR(20), | |||
"VALUE" DECIMAL(30,20), | |||
"VALUE" DOUBLE, | |||
"TEXT_VALUE" VARCHAR(256), | |||
"VARIATION" BOOLEAN | |||
); | |||
CREATE TABLE "DEPENDENCIES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"FROM_SNAPSHOT_ID" INTEGER, | |||
"FROM_RESOURCE_ID" INTEGER, | |||
"TO_SNAPSHOT_ID" INTEGER, | |||
@@ -102,9 +102,9 @@ CREATE TABLE "FILTER_COLUMNS" ( | |||
CREATE TABLE "MEASURE_DATA" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"MEASURE_ID" INTEGER, | |||
"MEASURE_ID" BIGINT, | |||
"SNAPSHOT_ID" INTEGER, | |||
"DATA" BLOB(2147483647) | |||
"DATA" BINARY(167772150) | |||
); | |||
CREATE TABLE "GROUPS" ( | |||
@@ -171,7 +171,7 @@ CREATE TABLE "RULES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"PLUGIN_RULE_KEY" VARCHAR(200) NOT NULL, | |||
"PLUGIN_NAME" VARCHAR(255) NOT NULL, | |||
"DESCRIPTION" CLOB(2147483647), | |||
"DESCRIPTION" VARCHAR(16777215), | |||
"PRIORITY" INTEGER, | |||
"ENABLED" BOOLEAN, | |||
"CARDINALITY" VARCHAR(10), | |||
@@ -238,7 +238,7 @@ CREATE TABLE "REVIEW_COMMENTS" ( | |||
"UPDATED_AT" TIMESTAMP, | |||
"REVIEW_ID" INTEGER, | |||
"USER_ID" INTEGER, | |||
"REVIEW_TEXT" CLOB(2147483647) | |||
"REVIEW_TEXT" VARCHAR(16777215) | |||
); | |||
CREATE TABLE "ACTIVE_RULE_CHANGES" ( | |||
@@ -254,8 +254,8 @@ CREATE TABLE "ACTIVE_RULE_CHANGES" ( | |||
); | |||
CREATE TABLE "PROJECT_MEASURES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"VALUE" DECIMAL(30,20), | |||
"ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"VALUE" DOUBLE, | |||
"METRIC_ID" INTEGER NOT NULL, | |||
"SNAPSHOT_ID" INTEGER, | |||
"RULE_ID" INTEGER, | |||
@@ -271,11 +271,11 @@ CREATE TABLE "PROJECT_MEASURES" ( | |||
"RULE_PRIORITY" INTEGER, | |||
"CHARACTERISTIC_ID" INTEGER, | |||
"PERSON_ID" INTEGER, | |||
"VARIATION_VALUE_1" DECIMAL(30,20), | |||
"VARIATION_VALUE_2" DECIMAL(30,20), | |||
"VARIATION_VALUE_3" DECIMAL(30,20), | |||
"VARIATION_VALUE_4" DECIMAL(30,20), | |||
"VARIATION_VALUE_5" DECIMAL(30,20) | |||
"VARIATION_VALUE_1" DOUBLE, | |||
"VARIATION_VALUE_2" DOUBLE, | |||
"VARIATION_VALUE_3" DOUBLE, | |||
"VARIATION_VALUE_4" DOUBLE, | |||
"VARIATION_VALUE_5" DOUBLE | |||
); | |||
CREATE TABLE "SNAPSHOT_SOURCES" ( | |||
@@ -321,10 +321,10 @@ CREATE TABLE "REVIEWS" ( | |||
); | |||
CREATE TABLE "MANUAL_MEASURES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"METRIC_ID" INTEGER NOT NULL, | |||
"RESOURCE_ID" INTEGER, | |||
"VALUE" DECIMAL(30,20), | |||
"VALUE" DOUBLE, | |||
"TEXT_VALUE" VARCHAR(4000), | |||
"USER_LOGIN" VARCHAR(40), | |||
"DESCRIPTION" VARCHAR(4000), | |||
@@ -343,7 +343,7 @@ CREATE TABLE "ACTIVE_RULES" ( | |||
CREATE TABLE "NOTIFICATIONS" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"CREATED_AT" TIMESTAMP, | |||
"DATA" BLOB(2147483647) | |||
"DATA" BINARY(167772150) | |||
); | |||
CREATE TABLE "USER_ROLES" ( | |||
@@ -371,7 +371,7 @@ CREATE TABLE "CHARACTERISTIC_PROPERTIES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"CHARACTERISTIC_ID" INTEGER, | |||
"KEE" VARCHAR(100), | |||
"VALUE" DECIMAL(30,20), | |||
"VALUE" DOUBLE, | |||
"TEXT_VALUE" VARCHAR(4000) | |||
); | |||
@@ -421,7 +421,7 @@ CREATE TABLE "RULE_FAILURES" ( | |||
"FAILURE_LEVEL" INTEGER NOT NULL, | |||
"MESSAGE" VARCHAR(4000), | |||
"LINE" INTEGER, | |||
"COST" DECIMAL(30,20), | |||
"COST" DOUBLE, | |||
"CREATED_AT" TIMESTAMP, | |||
"CHECKSUM" VARCHAR(1000), | |||
"PERMANENT_ID" INTEGER, | |||
@@ -441,8 +441,8 @@ CREATE TABLE "METRICS" ( | |||
"USER_MANAGED" BOOLEAN DEFAULT FALSE, | |||
"ENABLED" BOOLEAN DEFAULT TRUE, | |||
"ORIGIN" VARCHAR(3), | |||
"WORST_VALUE" DECIMAL(30,20), | |||
"BEST_VALUE" DECIMAL(30,20), | |||
"WORST_VALUE" DOUBLE, | |||
"BEST_VALUE" DOUBLE, | |||
"OPTIMIZED_BEST_VALUE" BOOLEAN, | |||
"HIDDEN" BOOLEAN, | |||
"DELETE_HISTORICAL_DATA" BOOLEAN | |||
@@ -486,7 +486,7 @@ CREATE TABLE "ACTIVE_RULE_NOTES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"ACTIVE_RULE_ID" INTEGER, | |||
"USER_LOGIN" VARCHAR(40), | |||
"DATA" BLOB(2147483647), | |||
"DATA" BINARY(167772150), | |||
"CREATED_AT" TIMESTAMP, | |||
"UPDATED_AT" TIMESTAMP | |||
); | |||
@@ -495,7 +495,7 @@ CREATE TABLE "RULE_NOTES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"RULE_ID" INTEGER, | |||
"USER_LOGIN" VARCHAR(40), | |||
"DATA" BLOB(2147483647), | |||
"DATA" BINARY(167772150), | |||
"CREATED_AT" TIMESTAMP, | |||
"UPDATED_AT" TIMESTAMP | |||
); | |||
@@ -507,194 +507,3 @@ CREATE TABLE "AUTHORS" ( | |||
"CREATED_AT" TIMESTAMP, | |||
"UPDATED_AT" TIMESTAMP | |||
); | |||
CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES" ("RESOURCE_ID"); | |||
CREATE INDEX "GROUP_ROLES_GROUP" ON "GROUP_ROLES" ("GROUP_ID"); | |||
CREATE INDEX "USER_ROLES_RESOURCE" ON "USER_ROLES" ("RESOURCE_ID"); | |||
CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES" ("USER_ID"); | |||
CREATE INDEX "DUPLICATIONS_INDEX_HASH" ON "DUPLICATIONS_INDEX" ("HASH"); | |||
CREATE INDEX "DUPLICATIONS_INDEX_SID" ON "DUPLICATIONS_INDEX" ("SNAPSHOT_ID"); | |||
CREATE INDEX "DUPLICATIONS_INDEX_PSID" ON "DUPLICATIONS_INDEX" ("PROJECT_SNAPSHOT_ID"); | |||
CREATE INDEX "SNAP_SOURCES_SNAPSHOT_ID" ON "SNAPSHOT_SOURCES" ("SNAPSHOT_ID"); | |||
CREATE INDEX "INDEX_GROUPS_USERS_ON_GROUP_ID" ON "GROUPS_USERS" ("GROUP_ID"); | |||
CREATE INDEX "INDEX_GROUPS_USERS_ON_USER_ID" ON "GROUPS_USERS" ("USER_ID"); | |||
CREATE INDEX "DEPS_TO_SID" ON "DEPENDENCIES" ("TO_SNAPSHOT_ID"); | |||
CREATE INDEX "DEPS_FROM_SID" ON "DEPENDENCIES" ("FROM_SNAPSHOT_ID"); | |||
CREATE INDEX "DEPS_PRJ_SID" ON "DEPENDENCIES" ("PROJECT_SNAPSHOT_ID"); | |||
CREATE INDEX "MEASURES_SID_METRIC" ON "PROJECT_MEASURES" ("SNAPSHOT_ID", "METRIC_ID"); | |||
CREATE INDEX "ACTIVE_RULE_CHANGES_PID" ON "ACTIVE_RULE_CHANGES" ("PROFILE_ID"); | |||
CREATE INDEX "CHARACTERISTIC_PROPERTIES_CID" ON "CHARACTERISTIC_PROPERTIES" ("CHARACTERISTIC_ID"); | |||
CREATE UNIQUE INDEX "METRICS_UNIQUE_NAME" ON "METRICS" ("NAME"); | |||
CREATE INDEX "ACTIVE_RULE_PARAM_CHANGES_CID" ON "ACTIVE_RULE_PARAM_CHANGES" ("ACTIVE_RULE_CHANGE_ID"); | |||
CREATE INDEX "M_DATA_SID" ON "MEASURE_DATA" ("SNAPSHOT_ID"); | |||
CREATE INDEX "MEASURE_DATA_MEASURE_ID" ON "MEASURE_DATA" ("MEASURE_ID"); | |||
CREATE INDEX "RF_PERMANENT_ID" ON "RULE_FAILURES" ("PERMANENT_ID"); | |||
CREATE INDEX "RULE_FAILURE_RULE_ID" ON "RULE_FAILURES" ("RULE_ID"); | |||
CREATE INDEX "RULE_FAILURE_SNAPSHOT_ID" ON "RULE_FAILURES" ("SNAPSHOT_ID"); | |||
CREATE INDEX "EVENTS_SNAPSHOT_ID" ON "EVENTS" ("SNAPSHOT_ID"); | |||
CREATE INDEX "EVENTS_RESOURCE_ID" ON "EVENTS" ("RESOURCE_ID"); | |||
CREATE INDEX "WIDGETS_WIDGETKEY" ON "WIDGETS" ("WIDGET_KEY"); | |||
CREATE INDEX "WIDGETS_DASHBOARDS" ON "WIDGETS" ("DASHBOARD_ID"); | |||
CREATE INDEX "SNAPSHOTS_QUALIFIER" ON "SNAPSHOTS" ("QUALIFIER"); | |||
CREATE INDEX "SNAPSHOTS_ROOT" ON "SNAPSHOTS" ("ROOT_SNAPSHOT_ID"); | |||
CREATE INDEX "SNAPSHOTS_PARENT" ON "SNAPSHOTS" ("PARENT_SNAPSHOT_ID"); | |||
CREATE INDEX "SNAPSHOT_PROJECT_ID" ON "SNAPSHOTS" ("PROJECT_ID"); | |||
CREATE INDEX "RULES_PARAMETERS_RULE_ID" ON "RULES_PARAMETERS" ("RULE_ID"); | |||
CREATE INDEX "ACTIVE_DASHBOARDS_DASHBOARDID" ON "ACTIVE_DASHBOARDS" ("DASHBOARD_ID"); | |||
CREATE INDEX "ACTIVE_DASHBOARDS_USERID" ON "ACTIVE_DASHBOARDS" ("USER_ID"); | |||
CREATE UNIQUE INDEX "UNIQUE_SCHEMA_MIGRATIONS" ON "SCHEMA_MIGRATIONS" ("VERSION"); | |||
CREATE INDEX "WIDGET_PROPERTIES_WIDGETS" ON "WIDGET_PROPERTIES" ("WIDGET_ID"); | |||
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY"); | |||
CREATE INDEX "MANUAL_MEASURES_RESOURCE_ID" ON "MANUAL_MEASURES" ("RESOURCE_ID"); | |||
CREATE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE"); | |||
CREATE INDEX "RESOURCE_INDEX_KEE" ON "RESOURCE_INDEX" ("KEE"); | |||
CREATE INDEX "RESOURCE_INDEX_RID" ON "RESOURCE_INDEX" ("RESOURCE_ID"); | |||
CREATE INDEX "INDEX_ACTION_PLANS_ON_PROJET_ID" ON "ACTION_PLANS" ("PROJECT_ID"); | |||
CREATE INDEX "INDEX_ACTION_PLANS_REVIEWS_ON_ACTION_PLAN_ID" ON "ACTION_PLANS_REVIEWS" ("ACTION_PLAN_ID"); | |||
CREATE INDEX "INDEX_ACTION_PLANS_REVIEWS_ON_REVIEW_ID" ON "ACTION_PLANS_REVIEWS" ("REVIEW_ID"); | |||
CREATE INDEX "INDEX_ACTIVE_RULE_NOTES_ON_ACTIVE_RULE_ID" ON "ACTIVE_RULE_NOTES" ("ACTIVE_RULE_ID"); | |||
CREATE INDEX "INDEX_RULE_NOTES_ON_ACTIVE_RULE_ID" ON "RULE_NOTES" ("RULE_ID"); | |||
CREATE INDEX "REVIEWS_RID" ON "REVIEWS" ("RESOURCE_ID"); | |||
ALTER TABLE "GROUP_ROLES" ADD CONSTRAINT "SQL110927104437910" PRIMARY KEY ("ID"); | |||
ALTER TABLE "REVIEWS" ADD CONSTRAINT "SQL110927104440700" PRIMARY KEY ("ID"); | |||
ALTER TABLE "RULES" ADD CONSTRAINT "SQL110927104437080" PRIMARY KEY ("ID"); | |||
ALTER TABLE "USER_ROLES" ADD CONSTRAINT "SQL110927104437940" PRIMARY KEY ("ID"); | |||
ALTER TABLE "SNAPSHOT_SOURCES" ADD CONSTRAINT "SQL110927104437590" PRIMARY KEY ("ID"); | |||
ALTER TABLE "NOTIFICATIONS" ADD CONSTRAINT "SQL110927104441030" PRIMARY KEY ("ID"); | |||
ALTER TABLE "DEPENDENCIES" ADD CONSTRAINT "SQL110927104438330" PRIMARY KEY ("ID"); | |||
ALTER TABLE "PROJECT_MEASURES" ADD CONSTRAINT "SQL110927104437040" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTIVE_RULE_CHANGES" ADD CONSTRAINT "SQL110927104440770" PRIMARY KEY ("ID"); | |||
ALTER TABLE "CHARACTERISTIC_PROPERTIES" ADD CONSTRAINT "SQL110927104439660" PRIMARY KEY ("ID"); | |||
ALTER TABLE "QUALITY_MODELS" ADD CONSTRAINT "SQL110927104439440" PRIMARY KEY ("ID"); | |||
ALTER TABLE "USERS" ADD CONSTRAINT "SQL110927104437310" PRIMARY KEY ("ID"); | |||
ALTER TABLE "CRITERIA" ADD CONSTRAINT "SQL110927104438720" PRIMARY KEY ("ID"); | |||
ALTER TABLE "METRICS" ADD CONSTRAINT "SQL110927104436990" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTIVE_RULE_PARAM_CHANGES" ADD CONSTRAINT "SQL110927104440790" PRIMARY KEY ("ID"); | |||
ALTER TABLE "MEASURE_DATA" ADD CONSTRAINT "SQL110927104437810" PRIMARY KEY ("ID"); | |||
ALTER TABLE "RULE_FAILURES" ADD CONSTRAINT "SQL110927104437100" PRIMARY KEY ("ID"); | |||
ALTER TABLE "EVENTS" ADD CONSTRAINT "SQL110927104437690" PRIMARY KEY ("ID"); | |||
ALTER TABLE "WIDGETS" ADD CONSTRAINT "SQL110927104439750" PRIMARY KEY ("ID"); | |||
ALTER TABLE "SNAPSHOTS" ADD CONSTRAINT "SQL110927104436960" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTIVE_RULES" ADD CONSTRAINT "SQL110927104437550" PRIMARY KEY ("ID"); | |||
ALTER TABLE "CHARACTERISTICS" ADD CONSTRAINT "SQL110927104439450" PRIMARY KEY ("ID"); | |||
ALTER TABLE "RULES_PARAMETERS" ADD CONSTRAINT "SQL110927104437130" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTIVE_DASHBOARDS" ADD CONSTRAINT "SQL110927104439710" PRIMARY KEY ("ID"); | |||
ALTER TABLE "FILTER_COLUMNS" ADD CONSTRAINT "SQL110927104438710" PRIMARY KEY ("ID"); | |||
ALTER TABLE "REVIEW_COMMENTS" ADD CONSTRAINT "SQL110927104440710" PRIMARY KEY ("ID"); | |||
ALTER TABLE "WIDGET_PROPERTIES" ADD CONSTRAINT "SQL110927104439770" PRIMARY KEY ("ID"); | |||
ALTER TABLE "PROPERTIES" ADD CONSTRAINT "SQL110927104437750" PRIMARY KEY ("ID"); | |||
ALTER TABLE "DASHBOARDS" ADD CONSTRAINT "SQL110927104439740" PRIMARY KEY ("ID"); | |||
ALTER TABLE "GROUPS" ADD CONSTRAINT "SQL110927104437850" PRIMARY KEY ("ID"); | |||
ALTER TABLE "PROJECT_LINKS" ADD CONSTRAINT "SQL110927104437150" PRIMARY KEY ("ID"); | |||
ALTER TABLE "FILTERS" ADD CONSTRAINT "SQL110927104438690" PRIMARY KEY ("ID"); | |||
ALTER TABLE "MANUAL_MEASURES" ADD CONSTRAINT "SQL110927104440930" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ALERTS" ADD CONSTRAINT "SQL110927104437730" PRIMARY KEY ("ID"); | |||
ALTER TABLE "PROJECTS" ADD CONSTRAINT "SQL110927104436930" PRIMARY KEY ("ID"); | |||
ALTER TABLE "RULES_PROFILES" ADD CONSTRAINT "SQL110927104437540" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTIVE_RULE_PARAMETERS" ADD CONSTRAINT "SQL110927104437560" PRIMARY KEY ("ID"); | |||
ALTER TABLE "LOADED_TEMPLATES" ADD CONSTRAINT "SQL110927104437650" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTION_PLANS" ADD CONSTRAINT "SQL110927104447650" PRIMARY KEY ("ID"); | |||
ALTER TABLE "ACTIVE_RULE_NOTES" ADD CONSTRAINT "SQL110927104847650" PRIMARY KEY ("ID"); | |||
ALTER TABLE "RULE_NOTES" ADD PRIMARY KEY ("ID"); | |||
ALTER TABLE "AUTHORS" ADD PRIMARY KEY ("ID"); | |||
ALTER TABLE "RESOURCE_INDEX" ADD PRIMARY KEY ("ID"); |
@@ -36,13 +36,13 @@ public class ConfigurationUtilsTest { | |||
input.setProperty("url", "${env:SONAR_JDBC_URL}"); | |||
input.setProperty("do_not_change", "${SONAR_JDBC_URL}"); | |||
Map<String, String> variables = Maps.newHashMap(); | |||
variables.put("SONAR_JDBC_URL", "jdbc:derby:mem"); | |||
variables.put("SONAR_JDBC_URL", "jdbc:h2:mem"); | |||
Properties output = ConfigurationUtils.interpolateVariables(input, variables); | |||
assertThat(output.size(), is(3)); | |||
assertThat(output.getProperty("hello"), is("world")); | |||
assertThat(output.getProperty("url"), is("jdbc:derby:mem")); | |||
assertThat(output.getProperty("url"), is("jdbc:h2:mem")); | |||
assertThat(output.getProperty("do_not_change"), is("${SONAR_JDBC_URL}")); | |||
// input is not changed |
@@ -60,17 +60,21 @@ public abstract class DaoTestCase { | |||
public static void startDatabase() throws Exception { | |||
Settings settings = new Settings(); | |||
settings.setProperties(Maps.fromProperties(System.getProperties())); | |||
if (settings.hasKey("sonar.jdbc.dialect")) { | |||
database = new DefaultDatabase(settings); | |||
} else { | |||
database = new InMemoryDatabase(); | |||
} | |||
database.start(); | |||
boolean hasDialect = settings.hasKey("sonar.jdbc.dialect"); | |||
if ((null == database) || (hasDialect)) { // Create database only once per vm (Only for in mempry database) | |||
if (hasDialect) { | |||
database = new DefaultDatabase(settings); | |||
} else { | |||
database = new H2Database(); | |||
} | |||
database.start(); | |||
myBatis = new MyBatis(database); | |||
myBatis.start(); | |||
myBatis = new MyBatis(database); | |||
myBatis.start(); | |||
databaseCommands = DatabaseCommands.forDialect(database.getDialect()); | |||
databaseCommands = DatabaseCommands.forDialect(database.getDialect()); | |||
} | |||
} | |||
@Before | |||
@@ -145,7 +149,7 @@ public abstract class DaoTestCase { | |||
} | |||
protected final void checkTables(String testName, String... tables) { | |||
checkTables(testName, new String[]{}, tables); | |||
checkTables(testName, new String[] {}, tables); | |||
} | |||
protected final void checkTables(String testName, String[] excludedColumnNames, String... tables) { |
@@ -20,15 +20,19 @@ | |||
package org.sonar.core.persistence; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.dbunit.dataset.datatype.DefaultDataTypeFactory; | |||
import org.dbunit.dataset.datatype.IDataTypeFactory; | |||
import org.dbunit.ext.h2.H2DataTypeFactory; | |||
import org.dbunit.ext.mssql.InsertIdentityOperation; | |||
import org.dbunit.ext.mssql.MsSqlDataTypeFactory; | |||
import org.dbunit.ext.mysql.MySqlDataTypeFactory; | |||
import org.dbunit.ext.oracle.Oracle10DataTypeFactory; | |||
import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory; | |||
import org.dbunit.operation.DatabaseOperation; | |||
import org.sonar.core.persistence.dialect.*; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
import org.sonar.core.persistence.dialect.MsSql; | |||
import org.sonar.core.persistence.dialect.MySql; | |||
import org.sonar.core.persistence.dialect.Oracle; | |||
import org.sonar.core.persistence.dialect.PostgreSql; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
@@ -64,7 +68,7 @@ public abstract class DatabaseCommands { | |||
return DatabaseOperation.CLEAN_INSERT; | |||
} | |||
static final DatabaseCommands DERBY = new DatabaseCommands(new DefaultDataTypeFactory()) { | |||
static final DatabaseCommands H2 = new DatabaseCommands(new H2DataTypeFactory()) { | |||
@Override | |||
public String truncate(String table) { | |||
return "TRUNCATE TABLE " + table; | |||
@@ -117,7 +121,7 @@ public abstract class DatabaseCommands { | |||
return Arrays.asList( | |||
"DROP SEQUENCE " + sequence, | |||
"CREATE SEQUENCE " + sequence + " INCREMENT BY 1 MINVALUE 1 START WITH 1" | |||
); | |||
); | |||
} | |||
@Override | |||
@@ -143,10 +147,9 @@ public abstract class DatabaseCommands { | |||
} | |||
}; | |||
public static DatabaseCommands forDialect(Dialect dialect) { | |||
if (Derby.ID.equals(dialect.getId())) { | |||
return DERBY; | |||
if (org.sonar.core.persistence.dialect.H2.ID.equals(dialect.getId())) { | |||
return H2; | |||
} | |||
if (MsSql.ID.equals(dialect.getId())) { | |||
return MSSQL; |
@@ -19,8 +19,7 @@ | |||
*/ | |||
package org.sonar.core.persistence; | |||
import org.apache.derby.jdbc.EmbeddedDriver; | |||
import org.hamcrest.core.Is; | |||
import org.h2.Driver; | |||
import org.junit.Test; | |||
import java.sql.Connection; | |||
@@ -28,39 +27,37 @@ import java.sql.DriverManager; | |||
import java.sql.ResultSet; | |||
import java.sql.SQLException; | |||
import static org.hamcrest.Matchers.greaterThan; | |||
import static org.junit.Assert.assertThat; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class DdlUtilsTest { | |||
static { | |||
DerbyUtils.fixDerbyLogs(); | |||
} | |||
@Test | |||
public void shouldSupportOnlyDerby() { | |||
assertThat(DdlUtils.supportsDialect("derby"), Is.is(true)); | |||
assertThat(DdlUtils.supportsDialect("mysql"), Is.is(false)); | |||
assertThat(DdlUtils.supportsDialect("oracle"), Is.is(false)); | |||
assertThat(DdlUtils.supportsDialect("mssql"), Is.is(false)); | |||
public void shouldSupportOnlyH2() { | |||
assertThat(DdlUtils.supportsDialect("h2")).isTrue(); | |||
assertThat(DdlUtils.supportsDialect("mysql")).isFalse(); | |||
assertThat(DdlUtils.supportsDialect("oracle")).isFalse(); | |||
assertThat(DdlUtils.supportsDialect("mssql")).isFalse(); | |||
} | |||
@Test | |||
public void shouldCreateDerbySchema() throws SQLException { | |||
int tables = 0; | |||
DriverManager.registerDriver(new EmbeddedDriver()); | |||
Connection connection = DriverManager.getConnection("jdbc:derby:memory:sonar;create=true"); | |||
DdlUtils.createSchema(connection, "derby"); | |||
public void shouldCreateSchema() throws SQLException { | |||
DriverManager.registerDriver(new Driver()); | |||
Connection connection = DriverManager.getConnection("jdbc:h2:mem:sonar_test"); | |||
DdlUtils.createSchema(connection, "h2"); | |||
int tables = countTables(connection); | |||
connection.close(); | |||
assertThat(tables).isGreaterThan(30); | |||
} | |||
ResultSet resultSet = connection.getMetaData().getTables("", null, null, new String[]{"TABLE"}); | |||
private int countTables(Connection connection) throws SQLException { | |||
int count = 0; | |||
ResultSet resultSet = connection.getMetaData().getTables(null, null, null, new String[] {"TABLE"}); | |||
while (resultSet.next()) { | |||
tables++; | |||
count++; | |||
} | |||
resultSet.close(); | |||
connection.commit(); | |||
connection.close(); | |||
assertThat(tables, greaterThan(30)); | |||
DerbyUtils.dropInMemoryDatabase(); | |||
return count; | |||
} | |||
} |
@@ -33,10 +33,6 @@ import static org.junit.Assert.assertThat; | |||
public class DefaultDatabaseTest { | |||
static { | |||
DerbyUtils.fixDerbyLogs(); | |||
} | |||
@Test | |||
public void shouldLoadDefaultValues() { | |||
DefaultDatabase db = new DefaultDatabase(new Settings()); | |||
@@ -45,8 +41,8 @@ public class DefaultDatabaseTest { | |||
Properties props = db.getProperties(); | |||
assertThat(props.getProperty("sonar.jdbc.username"), Is.is("sonar")); | |||
assertThat(props.getProperty("sonar.jdbc.password"), Is.is("sonar")); | |||
assertThat(props.getProperty("sonar.jdbc.url"), Is.is("jdbc:derby://localhost:1527/sonar")); | |||
assertThat(props.getProperty("sonar.jdbc.driverClassName"), Is.is("org.apache.derby.jdbc.ClientDriver")); | |||
assertThat(props.getProperty("sonar.jdbc.url"), Is.is("jdbc:h2:tcp://localhost/sonar")); | |||
assertThat(props.getProperty("sonar.jdbc.driverClassName"), Is.is("org.h2.Driver")); | |||
} | |||
@Test | |||
@@ -97,21 +93,17 @@ public class DefaultDatabaseTest { | |||
@Test | |||
public void shouldStart() { | |||
Settings settings = new Settings(); | |||
settings.setProperty("sonar.jdbc.url", "jdbc:derby:memory:sonar;create=true;user=sonar;password=sonar"); | |||
settings.setProperty("sonar.jdbc.driverClassName", "org.apache.derby.jdbc.EmbeddedDriver"); | |||
settings.setProperty("sonar.jdbc.url", "jdbc:h2:mem:sonar"); | |||
settings.setProperty("sonar.jdbc.driverClassName", "org.h2.Driver"); | |||
settings.setProperty("sonar.jdbc.username", "sonar"); | |||
settings.setProperty("sonar.jdbc.password", "sonar"); | |||
settings.setProperty("sonar.jdbc.maxActive", "1"); | |||
try { | |||
DefaultDatabase db = new DefaultDatabase(settings); | |||
db.start(); | |||
DefaultDatabase db = new DefaultDatabase(settings); | |||
db.start(); | |||
assertThat(db.getDialect().getId(), Is.is("derby")); | |||
assertThat(((BasicDataSource) db.getDataSource()).getMaxActive(), Is.is(1)); | |||
} finally { | |||
DerbyUtils.dropInMemoryDatabase(); | |||
} | |||
assertThat(db.getDialect().getId(), Is.is("h2")); | |||
assertThat(((BasicDataSource) db.getDataSource()).getMaxActive(), Is.is(1)); | |||
} | |||
@Test |
@@ -1,52 +0,0 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2008-2012 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.core.persistence; | |||
import java.io.OutputStream; | |||
import java.sql.DriverManager; | |||
public final class DerbyUtils { | |||
private DerbyUtils() { | |||
} | |||
public static final OutputStream DEV_NULL = new OutputStream() { | |||
@Override | |||
public void write(int b) { | |||
} | |||
}; | |||
/** | |||
* Disables Derby log. | |||
* Note: in order to work properly this method should be called before Derby boot. | |||
* See http://db.apache.org/derby/docs/10.7/ref/rrefproper33027.html | |||
*/ | |||
public static void fixDerbyLogs() { | |||
System.setProperty("derby.stream.error.field", "org.sonar.core.persistence.DerbyUtils.DEV_NULL"); | |||
} | |||
public static void dropInMemoryDatabase() { | |||
try { | |||
DriverManager.getConnection("jdbc:derby:memory:sonar;drop=true"); | |||
} catch (Exception e) { | |||
// silently ignore | |||
} | |||
} | |||
} |
@@ -22,33 +22,29 @@ package org.sonar.core.persistence; | |||
import org.apache.commons.dbcp.BasicDataSource; | |||
import org.apache.commons.dbcp.BasicDataSourceFactory; | |||
import org.hibernate.cfg.Environment; | |||
import org.sonar.core.persistence.dialect.Derby; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
import org.sonar.core.persistence.dialect.H2; | |||
import org.sonar.jpa.session.CustomHibernateConnectionProvider; | |||
import javax.sql.DataSource; | |||
import java.sql.*; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import java.util.Properties; | |||
/** | |||
* Derby in-memory database, used for unit tests only. | |||
* H2 in-memory database, used for unit tests only. | |||
* | |||
* @since 2.12 | |||
* @since 3.2 | |||
*/ | |||
public class InMemoryDatabase implements Database { | |||
static { | |||
DerbyUtils.fixDerbyLogs(); | |||
} | |||
public class H2Database implements Database { | |||
private static BasicDataSource datasource; | |||
public InMemoryDatabase start() { | |||
public H2Database start() { | |||
if (datasource == null) { | |||
startDatabase(); | |||
createSchema(); | |||
} | |||
truncateTables(); | |||
return this; | |||
} | |||
@@ -58,10 +54,10 @@ public class InMemoryDatabase implements Database { | |||
void startDatabase() { | |||
try { | |||
Properties properties = new Properties(); | |||
properties.put("driverClassName", "org.apache.derby.jdbc.EmbeddedDriver"); | |||
properties.put("driverClassName", "org.h2.Driver"); | |||
properties.put("username", "sonar"); | |||
properties.put("password", "sonar"); | |||
properties.put("url", "jdbc:derby:memory:sonar2;create=true;user=sonar;password=sonar"); | |||
properties.put("url", "jdbc:h2:mem:sonar2"); | |||
// limit to 2 because of Hibernate and MyBatis | |||
properties.put("maxActive", "2"); | |||
@@ -69,7 +65,7 @@ public class InMemoryDatabase implements Database { | |||
datasource = (BasicDataSource) BasicDataSourceFactory.createDataSource(properties); | |||
} catch (Exception e) { | |||
throw new IllegalStateException("Fail to start Derby", e); | |||
throw new IllegalStateException("Fail to start H2", e); | |||
} | |||
} | |||
@@ -77,67 +73,26 @@ public class InMemoryDatabase implements Database { | |||
Connection connection = null; | |||
try { | |||
connection = datasource.getConnection(); | |||
DdlUtils.createSchema(connection, "derby"); | |||
DdlUtils.createSchema(connection, "h2"); | |||
} catch (SQLException e) { | |||
throw new IllegalStateException("Fail to create schema", e); | |||
} finally { | |||
closeQuietly(connection); | |||
} | |||
} | |||
private void truncateTables() { | |||
Connection connection = null; | |||
try { | |||
connection = datasource.getConnection(); | |||
DatabaseMetaData meta = connection.getMetaData(); | |||
Statement statement = connection.createStatement(); | |||
ResultSet res = meta.getTables(null, null, null, new String[]{"TABLE"}); | |||
while (res.next()) { | |||
String tableName = res.getString("TABLE_NAME"); | |||
statement.executeUpdate("TRUNCATE TABLE " + tableName); | |||
} | |||
res.close(); | |||
// See https://issues.apache.org/jira/browse/DERBY-5403 | |||
res = meta.getColumns(null, null, null, "ID"); | |||
while (res.next()) { | |||
String tableName = res.getString("TABLE_NAME"); | |||
statement.executeUpdate("ALTER TABLE " + tableName + " ALTER COLUMN ID RESTART WITH 1"); | |||
} | |||
res.close(); | |||
statement.close(); | |||
} catch (SQLException e) { | |||
throw new IllegalStateException("Fail to truncate tables", e); | |||
} finally { | |||
closeQuietly(connection); // Important, otherwise tests can stuck | |||
} | |||
} | |||
public static void stopDatabase() { | |||
try { | |||
if (datasource != null) { | |||
datasource.close(); | |||
datasource = null; | |||
} | |||
DriverManager.getConnection("jdbc:derby:;shutdown=true"); | |||
} catch (SQLException e) { | |||
// See http://db.apache.org/derby/docs/dev/getstart/rwwdactivity3.html | |||
// XJ015 indicates successful shutdown of Derby | |||
// 08006 successful shutdown of a single database | |||
if (!"XJ015".equals(e.getSQLState())) { | |||
throw new IllegalStateException("Fail to stop Derby", e); | |||
} | |||
// Ignore error | |||
} | |||
} | |||
public InMemoryDatabase stop() { | |||
public H2Database stop() { | |||
return this; | |||
} | |||
@@ -146,7 +101,7 @@ public class InMemoryDatabase implements Database { | |||
} | |||
public Dialect getDialect() { | |||
return new Derby(); | |||
return new H2(); | |||
} | |||
public String getSchema() { |
@@ -31,16 +31,12 @@ import static org.hamcrest.number.OrderingComparisons.greaterThan; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertThat; | |||
public class InMemoryDatabaseTest { | |||
static { | |||
DerbyUtils.fixDerbyLogs(); | |||
} | |||
public class H2DatabaseTest { | |||
@Test | |||
public void shouldExecuteDdlAtStartup() throws SQLException { | |||
int tables = 0; | |||
InMemoryDatabase db = new InMemoryDatabase(); | |||
H2Database db = new H2Database(); | |||
try { | |||
db.start(); | |||
assertNotNull(db.getDataSource()); | |||
@@ -60,7 +56,7 @@ public class InMemoryDatabaseTest { | |||
@Test | |||
public void shouldLimitThePoolSize() { | |||
InMemoryDatabase db = new InMemoryDatabase(); | |||
H2Database db = new H2Database(); | |||
try { | |||
db.startDatabase(); | |||
assertThat(((BasicDataSource) db.getDataSource()).getMaxActive(), Is.is(2)); |
@@ -32,16 +32,12 @@ import static org.junit.Assert.assertThat; | |||
public class MyBatisTest { | |||
static { | |||
DerbyUtils.fixDerbyLogs(); | |||
} | |||
private static MyBatis myBatis; | |||
private static InMemoryDatabase database; | |||
private static H2Database database; | |||
@BeforeClass | |||
public static void start() { | |||
database = new InMemoryDatabase(); | |||
database = new H2Database(); | |||
myBatis = new MyBatis(database.start()); | |||
myBatis.start(); | |||
} |
@@ -24,19 +24,19 @@ import org.junit.Test; | |||
import static org.hamcrest.CoreMatchers.is; | |||
import static org.junit.Assert.assertThat; | |||
public class DerbyTest { | |||
public class H2Test { | |||
private Derby derby = new Derby(); | |||
private H2 h2 = new H2(); | |||
@Test | |||
public void matchesJdbcURL() { | |||
assertThat(derby.matchesJdbcURL("jdbc:derby:foo"), is(true)); | |||
assertThat(derby.matchesJdbcURL("jdbc:hsql:foo"), is(false)); | |||
assertThat(h2.matchesJdbcURL("jdbc:h2:foo"), is(true)); | |||
assertThat(h2.matchesJdbcURL("jdbc:hsql:foo"), is(false)); | |||
} | |||
@Test | |||
public void testBooleanSqlValues() { | |||
assertThat(derby.getTrueSqlValue(), is("true")); | |||
assertThat(derby.getFalseSqlValue(), is("false")); | |||
assertThat(h2.getTrueSqlValue(), is("true")); | |||
assertThat(h2.getFalseSqlValue(), is("false")); | |||
} | |||
} |
@@ -24,32 +24,30 @@ import org.dbunit.Assertion; | |||
import org.dbunit.DataSourceDatabaseTester; | |||
import org.dbunit.DatabaseUnitException; | |||
import org.dbunit.IDatabaseTester; | |||
import org.dbunit.database.DatabaseConfig; | |||
import org.dbunit.database.IDatabaseConnection; | |||
import org.dbunit.dataset.Column; | |||
import org.dbunit.dataset.CompositeDataSet; | |||
import org.dbunit.dataset.DataSetException; | |||
import org.dbunit.dataset.IDataSet; | |||
import org.dbunit.dataset.ITable; | |||
import org.dbunit.dataset.ITableMetaData; | |||
import org.dbunit.dataset.ReplacementDataSet; | |||
import org.dbunit.dataset.filter.DefaultColumnFilter; | |||
import org.dbunit.dataset.xml.FlatXmlDataSet; | |||
import org.dbunit.ext.h2.H2DataTypeFactory; | |||
import org.dbunit.operation.DatabaseOperation; | |||
import org.junit.After; | |||
import org.junit.AfterClass; | |||
import org.junit.Before; | |||
import org.junit.BeforeClass; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.core.persistence.Database; | |||
import org.sonar.core.persistence.DatabaseCommands; | |||
import org.sonar.core.persistence.InMemoryDatabase; | |||
import org.sonar.core.persistence.H2Database; | |||
import org.sonar.jpa.session.DatabaseSessionFactory; | |||
import org.sonar.jpa.session.DefaultDatabaseConnector; | |||
import org.sonar.jpa.session.JpaDatabaseSession; | |||
import org.sonar.jpa.session.MemoryDatabaseConnector; | |||
import java.io.InputStream; | |||
import java.sql.ResultSet; | |||
import java.sql.SQLException; | |||
import static org.junit.Assert.fail; | |||
@@ -68,13 +66,15 @@ public abstract class AbstractDbUnitTestCase { | |||
@BeforeClass | |||
public static void startDatabase() throws Exception { | |||
database = new InMemoryDatabase(); | |||
database.start(); | |||
if (null == database) { // Create only once per vm | |||
database = new H2Database(); | |||
database.start(); | |||
dbConnector = new MemoryDatabaseConnector(database); | |||
dbConnector.start(); | |||
dbConnector = new MemoryDatabaseConnector(database); | |||
dbConnector.start(); | |||
databaseCommands = DatabaseCommands.forDialect(database.getDialect()); | |||
databaseCommands = DatabaseCommands.forDialect(database.getDialect()); | |||
} | |||
} | |||
@Before | |||
@@ -96,12 +96,6 @@ public abstract class AbstractDbUnitTestCase { | |||
session.stop(); | |||
} | |||
@AfterClass | |||
public static void stopDatabase() { | |||
dbConnector.stop(); | |||
database.stop(); | |||
} | |||
public DatabaseSession getSession() { | |||
return session; | |||
} | |||
@@ -152,32 +146,14 @@ public abstract class AbstractDbUnitTestCase { | |||
databaseTester.setDataSet(compositeDataSet); | |||
connection = databaseTester.getConnection(); | |||
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new H2DataTypeFactory()); | |||
DatabaseOperation.CLEAN_INSERT.execute(connection, databaseTester.getDataSet()); | |||
resetDerbySequence(compositeDataSet); | |||
} catch (Exception e) { | |||
throw translateException("Could not setup DBUnit data", e); | |||
} | |||
} | |||
private void resetDerbySequence(CompositeDataSet compositeDataSet) throws DataSetException, SQLException { | |||
for (ITable table : compositeDataSet.getTables()) { | |||
ITableMetaData tableMetaData = table.getTableMetaData(); | |||
String tableName = tableMetaData.getTableName(); | |||
for (Column column : tableMetaData.getColumns()) { | |||
if ("id".equalsIgnoreCase(column.getColumnName())) { // TODO hard-coded value | |||
String maxSql = "SELECT MAX(id) FROM " + tableName; | |||
ResultSet res = connection.getConnection().prepareStatement(maxSql).executeQuery(); | |||
res.next(); | |||
int max = res.getInt(1); | |||
res.close(); | |||
String alterSql = "ALTER TABLE " + tableName + " ALTER COLUMN id RESTART WITH " + (max + 1); | |||
connection.getConnection().prepareStatement(alterSql).execute(); | |||
} | |||
} | |||
} | |||
} | |||
protected final void checkTables(String testName, String... tables) { | |||
checkTables(testName, new String[0], tables); | |||
} |
@@ -24,9 +24,9 @@ public interface DatabaseProperties { | |||
int MAX_TEXT_SIZE = 16777215; | |||
String PROP_URL = "sonar.jdbc.url"; | |||
String PROP_URL_DEFAULT_VALUE = "jdbc:derby://localhost:1527/sonar"; | |||
String PROP_URL_DEFAULT_VALUE = "jdbc:h2:tcp://localhost/sonar"; | |||
String PROP_DRIVER = "sonar.jdbc.driverClassName"; | |||
String PROP_DRIVER_DEFAULT_VALUE = "org.apache.derby.jdbc.ClientDriver"; | |||
String PROP_DRIVER_DEFAULT_VALUE = "org.h2.Driver"; | |||
String PROP_DRIVER_DEPRECATED = "sonar.jdbc.driver"; | |||
String PROP_USER = "sonar.jdbc.username"; | |||
String PROP_USER_DEPRECATED = "sonar.jdbc.user"; | |||
@@ -37,6 +37,15 @@ public interface DatabaseProperties { | |||
String PROP_HIBERNATE_GENERATE_STATISTICS = "sonar.jdbc.hibernate.generate_statistics"; | |||
String PROP_DIALECT = "sonar.jdbc.dialect"; | |||
String PROP_HIBERNATE_DEFAULT_SCHEMA = "sonar.hibernate.default_schema"; | |||
String PROP_EMBEDDED_DATA_DIR = "sonar.embeddedDatabase.dataDir"; | |||
/** | |||
* @since 3.2 | |||
*/ | |||
String PROP_EMBEDDED_PORT = "sonar.embeddedDatabase.port"; | |||
/** | |||
* @since 3.2 | |||
*/ | |||
String PROP_EMBEDDED_PORT_DEFAULT_VALUE = "9092"; | |||
} |
@@ -1,2 +1,2 @@ | |||
set MAVEN_OPTS='-Xmx768m -XX:MaxPermSize=128m' | |||
mvn clean jetty:run -Pstart-dev-server,derby | |||
mvn clean jetty:run -Pstart-dev-server,h2 |
@@ -1,3 +1,3 @@ | |||
#!/bin/sh | |||
export MAVEN_OPTS='-Xmx768m -XX:MaxPermSize=128m' | |||
mvn clean jetty:run -Pstart-dev-server,derby | |||
mvn clean jetty:run -Pstart-dev-server,h2 |
@@ -51,11 +51,6 @@ | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-update-center-common</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbyclient</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-plugin-api</artifactId> | |||
@@ -76,12 +71,8 @@ | |||
<artifactId>commons-configuration</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derby</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbynet</artifactId> | |||
<groupId>com.h2database</groupId> | |||
<artifactId>h2</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.thoughtworks.xstream</groupId> | |||
@@ -613,9 +604,9 @@ | |||
</profile> | |||
<profile> | |||
<id>derby</id> | |||
<id>h2</id> | |||
<properties> | |||
<jdbcDialect>derby</jdbcDialect> | |||
<jdbcDialect>h2</jdbcDialect> | |||
</properties> | |||
<build> | |||
<plugins> | |||
@@ -632,7 +623,7 @@ | |||
<outputDirectory>${project.build.directory}/classes</outputDirectory> | |||
<resources> | |||
<resource> | |||
<directory>${basedir}/src/dev/derby</directory> | |||
<directory>${basedir}/src/dev/h2</directory> | |||
<filtering>false</filtering> | |||
</resource> | |||
</resources> | |||
@@ -653,10 +644,9 @@ | |||
<configuration> | |||
<overWriteIfNewer>true</overWriteIfNewer> | |||
<overWriteReleases>true</overWriteReleases> | |||
<includeGroupIds>org.apache.derby</includeGroupIds> | |||
<includeArtifactIds>derbyclient</includeArtifactIds> | |||
<outputDirectory>${project.build.directory}/sonar-dev-home/extensions/jdbc-driver/derby/ | |||
</outputDirectory> | |||
<includeGroupIds>com.h2database</includeGroupIds> | |||
<includeArtifactIds>h2</includeArtifactIds> | |||
<outputDirectory>${project.build.directory}/sonar-dev-home/extensions/jdbc-driver/h2/</outputDirectory> | |||
</configuration> | |||
</execution> | |||
</executions> | |||
@@ -665,8 +655,8 @@ | |||
</build> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derbyclient</artifactId> | |||
<groupId>com.h2database</groupId> | |||
<artifactId>h2</artifactId> | |||
</dependency> | |||
</dependencies> | |||
</profile> |
@@ -1,6 +1,6 @@ | |||
# Derby | |||
sonar.jdbc.url: jdbc:derby://localhost:1527/sonar;create=true | |||
sonar.jdbc.driverClassName: org.apache.derby.jdbc.ClientDriver | |||
# H2 | |||
sonar.jdbc.url: jdbc:h2:tcp://localhost:9092/sonar | |||
sonar.jdbc.driverClassName: org.h2.Driver | |||
sonar.jdbc.defaultTransactionIsolation: 1 | |||
sonar.jdbc.username: sonar | |||
sonar.jdbc.password: sonar | |||
@@ -13,5 +13,5 @@ sonar.jdbc.timeBetweenEvictionRunsMillis: 30000 | |||
sonar.runtime.mode: development | |||
sonar.derby.drda.portNumber: 1527 | |||
sonar.derby.drda.host: localhost | |||
sonar.embeddedDatabase.port: 9092 | |||
@@ -19,171 +19,86 @@ | |||
*/ | |||
package org.sonar.server.database; | |||
import org.apache.commons.io.IOUtils; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.derby.drda.NetworkServerControl; | |||
import org.h2.tools.Server; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.api.utils.Logs; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.server.platform.ServerStartException; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.PrintWriter; | |||
import java.net.InetAddress; | |||
import java.util.Properties; | |||
import java.sql.DriverManager; | |||
import java.sql.SQLException; | |||
public class EmbeddedDatabase { | |||
private static final Logger LOG = LoggerFactory.getLogger(EmbeddedDatabase.class); | |||
private static final String DEFAULT_USER = "sonar"; | |||
private static final String DEFAULT_PWD = "sonar"; | |||
private NetworkServerControl serverControl = null; | |||
private File dbHome; | |||
private Properties dbProps; | |||
private PrintWriter dbLog; | |||
private final Settings settings; | |||
private Server server; | |||
public EmbeddedDatabase(Settings settings) { | |||
this.dbHome = getDataDirectory(settings); | |||
this.dbProps = getDefaultProperties(settings); | |||
} | |||
public EmbeddedDatabase(File dbHome, Properties dbProps) { | |||
this.dbHome = dbHome; | |||
this.dbProps = dbProps; | |||
} | |||
public File getDataDir() { | |||
return dbHome; | |||
} | |||
protected File getDataDirectory(Settings settings) { | |||
String dirName = settings.getString(DatabaseProperties.PROP_EMBEDDED_DATA_DIR); | |||
if (StringUtils.isBlank(dirName)) { | |||
File sonarHome = new File(settings.getString(CoreProperties.SONAR_HOME)); | |||
if (!sonarHome.isDirectory() || !sonarHome.exists()) { | |||
throw new ServerStartException("Sonar home directory does not exist"); | |||
} | |||
return new File(sonarHome, "data"); | |||
} | |||
return new File(dirName); | |||
} | |||
public void setDbLog(PrintWriter dbLog) { | |||
this.dbLog = dbLog; | |||
this.settings = settings; | |||
} | |||
public void start() { | |||
File dbHome = getDataDirectory(settings); | |||
if (dbHome.exists() && !dbHome.isDirectory()) { | |||
throw new SonarException("Database home " + dbHome.getPath() + " is not a directory"); | |||
} | |||
if (!dbHome.exists()) { | |||
dbHome.mkdirs(); | |||
} | |||
System.setProperty("derby.system.home", dbHome.getPath()); | |||
saveDerbyPropertiesFile(); | |||
startListening(); | |||
Logs.INFO.info("Embedded database started. Data stored in: " + dbHome.getAbsolutePath()); | |||
} | |||
String port = getSetting(DatabaseProperties.PROP_EMBEDDED_PORT, DatabaseProperties.PROP_EMBEDDED_PORT_DEFAULT_VALUE); | |||
String user = getSetting(DatabaseProperties.PROP_USER, DatabaseProperties.PROP_USER_DEFAULT_VALUE); | |||
String password = getSetting(DatabaseProperties.PROP_PASSWORD, DatabaseProperties.PROP_PASSWORD_DEFAULT_VALUE); | |||
private void startListening() { | |||
try { | |||
int port = Integer.parseInt(dbProps.getProperty("derby.drda.portNumber")); | |||
String host = dbProps.getProperty("derby.drda.host"); | |||
serverControl = new NetworkServerControl(InetAddress.getByName(host), port, DEFAULT_USER, DEFAULT_PWD); | |||
Logs.INFO.info("Starting embedded database on port " + port); | |||
serverControl.start(dbLog); | |||
ensureServerIsUp(); | |||
} catch (Exception e) { | |||
throw new SonarException(e); | |||
} | |||
} | |||
createDatabase(dbHome, user, password); | |||
private void saveDerbyPropertiesFile() { | |||
FileOutputStream output = null; | |||
try { | |||
File derbyProps = new File(dbHome.getPath() + "/derby.properties"); | |||
output = new FileOutputStream(derbyProps); | |||
dbProps.store(output, "GENERATED FILE, DO NOT EDIT ME UNLESS YOU WANT TO LOOSE YOUR TIME ;O)"); | |||
Server server = Server.createTcpServer("-tcpPort", port, "-tcpAllowOthers", "-ifExists", "-baseDir", dbHome.getAbsolutePath()); | |||
} catch (IOException e) { | |||
throw new SonarException(e); | |||
LOG.info("Starting embedded database on port " + server.getPort()); | |||
server.start(); | |||
} finally { | |||
IOUtils.closeQuietly(output); | |||
LOG.info("Embedded database started. Data stored in: " + dbHome.getAbsolutePath()); | |||
} catch (Exception e) { | |||
throw new SonarException("Unable to start database", e); | |||
} | |||
} | |||
public void stop() { | |||
if (serverControl != null) { | |||
try { | |||
serverControl.shutdown(); | |||
ensureServerIsDown(); | |||
serverControl = null; | |||
Logs.INFO.info("Embedded database stopped"); | |||
} catch (Exception e) { | |||
throw new SonarException(e); | |||
} | |||
if (server != null) { | |||
server.stop(); | |||
server = null; | |||
LOG.info("Embedded database stopped"); | |||
} | |||
} | |||
private void ensureServerIsUp() { | |||
for (int retry = 0; retry < 100; retry++) { | |||
try { | |||
serverControl.ping(); | |||
return; | |||
} catch (Exception ex) { | |||
sleep(300); | |||
} | |||
} | |||
throw new SonarException("Embedded database does not respond to ping requests"); | |||
private String getSetting(String name, String defaultValue) { | |||
return StringUtils.defaultIfBlank(settings.getString(name), defaultValue); | |||
} | |||
private void ensureServerIsDown() { | |||
for (int retry = 0; retry < 100; retry++) { | |||
try { | |||
serverControl.ping(); | |||
sleep(300); | |||
} catch (SonarException se) { | |||
throw se; | |||
private void createDatabase(File dbHome, String user, String password) throws SQLException { | |||
String url = String.format("jdbc:h2:%s/sonar;USER=%s;PASSWORD=%s", dbHome.getAbsolutePath(), user, password); | |||
} catch (Exception e) { | |||
// normal case: the database does not respond to ping | |||
return; | |||
} | |||
} | |||
throw new SonarException("Fail to stop embedded database"); | |||
DriverManager.getConnection(url).close(); | |||
} | |||
private static File getDataDirectory(Settings settings) { | |||
String dirName = settings.getString(DatabaseProperties.PROP_EMBEDDED_DATA_DIR); | |||
if (!StringUtils.isBlank(dirName)) { | |||
return new File(dirName); | |||
} | |||
private void sleep(long time) { | |||
try { | |||
Thread.sleep(time); | |||
} catch (InterruptedException e) { | |||
throw new SonarException("Fail to ping embedded database", e); | |||
File sonarHome = new File(settings.getString(CoreProperties.SONAR_HOME)); | |||
if (sonarHome.isDirectory() && sonarHome.exists()) { | |||
return new File(sonarHome, "data"); | |||
} | |||
} | |||
public static Properties getDefaultProperties(Settings settings) { | |||
Properties props = new Properties(); | |||
props.setProperty("derby.drda.startNetworkServer", "true"); | |||
props.setProperty("derby.drda.host", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.host"), "localhost")); | |||
props.setProperty("derby.drda.portNumber", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.portNumber"), "1527")); | |||
props.setProperty("derby.drda.maxThreads", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.maxThreads"), "20")); | |||
props.setProperty("derby.drda.minThreads", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.minThreads"), "2")); | |||
props.setProperty("derby.drda.logConnections", StringUtils.defaultIfBlank(settings.getString("sonar.derby.drda.logConnections"), "false")); | |||
props.setProperty("derby.stream.error.logSeverityLevel", StringUtils.defaultIfBlank(settings.getString("sonar.derby.stream.error.logSeverityLevel"), "20000")); | |||
props.setProperty("derby.connection.requireAuthentication", "true"); | |||
props.setProperty("derby.user." + DEFAULT_USER, DEFAULT_PWD); | |||
return props; | |||
throw new ServerStartException("Sonar home directory does not exist"); | |||
} | |||
} |
@@ -21,20 +21,25 @@ package org.sonar.server.database; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.core.persistence.dialect.H2; | |||
public class EmbeddedDatabaseFactory { | |||
private Settings settings; | |||
private final Settings settings; | |||
private final H2 dialect; | |||
private EmbeddedDatabase embeddedDatabase; | |||
public EmbeddedDatabaseFactory(Settings settings) { | |||
this.settings = settings; | |||
dialect = new H2(); | |||
} | |||
public void start() { | |||
String jdbcUrl = settings.getString(DatabaseProperties.PROP_URL); | |||
if (jdbcUrl != null && jdbcUrl.startsWith("jdbc:derby://") && jdbcUrl.contains("create=true") && embeddedDatabase == null) { | |||
embeddedDatabase = new EmbeddedDatabase(settings); | |||
embeddedDatabase.start(); | |||
if (embeddedDatabase == null) { | |||
String jdbcUrl = settings.getString(DatabaseProperties.PROP_URL); | |||
if (dialect.matchesJdbcURL(jdbcUrl)) { | |||
embeddedDatabase = new EmbeddedDatabase(settings); | |||
embeddedDatabase.start(); | |||
} | |||
} | |||
} | |||
@@ -97,7 +97,7 @@ public class BatchResourcesServlet extends HttpServlet { | |||
return libs; | |||
} | |||
private static final String[] IGNORE = { "derby", "jtds", "mysql", "postgresql", "jruby", "jfreechart", "eastwood", "jetty" }; | |||
private static final String[] IGNORE = {"h2", "jtds", "mysql", "postgresql", "jruby", "jfreechart", "eastwood", "jetty"}; | |||
/** | |||
* Dirty hack to disable downloading for certain files. |
@@ -19,120 +19,45 @@ | |||
*/ | |||
package org.sonar.server.database; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.commons.lang.SystemUtils; | |||
import org.apache.derby.jdbc.ClientDriver; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.core.persistence.InMemoryDatabase; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.net.ServerSocket; | |||
import java.sql.Connection; | |||
import java.sql.DriverManager; | |||
import java.util.Properties; | |||
import static junit.framework.Assert.fail; | |||
import static org.junit.Assert.assertTrue; | |||
public class EmbeddedDatabaseTest { | |||
@Test(timeout = 5000) | |||
public void should_start_and_stop() throws IOException { | |||
int port = freeServerPort(); | |||
private final static String TEST_ROOT_DIR = "./target/"; | |||
private final static String TEST_DB_DIR_PREFIX = "testDB"; | |||
private EmbeddedDatabase database; | |||
private String driverUrl; | |||
private Properties defaultProps; | |||
private static String testPort; | |||
@Before | |||
public void setUp() throws Exception { | |||
// This test doesn't work if InMemoryDatabase is active | |||
try { | |||
InMemoryDatabase.stopDatabase(); | |||
} catch (Exception e) { | |||
} | |||
windowsCleanup(); | |||
if (testPort == null) { | |||
testPort = Integer.toString(findFreeServerPort()); | |||
} | |||
defaultProps = EmbeddedDatabase.getDefaultProperties(new Settings()); | |||
defaultProps.put("derby.drda.portNumber", testPort); // changing the default port | |||
driverUrl = "jdbc:derby://localhost:" + testPort + "/sonar;create=true;user=sonar;password=sonar"; | |||
} | |||
private void windowsCleanup() { | |||
String os = System.getProperty("os.name"); | |||
if (os.toLowerCase().contains("windows")) { | |||
File testRoot = new File(TEST_ROOT_DIR); | |||
File[] files = testRoot.listFiles(); | |||
for (File file : files) { | |||
if (file.isDirectory() && | |||
file.getName().startsWith(TEST_DB_DIR_PREFIX)) { | |||
try { | |||
FileUtils.deleteDirectory(file); | |||
} catch (IOException e) { | |||
} | |||
} | |||
} | |||
} | |||
} | |||
private int findFreeServerPort() throws IOException, InterruptedException { | |||
ServerSocket srv = new ServerSocket(0); | |||
int port = srv.getLocalPort(); | |||
srv.close(); | |||
Thread.sleep(1500); | |||
return port; | |||
} | |||
@Test | |||
public void shouldStartAndStop() throws Exception { | |||
database = new EmbeddedDatabase(new File(TEST_ROOT_DIR + TEST_DB_DIR_PREFIX + testPort), defaultProps); | |||
EmbeddedDatabase database = new EmbeddedDatabase(settings(port)); | |||
database.start(); | |||
ClientDriver.class.newInstance(); | |||
Connection conn; | |||
try { | |||
conn = DriverManager.getConnection(driverUrl); | |||
conn.close(); | |||
String driverUrl = String.format("jdbc:h2:tcp://localhost:%d/sonar;USER=login;PASSWORD=pwd", port); | |||
DriverManager.getConnection(driverUrl).close(); | |||
} catch (Exception ex) { | |||
fail("Unable to connect after start"); | |||
} | |||
try { | |||
conn = DriverManager.getConnection("jdbc:derby://localhost:" + testPort + "/sonar;user=foo;password=bar"); | |||
conn.close(); | |||
fail("Able to connect with wrong username and password"); | |||
} catch (Exception ex) { | |||
} | |||
File testDb = new File(database.getDataDir(), "sonar"); | |||
assertTrue(testDb.exists()); | |||
assertTrue(testDb.isDirectory()); | |||
database.stop(); | |||
try { | |||
conn = DriverManager.getConnection(driverUrl); | |||
conn.close(); | |||
fail("Able to connect after stop"); | |||
} catch (Exception ex) { | |||
} | |||
} | |||
@After | |||
public void tearDown() throws IOException { | |||
if (database.getDataDir().exists()) { | |||
if (!SystemUtils.IS_OS_WINDOWS) { | |||
// avoid an issue with file lock issue under windows.. | |||
// thank you mr microsoft | |||
// solution : no really good solution found.., the db home is not deleted under windows on teardown but only during test startup | |||
FileUtils.deleteDirectory(database.getDataDir()); | |||
} | |||
} | |||
static Settings settings(int port) { | |||
return new Settings() | |||
.setProperty(DatabaseProperties.PROP_USER, "login") | |||
.setProperty(DatabaseProperties.PROP_PASSWORD, "pwd") | |||
.setProperty(DatabaseProperties.PROP_EMBEDDED_PORT, "" + port) | |||
.setProperty(DatabaseProperties.PROP_EMBEDDED_DATA_DIR, "./target/testDB"); | |||
} | |||
static int freeServerPort() throws IOException { | |||
ServerSocket srv = new ServerSocket(0); | |||
srv.close(); | |||
return srv.getLocalPort(); | |||
} | |||
} |
@@ -23,7 +23,7 @@ import com.google.common.collect.Sets; | |||
import org.junit.Test; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.resources.Resource; | |||
import org.sonar.core.persistence.dialect.Derby; | |||
import org.sonar.core.persistence.dialect.H2; | |||
import org.sonar.core.persistence.dialect.MsSql; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
@@ -39,7 +39,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void mustDefineAtLeastOneQualifier() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(new Filter()); | |||
assertThat(result.size()).isEqualTo(0);// no qualifiers | |||
} | |||
@@ -47,7 +47,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterOnScopes() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setScopes(Sets.newHashSet(Resource.SCOPE_SPACE))); | |||
assertSnapshotIds(result, 4); | |||
} | |||
@@ -55,7 +55,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterOnQualifiers() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(new Filter().setQualifiers(Sets.newHashSet(Resource.QUALIFIER_PROJECT, Resource.QUALIFIER_MODULE))); | |||
assertSnapshotIds(result, 2, 3); | |||
} | |||
@@ -63,7 +63,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterOnLanguages() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setLanguages(Sets.newHashSet("java"))); | |||
assertSnapshotIds(result, 2, 4); | |||
} | |||
@@ -71,7 +71,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterOnDate() throws ParseException { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2008-12-26 00:00"); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setDateCriterion(new DateCriterion(">", date))); | |||
assertSnapshotIds(result, 3); | |||
@@ -80,7 +80,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterOnDateIncludesTime() throws ParseException { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2008-12-25 03:00"); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setDateCriterion(new DateCriterion("<", date))); | |||
assertSnapshotIds(result, 2, 4); | |||
@@ -89,7 +89,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterOnBaseSnapshot() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setPath(2, 2, "")); | |||
assertSnapshotIds(result, 4); | |||
} | |||
@@ -97,7 +97,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByName() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setSortedByName()); | |||
assertSortedSnapshotIds(result, 2, 4, 3); | |||
} | |||
@@ -105,7 +105,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByKey() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setSortedByKey()); | |||
assertSortedSnapshotIds(result, 3, 2, 4); | |||
} | |||
@@ -113,7 +113,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByDate() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setSortedByDate()); | |||
assertSortedSnapshotIds(result, 2, 4, 3); | |||
} | |||
@@ -121,7 +121,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByDescendingDate() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setSortedByDate().setAscendingSort(false)); | |||
assertSortedSnapshotIds(result, 3, 4, 2); | |||
} | |||
@@ -129,7 +129,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByAscendingDate() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setSortedByDate().setAscendingSort(true)); | |||
assertSortedSnapshotIds(result, 2, 4, 3); | |||
} | |||
@@ -137,7 +137,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByAscendingMeasureValue() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.setSortedMetricId(2, true, false); | |||
@@ -149,7 +149,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByDecendingMeasureValue() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.setSortedMetricId(2, true, false) | |||
@@ -162,7 +162,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void applySingleMeasureCriterion() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(2, ">", 50.0, false)); | |||
@@ -174,7 +174,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void applyManyMeasureCriteria() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(2, ">", 50.0, false)) | |||
@@ -187,7 +187,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void criteriaAreExclusive() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(2, ">", 50.0, false)) | |||
@@ -200,7 +200,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortAndFilterMeasures() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(2, ">", 5.0, false)) | |||
@@ -214,7 +214,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortDescendingAndFilterMeasures() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(2, ">", 5.0, false)) // filter on coverage | |||
@@ -229,7 +229,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterByResourceKey() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setKeyRegexp("*:org.sonar.*")); | |||
assertSnapshotIds(result, 4); | |||
} | |||
@@ -237,7 +237,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterByResourceKeyIsCaseInsensitive() { | |||
setupData("shared"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
FilterResult result = executor.execute(Filter.createForAllQualifiers().setKeyRegexp("*:ORG.SonAR.*")); | |||
assertSnapshotIds(result, 4); | |||
} | |||
@@ -245,7 +245,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterByMissingMeasureValue() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(3, ">", 0.0, false)); // filter on duplicated lines | |||
@@ -257,7 +257,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterByMissingMeasureValues() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(1, ">", 0.0, false)) // filter on lines | |||
@@ -270,7 +270,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void sortByMissingMeasureValue() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.setSortedMetricId(3, true, false); // sort by duplicated lines | |||
@@ -282,7 +282,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void filterByMeasureValueAndSortOnOtherMetric() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(1, ">", 0.0, false)) // lines > 0 | |||
@@ -295,7 +295,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void intersectionOfCriteriaOnSameMetric() { | |||
setupData("shared", "measures"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.CLASS)) | |||
.addMeasureCriterion(new MeasureCriterion(1, ">", 400.0, false)) // lines > 400 | |||
@@ -308,7 +308,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void ignoreProjectCopiesOfViews() { | |||
setupData("views"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setQualifiers(Sets.newHashSet(Qualifiers.PROJECT)); | |||
@@ -319,7 +319,7 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void loadProjectCopiesIfPathIsAView() { | |||
setupData("views"); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new Derby()); | |||
FilterExecutor executor = new FilterExecutor(getSession(), new H2()); | |||
Filter filter = new Filter() | |||
.setPath(2, 2, "") | |||
.setQualifiers(Sets.newHashSet(Qualifiers.SUBVIEW, Qualifiers.PROJECT)); | |||
@@ -335,11 +335,10 @@ public class FilterExecutorTest extends AbstractDbUnitTestCase { | |||
String sql = new FilterExecutor(getSession(), new MsSql()).toSql(filter); | |||
assertThat(sql).contains(" WITH (INDEX(measures_sid_metric)) "); | |||
sql = new FilterExecutor(getSession(), new Derby()).toSql(filter); | |||
sql = new FilterExecutor(getSession(), new H2()).toSql(filter); | |||
assertThat(sql).doesNotContain(" WITH (INDEX(measures_sid_metric)) "); | |||
} | |||
private void assertSnapshotIds(FilterResult result, int... snapshotIds) { | |||
assertThat(result.size()).isEqualTo(snapshotIds.length); | |||
for (int snapshotId : snapshotIds) { |
@@ -79,9 +79,7 @@ public class BatchResourcesServletTest { | |||
@Test | |||
public void shouldIgnore() { | |||
assertThat(BatchResourcesServlet.isIgnored("sonar-batch-2.6-SNAPSHOT.jar"), is(false)); | |||
assertThat(BatchResourcesServlet.isIgnored("derby-10.6.1.0.jar"), is(true)); | |||
assertThat(BatchResourcesServlet.isIgnored("derbyclient-10.6.1.0.jar"), is(true)); | |||
assertThat(BatchResourcesServlet.isIgnored("derbynet-10.6.1.0.jar"), is(true)); | |||
assertThat(BatchResourcesServlet.isIgnored("h2-1.3.166.jar"), is(true)); | |||
assertThat(BatchResourcesServlet.isIgnored("mysql-connector-java-5.1.13.jar"), is(true)); | |||
assertThat(BatchResourcesServlet.isIgnored("postgresql-9.0-801.jdbc3.jar"), is(true)); | |||
assertThat(BatchResourcesServlet.isIgnored("jtds-1.2.4.jar"), is(true)); |
@@ -41,8 +41,8 @@ | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.derby</groupId> | |||
<artifactId>derby</artifactId> | |||
<groupId>com.h2database</groupId> | |||
<artifactId>h2</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.dbunit</groupId> |
@@ -0,0 +1,12 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar</artifactId> | |||
<version>3.2-SNAPSHOT</version> | |||
</parent> | |||
<artifactId>sonar-web-test</artifactId> | |||
<name>Sonar :: Web Test</name> | |||
<description>Test of the web site</description> | |||
</project> |