diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 1d6c58829b0..b4651f96eaf 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -399,18 +400,26 @@ private void insertOrUpdateFields(BibEntry localBibEntry) throws SQLException { /** * Removes the shared bibEntry. * - * @param bibEntry {@link BibEntry} to be deleted + * @param bibEntries {@link BibEntry} to be deleted */ - public void removeEntry(BibEntry bibEntry) { + public void removeEntries(List bibEntries) { + Objects.requireNonNull(bibEntries); + if (bibEntries.isEmpty()) { + return; + } StringBuilder query = new StringBuilder() .append("DELETE FROM ") .append(escape("ENTRY")) .append(" WHERE ") .append(escape("SHARED_ID")) - .append(" = ?"); + .append(" IN ("); + query.append("?, ".repeat(bibEntries.size() - 1)); + query.append("?)"); try (PreparedStatement preparedStatement = connection.prepareStatement(query.toString())) { - preparedStatement.setInt(1, bibEntry.getSharedBibEntryData().getSharedID()); + for (int j = 0; j < bibEntries.size(); j++) { + preparedStatement.setInt(j + 1, bibEntries.get(j).getSharedBibEntryData().getSharedID()); + } preparedStatement.executeUpdate(); } catch (SQLException e) { LOGGER.error("SQL Error: ", e); diff --git a/src/main/java/org/jabref/logic/shared/DBMSSynchronizer.java b/src/main/java/org/jabref/logic/shared/DBMSSynchronizer.java index f8216a2fdef..23753cdde40 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSSynchronizer.java +++ b/src/main/java/org/jabref/logic/shared/DBMSSynchronizer.java @@ -115,9 +115,7 @@ public void listen(EntriesRemovedEvent event) { // In this case DBSynchronizer should not try to delete the bibEntry entry again (but it would not harm). if (isEventSourceAccepted(event) && checkCurrentConnection()) { List entries = event.getBibEntries(); - for (BibEntry entry : entries) { - dbmsProcessor.removeEntry(entry); - } + dbmsProcessor.removeEntries(entries); synchronizeLocalMetaData(); synchronizeLocalDatabase(); // Pull changes for the case that there where some } diff --git a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java index 4a59dfea7cb..401ba599020 100644 --- a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java +++ b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java @@ -3,6 +3,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -164,11 +165,14 @@ void testUpdateEqualEntry(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMS @ParameterizedTest @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") - void testRemoveEntry(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { + void testRemoveAllEntries(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { dbmsProcessor.setupSharedDatabase(); - BibEntry bibEntry = getBibEntryExample(); - dbmsProcessor.insertEntry(bibEntry); - dbmsProcessor.removeEntry(bibEntry); + BibEntry firstEntry = getBibEntryExample(); + BibEntry secondEntry = getBibEntryExample(); + List entriesToRemove = Arrays.asList(firstEntry, secondEntry); + dbmsProcessor.insertEntry(firstEntry); + dbmsProcessor.insertEntry(secondEntry); + dbmsProcessor.removeEntries(entriesToRemove); try (ResultSet resultSet = selectFrom("ENTRY", dbmsConnection, dbmsProcessor)) { assertFalse(resultSet.next()); @@ -176,6 +180,67 @@ void testRemoveEntry(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProce clear(dbmsConnection); } + @ParameterizedTest + @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") + void testRemoveSomeEntries(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { + dbmsProcessor.setupSharedDatabase(); + BibEntry firstEntry = getBibEntryExample(); + BibEntry secondEntry = getBibEntryExample(); + BibEntry thirdEntry = getBibEntryExample(); + + // Remove the first and third entries - the second should remain (SHARED_ID will be 2) + + List entriesToRemove = Arrays.asList(firstEntry, thirdEntry); + dbmsProcessor.insertEntry(firstEntry); + dbmsProcessor.insertEntry(secondEntry); + dbmsProcessor.insertEntry(thirdEntry); + dbmsProcessor.removeEntries(entriesToRemove); + + try (ResultSet entryResultSet = selectFrom("ENTRY", dbmsConnection, dbmsProcessor)) { + assertTrue(entryResultSet.next()); + assertEquals(2, entryResultSet.getInt("SHARED_ID")); + assertFalse(entryResultSet.next()); + } + + clear(dbmsConnection); + } + + @ParameterizedTest + @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") + void testRemoveSingleEntry(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { + dbmsProcessor.setupSharedDatabase(); + BibEntry entryToRemove = getBibEntryExample(); + dbmsProcessor.insertEntry(entryToRemove); + dbmsProcessor.removeEntries(Collections.singletonList(entryToRemove)); + + try (ResultSet entryResultSet = selectFrom("ENTRY", dbmsConnection, dbmsProcessor)) { + assertFalse(entryResultSet.next()); + } + + clear(dbmsConnection); + } + + @ParameterizedTest + @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") + void testRemoveEntriesOnNullThrows(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { + dbmsProcessor.setupSharedDatabase(); + assertThrows(NullPointerException.class, () -> dbmsProcessor.removeEntries(null)); + clear(dbmsConnection); + } + + @ParameterizedTest + @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") + void testRemoveEmptyEntryList(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { + dbmsProcessor.setupSharedDatabase(); + dbmsProcessor.removeEntries(Collections.emptyList()); + + try (ResultSet entryResultSet = selectFrom("ENTRY", dbmsConnection, dbmsProcessor)) { + assertFalse(entryResultSet.next()); + } + + clear(dbmsConnection); + } + @ParameterizedTest @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") void testGetSharedEntries(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws SQLException { diff --git a/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java b/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java index 1f958db27b0..4d41a5a15d9 100644 --- a/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java +++ b/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java @@ -1,7 +1,6 @@ package org.jabref.logic.shared; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -90,7 +89,7 @@ public void testFieldChangedEventListener(DBMSType dbmsType, DBMSConnection dbms @ParameterizedTest @MethodSource("org.jabref.logic.shared.TestManager#getTestingDatabaseSystems") - public void testEntryRemovedEventListener(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws Exception { + public void testEntriesRemovedEventListener(DBMSType dbmsType, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) throws Exception { setUp(dbmsConnection); BibEntry bibEntry = getBibEntryExample(1); @@ -162,10 +161,9 @@ public void testSynchronizeLocalDatabaseWithEntryRemoval(DBMSType dbmsType, DBMS assertEquals(expectedBibEntries, bibDatabase.getEntries()); - dbmsProcessor.removeEntry(expectedBibEntries.get(0)); - dbmsProcessor.removeEntry(expectedBibEntries.get(1)); + dbmsProcessor.removeEntries(Collections.singletonList(expectedBibEntries.get(0))); - expectedBibEntries = new ArrayList<>(); + expectedBibEntries = Collections.singletonList(expectedBibEntries.get(1)); dbmsSynchronizer.synchronizeLocalDatabase();