From 526583323c8dd7f5ea174757726218cec784848a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lesaint?= Date: Fri, 2 Sep 2016 14:00:58 +0200 Subject: [PATCH] SONAR-7676 PropertiesDao supports IS_EMPTY, TEXT_VALUE and CLOB_VALUE --- .../sonar/ce/db/ReadOnlyPropertiesDao.java | 11 +- .../ComputeEngineContainerImplTest.java | 2 +- .../ce/db/ReadOnlyPropertiesDaoTest.java | 17 +- .../server/platform/PersistentSettings.java | 6 +- .../platform/StartupMetadataPersister.java | 2 +- .../server/qualitygate/QualityGates.java | 4 +- .../server/qualitygate/ws/SelectAction.java | 2 +- .../server/serverid/ws/GenerateAction.java | 6 +- .../sonar/server/setting/ws/SetAction.java | 8 +- .../batch/ProjectDataLoaderMediumTest.java | 72 +- .../component/SettingsRepositoryTest.java | 2 +- .../platform/PersistentSettingsTest.java | 4 +- .../qualitygate/QgateProjectFinderTest.java | 2 +- .../server/qualitygate/QualityGatesTest.java | 6 +- .../qualitygate/ws/DeselectActionTest.java | 2 +- .../ws/GetByProjectActionTest.java | 4 +- .../setting/DatabaseSettingLoaderTest.java | 3 +- .../server/setting/ws/SettingsFinderTest.java | 2 +- .../startup/ClearRulesOverloadedDebtTest.java | 2 +- .../ui/ws/ComponentNavigationActionTest.java | 2 +- .../MeasureFilterExecutorTest/shared.xml | 12 +- .../BackendCleanupMediumTest/shared.xml | 5 +- .../sonar/core/properties/PropertiesDao.java | 7 +- .../src/main/java/org/sonar/db/MyBatis.java | 4 +- .../org/sonar/db/property/PropertiesDao.java | 87 +- .../sonar/db/property/PropertiesMapper.java | 20 +- .../org/sonar/db/property/PropertyDto.java | 9 +- .../sonar/db/property/ScrapPropertyDto.java | 43 + .../sonar/db/property/PropertiesMapper.xml | 336 ++++-- .../sonar/db/property/PropertiesDaoTest.java | 964 ++++++++++++++---- .../org/sonar/db/property/PropertiesRow.java | 77 ++ .../db/property/PropertiesRowAssert.java | 203 ++++ .../sonar/db/property/PropertyDbTester.java | 4 +- .../sonar/db/property/PropertyDtoAssert.java | 93 ++ .../ProjectQgateAssociationDaoTest.java | 2 +- .../java/org/sonar/db/user/UserDaoTest.java | 4 +- .../PropertiesDaoTest/delete-result.xml | 14 - .../db/property/PropertiesDaoTest/delete.xml | 14 - .../deleteAllProperties-result.xml | 15 - .../PropertiesDaoTest/deleteAllProperties.xml | 15 - .../deleteGlobalProperties-result.xml | 12 - .../deleteGlobalProperties.xml | 12 - .../deleteGlobalProperty-result.xml | 13 - .../deleteGlobalProperty.xml | 13 - .../delete_project_properties-result.xml | 12 - .../delete_project_properties.xml | 13 - .../delete_project_property-result.xml | 55 - .../delete_project_property.xml | 62 -- .../PropertiesDaoTest/insert-result.xml | 12 - .../db/property/PropertiesDaoTest/insert.xml | 1 - .../insertGlobalProperties-result.xml | 5 - .../insertGlobalProperties.xml | 3 - .../renamePropertyKey-result.xml | 6 - .../PropertiesDaoTest/renamePropertyKey.xml | 6 - .../selectProjectPropertiesByResourceId.xml | 59 -- .../PropertiesDaoTest/select_by_query.xml | 19 - .../select_module_properties_tree.xml | 48 +- .../should_not_rename_if_same_key-result.xml | 5 - .../should_not_rename_if_same_key.xml | 5 - .../PropertiesDaoTest/update-result.xml | 15 - .../db/property/PropertiesDaoTest/update.xml | 14 - .../updateGlobalProperties-result.xml | 5 - .../updateGlobalProperties.xml | 5 - ...ertiesFromKeyAndValueToNewValue-result.xml | 9 - ...atePropertiesFromKeyAndValueToNewValue.xml | 9 - .../ProjectQgateAssociationDaoTest/shared.xml | 16 +- 66 files changed, 1646 insertions(+), 875 deletions(-) create mode 100644 sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java create mode 100644 sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java create mode 100644 sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java create mode 100644 sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml delete mode 100644 sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/db/ReadOnlyPropertiesDao.java b/server/sonar-ce/src/main/java/org/sonar/ce/db/ReadOnlyPropertiesDao.java index b33bbff2ec86..9049e0e47f29 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/db/ReadOnlyPropertiesDao.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/db/ReadOnlyPropertiesDao.java @@ -20,6 +20,7 @@ package org.sonar.ce.db; import java.util.Map; +import org.sonar.api.utils.System2; import org.sonar.core.properties.PropertiesDao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; @@ -35,17 +36,17 @@ *

*/ public class ReadOnlyPropertiesDao extends PropertiesDao { - public ReadOnlyPropertiesDao(MyBatis mybatis) { - super(mybatis); + public ReadOnlyPropertiesDao(MyBatis mybatis, System2 system2) { + super(mybatis, system2); } @Override - public void insertProperty(DbSession session, PropertyDto property) { + public void saveProperty(DbSession session, PropertyDto property) { // do nothing } @Override - public void insertProperty(PropertyDto property) { + public void saveProperty(PropertyDto property) { // do nothing } @@ -80,7 +81,7 @@ public void deleteGlobalProperty(String key) { } @Override - public void insertGlobalProperties(Map properties) { + public void saveGlobalProperties(Map properties) { // do nothing } diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java index 258b34ed9e09..fed55130524f 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java @@ -121,7 +121,7 @@ public void real_start() throws IOException { private void insertProperty(String key, String value) { PropertyDto dto = new PropertyDto().setKey(key).setValue(value); - dbTester.getDbClient().propertiesDao().insertProperty(dbTester.getSession(), dto); + dbTester.getDbClient().propertiesDao().saveProperty(dbTester.getSession(), dto); dbTester.commit(); } } diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/db/ReadOnlyPropertiesDaoTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/db/ReadOnlyPropertiesDaoTest.java index 68cb9b463507..405175939205 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/db/ReadOnlyPropertiesDaoTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/db/ReadOnlyPropertiesDaoTest.java @@ -20,6 +20,7 @@ package org.sonar.ce.db; import org.junit.Test; +import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; import org.sonar.db.property.PropertyDto; @@ -32,18 +33,18 @@ public class ReadOnlyPropertiesDaoTest { private DbSession dbSession = mock(DbSession.class); private PropertyDto propertyDto = mock(PropertyDto.class); private org.sonar.core.properties.PropertyDto oldPropertyDto = mock(org.sonar.core.properties.PropertyDto.class); - private ReadOnlyPropertiesDao underTest = new ReadOnlyPropertiesDao(myBatis); + private ReadOnlyPropertiesDao underTest = new ReadOnlyPropertiesDao(myBatis, System2.INSTANCE); @Test public void insertProperty() { - underTest.insertProperty(dbSession, propertyDto); + underTest.saveProperty(dbSession, propertyDto); assertNoInteraction(); } @Test public void insertProperty1() { - underTest.insertProperty(propertyDto); + underTest.saveProperty(propertyDto); assertNoInteraction(); } @@ -98,7 +99,7 @@ public void deleteGlobalProperty1() { @Test public void insertGlobalProperties() { - underTest.insertGlobalProperties(null); + underTest.saveGlobalProperties(null); assertNoInteraction(); @@ -112,12 +113,18 @@ public void renamePropertyKey() { } + @Test + public void saveProperty() { + underTest.saveProperty(oldPropertyDto); + + assertNoInteraction(); + } + @Test public void setProperty() { underTest.setProperty(oldPropertyDto); assertNoInteraction(); - } private void assertNoInteraction() { diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java b/server/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java index 454a8c11fcb1..006ca5b87916 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java @@ -49,11 +49,7 @@ public String getString(String key) { * are executed. */ public PersistentSettings saveProperty(DbSession dbSession, String key, @Nullable String value) { - if (value == null) { - dbClient.propertiesDao().deleteGlobalProperty(key, dbSession); - } else { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey(key).setValue(value)); - } + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey(key).setValue(value)); // refresh the cache of settings delegate.setProperty(key, value); diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/StartupMetadataPersister.java b/server/sonar-server/src/main/java/org/sonar/server/platform/StartupMetadataPersister.java index 10a63b2fd696..ac9ee2861ee9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/StartupMetadataPersister.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/StartupMetadataPersister.java @@ -55,7 +55,7 @@ public void start() { } private void save(String key, String value) { - dbClient.propertiesDao().insertProperty(new PropertyDto().setKey(key).setValue(value)); + dbClient.propertiesDao().saveProperty(new PropertyDto().setKey(key).setValue(value)); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java index aa49cd36df39..a82529336e82 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java @@ -154,7 +154,7 @@ public void setDefault(@Nullable Long idToUseAsDefault) { propertiesDao.deleteGlobalProperty(SONAR_QUALITYGATE_PROPERTY); } else { QualityGateDto newDefault = getNonNullQgate(idToUseAsDefault); - propertiesDao.insertProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setValue(newDefault.getId().toString())); + propertiesDao.saveProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setValue(newDefault.getId().toString())); } } @@ -225,7 +225,7 @@ public void associateProject(Long qGateId, Long projectId) { try { getNonNullQgate(qGateId); checkPermission(projectId, session); - propertiesDao.insertProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setResourceId(projectId).setValue(qGateId.toString())); + propertiesDao.saveProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setResourceId(projectId).setValue(qGateId.toString())); } finally { MyBatis.closeQuietly(session); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java index 0dcea16e9c1f..8791715abcbe 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java @@ -95,7 +95,7 @@ private void doHandle(SelectWsRequest request) { checkQualityGate(dbClient, request.getGateId()); ComponentDto project = getProject(dbSession, request.getProjectId(), request.getProjectKey()); - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto() + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() .setKey(SONAR_QUALITYGATE_PROPERTY) .setResourceId(project.getId()) .setValue(String.valueOf(request.getGateId()))); diff --git a/server/sonar-server/src/main/java/org/sonar/server/serverid/ws/GenerateAction.java b/server/sonar-server/src/main/java/org/sonar/server/serverid/ws/GenerateAction.java index bfe0690f728e..4b6b50242ce1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/serverid/ws/GenerateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/serverid/ws/GenerateAction.java @@ -91,9 +91,9 @@ public void handle(Request request, Response response) throws Exception { private GenerateWsResponse doHandle(DbSession dbSession, GenerateRequest request) { String serverId = generator.generate(request.getOrganization(), request.getIp()); - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey(PERMANENT_SERVER_ID).setValue(serverId)); - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey(ORGANISATION).setValue(request.getOrganization())); - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey(SERVER_ID_IP_ADDRESS).setValue(request.getIp())); + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey(PERMANENT_SERVER_ID).setValue(serverId)); + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey(ORGANISATION).setValue(request.getOrganization())); + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey(SERVER_ID_IP_ADDRESS).setValue(request.getIp())); dbSession.commit(); LOG.info("Generated new server ID={}", serverId); diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java index 2a9cd7337ef1..142659594bd5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java @@ -168,7 +168,7 @@ private void doHandle(DbSession dbSession, SetRequest request) { validate(request); PropertyDto property = toProperty(request, component); value = property.getValue(); - dbClient.propertiesDao().insertProperty(dbSession, property); + dbClient.propertiesDao().saveProperty(dbSession, property); } dbSession.commit(); @@ -187,13 +187,13 @@ private String doHandlePropertySet(DbSession dbSession, SetRequest request, @Nul Long componentId = component.isPresent() ? component.get().getId() : null; deleteSettings(dbSession, component, key); - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey(key).setValue(inlinedFieldKeys).setResourceId(componentId)); + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey(key).setValue(inlinedFieldKeys).setResourceId(componentId)); List fieldValues = request.getFieldValues(); IntStream.of(fieldIds).boxed() .flatMap(i -> readOneFieldValues(fieldValues.get(i - 1), request.getKey()).entrySet().stream() - .map(entry -> new KeyValue(key + "." + i + "." + entry.getKey(), entry.getValue()))) - .forEach(keyValue -> dbClient.propertiesDao().insertProperty(dbSession, toFieldProperty(keyValue, componentId))); + .map(entry -> new KeyValue(key + "." + i + "." + entry.getKey(), entry.getValue()))) + .forEach(keyValue -> dbClient.propertiesDao().saveProperty(dbSession, toFieldProperty(keyValue, componentId))); return inlinedFieldKeys; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java index 59c2f1c992d8..47759adbd9b1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java @@ -87,9 +87,9 @@ public void return_project_settings_with_global_scan_permission() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); dbSession.commit(); @@ -109,9 +109,9 @@ public void return_project_settings_with_project_scan_permission() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); dbSession.commit(); @@ -131,9 +131,9 @@ public void not_returned_secured_settings_when_lgged_but_no_scan_permission() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); dbSession.commit(); @@ -151,18 +151,18 @@ public void return_project_with_module_settings() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); ComponentDto module = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module); // Module properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId())); dbSession.commit(); @@ -185,9 +185,9 @@ public void return_project_with_module_settings_inherited_from_project() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); ComponentDto module = ComponentTesting.newModuleDto(project); @@ -214,25 +214,25 @@ public void return_project_with_module_with_sub_module() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); ComponentDto module = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module); // Module properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId())); ComponentDto subModule = ComponentTesting.newModuleDto(module); tester.get(DbClient.class).componentDao().insert(dbSession, subModule); // Sub module properties - tester.get(DbClient.class).propertiesDao().insertProperty( + tester.get(DbClient.class).propertiesDao().saveProperty( dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId())); dbSession.commit(); @@ -259,25 +259,25 @@ public void return_project_with_two_modules() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); ComponentDto module1 = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module1); // Module 1 properties tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId())); // This property should not be found on the other module tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId())); ComponentDto module2 = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module2); // Module 2 property tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId())); dbSession.commit(); @@ -303,8 +303,8 @@ public void return_provisioned_project_settings() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); dbSession.commit(); @@ -330,10 +330,10 @@ public void return_sub_module_settings() { tester.get(DbClient.class).componentDao().insert(dbSession, subModule); // Sub module properties - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId())); tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); dbSession.commit(); @@ -353,13 +353,13 @@ public void return_sub_module_settings_including_settings_from_parent_modules() addDefaultProfile(); // Project property - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); ComponentDto module = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module); // Module property - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId())); ComponentDto subModule = ComponentTesting.newModuleDto(module); userSessionRule.login("john").setGlobalPermissions(SCAN_EXECUTION); @@ -367,7 +367,7 @@ public void return_sub_module_settings_including_settings_from_parent_modules() // Sub module properties tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId())); dbSession.commit(); @@ -387,10 +387,10 @@ public void return_sub_module_settings_only_inherited_from_project() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId())); ComponentDto module = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module); @@ -419,15 +419,15 @@ public void return_sub_module_settings_inherited_from_project_and_module() { addDefaultProfile(); // Project properties - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId())); tester.get(DbClient.class).propertiesDao() - .insertProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId())); + .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId())); ComponentDto module = ComponentTesting.newModuleDto(project); tester.get(DbClient.class).componentDao().insert(dbSession, module); // Module property - tester.get(DbClient.class).propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); + tester.get(DbClient.class).propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId())); ComponentDto subModule = ComponentTesting.newModuleDto(module); userSessionRule.login("john").setGlobalPermissions(SCAN_EXECUTION); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/SettingsRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/SettingsRepositoryTest.java index c89fdb24d755..212ce5ae9965 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/SettingsRepositoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/SettingsRepositoryTest.java @@ -78,7 +78,7 @@ public void get_project_settings_from_global_settings() { public void get_project_settings_from_db() { ComponentDto project = ComponentTesting.newProjectDto().setKey(ROOT.getKey()); dbClient.componentDao().insert(session, project); - dbClient.propertiesDao().insertProperty(session, new PropertyDto().setResourceId(project.getId()).setKey("key").setValue("value")); + dbClient.propertiesDao().saveProperty(session, new PropertyDto().setResourceId(project.getId()).setKey("key").setValue("value")); session.commit(); Settings settings = underTest.getSettings(ROOT); diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java index 0239f6d8cbf2..044a1cfeaeda 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java @@ -25,6 +25,7 @@ import org.sonar.api.config.Settings; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; +import org.sonar.db.property.PropertyDto; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -54,7 +55,8 @@ public void delete_property_from_database_and_notify_extensions() { underTest.saveProperty("foo", null); assertThat(underTest.getString("foo")).isNull(); - assertThat(dbTester.getDbClient().propertiesDao().selectGlobalProperty("foo")).isNull(); + PropertyDto dto = dbTester.getDbClient().propertiesDao().selectGlobalProperty("foo"); + assertThat(dto.getValue()).isEmpty(); verify(changeNotifier).onGlobalPropertyChange("foo", null); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java index a35f3b095f86..4a02d85b0764 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java @@ -237,7 +237,7 @@ private void verifyPaging(Association association, boolean expectedHasMoreResult } private void associateProjectToQualitGate(long projectId) { - dbClient.propertiesDao().insertProperty( + dbClient.propertiesDao().saveProperty( new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY) .setResourceId(projectId) .setValue(Long.toString(qGate.getId()))); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java index 8d07a418e9d4..61f22762d9a0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java @@ -233,7 +233,7 @@ public void should_select_default_qgate() { verify(dao).selectById(defaultId); ArgumentCaptor propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class); - verify(propertiesDao).insertProperty(propertyCaptor.capture()); + verify(propertiesDao).saveProperty(propertyCaptor.capture()); assertThat(propertyCaptor.getValue().getKey()).isEqualTo("sonar.qualitygate"); assertThat(propertyCaptor.getValue().getValue()).isEqualTo("42"); @@ -551,7 +551,7 @@ public void should_associate_project() { underTest.associateProject(qGateId, projectId); verify(dao).selectById(qGateId); ArgumentCaptor propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class); - verify(propertiesDao).insertProperty(propertyCaptor.capture()); + verify(propertiesDao).saveProperty(propertyCaptor.capture()); PropertyDto property = propertyCaptor.getValue(); assertThat(property.getKey()).isEqualTo("sonar.qualitygate"); assertThat(property.getResourceId()).isEqualTo(projectId); @@ -568,7 +568,7 @@ public void associate_project_with_project_admin_permission() { underTest.associateProject(qGateId, projectId); verify(dao).selectById(qGateId); ArgumentCaptor propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class); - verify(propertiesDao).insertProperty(propertyCaptor.capture()); + verify(propertiesDao).saveProperty(propertyCaptor.capture()); PropertyDto property = propertyCaptor.getValue(); assertThat(property.getKey()).isEqualTo("sonar.qualitygate"); assertThat(property.getResourceId()).isEqualTo(projectId); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DeselectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DeselectActionTest.java index b71b39365269..a37282721f6e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DeselectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DeselectActionTest.java @@ -244,7 +244,7 @@ private void callByUuid(String gateId, String projectUuid) { } private void associateProjectToQualityGate(long projectId, String gateId) { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto() + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() .setResourceId(projectId) .setValue(gateId) .setKey(SONAR_QUALITYGATE_PROPERTY)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java index c0c3931d7157..d07e2cec6f90 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java @@ -228,7 +228,7 @@ private QualityGateDto insertQualityGate(String name) { } private void associateProjectToQualityGate(long componentId, long qualityGateId) { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto() + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() .setKey("sonar.qualitygate") .setResourceId(componentId) .setValue(String.valueOf(qualityGateId))); @@ -236,7 +236,7 @@ private void associateProjectToQualityGate(long componentId, long qualityGateId) } private void setDefaultQualityGate(long qualityGateId) { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto() + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() .setKey("sonar.qualitygate") .setValue(String.valueOf(qualityGateId))); db.commit(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java index 5cc2a1c6b5bd..267089d228e0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java @@ -25,7 +25,6 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbTester; import org.sonar.db.property.PropertyDto; -import org.sonar.server.setting.DatabaseSettingLoader; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.data.MapEntry.entry; @@ -76,7 +75,7 @@ public void test_loadAll() { } private void insertPropertyIntoDb(String key, String value) { - dbTester.getDbClient().propertiesDao().insertProperty(new PropertyDto().setKey(key).setValue(value)); + dbTester.getDbClient().propertiesDao().saveProperty(new PropertyDto().setKey(key).setValue(value)); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/SettingsFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/SettingsFinderTest.java index f70a47fddb58..83e7fe29a4f2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/setting/ws/SettingsFinderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/setting/ws/SettingsFinderTest.java @@ -197,7 +197,7 @@ private void assertSetting(Setting setting, String expectedKey, String expectedV private void insertProperties(PropertyDto... properties) { for (PropertyDto propertyDto : properties) { - dbClient.propertiesDao().insertProperty(dbSession, propertyDto); + dbClient.propertiesDao().saveProperty(dbSession, propertyDto); } dbSession.commit(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java index 85260daa9bf4..64531b1483ce 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java @@ -148,7 +148,7 @@ private RuleDto insertRuleDto(RuleKey ruleKey, @Nullable String function, @Nulla } private void insertSqaleProperty() { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey("sonar.sqale.licenseHash.secured").setValue("ABCD")); + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.sqale.licenseHash.secured").setValue("ABCD")); dbSession.commit(); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java index d9e0d745f66c..a30fe1ea202d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java @@ -128,7 +128,7 @@ public void no_snapshot_connected_user_and_favorite() throws Exception { ComponentDto project = ComponentTesting.newProjectDto("abcd") .setKey("polop").setName("Polop"); dbClient.componentDao().insert(dbTester.getSession(), project); - dbClient.propertiesDao().insertProperty(dbTester.getSession(), new PropertyDto().setKey("favourite").setResourceId(project.getId()).setUserId((long) userId)); + dbClient.propertiesDao().saveProperty(dbTester.getSession(), new PropertyDto().setKey("favourite").setResourceId(project.getId()).setUserId((long) userId)); dbTester.getSession().commit(); userSessionRule.login("obiwan").setUserId(userId).addProjectUuidPermissions(UserRole.USER, "abcd"); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/measure/MeasureFilterExecutorTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/measure/MeasureFilterExecutorTest/shared.xml index 8a870e0ab2cd..1dc8bd5a4d82 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/measure/MeasureFilterExecutorTest/shared.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/measure/MeasureFilterExecutorTest/shared.xml @@ -390,24 +390,28 @@ + is_empty="[true]"/> + is_empty="[true]"/> + is_empty="[true]"/> + is_empty="[true]"/> diff --git a/server/sonar-server/src/test/resources/org/sonar/server/platform/BackendCleanupMediumTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/platform/BackendCleanupMediumTest/shared.xml index 24e2b2ac42fb..c34799a9cff1 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/platform/BackendCleanupMediumTest/shared.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/platform/BackendCleanupMediumTest/shared.xml @@ -54,8 +54,9 @@ + user_id="[null]" + is_empty="[true]" + text_value="Sonar Way"/> diff --git a/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java index 2c97e6f2561a..2c64a11ec9c3 100644 --- a/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java +++ b/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java @@ -19,6 +19,7 @@ */ package org.sonar.core.properties; +import org.sonar.api.utils.System2; import org.sonar.db.MyBatis; /** @@ -29,11 +30,11 @@ @Deprecated public class PropertiesDao extends org.sonar.db.property.PropertiesDao { - public PropertiesDao(MyBatis mybatis) { - super(mybatis); + public PropertiesDao(MyBatis mybatis, System2 system2) { + super(mybatis, system2); } public void setProperty(PropertyDto property) { - super.insertProperty(property); + super.saveProperty(property); } } 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 c9df79927b75..e2d37996d3cf 100644 --- a/sonar-db/src/main/java/org/sonar/db/MyBatis.java +++ b/sonar-db/src/main/java/org/sonar/db/MyBatis.java @@ -95,7 +95,7 @@ import org.sonar.db.property.InternalPropertiesMapper; import org.sonar.db.property.InternalPropertyDto; import org.sonar.db.property.PropertiesMapper; -import org.sonar.db.property.PropertyDto; +import org.sonar.db.property.ScrapPropertyDto; import org.sonar.db.purge.IdUuidPair; import org.sonar.db.purge.PurgeMapper; import org.sonar.db.purge.PurgeableAnalysisDto; @@ -176,7 +176,7 @@ public MyBatis start() { confBuilder.loadAlias("MeasureFilter", MeasureFilterDto.class); confBuilder.loadAlias("MeasureFilterFavourite", MeasureFilterFavouriteDto.class); confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class); - confBuilder.loadAlias("Property", PropertyDto.class); + confBuilder.loadAlias("ScrapProperty", ScrapPropertyDto.class); confBuilder.loadAlias("InternalProperty", InternalPropertyDto.class); confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class); confBuilder.loadAlias("QualityGate", QualityGateDto.class); diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java b/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java index 86d8c594e96f..7af843913312 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -30,8 +30,8 @@ import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.System2; import org.sonar.db.Dao; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; @@ -43,10 +43,14 @@ public class PropertiesDao implements Dao { private static final String NOTIFICATION_PREFIX = "notification."; - private MyBatis mybatis; + private static final int VARCHAR_MAXSIZE = 4000; - public PropertiesDao(MyBatis mybatis) { + private final MyBatis mybatis; + private final System2 system2; + + public PropertiesDao(MyBatis mybatis, System2 system2) { this.mybatis = mybatis; + this.system2 = system2; } /** @@ -130,15 +134,15 @@ public List selectEnabledDescendantModuleProperties(String moduleUu } @CheckForNull - public PropertyDto selectProjectProperty(long resourceId, String propertyKey) { + public PropertyDto selectProjectProperty(long componentId, String propertyKey) { try (DbSession session = mybatis.openSession(false)) { - return selectProjectProperty(session, resourceId, propertyKey); + return selectProjectProperty(session, componentId, propertyKey); } } @CheckForNull - public PropertyDto selectProjectProperty(DbSession dbSession, long resourceId, String propertyKey) { - return getMapper(dbSession).selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(resourceId)); + public PropertyDto selectProjectProperty(DbSession dbSession, long componentId, String propertyKey) { + return getMapper(dbSession).selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(componentId)); } public List selectByQuery(PropertyQuery query, DbSession session) { @@ -162,24 +166,57 @@ private List selectByKeys(DbSession session, Set keys, @Nul return executeLargeInputs(keys, partitionKeys -> getMapper(session).selectByKeys(partitionKeys, componentId)); } - public void insertProperty(DbSession session, PropertyDto property) { - PropertiesMapper mapper = getMapper(session); - PropertyDto persistedProperty = mapper.selectByKey(property); - if (persistedProperty != null && !StringUtils.equals(persistedProperty.getValue(), property.getValue())) { - persistedProperty.setValue(property.getValue()); - mapper.update(persistedProperty); - } else if (persistedProperty == null) { - mapper.insert(property); + /** + * Saves the specified property and its value. + *

+ * If {@link PropertyDto#getValue()} is {@code null} or empty, the properties is persisted as empty. + *

+ * + * @throws IllegalArgumentException if {@link PropertyDto#getKey()} is {@code null} or empty + */ + public void saveProperty(DbSession session, PropertyDto property) { + save(getMapper(session), property.getKey(), property.getUserId(), property.getResourceId(), property.getValue()); + } + + private void save(PropertiesMapper mapper, + String key, @Nullable Long userId, @Nullable Long componentId, + @Nullable String value) { + checkKey(key); + + long now = system2.now(); + mapper.delete(key, userId, componentId); + if (isEmpty(value)) { + mapper.insertAsEmpty(key, userId, componentId, now); + } else if (mustBeStoredInClob(value)) { + mapper.insertAsClob(key, userId, componentId, value, now); + } else { + mapper.insertAsText(key, userId, componentId, value, now); } } - public void insertProperty(PropertyDto property) { + private static boolean mustBeStoredInClob(String value) { + return value.length() > VARCHAR_MAXSIZE; + } + + private static void checkKey(@Nullable String key) { + checkArgument(!isEmpty(key), "key can't be null nor empty"); + } + + private static boolean isEmpty(@Nullable String str) { + return str == null || str.isEmpty(); + } + + public void saveProperty(PropertyDto property) { try (DbSession session = mybatis.openSession(false)) { - insertProperty(session, property); + saveProperty(session, property); session.commit(); } } + public int delete(DbSession dbSession, PropertyDto dto) { + return getMapper(dbSession).delete(dto.getKey(), dto.getUserId(), dto.getResourceId()); + } + public void deleteById(DbSession dbSession, long id) { getMapper(dbSession).deleteById(id); } @@ -217,23 +254,17 @@ public void deleteGlobalProperty(String key) { } } - public void insertGlobalProperties(Map properties) { + public void saveGlobalProperties(Map properties) { try (DbSession session = mybatis.openSession(false)) { PropertiesMapper mapper = getMapper(session); - properties.entrySet().forEach(entry -> delete(mapper, entry)); - properties.entrySet().forEach(entry -> insert(mapper, entry)); + properties.entrySet().forEach(entry -> { + mapper.deleteGlobalProperty(entry.getKey()); + save(mapper, entry.getKey(), null, null, entry.getValue()); + }); session.commit(); } } - private static void delete(PropertiesMapper mapper, Map.Entry entry) { - mapper.deleteGlobalProperty(entry.getKey()); - } - - private static void insert(PropertiesMapper mapper, Map.Entry entry) { - mapper.insert(new PropertyDto().setKey(entry.getKey()).setValue(entry.getValue())); - } - public void renamePropertyKey(String oldKey, String newKey) { checkArgument(!Strings.isNullOrEmpty(oldKey), "Old property key must not be empty"); checkArgument(!Strings.isNullOrEmpty(newKey), "New property key must not be empty"); diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java b/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java index bb58987065d3..e438c73c8c90 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java @@ -44,18 +44,24 @@ public interface PropertiesMapper { List selectDescendantModuleProperties(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope, @Param(value = "excludeDisabled") boolean excludeDisabled); - void update(PropertyDto property); + void insertAsEmpty(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId, + @Param("now") long now); - void insert(PropertyDto property); + void insertAsText(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId, + @Param("value") String value, @Param("now") long now); - void deleteById(long id); + void insertAsClob(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId, + @Param("value") String value, @Param("now") long now); - void deleteProjectProperty(@Param("key") String key, @Param("rId") Long resourceId); + int delete(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId); - void deleteProjectProperties(@Param("key") String key, @Param("value") String value); + int deleteById(long id); - void deleteGlobalProperty(String key); + int deleteProjectProperty(@Param("key") String key, @Param("rId") Long componentId); - void renamePropertyKey(@Param("oldKey") String oldKey, @Param("newKey") String newKey); + int deleteProjectProperties(@Param("key") String key, @Param("value") String value); + int deleteGlobalProperty(@Param("key") String key); + + int renamePropertyKey(@Param("oldKey") String oldKey, @Param("newKey") String newKey); } diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java b/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java index 404be7e30ada..22f0998b3532 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java @@ -58,7 +58,7 @@ public String getValue() { return value; } - public PropertyDto setValue(String value) { + public PropertyDto setValue(@Nullable String value) { this.value = value; return this; } @@ -91,12 +91,11 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final PropertyDto other = (PropertyDto) obj; - + PropertyDto other = (PropertyDto) obj; return Objects.equals(this.key, other.key) - && Objects.equals(this.value, other.value) && Objects.equals(this.userId, other.userId) - && Objects.equals(this.resourceId, other.resourceId); + && Objects.equals(this.resourceId, other.resourceId) + && Objects.equals(this.value, other.value); } @Override diff --git a/sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java b/sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java new file mode 100644 index 000000000000..ded0ac705497 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java @@ -0,0 +1,43 @@ +/* + * 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.property; + +import javax.annotation.Nullable; + +public class ScrapPropertyDto extends PropertyDto { + public void setEmpty(boolean flag) { + if (flag) { + setValue(""); + } + } + + public void setTextValue(@Nullable String value) { + if (value != null) { + setValue(value); + } + } + + public void setClobValue(@Nullable String value) { + if (value != null) { + setValue(value); + } + } + +} diff --git a/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml b/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml index e94a1cc31d1b..e3bae5b1baa3 100644 --- a/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml @@ -4,156 +4,292 @@ - + select + + from + properties p + where + p.resource_id is null + and p.user_id is null - + select + + from + properties p, + projects r + where + p.resource_id=r.id + and p.user_id is null + and r.kee=#{resourceKey} - + select + + from + properties p + inner join (select p.id from projects p) modules + on modules.id=p.resource_id + where + p.user_id is null - + select + + from + properties p + where + p.prop_key=#{key} + + and p.resource_id is null + + + and p.resource_id=#{resourceId} + + + and p.user_id is null + + + and p.user_id=#{userId} + - + select + + from + properties p + where + p.prop_key in + + #{key} + - AND p.resource_id is null + and p.resource_id is null - AND p.resource_id=#{componentId} + and p.resource_id=#{componentId} - AND p.user_id is null - + and p.user_id is null - + select + + from + properties p + where + p.prop_key in + + #{key} + + and p.resource_id in + + #{componentId} + + and p.user_id is null - + select + + from + properties p - AND p.prop_key=#{query.key} + and p.prop_key=#{query.key} - AND p.resource_id=#{query.componentId} + and p.resource_id=#{query.componentId} - AND p.user_id=#{query.userId} + and p.user_id=#{query.userId} - - update properties set text_value = #{value} where id = #{id} - + + insert into properties + ( + prop_key, + resource_id, + user_id, + is_empty, + created_at + ) + values ( + #{key}, + #{componentId}, + #{userId}, + ${_true}, + #{now} + ) + - - INSERT INTO properties (prop_key, resource_id, user_id, text_value) - VALUES (#{key}, #{resourceId}, #{userId}, #{value}) + + insert into properties + ( + prop_key, + resource_id, + user_id, + is_empty, + text_value, + created_at + ) + values ( + #{key}, + #{componentId}, + #{userId}, + ${_false}, + #{value}, + #{now} + ) + + insert into properties + ( + prop_key, + resource_id, + user_id, + is_empty, + clob_value, + created_at + ) + values ( + #{key}, + #{componentId}, + #{userId}, + ${_false}, + #{value}, + #{now} + ) + + + + delete from properties + where + prop_key=#{key} + + + and resource_id=#{componentId} + and user_id=#{userId} + + + and resource_id=#{componentId} + and user_id is null + + + and resource_id is null + and user_id=#{userId} + + + and resource_id is null + and user_id is null + + + + - delete from properties where id=#{id} + delete from properties + where + id=#{id} - delete from properties where prop_key=#{key} and resource_id=#{rId} and user_id is null + delete from properties + where + prop_key=#{key} + and resource_id=#{rId} + and user_id is null - DELETE FROM properties - WHERE - prop_key=#{key} - AND text_value LIKE #{value} - AND resource_id IS NOT NULL - AND user_id IS NULL + delete from properties + where + prop_key=#{key} + and text_value = #{value} + and resource_id is not null + and user_id is null - delete from properties where prop_key=#{id} and resource_id is null and user_id is null + delete from properties + where + prop_key=#{key} + and resource_id is null + and user_id is null - delete from properties where resource_id is null and user_id is null + delete from properties + where + resource_id is null + and user_id is null - update properties set prop_key=#{newKey} where prop_key=#{oldKey} + update properties set + prop_key=#{newKey} + where + prop_key=#{oldKey} diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java b/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java index 2a0b8c1b6bf3..4ad5862b347b 100644 --- a/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java @@ -20,12 +20,21 @@ package org.sonar.db.property; import com.google.common.collect.ImmutableMap; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; import org.assertj.core.groups.Tuple; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -36,20 +45,30 @@ import org.sonar.db.user.UserTesting; import static com.google.common.collect.Sets.newHashSet; -import static java.lang.String.valueOf; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto; import static org.sonar.db.property.PropertyTesting.newUserPropertyDto; +@RunWith(DataProviderRunner.class) public class PropertiesDaoTest { + private static final String VALUE_SIZE_4000 = String.format("%1$4000.4000s", "*"); + private static final String VALUE_SIZE_4001 = VALUE_SIZE_4000 + "P"; + private static final long DATE_1 = 1_555_000L; + private static final long DATE_2 = 1_666_000L; + private static final long DATE_3 = 1_777_000L; + private static final long DATE_4 = 1_888_000L; + private static final long DATE_5 = 1_999_000L; + + private System2 system2 = mock(System2.class); @Rule public ExpectedException thrown = ExpectedException.none(); @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); + public DbTester dbTester = DbTester.create(system2); private DbClient dbClient = dbTester.getDbClient(); private DbSession session = dbTester.getSession(); @@ -57,133 +76,162 @@ public class PropertiesDaoTest { private PropertiesDao underTest = dbTester.getDbClient().propertiesDao(); @Test - public void shouldFindUsersForNotification() { - insertProject("uuid_45", 45); - insertProject("uuid_56", 56); - insertUser(1); - insertUser(2); - insertUser(3); - insertProperty(1, "notification.NewViolations.Email", "true", 45, 2); - insertProperty(2, "notification.NewViolations.Twitter", "true", null, 3); - insertProperty(3, "notification.NewViolations.Twitter", "true", 56, 1); - insertProperty(4, "notification.NewViolations.Twitter", "true", 56, 3); - - List users = underTest.selectUsersForNotification("NewViolations", "Email", null); - assertThat(users).isEmpty(); - - users = underTest.selectUsersForNotification("NewViolations", "Email", "uuid_78"); - assertThat(users).isEmpty(); - - users = underTest.selectUsersForNotification("NewViolations", "Email", "uuid_45"); - assertThat(users).hasSize(1); - assertThat(users).containsOnly("user2"); - - users = underTest.selectUsersForNotification("NewViolations", "Twitter", null); - assertThat(users).hasSize(1); - assertThat(users).containsOnly("user3"); - - users = underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_78"); - assertThat(users).isEmpty(); - - users = underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_56"); - assertThat(users).hasSize(2); - assertThat(users).containsOnly("user1", "user3"); + public void shouldFindUsersForNotification() throws SQLException { + ComponentDto project1 = insertProject("uuid_45"); + ComponentDto project2 = insertProject("uuid_56"); + long userId1 = insertUser("user1"); + long userId2 = insertUser("user2"); + long userId3 = insertUser("user3"); + insertProperty("notification.NewViolations.Email", "true", project1.getId(), userId2); + insertProperty("notification.NewViolations.Twitter", "true", null, userId3); + insertProperty("notification.NewViolations.Twitter", "true", project2.getId(), userId1); + insertProperty("notification.NewViolations.Twitter", "true", project2.getId(), userId3); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Email", null)) + .isEmpty(); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Email", "uuid_78")) + .isEmpty(); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Email", "uuid_45")) + .hasSize(1).containsOnly("user2"); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Twitter", null)) + .hasSize(1) + .containsOnly("user3"); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_78")) + .isEmpty(); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_56")) + .hasSize(2) + .containsOnly("user1", "user3"); } @Test - public void findNotificationSubscribers() { - insertUser(1); - insertUser(2); - insertProject("PROJECT_A", 42); + public void findNotificationSubscribers() throws SQLException { + long userId1 = insertUser("user1"); + long userId2 = insertUser("user2"); + ComponentDto projectDto = insertProject("PROJECT_A"); + long projectId = projectDto.getId(); + String projectKey = projectDto.key(); + // global subscription - insertProperty(1, "notification.DispatcherWithGlobalSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalSubscribers.Email", "true", null, userId2); // project subscription - insertProperty(2, "notification.DispatcherWithProjectSubscribers.Email", "true", 42, 1); - insertProperty(3, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56, 1); - insertProperty(4, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 42, 1); + insertProperty("notification.DispatcherWithProjectSubscribers.Email", "true", projectId, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56L, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", projectId, userId1); // global subscription - insertProperty(5, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, userId2); // Nobody is subscribed - List users = underTest.selectNotificationSubscribers("NotSexyDispatcher", "Email", "project42"); - assertThat(users).isEmpty(); + assertThat(underTest.selectNotificationSubscribers("NotSexyDispatcher", "Email", projectKey)) + .isEmpty(); // Global subscribers - users = underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", "project42"); - assertThat(users).containsOnly("user2"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", projectKey)) + .containsOnly("user2"); - users = underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", null); - assertThat(users).containsOnly("user2"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", null)) + .containsOnly("user2"); // Project subscribers - users = underTest.selectNotificationSubscribers("DispatcherWithProjectSubscribers", "Email", "project42"); - assertThat(users).containsOnly("user1"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithProjectSubscribers", "Email", projectKey)) + .containsOnly("user1"); // Global + Project subscribers - users = underTest.selectNotificationSubscribers("DispatcherWithGlobalAndProjectSubscribers", "Email", "project42"); - assertThat(users).containsOnly("user1", "user2"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithGlobalAndProjectSubscribers", "Email", projectKey)) + .containsOnly("user1", "user2"); } @Test - public void hasNotificationSubscribers() { - insertUser(1); - insertUser(2); - insertProject("PROJECT_A", 42); + public void hasNotificationSubscribers() throws SQLException { + long userId1 = insertUser("user1"); + long userId2 = insertUser("user2"); + Long projectId = insertProject("PROJECT_A").getId(); // global subscription - insertProperty(1, "notification.DispatcherWithGlobalSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalSubscribers.Email", "true", null, userId2); // project subscription - insertProperty(2, "notification.DispatcherWithProjectSubscribers.Email", "true", 42, 1); - insertProperty(3, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56, 1); - insertProperty(4, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 42, 1); + insertProperty("notification.DispatcherWithProjectSubscribers.Email", "true", projectId, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56L, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", projectId, userId1); // global subscription - insertProperty(5, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, userId2); // Nobody is subscribed - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("NotSexyDispatcher"))).isFalse(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("NotSexyDispatcher"))) + .isFalse(); // Global subscribers - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalSubscribers"))).isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalSubscribers"))) + .isTrue(); // Project subscribers - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithProjectSubscribers"))).isTrue(); - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithProjectSubscribers"))).isFalse(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithProjectSubscribers"))) + .isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithProjectSubscribers"))) + .isFalse(); // Global + Project subscribers - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalAndProjectSubscribers"))).isTrue(); - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithGlobalAndProjectSubscribers"))).isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalAndProjectSubscribers"))) + .isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithGlobalAndProjectSubscribers"))) + .isTrue(); } @Test - public void selectGlobalProperties() { + public void selectGlobalProperties() throws SQLException { // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); + long id1 = insertProperty("global.one", "one", null, null); + long id2 = insertProperty("global.two", "two", null, null); List properties = underTest.selectGlobalProperties(); - assertThat(properties.size()).isEqualTo(2); - - PropertyDto first = findById(properties, 1); - assertThat(first.getKey()).isEqualTo("global.one"); - assertThat(first.getValue()).isEqualTo("one"); + assertThat(properties.size()) + .isEqualTo(2); + + assertThatDto(findById(properties, id1)) + .hasKey("global.one") + .hasNoUserId() + .hasNoResourceId() + .hasValue("one"); + + assertThatDto(findById(properties, id2)) + .hasKey("global.two") + .hasNoResourceId() + .hasNoUserId() + .hasValue("two"); + } - PropertyDto second = findById(properties, 2); - assertThat(second.getKey()).isEqualTo("global.two"); - assertThat(second.getValue()).isEqualTo("two"); + @Test + @UseDataProvider("allValuesForSelect") + public void selectGlobalProperties_supports_all_values(String dbValue, String expected) throws SQLException { + insertProperty("global.one", dbValue, null, null); + + List dtos = underTest.selectGlobalProperties(); + assertThat(dtos) + .hasSize(1); + assertThatDto(dtos.iterator().next()) + .hasKey("global.one") + .hasNoResourceId() + .hasNoUserId() + .hasValue(expected); } @Test - public void selectGlobalProperty() { + public void selectGlobalProperty() throws SQLException { // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); + insertProperty("global.one", "one", null, null); + insertProperty("global.two", "two", null, null); // project - insertProperty(3, "project.one", "one", 10, null); + insertProperty("project.one", "one", 10L, null); // user - insertProperty(4, "user.one", "one", null, 100); + insertProperty("user.one", "one", null, 100L); - PropertyDto prop = underTest.selectGlobalProperty("global.one"); - assertThat(prop).isNotNull(); - assertThat(prop.getValue()).isEqualTo("one"); + assertThatDto(underTest.selectGlobalProperty("global.one")) + .hasNoResourceId() + .hasNoUserId() + .hasValue("one"); assertThat(underTest.selectGlobalProperty("project.one")).isNull(); assertThat(underTest.selectGlobalProperty("user.one")).isNull(); @@ -191,39 +239,80 @@ public void selectGlobalProperty() { } @Test - public void selectProjectProperties() { - insertProject("A", 10); + @UseDataProvider("allValuesForSelect") + public void selectGlobalProperty_supports_all_values(String dbValue, String expected) throws SQLException { + insertProperty("global.one", dbValue, null, null); + + assertThatDto(underTest.selectGlobalProperty("global.one")) + .hasNoResourceId() + .hasNoUserId() + .hasValue(expected); + } + + @Test + public void selectProjectProperties() throws SQLException { + ComponentDto projectDto = insertProject("A"); + long projectId = projectDto.getId(); // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); + insertProperty("global.one", "one", null, null); + insertProperty("global.two", "two", null, null); // project - insertProperty(3, "project.one", "one", 10, null); - insertProperty(4, "project.two", "two", 10, null); + long id3 = insertProperty("project.one", "Pone", projectId, null); + long id4 = insertProperty("project.two", "Ptwo", projectId, null); + + List dtos = underTest.selectProjectProperties(projectDto.key()); + assertThat(dtos) + .hasSize(2); + assertThatDto(findById(dtos, id3)) + .hasKey("project.one") + .hasResourceId(projectId) + .hasValue("Pone"); + assertThatDto(findById(dtos, id4)) + .hasKey("project.two") + .hasResourceId(projectId) + .hasValue("Ptwo"); + } - List properties = underTest.selectProjectProperties("project10"); - assertThat(properties) - .hasSize(2) - .extracting("key", "value") - .containsOnly(tuple("project.one", "one"), tuple("project.two", "two")); + @Test + @UseDataProvider("allValuesForSelect") + public void selectProjectProperties_supports_all_values(String dbValue, String expected) throws SQLException { + ComponentDto projectDto = insertProject("A"); + insertProperty("project.one", dbValue, projectDto.getId(), null); + + List dtos = underTest.selectProjectProperties(projectDto.key()); + assertThat(dtos).hasSize(1); + assertThatDto(dtos.iterator().next()) + .hasKey("project.one") + .hasResourceId(projectDto.getId()) + .hasValue(expected); + } + + @DataProvider + public static Object[][] allValuesForSelect() { + return new Object[][] { + {null, ""}, + {"", ""}, + {"some value", "some value"}, + {VALUE_SIZE_4000, VALUE_SIZE_4000}, + {VALUE_SIZE_4001, VALUE_SIZE_4001} + }; } @Test - public void selectProjectProperty() { - insertProject("A", 10); - // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); - // project - insertProperty(3, "project.one", "one", 10, null); + public void selectProjectProperty() throws SQLException { + insertProperty("project.one", "one", 10L, null); PropertyDto property = underTest.selectProjectProperty(10L, "project.one"); - assertThat(property.getKey()).isEqualTo("project.one"); - assertThat(property.getValue()).isEqualTo("one"); + assertThatDto(property) + .hasKey("project.one") + .hasResourceId(10L) + .hasNoUserId() + .hasValue("one"); } @Test - public void select_module_properties_tree() { + public void selectEnabledDescendantModuleProperties() { dbTester.prepareDbUnit(getClass(), "select_module_properties_tree.xml"); List properties = underTest.selectEnabledDescendantModuleProperties("ABCD", dbTester.getSession()); @@ -243,8 +332,38 @@ public void select_module_properties_tree() { } @Test - public void select_by_query() { - dbTester.prepareDbUnit(getClass(), "select_by_query.xml"); + @UseDataProvider("allValuesForSelect") + public void selectEnabledDescendantModuleProperties_supports_all_values(String dbValue, String expected) throws SQLException { + String projectUuid = "A"; + ComponentDto project = ComponentTesting.newProjectDto(projectUuid); + dbClient.componentDao().insert(session, project); + long projectId = project.getId(); + insertProperty("project.one", dbValue, projectId, null); + + List dtos = underTest.selectEnabledDescendantModuleProperties(projectUuid, dbTester.getSession()); + assertThat(dtos) + .hasSize(1); + assertThatDto(dtos.iterator().next()) + .hasKey("project.one") + .hasResourceId(projectId) + .hasNoUserId() + .hasValue(expected); + } + + @Test + public void select_by_query() throws SQLException { + // global + insertProperty("global.one", "one", null, null); + insertProperty("global.two", "two", null, null); + // struts + insertProperty("struts.one", "one", 10L, null); + // commons + insertProperty("commonslang.one", "one", 11L, null); + // user + insertProperty("user.one", "one", null, 100L); + insertProperty("user.two", "two", 10L, 100L); + // other + insertProperty("other.one", "one", 12L, null); List results = underTest.selectByQuery(PropertyQuery.builder().setKey("user.two").setComponentId(10L).setUserId(100).build(), dbTester.getSession()); assertThat(results).hasSize(1); @@ -257,24 +376,27 @@ public void select_by_query() { @Test public void select_global_properties_by_keys() throws Exception { - ComponentDto project = ComponentTesting.newProjectDto(); - dbClient.componentDao().insert(session, project); - UserDto user = UserTesting.newUserDto(); - dbClient.userDao().insert(session, user); + insertProject("A"); + long userId = insertUser("B"); String key = "key"; String anotherKey = "anotherKey"; - insertProperties( - newGlobalPropertyDto().setKey(key), - newComponentPropertyDto(project).setKey(key), - newUserPropertyDto(user).setKey(key), - newGlobalPropertyDto().setKey(anotherKey)); - - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key))).extracting("key").containsOnly(key); - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey))).extracting("key").containsOnly(key, anotherKey); - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey, "unknown"))).extracting("key").containsOnly(key, anotherKey); - - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet("unknown"))).isEmpty(); + insertProperty(key, "value", null, null); + insertProperty(key, "value", 10L, null); + insertProperty(key, "value", null, userId); + insertProperty(anotherKey, "value", null, null); + + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key))) + .extracting("key") + .containsOnly(key); + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey))) + .extracting("key") + .containsOnly(key, anotherKey); + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey, "unknown"))) + .extracting("key") + .containsOnly(key, anotherKey); + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet("unknown"))) + .isEmpty(); } @Test @@ -337,99 +459,527 @@ public void select_properties_by_keys_and_component_ids() throws Exception { } @Test - public void setProperty_update() { - dbTester.prepareDbUnit(getClass(), "update.xml"); + public void saveProperty_inserts_global_properties_when_they_do_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + underTest.saveProperty(new PropertyDto().setKey("global.null").setValue(null)); + underTest.saveProperty(new PropertyDto().setKey("global.empty").setValue("")); + underTest.saveProperty(new PropertyDto().setKey("global.text").setValue("some text")); + underTest.saveProperty(new PropertyDto().setKey("global.4000").setValue(VALUE_SIZE_4000)); + underTest.saveProperty(new PropertyDto().setKey("global.clob").setValue(VALUE_SIZE_4001)); + + assertThatPropertiesRow("global.null") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("global.empty") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("global.text") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("some text") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("global.4000") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("global.clob") + .hasNoResourceId() + .hasNoUserId() + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); + } - underTest.insertProperty(new PropertyDto().setKey("global.key").setValue("new_global")); - underTest.insertProperty(new PropertyDto().setKey("project.key").setResourceId(10L).setValue("new_project")); - underTest.insertProperty(new PropertyDto().setKey("user.key").setUserId(100L).setValue("new_user")); - underTest.insertProperty(new PropertyDto().setKey("null.value").setValue(null)); + @Test + public void saveProperty_inserts_component_properties_when_they_do_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + long resourceId = 12; + underTest.saveProperty(new PropertyDto().setKey("component.null").setResourceId(resourceId).setValue(null)); + underTest.saveProperty(new PropertyDto().setKey("component.empty").setResourceId(resourceId).setValue("")); + underTest.saveProperty(new PropertyDto().setKey("component.text").setResourceId(resourceId).setValue("some text")); + underTest.saveProperty(new PropertyDto().setKey("component.4000").setResourceId(resourceId).setValue(VALUE_SIZE_4000)); + underTest.saveProperty(new PropertyDto().setKey("component.clob").setResourceId(resourceId).setValue(VALUE_SIZE_4001)); + + assertThatPropertiesRow("component.null") + .hasResourceId(resourceId) + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("component.empty") + .hasResourceId(resourceId) + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("component.text") + .hasResourceId(resourceId) + .hasNoUserId() + .hasTextValue("some text") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("component.4000") + .hasResourceId(resourceId) + .hasNoUserId() + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("component.clob") + .hasResourceId(resourceId) + .hasNoUserId() + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); + } - dbTester.assertDbUnit(getClass(), "update-result.xml", "properties"); + @Test + public void saveProperty_inserts_user_properties_when_they_do_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + long userId = 100; + underTest.saveProperty(new PropertyDto().setKey("user.null").setUserId(userId).setValue(null)); + underTest.saveProperty(new PropertyDto().setKey("user.empty").setUserId(userId).setValue("")); + underTest.saveProperty(new PropertyDto().setKey("user.text").setUserId(userId).setValue("some text")); + underTest.saveProperty(new PropertyDto().setKey("user.4000").setUserId(userId).setValue(VALUE_SIZE_4000)); + underTest.saveProperty(new PropertyDto().setKey("user.clob").setUserId(userId).setValue(VALUE_SIZE_4001)); + + assertThatPropertiesRow("user.null") + .hasNoResourceId() + .hasUserId(userId) + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("user.empty") + .hasNoResourceId() + .hasUserId(userId) + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("user.text") + .hasNoResourceId() + .hasUserId(userId) + .hasTextValue("some text") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("user.4000") + .hasNoResourceId() + .hasUserId(userId) + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("user.clob") + .hasNoResourceId() + .hasUserId(userId) + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); } @Test - public void setProperty_insert() { - dbTester.prepareDbUnit(getClass(), "insert.xml"); + @UseDataProvider("valueUpdatesDataProvider") + public void saveProperty_deletes_then_inserts_global_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException { + long id = insertProperty("global", oldValue, null, null, DATE_1); + when(system2.now()).thenReturn(DATE_4); + + underTest.saveProperty(new PropertyDto().setKey("global").setValue(newValue)); + + assertThatPropertiesRow(id) + .doesNotExist(); + + PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global") + .hasNoResourceId() + .hasNoUserId() + .hasCreatedAt(DATE_4); + if (newValue == null || newValue.isEmpty()) { + propertiesRowAssert.isEmpty(); + } else if (newValue.length() > 4000) { + propertiesRowAssert.hasClobValue(newValue); + } else { + propertiesRowAssert.hasTextValue(newValue); + } + } + + @Test + @UseDataProvider("valueUpdatesDataProvider") + public void saveProperty_deletes_then_inserts_component_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException { + long resourceId = 999L; + long id = insertProperty("global", oldValue, resourceId, null, DATE_1); + when(system2.now()).thenReturn(DATE_4); + + underTest.saveProperty(new PropertyDto().setKey("global").setResourceId(resourceId).setValue(newValue)); + + assertThatPropertiesRow(id) + .doesNotExist(); + + PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global") + .hasResourceId(resourceId) + .hasNoUserId() + .hasCreatedAt(DATE_4); + if (newValue == null || newValue.isEmpty()) { + propertiesRowAssert.isEmpty(); + } else if (newValue.length() > 4000) { + propertiesRowAssert.hasClobValue(newValue); + } else { + propertiesRowAssert.hasTextValue(newValue); + } + } - underTest.insertProperty(new PropertyDto().setKey("global.key").setValue("new_global")); - underTest.insertProperty(new PropertyDto().setKey("project.key").setResourceId(10L).setValue("new_project")); - underTest.insertProperty(new PropertyDto().setKey("user.key").setUserId(100L).setValue("new_user")); + @Test + @UseDataProvider("valueUpdatesDataProvider") + public void saveProperty_deletes_then_inserts_user_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException { + long userId = 90L; + long id = insertProperty("global", oldValue, null, userId, DATE_1); + when(system2.now()).thenReturn(DATE_4); + + underTest.saveProperty(new PropertyDto().setKey("global").setUserId(userId).setValue(newValue)); + + assertThatPropertiesRow(id) + .doesNotExist(); + + PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global") + .hasNoResourceId() + .hasUserId(userId) + .hasCreatedAt(DATE_4); + if (newValue == null || newValue.isEmpty()) { + propertiesRowAssert.isEmpty(); + } else if (newValue.length() > 4000) { + propertiesRowAssert.hasClobValue(newValue); + } else { + propertiesRowAssert.hasTextValue(newValue); + } + } - dbTester.assertDbUnit(getClass(), "insert-result.xml", "properties"); + @DataProvider + public static Object[][] valueUpdatesDataProvider() { + return new Object[][] { + {null, null}, + {null, ""}, + {null, "some value"}, + {null, VALUE_SIZE_4000}, + {null, VALUE_SIZE_4001}, + {"", null}, + {"", ""}, + {"", "some value"}, + {"", VALUE_SIZE_4000}, + {"", VALUE_SIZE_4001}, + {"a value", null}, + {"a value", ""}, + {"a value", "a value"}, + {"a value", "some value"}, + {"a value", VALUE_SIZE_4000}, + {"a value", VALUE_SIZE_4001}, + {VALUE_SIZE_4000, null}, + {VALUE_SIZE_4000, ""}, + {VALUE_SIZE_4000, "a value"}, + {VALUE_SIZE_4000, VALUE_SIZE_4000}, + {VALUE_SIZE_4000, VALUE_SIZE_4000.substring(1) + "a"}, + {VALUE_SIZE_4000, VALUE_SIZE_4001}, + {VALUE_SIZE_4001, null}, + {VALUE_SIZE_4001, ""}, + {VALUE_SIZE_4001, "a value"}, + {VALUE_SIZE_4001, VALUE_SIZE_4000}, + {VALUE_SIZE_4001, VALUE_SIZE_4001}, + {VALUE_SIZE_4001, VALUE_SIZE_4001 + "dfsdfs"}, + }; } @Test - public void delete_property_by_id() { - dbTester.prepareDbUnit(getClass(), "delete.xml"); + @UseDataProvider("possibleValuesProvider") + public void deleteById(String value) throws SQLException { + long id1 = insertProperty("global.key", value, null, null); + long id2 = insertProperty("component.key", value, 10L, null); + long id3 = insertProperty("user.key", value, null, 100L); + + underTest.deleteById(dbTester.getSession(), id1); + dbTester.getSession().commit(); - underTest.deleteById(dbTester.getSession(), 1L); + assertThatPropertiesRow(id1) + .doesNotExist(); + assertThatPropertiesRow(id2) + .hasKey("component.key"); + assertThatPropertiesRow(id3) + .hasKey("user.key"); + + underTest.deleteById(dbTester.getSession(), id2); + dbTester.getSession().commit(); + + assertThatPropertiesRow(id2) + .doesNotExist(); + assertThatPropertiesRow(id3) + .hasKey("user.key"); + + underTest.deleteById(dbTester.getSession(), id3); dbTester.getSession().commit(); - dbTester.assertDbUnit(getClass(), "delete-result.xml", "properties"); + assertThatPropertiesRow(id3) + .doesNotExist(); } - @Test - public void delete_project_property() { - dbTester.prepareDbUnit(getClass(), "delete_project_property.xml"); + @DataProvider + public static Object[][] possibleValuesProvider() { + return new Object[][] { + {null}, + {""}, + {"some value"}, + {VALUE_SIZE_4000}, + {VALUE_SIZE_4001} + }; + } - underTest.deleteProjectProperty("struts.one", 10L); + @Test + public void deleteById_does_not_fail_if_row_with_specified_id_does_not_exist() { + underTest.deleteById(dbTester.getSession(), 12L); + dbTester.getSession().commit(); + } - dbTester.assertDbUnit(getClass(), "delete_project_property-result.xml", "properties"); + @Test + public void delete_project_property() throws SQLException { + long projectId1 = insertProject("A").getId(); + long projectId2 = insertProject("B").getId(); + long projectId3 = insertProject("C").getId(); + long id1 = insertProperty("global.one", "one", null, null); + long id2 = insertProperty("global.two", "two", null, null); + long id3 = insertProperty("struts.one", "one", projectId1, null); + long id4 = insertProperty("commonslang.one", "one", projectId2, null); + long id5 = insertProperty("user.one", "one", null, 100L); + long id6 = insertProperty("user.two", "two", null, 100L); + long id7 = insertProperty("other.one", "one", projectId3, null); + + underTest.deleteProjectProperty("struts.one", projectId1); + + assertThatPropertiesRow(id1) + .hasKey("global.one") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("one"); + assertThatPropertiesRow(id2) + .hasKey("global.two") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("two"); + assertThatPropertiesRow(id3) + .doesNotExist(); + assertThatPropertiesRow(id4) + .hasKey("commonslang.one") + .hasResourceId(projectId2) + .hasNoUserId() + .hasTextValue("one"); + assertThatPropertiesRow(id5) + .hasKey("user.one") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("one"); + assertThatPropertiesRow(id6) + .hasKey("user.two") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("two"); + assertThatPropertiesRow(id7) + .hasKey("other.one") + .hasResourceId(projectId3) + .hasNoUserId() + .hasTextValue("one"); } @Test - public void delete_project_properties() { - dbTester.prepareDbUnit(getClass(), "delete_project_properties.xml"); + public void delete_project_properties() throws SQLException { + long id1 = insertProperty("sonar.profile.java", "Sonar Way", 1L, null); + long id2 = insertProperty("sonar.profile.java", "Sonar Way", 2L, null); + + long id3 = insertProperty("sonar.profile.java", "Sonar Way", null, null); + + long id4 = insertProperty("sonar.profile.js", "Sonar Way", 1L, null); + long id5 = insertProperty("sonar.profile.js", "Sonar Way", 2L, null); + long id6 = insertProperty("sonar.profile.js", "Sonar Way", null, null); underTest.deleteProjectProperties("sonar.profile.java", "Sonar Way"); - dbTester.assertDbUnit(getClass(), "delete_project_properties-result.xml", "properties"); + assertThatPropertiesRow(id1) + .doesNotExist(); + assertThatPropertiesRow(id2) + .doesNotExist(); + assertThatPropertiesRow(id3) + .hasKey("sonar.profile.java") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("Sonar Way"); + assertThatPropertiesRow(id4) + .hasKey("sonar.profile.js") + .hasResourceId(1) + .hasNoUserId() + .hasTextValue("Sonar Way"); + assertThatPropertiesRow(id5) + .hasKey("sonar.profile.js") + .hasResourceId(2) + .hasNoUserId() + .hasTextValue("Sonar Way"); + assertThatPropertiesRow(id6) + .hasKey("sonar.profile.js") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("Sonar Way"); } @Test - public void deleteGlobalProperty() { - dbTester.prepareDbUnit(getClass(), "deleteGlobalProperty.xml"); + public void deleteGlobalProperty() throws SQLException { + // global + long id1 = insertProperty("global.key", "new_global", null, null); + long id2 = insertProperty("to_be_deleted", "xxx", null, null); + // project - do not delete this project property that has the same key + long id3 = insertProperty("to_be_deleted", "new_project", 10L, null); + // user + long id4 = insertProperty("user.key", "new_user", null, 100L); underTest.deleteGlobalProperty("to_be_deleted"); - dbTester.assertDbUnit(getClass(), "deleteGlobalProperty-result.xml", "properties"); + assertThatPropertiesRow(id1) + .hasKey("global.key") + .hasNoUserId() + .hasNoResourceId() + .hasTextValue("new_global"); + assertThatPropertiesRow(id2) + .doesNotExist(); + assertThatPropertiesRow("to_be_deleted", null, null) + .doesNotExist(); + assertThatPropertiesRow(id3) + .hasKey("to_be_deleted") + .hasResourceId(10) + .hasNoUserId() + .hasTextValue("new_project"); + assertThatPropertiesRow(id4) + .hasKey("user.key") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("new_user"); + } @Test - public void insertGlobalProperties() { - dbTester.prepareDbUnit(getClass(), "insertGlobalProperties.xml"); - - underTest.insertGlobalProperties(ImmutableMap.of("to_be_inserted", "inserted")); - - dbTester.assertDbUnitTable(getClass(), "insertGlobalProperties-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); + public void saveGlobalProperties_insert_property_if_does_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + underTest.saveGlobalProperties(mapOf( + "null_value_property", null, + "empty_value_property", "", + "text_value_property", "dfdsfsd", + "4000_char_value_property", VALUE_SIZE_4000, + "clob_value_property", VALUE_SIZE_4001)); + + assertThatPropertiesRow("null_value_property") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("empty_value_property") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("text_value_property") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("dfdsfsd") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("4000_char_value_property") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("clob_value_property") + .hasNoResourceId() + .hasNoUserId() + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); } @Test - public void updateGlobalProperties() { - dbTester.prepareDbUnit(getClass(), "updateGlobalProperties.xml"); + public void saveGlobalProperties_delete_and_insert_new_value_when_property_exists_in_db() throws SQLException { + long id = insertProperty("to_be_updated", "old_value", null, null, DATE_1); + when(system2.now()).thenReturn(DATE_3); - underTest.insertGlobalProperties(ImmutableMap.of("to_be_updated", "updated")); + underTest.saveGlobalProperties(ImmutableMap.of("to_be_updated", "new value")); - dbTester.assertDbUnitTable(getClass(), "updateGlobalProperties-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); - } + assertThatPropertiesRow(id) + .doesNotExist(); - @Test - public void renamePropertyKey() { - dbTester.prepareDbUnit(getClass(), "renamePropertyKey.xml"); + assertThatPropertiesRow("to_be_updated") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("new value") + .hasCreatedAt(DATE_3); + } - underTest.renamePropertyKey("sonar.license.secured", "sonar.license"); + private static Map mapOf(String... values) { + // use LinkedHashMap to keep order of array + Map res = new LinkedHashMap<>(values.length / 2); + Iterator iterator = Arrays.asList(values).iterator(); + while (iterator.hasNext()) { + res.put(iterator.next(), iterator.next()); + } + return res; + } - dbTester.assertDbUnitTable(getClass(), "renamePropertyKey-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); + @Test + public void renamePropertyKey_updates_global_component_and_user_properties() throws SQLException { + long id1 = insertProperty("foo", "bar", null, null, DATE_1); + long id2 = insertProperty("old_name", "doc1", null, null, DATE_1); + long id3 = insertProperty("old_name", "doc2", 15L, null, DATE_1); + long id4 = insertProperty("old_name", "doc3", 16L, null, DATE_1); + long id5 = insertProperty("old_name", "doc4", null, 100L, DATE_1); + long id6 = insertProperty("old_name", "doc5", null, 101L, DATE_1); + + underTest.renamePropertyKey("old_name", "new_name"); + + assertThatPropertiesRow(id1) + .hasKey("foo") + .hasNoUserId() + .hasNoResourceId() + .hasTextValue("bar") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id2) + .hasKey("new_name") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("doc1") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id3) + .hasKey("new_name") + .hasResourceId(15) + .hasNoUserId() + .hasTextValue("doc2") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id4) + .hasKey("new_name") + .hasResourceId(16) + .hasNoUserId() + .hasTextValue("doc3") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id5) + .hasKey("new_name") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("doc4") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id6) + .hasKey("new_name") + .hasNoResourceId() + .hasUserId(101) + .hasTextValue("doc5") + .hasCreatedAt(DATE_1); } @Test - public void should_not_rename_if_same_key() { - dbTester.prepareDbUnit(getClass(), "should_not_rename_if_same_key.xml"); + public void rename_to_same_key_has_no_effect() throws SQLException { + long now = 1_890_999L; + long id = insertProperty("foo", "bar", null, null, now); + + assertThatPropertiesRow(id) + .hasCreatedAt(now); underTest.renamePropertyKey("foo", "foo"); - dbTester.assertDbUnitTable(getClass(), "should_not_rename_if_same_key-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); + assertThatPropertiesRow(id) + .hasKey("foo") + .hasNoUserId() + .hasNoResourceId() + .hasTextValue("bar") + .hasCreatedAt(now); } @Test @@ -444,7 +994,7 @@ public void should_not_rename_an_empty_key() { underTest.renamePropertyKey(null, "foo"); } - private PropertyDto findById(List properties, int id) { + private PropertyDto findById(List properties, long id) { for (PropertyDto property : properties) { if (property.getId() == id) { return property; @@ -455,35 +1005,61 @@ private PropertyDto findById(List properties, int id) { private void insertProperties(PropertyDto... properties) { for (PropertyDto propertyDto : properties) { - underTest.insertProperty(session, propertyDto); + underTest.saveProperty(session, propertyDto); } session.commit(); } - private void insertProperty(int id, String key, String value, @Nullable Integer resourceId, @Nullable Integer userId) { - dbTester.executeInsert("PROPERTIES", - "ID", valueOf(id), - "prop_key", key, - "text_value", value, - "resource_id", resourceId == null ? null : valueOf(resourceId), - "user_id", userId == null ? null : valueOf(userId)); - dbTester.commit(); + private long insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Long userId, long createdAt) throws SQLException { + when(system2.now()).thenReturn(createdAt); + return insertProperty(key, value, resourceId, userId); } - private void insertProject(String uuid, int id) { - dbTester.executeInsert("PROJECTS", - "uuid", uuid, - "uuid_path", "NOT_USED", - "root_uuid", uuid, - "kee", "project" + id, - "id", valueOf(id)); - dbTester.commit(); + private long insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Long userId) throws SQLException { + DbSession session = dbTester.getSession(); + PropertyDto dto = new PropertyDto().setKey(key) + .setResourceId(resourceId == null ? null : resourceId.longValue()) + .setUserId(userId == null ? null : userId) + .setValue(value); + dbTester.getDbClient().propertiesDao().saveProperty(session, dto); + session.commit(); + + return (long) dbTester.selectFirst(session, "select id as \"id\" from properties" + + " where prop_key='" + key + "'" + + " and user_id" + (userId == null ? " is null" : "='" + userId + "'") + + " and resource_id" + (resourceId == null ? " is null" : "='" + resourceId + "'")).get("id"); } - private void insertUser(int id) { - dbTester.executeInsert("USERS", - "id", valueOf(id), - "login", "user" + id); + private ComponentDto insertProject(String uuid) { + String key = "project" + uuid; + ComponentDto project = ComponentTesting.newProjectDto(uuid).setKey(key); + dbClient.componentDao().insert(session, project); dbTester.commit(); + return project; } + + private long insertUser(String login) { + UserDto dto = new UserDto().setLogin(login); + DbSession session = dbTester.getSession(); + dbClient.userDao().insert(session, dto); + session.commit(); + return dto.getId(); + } + + private static PropertyDtoAssert assertThatDto(@Nullable PropertyDto dto) { + return new PropertyDtoAssert(dto); + } + + private PropertiesRowAssert assertThatPropertiesRow(String key, @Nullable Integer userId, @Nullable Integer componentId) { + return new PropertiesRowAssert(dbTester, key, userId, componentId); + } + + private PropertiesRowAssert assertThatPropertiesRow(String key) { + return new PropertiesRowAssert(dbTester, key); + } + + private PropertiesRowAssert assertThatPropertiesRow(long id) { + return new PropertiesRowAssert(dbTester, id); + } + } diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java new file mode 100644 index 000000000000..e677c16cc0e9 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java @@ -0,0 +1,77 @@ +/* + * 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.property; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +final class PropertiesRow { + private final String key; + private final Long userId; + private final Long resourceId; + private final Boolean empty; + private final String textValue; + private final String clobValue; + private final Long createdAt; + + public PropertiesRow(String key, @Nullable Long userId, @Nullable Long resourceId, + @Nullable Boolean empty, @Nullable String textValue, @Nullable String clobValue, + @Nullable Long createdAt) { + this.key = key; + this.userId = userId; + this.resourceId = resourceId; + this.empty = empty; + this.textValue = textValue; + this.clobValue = clobValue; + this.createdAt = createdAt; + } + + public String getKey() { + return key; + } + + public Long getUserId() { + return userId; + } + + public Long getResourceId() { + return resourceId; + } + + @CheckForNull + public Boolean getEmpty() { + return empty; + } + + @CheckForNull + public String getTextValue() { + return textValue; + } + + @CheckForNull + public String getClobValue() { + return clobValue; + } + + @CheckForNull + public Long getCreatedAt() { + return createdAt; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java new file mode 100644 index 000000000000..d64838394e92 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java @@ -0,0 +1,203 @@ +/* + * 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.property; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.assertj.core.api.AbstractAssert; +import org.sonar.db.DbTester; + +import static com.google.common.base.Preconditions.checkState; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static java.util.Objects.requireNonNull; + +final class PropertiesRowAssert extends AbstractAssert { + + PropertiesRowAssert(DbTester dbTester, String propertyKey, @Nullable Integer userId, @Nullable Integer componentId) { + super( + asInternalProperty( + dbTester, + () -> " where prop_key='" + propertyKey + "'" + + " and user_id" + (userId == null ? " is null" : "='" + userId + "'") + + " and resource_id" + (componentId == null ? " is null" : "='" + componentId + "'")), + PropertiesRowAssert.class); + } + + PropertiesRowAssert(DbTester dbTester, String key) { + super(asInternalProperty(dbTester, () -> " where prop_key='" + key + "'"), PropertiesRowAssert.class); + } + + PropertiesRowAssert(DbTester dbTester, long id) { + super(asInternalProperty(dbTester, () -> " where id=" + id), PropertiesRowAssert.class); + } + + @CheckForNull + private static PropertiesRow asInternalProperty(DbTester dbTester, Supplier whereClauseSupplier) { + String whereClause = whereClauseSupplier.get(); + List> rows = dbTester.select( + "select" + + " prop_key as \"key\", user_id as \"userId\", resource_id as \"resourceId\", is_empty as \"isEmpty\", text_value as \"textValue\", clob_value as \"clobValue\", created_at as \"createdAt\"" + + + " from properties" + + whereClause); + checkState(rows.size() < 2, "More than one property found for where clause \"" + whereClause + "\""); + if (rows.isEmpty()) { + return null; + } else { + Map row = rows.iterator().next(); + return new PropertiesRow( + (String) row.get("key"), + (Long) row.get("userId"), + (Long) row.get("resourceId"), + toBoolean(row.get("isEmpty")), + (String) row.get("textValue"), + (String) row.get("clobValue"), + (Long) row.get("createdAt")); + } + } + + private static Boolean toBoolean(Object flag) { + if (flag instanceof Boolean) { + return (Boolean) flag; + } + if (flag instanceof Long) { + Long longBoolean = (Long) flag; + return longBoolean.equals(1L); + } + throw new IllegalArgumentException("Unsupported object type returned for column \"isEmpty\": " + flag.getClass()); + } + + public void doesNotExist() { + isNull(); + } + + public PropertiesRowAssert hasKey(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getKey(), expected)) { + failWithMessage("Expected PropertiesRow to have column PROP_KEY to be <%s> but was <%s>", expected, actual.getKey()); + } + + return this; + } + + public PropertiesRowAssert hasNoUserId() { + isNotNull(); + + if (actual.getUserId() != null) { + failWithMessage("Expected PropertiesRow to have column USER_ID to be null but was <%s>", actual.getUserId()); + } + + return this; + } + + public PropertiesRowAssert hasUserId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getUserId(), expected)) { + failWithMessage("Expected PropertiesRow to have column USER_ID to be <%s> but was <%s>", true, actual.getUserId()); + } + + return this; + } + + public PropertiesRowAssert hasNoResourceId() { + isNotNull(); + + if (actual.getResourceId() != null) { + failWithMessage("Expected PropertiesRow to have column RESOURCE_ID to be null but was <%s>", actual.getResourceId()); + } + + return this; + } + + public PropertiesRowAssert hasResourceId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getResourceId(), expected)) { + failWithMessage("Expected PropertiesRow to have column RESOURCE_ID to be <%s> but was <%s>", true, actual.getResourceId()); + } + + return this; + } + + public PropertiesRowAssert isEmpty() { + isNotNull(); + + if (!Objects.equals(actual.getEmpty(), TRUE)) { + failWithMessage("Expected PropertiesRow to have column IS_EMPTY to be <%s> but was <%s>", true, actual.getEmpty()); + } + if (actual.getTextValue() != null) { + failWithMessage("Expected PropertiesRow to have column TEXT_VALUE to be null but was <%s>", actual.getTextValue()); + } + if (actual.getClobValue() != null) { + failWithMessage("Expected PropertiesRow to have column CLOB_VALUE to be null but was <%s>", actual.getClobValue()); + } + + return this; + } + + public PropertiesRowAssert hasTextValue(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getTextValue(), requireNonNull(expected))) { + failWithMessage("Expected PropertiesRow to have column TEXT_VALUE to be <%s> but was <%s>", expected, actual.getTextValue()); + } + if (actual.getClobValue() != null) { + failWithMessage("Expected PropertiesRow to have column CLOB_VALUE to be null but was <%s>", actual.getClobValue()); + } + if (!Objects.equals(actual.getEmpty(), FALSE)) { + failWithMessage("Expected PropertiesRow to have column IS_EMPTY to be <%s> but was <%s>", false, actual.getEmpty()); + } + + return this; + } + + public PropertiesRowAssert hasClobValue(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getClobValue(), requireNonNull(expected))) { + failWithMessage("Expected PropertiesRow to have column CLOB_VALUE to be <%s> but was <%s>", true, actual.getClobValue()); + } + if (actual.getTextValue() != null) { + failWithMessage("Expected PropertiesRow to have column TEXT_VALUE to be null but was <%s>", actual.getTextValue()); + } + if (!Objects.equals(actual.getEmpty(), FALSE)) { + failWithMessage("Expected PropertiesRow to have column IS_EMPTY to be <%s> but was <%s>", false, actual.getEmpty()); + } + + return this; + } + + public PropertiesRowAssert hasCreatedAt(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getCreatedAt(), expected)) { + failWithMessage("Expected PropertiesRow to have column CREATED_AT to be <%s> but was <%s>", expected, actual.getCreatedAt()); + } + + return this; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java b/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java index bbef4a057f30..d43e8d08a245 100644 --- a/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java @@ -46,7 +46,7 @@ public PropertyDbTester(DbTester db) { } public PropertyDto insertProperty(PropertyDto property) { - dbClient.propertiesDao().insertProperty(dbSession, property); + dbClient.propertiesDao().saveProperty(dbSession, property); db.commit(); return property; @@ -58,7 +58,7 @@ public void insertProperties(PropertyDto... properties) { public void insertProperties(List properties) { for (PropertyDto propertyDto : properties) { - dbClient.propertiesDao().insertProperty(dbSession, propertyDto); + dbClient.propertiesDao().saveProperty(dbSession, propertyDto); } dbSession.commit(); } diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java b/sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java new file mode 100644 index 000000000000..93f94e95a7bf --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java @@ -0,0 +1,93 @@ +/* + * 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.property; + +import java.util.Objects; +import javax.annotation.Nullable; +import org.assertj.core.api.AbstractAssert; + +import static java.util.Objects.requireNonNull; + +public class PropertyDtoAssert extends AbstractAssert { + protected PropertyDtoAssert(@Nullable PropertyDto actual) { + super(actual, PropertyDtoAssert.class); + } + + public PropertyDtoAssert hasKey(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getKey(), expected)) { + failWithMessage("Expected PropertyDto to have key to be <%s> but was <%s>", expected, actual.getKey()); + } + + return this; + } + + public PropertyDtoAssert hasNoUserId() { + isNotNull(); + + if (actual.getUserId() != null) { + failWithMessage("Expected PropertyDto to have userId to be null but was <%s>", actual.getUserId()); + } + + return this; + } + + public PropertyDtoAssert hasUserId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getUserId(), expected)) { + failWithMessage("Expected PropertyDto to have userId to be <%s> but was <%s>", true, actual.getUserId()); + } + + return this; + } + + public PropertyDtoAssert hasNoResourceId() { + isNotNull(); + + if (actual.getResourceId() != null) { + failWithMessage("Expected PropertyDto to have resourceId to be null but was <%s>", actual.getResourceId()); + } + + return this; + } + + public PropertyDtoAssert hasResourceId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getResourceId(), expected)) { + failWithMessage("Expected PropertyDto to have resourceId to be <%s> but was <%s>", true, actual.getResourceId()); + } + + return this; + } + + public PropertyDtoAssert hasValue(String expected) { + requireNonNull(expected); + isNotNull(); + + if (!Objects.equals(actual.getValue(), expected)) { + failWithMessage("Expected PropertyDto to have value to be <%s> but was <%s>", true, actual.getValue()); + } + + return this; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java b/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java index 5673fe776a3c..220620323e03 100644 --- a/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java @@ -109,7 +109,7 @@ public void select_qgate_id() { } private void associateProjectToQualityGate(long componentId, long qualityGateId) { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto() + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() .setKey("sonar.qualitygate") .setResourceId(componentId) .setValue(String.valueOf(qualityGateId))); diff --git a/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java b/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java index aa2458da8aa9..6e5a916033c9 100644 --- a/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java @@ -525,13 +525,13 @@ private MeasureFilterFavouriteDto insertMeasureFilterFavourite(MeasureFilterDto private PropertyDto insertProperty(UserDto user) { PropertyDto dto = new PropertyDto().setKey(randomAlphanumeric(100)).setUserId(user.getId()); - dbClient.propertiesDao().insertProperty(session, dto); + dbClient.propertiesDao().saveProperty(session, dto); return dto; } private PropertyDto insertProperty(String key, String value, long componentId) { PropertyDto dto = new PropertyDto().setKey(key).setValue(value).setResourceId(componentId); - dbClient.propertiesDao().insertProperty(session, dto); + dbClient.propertiesDao().saveProperty(session, dto); return dto; } diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml deleted file mode 100644 index ef4ec2a18b2c..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml deleted file mode 100644 index 5229a2b791a9..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml deleted file mode 100644 index ba4619fbedd3..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml deleted file mode 100644 index 0953b0ecd9f8..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml deleted file mode 100644 index a5cfed3378bf..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml deleted file mode 100644 index 3e5eb87705cc..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml deleted file mode 100644 index 0428139feb6e..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml deleted file mode 100644 index aaf0fd642d35..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml deleted file mode 100644 index 97b8b6f02b37..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml deleted file mode 100644 index 4e07f27e2834..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml deleted file mode 100644 index 0305f9f545c6..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml deleted file mode 100644 index 4c532602cf0d..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml deleted file mode 100644 index 3e5eb87705cc..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml deleted file mode 100644 index 5ed00ba028b5..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml deleted file mode 100644 index 5594180c370d..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml deleted file mode 100644 index 871dedcb5e9f..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml deleted file mode 100644 index 0877b0035fe5..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml deleted file mode 100644 index 6ab761e2c6f6..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml deleted file mode 100644 index d420c9dadc49..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml deleted file mode 100644 index 2873d69a5bcd..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml index 9c6b865eaa45..8b837110e6bb 100644 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml +++ b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml @@ -3,52 +3,68 @@ + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> + user_id="[null]" + is_empty="[false]" + text_value="two" + created_at="1555000"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> + user_id="[null]" + is_empty="[false]" + text_value="two" + created_at="1555000"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> + user_id="100" + is_empty="[false]" + text_value="one" + created_at="1555000"/> + user_id="102" + is_empty="[false]" + text_value="two" + created_at="1555000"/> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml deleted file mode 100644 index b4fc11a8cdbc..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml deleted file mode 100644 index b4fc11a8cdbc..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml deleted file mode 100644 index c3268596de33..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml deleted file mode 100644 index 5229a2b791a9..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml deleted file mode 100644 index 12033fdc629c..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml deleted file mode 100644 index 4616072f3d9e..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml deleted file mode 100644 index 194761a6b2dc..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml deleted file mode 100644 index 5567744e1460..000000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml index e37eb2643eab..431aafa0198d 100644 --- a/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml +++ b/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml @@ -185,18 +185,26 @@ + is_empty="[false]" + text_value="43" + created_at="1555000"/> + is_empty="[false]" + text_value="42" + created_at="1555000"/> + is_empty="[false]" + text_value="42" + created_at="1555000"/> + is_empty="[false]" + text_value="42" + created_at="1555000"/>