aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db/src/main
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-08-17 16:49:34 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-08-22 10:25:43 +0200
commite9ac521dd1204c523dc0e497f141529e6abd4e3f (patch)
tree6d0272be6f1b2433affd3196e132d14d8fbe4fe2 /sonar-db/src/main
parent6dac2f2642d8ac888e1c07066f2081b61ea37ae3 (diff)
downloadsonarqube-e9ac521dd1204c523dc0e497f141529e6abd4e3f.tar.gz
sonarqube-e9ac521dd1204c523dc0e497f141529e6abd4e3f.zip
SONAR-7844 add ScannerContextDao
Diffstat (limited to 'sonar-db/src/main')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DaoModule.java10
-rw-r--r--sonar-db/src/main/java/org/sonar/db/DbClient.java7
-rw-r--r--sonar-db/src/main/java/org/sonar/db/MyBatis.java8
-rw-r--r--sonar-db/src/main/java/org/sonar/db/scannercontext/LogsIteratorInputStream.java91
-rw-r--r--sonar-db/src/main/java/org/sonar/db/scannercontext/ScannerContextDao.java84
-rw-r--r--sonar-db/src/main/java/org/sonar/db/scannercontext/package-info.java24
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl1
7 files changed, 217 insertions, 8 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/DaoModule.java b/sonar-db/src/main/java/org/sonar/db/DaoModule.java
index ba299a873ca..d18f35a86dd 100644
--- a/sonar-db/src/main/java/org/sonar/db/DaoModule.java
+++ b/sonar-db/src/main/java/org/sonar/db/DaoModule.java
@@ -27,10 +27,10 @@ import org.sonar.db.ce.CeActivityDao;
import org.sonar.db.ce.CeQueueDao;
import org.sonar.db.ce.CeTaskInputDao;
import org.sonar.db.component.ComponentDao;
+import org.sonar.db.component.ComponentKeyUpdaterDao;
import org.sonar.db.component.ComponentLinkDao;
import org.sonar.db.component.ResourceDao;
import org.sonar.db.component.ResourceIndexDao;
-import org.sonar.db.component.ComponentKeyUpdaterDao;
import org.sonar.db.component.SnapshotDao;
import org.sonar.db.dashboard.ActiveDashboardDao;
import org.sonar.db.dashboard.DashboardDao;
@@ -50,8 +50,8 @@ import org.sonar.db.measure.custom.CustomMeasureDao;
import org.sonar.db.metric.MetricDao;
import org.sonar.db.notification.NotificationQueueDao;
import org.sonar.db.permission.PermissionDao;
-import org.sonar.db.permission.template.PermissionTemplateDao;
import org.sonar.db.permission.template.PermissionTemplateCharacteristicDao;
+import org.sonar.db.permission.template.PermissionTemplateDao;
import org.sonar.db.property.PropertiesDao;
import org.sonar.db.purge.PurgeDao;
import org.sonar.db.qualitygate.ProjectQgateAssociationDao;
@@ -60,6 +60,7 @@ import org.sonar.db.qualitygate.QualityGateDao;
import org.sonar.db.qualityprofile.ActiveRuleDao;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.rule.RuleDao;
+import org.sonar.db.scannercontext.ScannerContextDao;
import org.sonar.db.source.FileSourceDao;
import org.sonar.db.user.AuthorDao;
import org.sonar.db.user.AuthorizationDao;
@@ -102,11 +103,12 @@ public class DaoModule extends Module {
PermissionTemplateDao.class,
PermissionTemplateCharacteristicDao.class,
PropertiesDao.class,
+ ProjectQgateAssociationDao.class,
+ PurgeDao.class,
QualityGateDao.class,
QualityGateConditionDao.class,
- ProjectQgateAssociationDao.class,
QualityProfileDao.class,
- PurgeDao.class,
+ ScannerContextDao.class,
RuleDao.class,
ActiveRuleDao.class,
ResourceIndexDao.class,
diff --git a/sonar-db/src/main/java/org/sonar/db/DbClient.java b/sonar-db/src/main/java/org/sonar/db/DbClient.java
index 527b3dd7630..929813bfd66 100644
--- a/sonar-db/src/main/java/org/sonar/db/DbClient.java
+++ b/sonar-db/src/main/java/org/sonar/db/DbClient.java
@@ -60,6 +60,7 @@ import org.sonar.db.qualitygate.QualityGateDao;
import org.sonar.db.qualityprofile.ActiveRuleDao;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.rule.RuleDao;
+import org.sonar.db.scannercontext.ScannerContextDao;
import org.sonar.db.source.FileSourceDao;
import org.sonar.db.user.AuthorDao;
import org.sonar.db.user.AuthorizationDao;
@@ -121,6 +122,7 @@ public class DbClient {
private final GroupDao groupDao;
private final RuleDao ruleDao;
private final ActiveRuleDao activeRuleDao;
+ private final ScannerContextDao scannerContextDao;
public DbClient(Database database, MyBatis myBatis, Dao... daos) {
this.database = database;
@@ -177,6 +179,7 @@ public class DbClient {
groupDao = getDao(map, GroupDao.class);
ruleDao = getDao(map, RuleDao.class);
activeRuleDao = getDao(map, ActiveRuleDao.class);
+ scannerContextDao = getDao(map, ScannerContextDao.class);
doOnLoad(map);
}
@@ -385,6 +388,10 @@ public class DbClient {
return activeRuleDao;
}
+ public ScannerContextDao scannerContextDao() {
+ return scannerContextDao;
+ }
+
protected <K extends Dao> K getDao(Map<Class, Dao> map, Class<K> clazz) {
return (K) map.get(clazz);
}
diff --git a/sonar-db/src/main/java/org/sonar/db/MyBatis.java b/sonar-db/src/main/java/org/sonar/db/MyBatis.java
index a4666c5c1e9..9ea48e9e2cb 100644
--- a/sonar-db/src/main/java/org/sonar/db/MyBatis.java
+++ b/sonar-db/src/main/java/org/sonar/db/MyBatis.java
@@ -36,6 +36,7 @@ import org.sonar.db.ce.CeQueueMapper;
import org.sonar.db.ce.CeTaskInputMapper;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentDtoWithSnapshotId;
+import org.sonar.db.component.ComponentKeyUpdaterMapper;
import org.sonar.db.component.ComponentLinkDto;
import org.sonar.db.component.ComponentLinkMapper;
import org.sonar.db.component.ComponentMapper;
@@ -43,7 +44,6 @@ import org.sonar.db.component.FilePathWithHashDto;
import org.sonar.db.component.ResourceDto;
import org.sonar.db.component.ResourceIndexDto;
import org.sonar.db.component.ResourceIndexMapper;
-import org.sonar.db.component.ComponentKeyUpdaterMapper;
import org.sonar.db.component.ResourceMapper;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.component.SnapshotMapper;
@@ -84,13 +84,13 @@ import org.sonar.db.metric.MetricMapper;
import org.sonar.db.notification.NotificationQueueDto;
import org.sonar.db.notification.NotificationQueueMapper;
import org.sonar.db.permission.GroupWithPermissionDto;
+import org.sonar.db.permission.UserWithPermissionDto;
+import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto;
+import org.sonar.db.permission.template.PermissionTemplateCharacteristicMapper;
import org.sonar.db.permission.template.PermissionTemplateDto;
import org.sonar.db.permission.template.PermissionTemplateGroupDto;
import org.sonar.db.permission.template.PermissionTemplateMapper;
import org.sonar.db.permission.template.PermissionTemplateUserDto;
-import org.sonar.db.permission.UserWithPermissionDto;
-import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto;
-import org.sonar.db.permission.template.PermissionTemplateCharacteristicMapper;
import org.sonar.db.property.PropertiesMapper;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.purge.IdUuidPair;
diff --git a/sonar-db/src/main/java/org/sonar/db/scannercontext/LogsIteratorInputStream.java b/sonar-db/src/main/java/org/sonar/db/scannercontext/LogsIteratorInputStream.java
new file mode 100644
index 00000000000..ab55e461818
--- /dev/null
+++ b/sonar-db/src/main/java/org/sonar/db/scannercontext/LogsIteratorInputStream.java
@@ -0,0 +1,91 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.scannercontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import org.sonar.core.util.CloseableIterator;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * An {@link InputStream} that will read from a {@link CloseableIterator} of {@link String}, inserting {@code \n} between
+ * each element of the Iterator.
+ */
+final class LogsIteratorInputStream extends InputStream {
+ private static final int UNSET = -1;
+ private static final int END_OF_STREAM = -1;
+
+ private final Charset charset;
+ private final byte[] lineFeed;
+ private CloseableIterator<String> logsIterator;
+ private byte[] buf;
+ private int nextChar = UNSET;
+
+ LogsIteratorInputStream(CloseableIterator<String> logsIterator, Charset charset) {
+ checkArgument(logsIterator.hasNext(), "LogsIterator can't be empty or already read");
+ this.charset = charset;
+ this.lineFeed = "\n".getBytes(charset);
+ this.logsIterator = logsIterator;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (nextChar == UNSET || nextChar >= buf.length) {
+ fill();
+ if (nextChar == UNSET) {
+ return END_OF_STREAM;
+ }
+ }
+ return buf[nextChar++];
+ }
+
+ private void fill() {
+ if (logsIterator.hasNext()) {
+ byte[] line = logsIterator.next().getBytes(charset);
+ boolean hasNextLine = logsIterator.hasNext();
+ int bufLength = hasNextLine ? (line.length + lineFeed.length) : line.length;
+ // empty last line
+ if (bufLength == 0) {
+ this.buf = null;
+ this.nextChar = UNSET;
+ } else {
+ this.buf = new byte[bufLength];
+ System.arraycopy(line, 0, buf, 0, line.length);
+ if (hasNextLine) {
+ System.arraycopy(lineFeed, 0, buf, line.length, lineFeed.length);
+ }
+ this.nextChar = 0;
+ }
+ } else {
+ this.buf = null;
+ this.nextChar = UNSET;
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ this.logsIterator.close();
+ this.buf = null;
+
+ super.close();
+ }
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/scannercontext/ScannerContextDao.java b/sonar-db/src/main/java/org/sonar/db/scannercontext/ScannerContextDao.java
new file mode 100644
index 00000000000..c294922548c
--- /dev/null
+++ b/sonar-db/src/main/java/org/sonar/db/scannercontext/ScannerContextDao.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.scannercontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Optional;
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.core.util.CloseableIterator;
+import org.sonar.db.Dao;
+import org.sonar.db.DbSession;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class ScannerContextDao implements Dao {
+
+ private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ private final System2 system;
+
+ public ScannerContextDao(System2 system) {
+ this.system = system;
+ }
+
+ /**
+ * @throws IllegalArgumentException if {@code scannerContextLines} is empty or fully read.
+ */
+ public void insert(DbSession dbSession, String analysisUuid, CloseableIterator<String> scannerContextLines) {
+ checkArgument(scannerContextLines.hasNext(), "Scanner context can not be empty");
+ long now = system.now();
+ try (PreparedStatement stmt = dbSession.getConnection().prepareStatement(
+ "INSERT INTO scanner_context (analysis_uuid, created_at, updated_at, data) VALUES (?, ?, ?, ?)");
+ InputStream inputStream = new LogsIteratorInputStream(scannerContextLines, UTF_8)) {
+ stmt.setString(1, analysisUuid);
+ stmt.setLong(2, now);
+ stmt.setLong(3, now);
+ stmt.setBinaryStream(4, inputStream);
+ stmt.executeUpdate();
+ } catch (SQLException | IOException e) {
+ throw new IllegalStateException("Fail to insert scanner context for analysis " + analysisUuid, e);
+ }
+ }
+
+ /**
+ * The scanner context is very likely to contain lines, which are forcefully separated by {@code \n} characters,
+ * whichever the platform SQ is running on ({@see LogsIteratorInputStream}).
+ */
+ public Optional<String> selectScannerContext(DbSession dbSession, String analysisUuid) {
+ try (PreparedStatement stmt = dbSession.getConnection().prepareStatement("select data from scanner_context where analysis_uuid=?")) {
+ stmt.setString(1, analysisUuid);
+ try (ResultSet rs = stmt.executeQuery()) {
+ if (rs.next()) {
+ return Optional.of(IOUtils.toString(rs.getBinaryStream(1), UTF_8));
+ }
+ return Optional.empty();
+ }
+ } catch (SQLException | IOException e) {
+ throw new IllegalStateException("Fail to retrieve scanner context of analysis " + analysisUuid, e);
+ }
+ }
+
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/scannercontext/package-info.java b/sonar-db/src/main/java/org/sonar/db/scannercontext/package-info.java
new file mode 100644
index 00000000000..de8b7394f01
--- /dev/null
+++ b/sonar-db/src/main/java/org/sonar/db/scannercontext/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.db.scannercontext;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl b/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
index 7559720c657..3aeed281ed8 100644
--- a/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
+++ b/sonar-db/src/main/resources/org/sonar/db/version/schema-h2.ddl
@@ -544,6 +544,7 @@ CREATE TABLE "CE_ACTIVITY" (
);
CREATE TABLE "CE_TASK_INPUT" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"TASK_UUID" VARCHAR(40) NOT NULL,
"DATA" BLOB(167772150),
"CREATED_AT" BIGINT NOT NULL,