Skip to content

Commit 71936b4

Browse files
SLCORE-1845 Enable the new database globally
1 parent 08fffa1 commit 71936b4

File tree

64 files changed

+596
-3915
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+596
-3915
lines changed

backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/storage/SonarLintDatabase.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,18 @@
2121

2222
import java.nio.file.Files;
2323
import java.nio.file.Path;
24-
import java.util.Set;
25-
import java.util.function.Consumer;
2624
import org.apache.commons.io.FileUtils;
2725
import org.apache.commons.lang3.StringUtils;
2826
import org.flywaydb.core.Flyway;
2927
import org.h2.jdbcx.JdbcConnectionPool;
30-
import org.jooq.Configuration;
3128
import org.jooq.DSLContext;
3229
import org.jooq.SQLDialect;
3330
import org.jooq.impl.DSL;
3431
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
3532

36-
import static org.sonarsource.sonarlint.core.commons.storage.model.Tables.AI_CODEFIX_SETTINGS;
37-
3833
public final class SonarLintDatabase {
3934
private static final SonarLintLogger LOG = SonarLintLogger.get();
35+
4036
public static final String SQ_IDE_DB_FILENAME = "sq-ide";
4137

4238
private final JdbcConnectionPool dataSource;
@@ -91,10 +87,6 @@ public DSLContext dsl() {
9187
return dsl;
9288
}
9389

94-
public void withTransaction(Consumer<Configuration> transaction) {
95-
dsl.transaction(transaction::accept);
96-
}
97-
9890
public void shutdown() {
9991
try {
10092
dataSource.dispose();
@@ -103,10 +95,4 @@ public void shutdown() {
10395
LOG.debug("Error while disposing H2Database: {}", e.getMessage());
10496
}
10597
}
106-
107-
public void cleanupNonExistingConnections(Set<String> existingConnectionIds) {
108-
dsl.deleteFrom(AI_CODEFIX_SETTINGS)
109-
.where(AI_CODEFIX_SETTINGS.CONNECTION_ID.notIn(existingConnectionIds))
110-
.execute();
111-
}
11298
}

backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/storage/XodusPurgeUtils.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import java.nio.file.Files;
2323
import java.nio.file.Path;
24-
import java.util.Date;
2524
import org.apache.commons.io.FileUtils;
2625
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
2726

@@ -33,23 +32,6 @@ private XodusPurgeUtils() {
3332

3433
private static final SonarLintLogger LOG = SonarLintLogger.get();
3534

36-
public static void purgeOldTemporaryFiles(Path workDir, Integer purgeDays, String pattern) {
37-
if (Files.exists(workDir)) {
38-
try (var stream = Files.newDirectoryStream(workDir, pattern)) {
39-
for (var path : stream) {
40-
var file = path.toFile();
41-
var diff = new Date().getTime() - file.lastModified();
42-
if (diff > purgeDays * 24 * 60 * 60 * 1000) {
43-
FileUtils.deleteQuietly(file);
44-
LOG.debug("Successfully purged " + path);
45-
}
46-
}
47-
} catch (Exception e) {
48-
LOG.error("Unable to purge old temporary files for pattern " + pattern);
49-
}
50-
}
51-
}
52-
5335
public static void deleteInFolderWithPattern(Path folder, String pattern) {
5436
if (Files.exists(folder)) {
5537
try (var stream = Files.newDirectoryStream(folder, pattern)) {

backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/storage/model/package-info.java

Lines changed: 0 additions & 23 deletions
This file was deleted.

backend/commons/src/main/java/org/sonarsource/sonarlint/core/commons/storage/repository/package-info.java

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Flyway computes checksums of migration files and saves them in the DB.
2+
3+
Once a migration has been shipped and applied by some users, it is forbidden to modify a migration file, as the checksum would differ.
4+
5+
This would fail the migration validation at startup, preventing SQ-IDE from starting.
6+
7+
As a rule of thumb, please do not modify a migration file after it has been merged to master, because we cannot know if it has been applied by users.
8+
9+
Instead, please add a new migration file, by respecting the pattern VX__description.sql, and the numbering (+1 compared to the latest migration).

backend/core/src/main/java/org/sonarsource/sonarlint/core/issue/IssueService.java

Lines changed: 27 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
package org.sonarsource.sonarlint.core.issue;
2121

2222
import jakarta.annotation.PostConstruct;
23-
import java.nio.file.Path;
2423
import java.util.ArrayList;
2524
import java.util.Collections;
2625
import java.util.EnumMap;
@@ -44,13 +43,12 @@
4443
import org.sonarsource.sonarlint.core.commons.Transition;
4544
import org.sonarsource.sonarlint.core.commons.Version;
4645
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
47-
import org.sonarsource.sonarlint.core.commons.monitoring.DogfoodEnvironmentDetectionService;
4846
import org.sonarsource.sonarlint.core.commons.progress.SonarLintCancelMonitor;
49-
import org.sonarsource.sonarlint.core.commons.storage.repository.LocalOnlyIssuesRepository;
47+
import org.sonarsource.sonarlint.core.serverconnection.issues.LocalOnlyIssuesRepository;
5048
import org.sonarsource.sonarlint.core.event.LocalOnlyIssueStatusChangedEvent;
5149
import org.sonarsource.sonarlint.core.event.ServerIssueStatusChangedEvent;
5250
import org.sonarsource.sonarlint.core.event.SonarServerEventReceivedEvent;
53-
import org.sonarsource.sonarlint.core.local.only.LocalOnlyIssueStorageService;
51+
import org.sonarsource.sonarlint.core.local.only.XodusLocalOnlyIssueStorageService;
5452
import org.sonarsource.sonarlint.core.mode.SeverityModeService;
5553
import org.sonarsource.sonarlint.core.newcode.NewCodeService;
5654
import org.sonarsource.sonarlint.core.remediation.aicodefix.AiCodeFixService;
@@ -77,7 +75,6 @@
7775
import org.sonarsource.sonarlint.core.serverapi.push.IssueChangedEvent;
7876
import org.sonarsource.sonarlint.core.serverconnection.ServerInfoSynchronizer;
7977
import org.sonarsource.sonarlint.core.serverconnection.storage.ProjectServerIssueStore;
80-
import org.sonarsource.sonarlint.core.storage.SonarLintDatabaseService;
8178
import org.sonarsource.sonarlint.core.storage.StorageService;
8279
import org.sonarsource.sonarlint.core.tracking.LocalOnlyIssueRepository;
8380
import org.sonarsource.sonarlint.core.tracking.TaintVulnerabilityTrackingService;
@@ -105,7 +102,7 @@ public class IssueService {
105102
private final ConfigurationRepository configurationRepository;
106103
private final SonarQubeClientManager sonarQubeClientManager;
107104
private final StorageService storageService;
108-
private final LocalOnlyIssueStorageService localOnlyIssueStorageService;
105+
private final XodusLocalOnlyIssueStorageService localOnlyIssueStorageService;
109106
private final LocalOnlyIssueRepository localOnlyIssueRepository;
110107
private final ApplicationEventPublisher eventPublisher;
111108
private final FindingReportingService findingReportingService;
@@ -114,14 +111,12 @@ public class IssueService {
114111
private final ActiveRulesService activeRulesService;
115112
private final TaintVulnerabilityTrackingService taintVulnerabilityTrackingService;
116113
private final AiCodeFixService aiCodeFixService;
117-
private final DogfoodEnvironmentDetectionService dogfoodEnvironmentDetectionService;
118-
private final SonarLintDatabaseService databaseService;
114+
private final LocalOnlyIssuesRepository localOnlyIssuesRepository;
119115

120116
public IssueService(ConfigurationRepository configurationRepository, SonarQubeClientManager sonarQubeClientManager, StorageService storageService,
121-
LocalOnlyIssueStorageService localOnlyIssueStorageService, LocalOnlyIssueRepository localOnlyIssueRepository,
122-
ApplicationEventPublisher eventPublisher, FindingReportingService findingReportingService, SeverityModeService severityModeService,
123-
NewCodeService newCodeService, ActiveRulesService activeRulesService, TaintVulnerabilityTrackingService taintVulnerabilityTrackingService, AiCodeFixService aiCodeFixService,
124-
DogfoodEnvironmentDetectionService dogfoodEnvironmentDetectionService, SonarLintDatabaseService databaseService) {
117+
XodusLocalOnlyIssueStorageService localOnlyIssueStorageService, LocalOnlyIssueRepository localOnlyIssueRepository, ApplicationEventPublisher eventPublisher,
118+
FindingReportingService findingReportingService, SeverityModeService severityModeService, NewCodeService newCodeService, ActiveRulesService activeRulesService,
119+
TaintVulnerabilityTrackingService taintVulnerabilityTrackingService, AiCodeFixService aiCodeFixService, LocalOnlyIssuesRepository localOnlyIssuesRepository) {
125120
this.configurationRepository = configurationRepository;
126121
this.sonarQubeClientManager = sonarQubeClientManager;
127122
this.storageService = storageService;
@@ -134,26 +129,22 @@ public IssueService(ConfigurationRepository configurationRepository, SonarQubeCl
134129
this.activeRulesService = activeRulesService;
135130
this.taintVulnerabilityTrackingService = taintVulnerabilityTrackingService;
136131
this.aiCodeFixService = aiCodeFixService;
137-
this.dogfoodEnvironmentDetectionService = dogfoodEnvironmentDetectionService;
138-
this.databaseService = databaseService;
132+
this.localOnlyIssuesRepository = localOnlyIssuesRepository;
139133
}
140134

141135
@PostConstruct
142136
public void migrateData() {
143-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
144-
if (localOnlyIssueStorageService.exists()) {
145-
try {
146-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
147-
var xodusLocalOnlyIssueStore = localOnlyIssueStorageService.get();
148-
var issuesPerConfigScope = xodusLocalOnlyIssueStore.loadAll();
149-
repository.storeIssues(issuesPerConfigScope);
150-
} catch (Exception e) {
151-
LOG.error("Unable to migrate local-only findings, will use fresh DB", e);
152-
}
137+
if (localOnlyIssueStorageService.exists()) {
138+
try {
139+
var xodusLocalOnlyIssueStore = localOnlyIssueStorageService.get();
140+
var issuesPerConfigScope = xodusLocalOnlyIssueStore.loadAll();
141+
localOnlyIssuesRepository.storeIssues(issuesPerConfigScope);
142+
} catch (Exception e) {
143+
LOG.error("Unable to migrate local-only findings, will use fresh DB", e);
153144
}
154-
// always call to remove lingering temporary files
155-
localOnlyIssueStorageService.delete();
156145
}
146+
// always call to remove lingering temporary files
147+
localOnlyIssueStorageService.delete();
157148
}
158149

159150
public void changeStatus(String configurationScopeId, String issueKey, ResolutionStatus newStatus, boolean isTaintIssue, SonarLintCancelMonitor cancelMonitor) {
@@ -181,10 +172,10 @@ public void changeStatus(String configurationScopeId, String issueKey, Resolutio
181172
var coreStatus = org.sonarsource.sonarlint.core.commons.IssueStatus.valueOf(newStatus.name());
182173
var issue = localIssueOpt.get();
183174
issue.resolve(coreStatus);
184-
var allIssues = loadAllLocalOnlyIssues(configurationScopeId);
175+
var allIssues = localOnlyIssuesRepository.loadAll(configurationScopeId);
185176
serverConnection.withClientApi(serverApi -> serverApi.issue()
186177
.anticipatedTransitions(binding.sonarProjectKey(), concat(allIssues, issue), cancelMonitor));
187-
storeLocalOnlyIssue(configurationScopeId, issue);
178+
localOnlyIssuesRepository.storeLocalOnlyIssue(configurationScopeId, issue);
188179
eventPublisher.publishEvent(new LocalOnlyIssueStatusChangedEvent(issue));
189180
}
190181
}
@@ -314,40 +305,36 @@ public boolean reopenIssue(String configurationScopeId, String issueId, boolean
314305
public boolean reopenAllIssuesForFile(ReopenAllIssuesForFileParams params, SonarLintCancelMonitor cancelMonitor) {
315306
var configurationScopeId = params.getConfigurationScopeId();
316307
var ideRelativePath = params.getIdeRelativePath();
317-
removeAllIssuesForFile(configurationScopeId, ideRelativePath, cancelMonitor);
318-
return removeAllIssuesForFileFromStore(configurationScopeId, ideRelativePath);
319-
}
320-
321-
private void removeAllIssuesForFile(String configurationScopeId, Path filePath, SonarLintCancelMonitor cancelMonitor) {
322-
var allIssues = loadAllLocalOnlyIssues(configurationScopeId);
323-
var issuesForFile = loadLocalOnlyIssuesForFile(configurationScopeId, filePath);
308+
var allIssues = localOnlyIssuesRepository.loadAll(configurationScopeId);
309+
var issuesForFile = localOnlyIssuesRepository.loadForFile(configurationScopeId, ideRelativePath);
324310
var issuesToSync = subtract(allIssues, issuesForFile);
325311
var binding = configurationRepository.getEffectiveBindingOrThrow(configurationScopeId);
326312
sonarQubeClientManager.getClientOrThrow(binding.connectionId())
327313
.withClientApi(serverApi -> serverApi.issue().anticipatedTransitions(binding.sonarProjectKey(), issuesToSync, cancelMonitor));
314+
return localOnlyIssuesRepository.removeAllIssuesForFile(configurationScopeId, ideRelativePath);
328315
}
329316

330317
private void removeIssueOnServer(String configurationScopeId, UUID issueId, SonarLintCancelMonitor cancelMonitor) {
331-
var allIssues = loadAllLocalOnlyIssues(configurationScopeId);
318+
var allIssues = localOnlyIssuesRepository.loadAll(configurationScopeId);
332319
var issuesToSync = allIssues.stream().filter(it -> !it.getId().equals(issueId)).toList();
333320
var binding = configurationRepository.getEffectiveBindingOrThrow(configurationScopeId);
334321
sonarQubeClientManager.getClientOrThrow(binding.connectionId())
335322
.withClientApi(serverApi -> serverApi.issue().anticipatedTransitions(binding.sonarProjectKey(), issuesToSync, cancelMonitor));
336323
}
337324

338325
private void setCommentOnLocalOnlyIssue(String configurationScopeId, UUID issueId, String comment, SonarLintCancelMonitor cancelMonitor) {
339-
var optionalLocalOnlyIssue = findLocalOnlyIssue(issueId);
326+
var optionalLocalOnlyIssue = localOnlyIssuesRepository.find(issueId);
340327
if (optionalLocalOnlyIssue.isPresent()) {
341328
var commentedIssue = optionalLocalOnlyIssue.get();
342329
var resolution = commentedIssue.getResolution();
343330
if (resolution != null) {
344331
resolution.setComment(comment);
345-
var issuesToSync = new ArrayList<>(loadAllLocalOnlyIssues(configurationScopeId));
332+
var issuesToSync = new ArrayList<>(localOnlyIssuesRepository.loadAll(configurationScopeId));
346333
issuesToSync.replaceAll(issue -> issue.getId().equals(issueId) ? commentedIssue : issue);
347334
var binding = configurationRepository.getEffectiveBindingOrThrow(configurationScopeId);
348335
sonarQubeClientManager.getClientOrThrow(binding.connectionId())
349336
.withClientApi(serverApi -> serverApi.issue().anticipatedTransitions(binding.sonarProjectKey(), issuesToSync, cancelMonitor));
350-
storeLocalOnlyIssue(configurationScopeId, commentedIssue);
337+
localOnlyIssuesRepository.storeLocalOnlyIssue(configurationScopeId, commentedIssue);
351338
}
352339
} else {
353340
throw issueNotFoundException(issueId.toString());
@@ -380,7 +367,7 @@ private boolean reopenLocalIssue(String issueId, String configurationScopeId, So
380367
}
381368
var issueUuid = issueUuidOptional.get();
382369
removeIssueOnServer(configurationScopeId, issueUuid, cancelMonitor);
383-
return removeLocalOnlyIssue(issueUuid);
370+
return localOnlyIssuesRepository.removeIssue(issueUuid);
384371
}
385372

386373
public EffectiveIssueDetailsDto getEffectiveIssueDetails(String configurationScopeId, UUID findingId, SonarLintCancelMonitor cancelMonitor)
@@ -558,59 +545,4 @@ private static Optional<UUID> asUUID(String key) {
558545
return Optional.empty();
559546
}
560547
}
561-
562-
// Helper methods to abstract between Xodus and H2 storage
563-
public List<LocalOnlyIssue> loadAllLocalOnlyIssues(String configurationScopeId) {
564-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
565-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
566-
return repository.loadAll(configurationScopeId);
567-
} else {
568-
return localOnlyIssueStorageService.get().loadAll(configurationScopeId);
569-
}
570-
}
571-
572-
private List<LocalOnlyIssue> loadLocalOnlyIssuesForFile(String configurationScopeId, Path filePath) {
573-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
574-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
575-
return repository.loadForFile(configurationScopeId, filePath);
576-
} else {
577-
return localOnlyIssueStorageService.get().loadForFile(configurationScopeId, filePath);
578-
}
579-
}
580-
581-
private Optional<LocalOnlyIssue> findLocalOnlyIssue(UUID issueId) {
582-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
583-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
584-
return repository.find(issueId);
585-
} else {
586-
return localOnlyIssueStorageService.get().find(issueId);
587-
}
588-
}
589-
590-
private void storeLocalOnlyIssue(String configurationScopeId, LocalOnlyIssue issue) {
591-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
592-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
593-
repository.storeLocalOnlyIssue(configurationScopeId, issue);
594-
} else {
595-
localOnlyIssueStorageService.get().storeLocalOnlyIssue(configurationScopeId, issue);
596-
}
597-
}
598-
599-
private boolean removeLocalOnlyIssue(UUID issueId) {
600-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
601-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
602-
return repository.removeIssue(issueId);
603-
} else {
604-
return localOnlyIssueStorageService.get().removeIssue(issueId);
605-
}
606-
}
607-
608-
private boolean removeAllIssuesForFileFromStore(String configurationScopeId, Path filePath) {
609-
if (dogfoodEnvironmentDetectionService.isDogfoodEnvironment()) {
610-
var repository = new LocalOnlyIssuesRepository(databaseService.getDatabase());
611-
return repository.removeAllIssuesForFile(configurationScopeId, filePath);
612-
} else {
613-
return localOnlyIssueStorageService.get().removeAllIssuesForFile(configurationScopeId, filePath);
614-
}
615-
}
616548
}

0 commit comments

Comments
 (0)