Skip to content

Commit

Permalink
Batch DBMSProcessor fields insertion (#5812)
Browse files Browse the repository at this point in the history
Batch DBMSProcessor fields insertion
  • Loading branch information
koppor authored Jan 7, 2020
2 parents 0dd2c5f + 931ccad commit 2f5565b
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 20 deletions.
39 changes: 22 additions & 17 deletions src/main/java/org/jabref/logic/shared/DBMSProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,25 +213,30 @@ private boolean checkForBibEntryExistence(BibEntry bibEntry) {
private void insertIntoFieldTable(BibEntry bibEntry) {
try {
// Inserting into FIELD table
for (Field field : bibEntry.getFields()) {
StringBuilder insertFieldQuery = new StringBuilder()
.append("INSERT INTO ")
.append(escape("FIELD"))
.append("(")
.append(escape("ENTRY_SHARED_ID"))
.append(", ")
.append(escape("NAME"))
.append(", ")
.append(escape("VALUE"))
.append(") VALUES(?, ?, ?)");

try (PreparedStatement preparedFieldStatement = connection.prepareStatement(insertFieldQuery.toString())) {
// Coerce to ArrayList in order to use List.get()
List<Field> fields = new ArrayList<>(bibEntry.getFields());
StringBuilder insertFieldQuery = new StringBuilder()
.append("INSERT INTO ")
.append(escape("FIELD"))
.append("(")
.append(escape("ENTRY_SHARED_ID"))
.append(", ")
.append(escape("NAME"))
.append(", ")
.append(escape("VALUE"))
.append(") VALUES(?, ?, ?)");
// Number of commas is fields.size() - 1
for (int i = 0; i < fields.size() - 1; i++) {
insertFieldQuery.append(", (?, ?, ?)");
}
try (PreparedStatement preparedFieldStatement = connection.prepareStatement(insertFieldQuery.toString())) {
for (int i = 0; i < fields.size(); i++) {
// columnIndex starts with 1
preparedFieldStatement.setInt(1, bibEntry.getSharedBibEntryData().getSharedID());
preparedFieldStatement.setString(2, field.getName());
preparedFieldStatement.setString(3, bibEntry.getField(field).get());
preparedFieldStatement.executeUpdate();
preparedFieldStatement.setInt((3 * i) + 1, bibEntry.getSharedBibEntryData().getSharedID());
preparedFieldStatement.setString((3 * i) + 2, fields.get(i).getName());
preparedFieldStatement.setString((3 * i) + 3, bibEntry.getField(fields.get(i)).get());
}
preparedFieldStatement.executeUpdate();
}
} catch (SQLException e) {
LOGGER.error("SQL Error: ", e);
Expand Down
77 changes: 74 additions & 3 deletions src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,59 @@ void testInsertEntry() throws SQLException {
assertEquals(expectedFieldMap, actualFieldMap);
}

@Test
void testInsertMultipleEntries() throws SQLException {
BibEntry firstEntry = getBibEntryExample();
String firstId = firstEntry.getId();
BibEntry secondEntry = getBibEntryExample2();
String secondId = secondEntry.getId();
BibEntry thirdEntry = getBibEntryExample3();
String thirdId = thirdEntry.getId();

// This must eventually be changed to insertEntries() once that method is implemented
dbmsProcessor.insertEntry(firstEntry);
dbmsProcessor.insertEntry(secondEntry);
dbmsProcessor.insertEntry(thirdEntry);

Map<Integer, Map<String, String>> actualFieldMap = new HashMap<>();

try (ResultSet entryResultSet = selectFrom("ENTRY", dbmsConnection, dbmsProcessor)) {
assertTrue(entryResultSet.next());
assertEquals(1, entryResultSet.getInt("SHARED_ID"));
assertEquals("inproceedings", entryResultSet.getString("TYPE"));
assertEquals(1, entryResultSet.getInt("VERSION"));
assertTrue(entryResultSet.next());
assertEquals(2, entryResultSet.getInt("SHARED_ID"));
assertEquals("inproceedings", entryResultSet.getString("TYPE"));
assertEquals(1, entryResultSet.getInt("VERSION"));
assertTrue(entryResultSet.next());
assertEquals(3, entryResultSet.getInt("SHARED_ID"));
assertFalse(entryResultSet.next());

try (ResultSet fieldResultSet = selectFrom("FIELD", dbmsConnection, dbmsProcessor)) {
while (fieldResultSet.next()) {
if (actualFieldMap.keySet().contains(fieldResultSet.getInt("ENTRY_SHARED_ID"))) {
actualFieldMap.get(fieldResultSet.getInt("ENTRY_SHARED_ID")).put(
fieldResultSet.getString("NAME"), fieldResultSet.getString("VALUE"));
} else {
int sharedId = fieldResultSet.getInt("ENTRY_SHARED_ID");
actualFieldMap.put(sharedId,
new HashMap<>());
actualFieldMap.get(sharedId).put(fieldResultSet.getString("NAME"),
fieldResultSet.getString("VALUE"));
}
}
}
}
List<BibEntry> entries = Arrays.asList(firstEntry, secondEntry, thirdEntry);
Map<Integer, Map<String, String>> expectedFieldMap = entries.stream()
.collect(Collectors.toMap(bibEntry -> bibEntry.getSharedBibEntryData().getSharedID(),
(bibEntry) -> bibEntry.getFieldMap().entrySet().stream()
.collect(Collectors.toMap((entry) -> entry.getKey().getName(), Map.Entry::getValue))));

assertEquals(expectedFieldMap, actualFieldMap);
}

@Test
void testUpdateEntry() throws Exception {
BibEntry expectedEntry = getBibEntryExample();
Expand Down Expand Up @@ -156,7 +209,7 @@ void testUpdateEqualEntry() throws OfflineLockException, SQLException {
@Test
void testRemoveAllEntries() throws SQLException {
BibEntry firstEntry = getBibEntryExample();
BibEntry secondEntry = getBibEntryExample();
BibEntry secondEntry = getBibEntryExample2();
List<BibEntry> entriesToRemove = Arrays.asList(firstEntry, secondEntry);
dbmsProcessor.insertEntry(firstEntry);
dbmsProcessor.insertEntry(secondEntry);
Expand All @@ -170,8 +223,8 @@ void testRemoveAllEntries() throws SQLException {
@Test
void testRemoveSomeEntries() throws SQLException {
BibEntry firstEntry = getBibEntryExample();
BibEntry secondEntry = getBibEntryExample();
BibEntry thirdEntry = getBibEntryExample();
BibEntry secondEntry = getBibEntryExample2();
BibEntry thirdEntry = getBibEntryExample3();

// Remove the first and third entries - the second should remain (SHARED_ID will be 2)

Expand Down Expand Up @@ -311,6 +364,24 @@ private static BibEntry getBibEntryExample() {
.withCiteKey("nanoproc1994");
}

private static BibEntry getBibEntryExample2() {
return new BibEntry(StandardEntryType.InProceedings)
.withField(StandardField.AUTHOR, "Shelah, Saharon and Ziegler, Martin")
.withField(StandardField.TITLE, "Algebraically closed groups of large cardinality")
.withField(StandardField.JOURNAL, "The Journal of Symbolic Logic")
.withField(StandardField.YEAR, "1979")
.withCiteKey("algegrou1979");
}

private static BibEntry getBibEntryExample3() {
return new BibEntry(StandardEntryType.InProceedings)
.withField(StandardField.AUTHOR, "Hodges, Wilfrid and Shelah, Saharon")
.withField(StandardField.TITLE, "Infinite games and reduced products")
.withField(StandardField.JOURNAL, "Annals of Mathematical Logic")
.withField(StandardField.YEAR, "1981")
.withCiteKey("infigame1981");
}

private ResultSet selectFrom(String table, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) {
try {
return dbmsConnection.getConnection().createStatement().executeQuery("SELECT * FROM " + escape(table, dbmsProcessor));
Expand Down

0 comments on commit 2f5565b

Please sign in to comment.