@Override
public final void execute() throws SQLException {
- Connection connection = null;
+ Connection readConnection = null, writeConnection = null;
try {
- connection = db.getDataSource().getConnection();
- connection.setAutoCommit(false);
- Context context = new Context(db, connection);
+ readConnection = db.getDataSource().getConnection();
+ writeConnection = db.getDataSource().getConnection();
+ writeConnection.setAutoCommit(false);
+ Context context = new Context(db, readConnection, writeConnection);
execute(context);
} finally {
- DbUtils.closeQuietly(connection);
+ DbUtils.closeQuietly(readConnection);
+ DbUtils.closeQuietly(writeConnection);
}
}
}
import org.apache.commons.dbutils.DbUtils;
import javax.annotation.Nullable;
-
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
public CHILD close() {
DbUtils.closeQuietly(pstmt);
pstmt = null;
- return (CHILD)this;
+ return (CHILD) this;
}
@Override
return (CHILD) this;
}
+ @Override
+ public CHILD setDouble(int columnIndex, @Nullable Double value) throws SQLException {
+ if (value == null) {
+ pstmt.setNull(columnIndex, Types.DECIMAL);
+ } else {
+ pstmt.setDouble(columnIndex, value);
+ }
+ return (CHILD) this;
+ }
+
@Override
public CHILD setDate(int columnIndex, @Nullable Date value) throws SQLException {
if (value == null) {
class Context {
private final Database db;
- private final Connection connection;
+ private final Connection readConnection, writeConnection;
- public Context(Database db, Connection connection) {
+ public Context(Database db, Connection readConnection, Connection writeConnection) {
this.db = db;
- this.connection = connection;
+ this.readConnection = readConnection;
+ this.writeConnection = writeConnection;
}
public Select prepareSelect(String sql) throws SQLException {
- return SelectImpl.create(db, connection, sql);
+ return SelectImpl.create(db, readConnection, sql);
}
public Upsert prepareUpsert(String sql) throws SQLException {
- return UpsertImpl.create(connection, sql);
+ return UpsertImpl.create(writeConnection, sql);
}
public MassUpdate prepareMassUpdate() throws SQLException {
- return new MassUpdate(db, connection);
+ return new MassUpdate(db, writeConnection);
}
}
}
static interface RowReader<T> {
+ RowReader<Long> LONG = new LongReader();
T read(Row row) throws SQLException;
}
}
}
- public static final LongReader LONG_READER = new LongReader();
-
static interface RowHandler<T> {
void handle(Row row) throws SQLException;
}
- <T> List<T> query(RowReader<T> reader) throws SQLException;
+ <T> List<T> list(RowReader<T> reader) throws SQLException;
+
+ @CheckForNull
+ <T> T get(RowReader<T> reader) throws SQLException;
void scroll(RowHandler handler) throws SQLException;
}
}
@Override
- public <T> List<T> query(Select.RowReader<T> reader) throws SQLException {
+ public <T> List<T> list(Select.RowReader<T> reader) throws SQLException {
ResultSet rs = pstmt.executeQuery();
Select.Row row = new Select.Row(rs);
try {
}
}
+ @Override
+ public <T> T get(Select.RowReader<T> reader) throws SQLException {
+ ResultSet rs = pstmt.executeQuery();
+ Select.Row row = new Select.Row(rs);
+ try {
+ if (rs.next()) {
+ return reader.read(row);
+ }
+ return null;
+ } finally {
+ DbUtils.closeQuietly(rs);
+ close();
+ }
+ }
+
@Override
public void scroll(Select.RowHandler handler) throws SQLException {
ResultSet rs = pstmt.executeQuery();
CHILD setDate(int columnIndex, @Nullable Date value) throws SQLException;
+ CHILD setDouble(int columnIndex, @Nullable Double value) throws SQLException;
+
CHILD setInt(int columnIndex, @Nullable Integer value) throws SQLException;
CHILD setLong(int columnIndex, @Nullable Long value) throws SQLException;
*/
package org.sonar.server.db.migrations.v45;
-import org.apache.commons.dbutils.DbUtils;
+import org.sonar.api.utils.System2;
import org.sonar.core.persistence.Database;
import org.sonar.server.db.migrations.BaseDataChange;
import org.sonar.server.db.migrations.Select;
import org.sonar.server.db.migrations.Upsert;
-import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
*/
public class AddMissingRuleParameterDefaultValuesMigration extends BaseDataChange {
- public AddMissingRuleParameterDefaultValuesMigration(Database db) {
+ private final System2 system;
+
+ public AddMissingRuleParameterDefaultValuesMigration(Database db, System2 system) {
super(db);
+ this.system = system;
}
@Override
public void execute(Context context) {
- Connection connection = null;
try {
// get all the parameters with default value
List<RuleParam> ruleParameters = context.prepareSelect("select id,rule_id,name,default_value from rules_parameters where default_value is not null")
- .query(new Select.RowReader<RuleParam>() {
+ .list(new Select.RowReader<RuleParam>() {
@Override
public RuleParam read(Select.Row row) throws SQLException {
return new RuleParam(row.getLong(1), row.getLong(2), row.getString(3), row.getString(4));
"where ar.rule_id=? and arp.id is null")
.setLong(1, ruleParameter.id)
.setLong(2, ruleParameter.ruleId)
- .query(new Select.RowReader<ActiveRule>() {
+ .list(new Select.RowReader<ActiveRule>() {
@Override
public ActiveRule read(Select.Row row) throws SQLException {
return new ActiveRule(row.getLong(1), row.getLong(2));
.setString(4, ruleParameter.name)
.addBatch();
}
- upsert.execute();
+ upsert.execute().commit().close();
// update date for ES indexation
upsert = context.prepareUpsert("update active_rules set updated_at=? where id=?");
- Date now = new Date();
+ Date now = new Date(system.now());
for (ActiveRule activeRule : activeRules) {
upsert
.setDate(1, now)
.setLong(2, activeRule.id)
.addBatch();
}
- upsert.execute();
+ upsert.execute().commit().close();
}
} catch (SQLException e) {
e.printStackTrace();
- } finally {
- DbUtils.closeQuietly(connection);
}
}
this.profileId = profileId;
}
}
-
- private static class ActiveRuleParam {
- final long activeRuleId, ruleParamId;
- final String value, ruleParamKey;
-
- ActiveRuleParam(long activeRuleId, long ruleParamId, String ruleParamKey, String value) {
- this.activeRuleId = activeRuleId;
- this.ruleParamId = ruleParamId;
- this.ruleParamKey = ruleParamKey;
- this.value = value;
- }
- }
}
new BaseDataChange(db.database()) {
@Override
public void execute(Context context) throws SQLException {
- ids.addAll(context.prepareSelect("select id from persons order by id desc").query(Select.LONG_READER));
+ ids.addAll(context.prepareSelect("select id from persons order by id desc").list(Select.RowReader.LONG));
}
}.execute();
assertThat(ids).containsExactly(3L, 2L, 1L);
public void execute(Context context) throws SQLException {
persons.addAll(context
.prepareSelect("select id,login,age,enabled,updated_at from persons where id=2")
- .query(new UserReader()));
+ .list(new UserReader()));
}
}.execute();
assertThat(persons).hasSize(1);
new BaseDataChange(db.database()) {
@Override
public void execute(Context context) throws SQLException {
- ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).query(Select.LONG_READER));
+ ids.addAll(context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(Select.RowReader.LONG));
}
}.execute();
assertThat(ids).containsOnly(2L, 3L);
@Override
public void execute(Context context) throws SQLException {
// parameter value is not set
- ids.addAll(context.prepareSelect("select id from persons where id>=?").query(Select.LONG_READER));
+ ids.addAll(context.prepareSelect("select id from persons where id>=?").list(Select.RowReader.LONG));
}
};
try {
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.db.migrations.v45;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.server.db.migrations.DatabaseMigration;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AddMissingRuleParameterDefaultValuesMigrationTest {
+
+ @ClassRule
+ public static TestDatabase db = new TestDatabase().schema(AddMissingRuleParameterDefaultValuesMigrationTest.class, "schema.sql");
+
+ DatabaseMigration migration;
+ System2 system = mock(System2.class);
+
+ @Before
+ public void setUp() throws Exception {
+ db.executeUpdateSql("truncate table rules_parameters");
+ db.executeUpdateSql("truncate table active_rules");
+ db.executeUpdateSql("truncate table active_rule_parameters");
+ migration = new AddMissingRuleParameterDefaultValuesMigration(db.database(), system);
+ when(system.now()).thenReturn(DateUtils.parseDate("2014-04-28").getTime());
+ }
+
+ @Test
+ public void execute() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "after.xml", "rules_parameters", "active_rules", "active_rule_parameters");
+ }
+
+}
--- /dev/null
+<dataset>
+ <!-- with default value -->
+ <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]" />
+
+ <!-- without default value, to be ignored -->
+ <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]" />
+
+ <!-- this active rule has all parameters -->
+ <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01" />
+ <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+ <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+ <!-- this active rule does not have parameters. UPDATED_AT CHANGED -->
+ <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2014-04-28" />
+
+ <!-- newly created -->
+ <active_rule_parameters id="10002" active_rule_id="101" rules_parameter_id="1" rules_parameter_key="max" value="10"/>
+</dataset>
--- /dev/null
+<dataset>
+ <!-- with default value -->
+ <rules_parameters id="1" rule_id="10" name="max" param_type="INT" default_value="10" description="[null]" />
+
+ <!-- without default value, to be ignored -->
+ <rules_parameters id="2" rule_id="10" name="min" param_type="INT" default_value="[null]" description="[null]" />
+
+ <!-- this active rule has all parameters -->
+ <active_rules id="100" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01" />
+ <active_rule_parameters id="10000" active_rule_id="100" rules_parameter_id="1" rules_parameter_key="max" value="9"/>
+ <active_rule_parameters id="10001" active_rule_id="100" rules_parameter_id="2" rules_parameter_key="min" value="4"/>
+
+ <!-- this active rule does not have parameters -->
+ <active_rules id="101" profile_id="1000" rule_id="10" failure_level="3" inheritance="[null]"
+ created_at="2012-01-01" updated_at="2012-01-01" />
+</dataset>
--- /dev/null
+CREATE TABLE "RULES_PARAMETERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "RULE_ID" INTEGER NOT NULL,
+ "NAME" VARCHAR(128) NOT NULL,
+ "PARAM_TYPE" VARCHAR(512) NOT NULL,
+ "DEFAULT_VALUE" VARCHAR(4000),
+ "DESCRIPTION" VARCHAR(4000)
+);
+
+
+CREATE TABLE "ACTIVE_RULES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROFILE_ID" INTEGER NOT NULL,
+ "RULE_ID" INTEGER NOT NULL,
+ "FAILURE_LEVEL" INTEGER NOT NULL,
+ "INHERITANCE" VARCHAR(10),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+
+CREATE TABLE "ACTIVE_RULE_PARAMETERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "ACTIVE_RULE_ID" INTEGER NOT NULL,
+ "RULES_PARAMETER_ID" INTEGER NOT NULL,
+ "RULES_PARAMETER_KEY" VARCHAR(128),
+ "VALUE" VARCHAR(4000)
+);