From a743e647645c0af10d5960e0b034b7f8f54a57df Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 01/75] Add schema 'jabref' in pgsql processor --- .../jabref/logic/shared/DBMSProcessor.java | 44 ++++++++++--------- .../logic/shared/PostgreSQLProcessor.java | 17 ++++--- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 81e775a5ff2..4952c4f4a85 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -55,7 +55,7 @@ protected DBMSProcessor(DatabaseConnection dbmsConnection) { * @throws SQLException */ public boolean checkBaseIntegrity() throws SQLException { - return checkTableAvailability("ENTRY", "FIELD", "METADATA"); + return checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); } /** @@ -130,6 +130,10 @@ public void setupSharedDatabase() throws SQLException { */ abstract String escape(String expression); + String escape_Table(String expression) { + return escape(expression); + } + /** * For use in test only. Inserts the BibEntry into the shared database. * @@ -161,7 +165,7 @@ public void insertEntries(List bibEntries) { protected void insertIntoEntryTable(List bibEntries) { StringBuilder insertIntoEntryQuery = new StringBuilder() .append("INSERT INTO ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) .append("(") .append(escape("TYPE")) .append(") VALUES(?)"); @@ -212,7 +216,7 @@ private List getNotYetExistingEntries(List bibEntries) { try { StringBuilder selectQuery = new StringBuilder() .append("SELECT * FROM ") - .append(escape("ENTRY")); + .append(escape_Table("ENTRY")); try (ResultSet resultSet = connection.createStatement().executeQuery(selectQuery.toString())) { while (resultSet.next()) { @@ -242,7 +246,7 @@ protected void insertIntoFieldTable(List bibEntries) { StringBuilder insertFieldQuery = new StringBuilder() .append("INSERT INTO ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append("(") .append(escape("ENTRY_SHARED_ID")) .append(", ") @@ -310,7 +314,7 @@ public void updateEntry(BibEntry localBibEntry) throws OfflineLockException, SQL // updating entry type StringBuilder updateEntryTypeQuery = new StringBuilder() .append("UPDATE ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) .append(" SET ") .append(escape("TYPE")) .append(" = ?, ") @@ -348,7 +352,7 @@ private void removeSharedFieldsByDifference(BibEntry localBibEntry, BibEntry sha for (Field nullField : nullFields) { StringBuilder deleteFieldQuery = new StringBuilder() .append("DELETE FROM ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append(" WHERE ") .append(escape("NAME")) .append(" = ? AND ") @@ -379,7 +383,7 @@ private void insertOrUpdateFields(BibEntry localBibEntry) throws SQLException { StringBuilder selectFieldQuery = new StringBuilder() .append("SELECT * FROM ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append(" WHERE ") .append(escape("NAME")) .append(" = ? AND ") @@ -395,7 +399,7 @@ private void insertOrUpdateFields(BibEntry localBibEntry) throws SQLException { if (selectFieldResultSet.next()) { // check if field already exists StringBuilder updateFieldQuery = new StringBuilder() .append("UPDATE ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append(" SET ") .append(escape("VALUE")) .append(" = ? WHERE ") @@ -414,7 +418,7 @@ private void insertOrUpdateFields(BibEntry localBibEntry) throws SQLException { } else { StringBuilder insertFieldQuery = new StringBuilder() .append("INSERT INTO ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append("(") .append(escape("ENTRY_SHARED_ID")) .append(", ") @@ -448,7 +452,7 @@ public void removeEntries(List bibEntries) { } StringBuilder query = new StringBuilder() .append("DELETE FROM ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) .append(" WHERE ") .append(escape("SHARED_ID")) .append(" IN ("); @@ -506,19 +510,19 @@ public List getSharedEntries(List sharedIDs) { StringBuilder query = new StringBuilder(); query.append("SELECT ") - .append(escape("ENTRY")).append(".").append(escape("SHARED_ID")).append(", ") - .append(escape("ENTRY")).append(".").append(escape("TYPE")).append(", ") - .append(escape("ENTRY")).append(".").append(escape("VERSION")).append(", ") + .append(escape_Table("ENTRY")).append(".").append(escape("SHARED_ID")).append(", ") + .append(escape_Table("ENTRY")).append(".").append(escape("TYPE")).append(", ") + .append(escape_Table("ENTRY")).append(".").append(escape("VERSION")).append(", ") .append("F.").append(escape("ENTRY_SHARED_ID")).append(", ") .append("F.").append(escape("NAME")).append(", ") .append("F.").append(escape("VALUE")) .append(" FROM ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) // Handle special case if entry does not have any fields (yet) .append(" left outer join ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append(" F on ") - .append(escape("ENTRY")).append(".").append(escape("SHARED_ID")) + .append(escape_Table("ENTRY")).append(".").append(escape("SHARED_ID")) .append(" = F.").append(escape("ENTRY_SHARED_ID")); if (!sharedIDs.isEmpty()) { @@ -577,7 +581,7 @@ public Map getSharedIDVersionMapping() { Map sharedIDVersionMapping = new HashMap<>(); StringBuilder selectEntryQuery = new StringBuilder() .append("SELECT * FROM ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) .append(" ORDER BY ") .append(escape("SHARED_ID")); @@ -598,7 +602,7 @@ public Map getSharedIDVersionMapping() { public Map getSharedMetaData() { Map data = new HashMap<>(); - try (ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM " + escape("METADATA"))) { + try (ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM " + escape_Table("METADATA"))) { while (resultSet.next()) { data.put(resultSet.getString("KEY"), resultSet.getString("VALUE")); } @@ -617,7 +621,7 @@ public Map getSharedMetaData() { public void setSharedMetaData(Map data) throws SQLException { StringBuilder updateQuery = new StringBuilder() .append("UPDATE ") - .append(escape("METADATA")) + .append(escape_Table("METADATA")) .append(" SET ") .append(escape("VALUE")) .append(" = ? ") @@ -627,7 +631,7 @@ public void setSharedMetaData(Map data) throws SQLException { StringBuilder insertQuery = new StringBuilder() .append("INSERT INTO ") - .append(escape("METADATA")) + .append(escape_Table("METADATA")) .append("(") .append(escape("KEY")) .append(", ") diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index 8d040a008a4..0c536c6b63d 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -30,20 +30,22 @@ public PostgreSQLProcessor(DatabaseConnection connection) { */ @Override public void setUp() throws SQLException { + connection.createStatement().executeUpdate("CREATE SCHEMA IF NOT EXISTS jabref"); + connection.createStatement().executeUpdate( - "CREATE TABLE IF NOT EXISTS \"ENTRY\" (" + + "CREATE TABLE IF NOT EXISTS " + escape_Table("ENTRY") + " (" + "\"SHARED_ID\" SERIAL PRIMARY KEY, " + "\"TYPE\" VARCHAR, " + "\"VERSION\" INTEGER DEFAULT 1)"); connection.createStatement().executeUpdate( - "CREATE TABLE IF NOT EXISTS \"FIELD\" (" + - "\"ENTRY_SHARED_ID\" INTEGER REFERENCES \"ENTRY\"(\"SHARED_ID\") ON DELETE CASCADE, " + + "CREATE TABLE IF NOT EXISTS " + escape_Table("FIELD") + " (" + + "\"ENTRY_SHARED_ID\" INTEGER REFERENCES " + escape_Table("ENTRY") + "(\"SHARED_ID\") ON DELETE CASCADE, " + "\"NAME\" VARCHAR, " + "\"VALUE\" TEXT)"); connection.createStatement().executeUpdate( - "CREATE TABLE IF NOT EXISTS \"METADATA\" (" + "CREATE TABLE IF NOT EXISTS " + escape_Table("METADATA") + " (" + "\"KEY\" VARCHAR," + "\"VALUE\" TEXT)"); } @@ -52,7 +54,7 @@ public void setUp() throws SQLException { protected void insertIntoEntryTable(List bibEntries) { StringBuilder insertIntoEntryQuery = new StringBuilder() .append("INSERT INTO ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) .append("(") .append(escape("TYPE")) .append(") VALUES(?)"); @@ -88,6 +90,11 @@ String escape(String expression) { return "\"" + expression + "\""; } + @Override + String escape_Table(String expression) { + return "jabref." + escape(expression); + } + @Override public void startNotificationListener(DBMSSynchronizer dbmsSynchronizer) { // Disable cleanup output of ThreadedHousekeeper From d840de4d89c5968c2781332cde3d6713d5dd5b66 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 02/75] Update MetaData and MetaDataParser (METADATA_VERSION) --- .../jabref/logic/importer/util/MetaDataParser.java | 2 ++ src/main/java/org/jabref/model/metadata/MetaData.java | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java b/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java index c918d431700..18a4a85cb7b 100644 --- a/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java +++ b/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java @@ -90,6 +90,8 @@ public MetaData parse(MetaData metaData, Map data, Character key metaData.setSaveOrderConfig(SaveOrderConfig.parse(value)); } else if (entry.getKey().equals(MetaData.GROUPSTREE) || entry.getKey().equals(MetaData.GROUPSTREE_LEGACY)) { metaData.setGroups(GroupsParser.importGroups(value, keywordSeparator, fileMonitor, metaData)); + } else if (entry.getKey().equals(MetaData.METADATA_VERSION)) { + metaData.setMetadataVersion(getSingleItem(value)); } else { // Keep meta data items that we do not know in the file metaData.putUnknownMetaDataItem(entry.getKey(), value); diff --git a/src/main/java/org/jabref/model/metadata/MetaData.java b/src/main/java/org/jabref/model/metadata/MetaData.java index 531ac1985be..bcffa913f2e 100644 --- a/src/main/java/org/jabref/model/metadata/MetaData.java +++ b/src/main/java/org/jabref/model/metadata/MetaData.java @@ -40,6 +40,7 @@ public class MetaData { public static final String PREFIX_KEYPATTERN = "keypattern_"; public static final String KEYPATTERNDEFAULT = "keypatterndefault"; public static final String DATABASE_TYPE = "databaseType"; + public static final String METADATA_VERSION = "metadataVersion"; public static final String GROUPSTREE = "grouping"; public static final String GROUPSTREE_LEGACY = "groupstree"; public static final String FILE_DIRECTORY = "fileDirectory"; @@ -69,6 +70,7 @@ public class MetaData { private final Map> unknownMetaData = new HashMap<>(); private boolean isEventPropagationEnabled = true; private boolean encodingExplicitlySupplied; + private String metadataVersion; /** * Constructs an empty metadata. @@ -209,6 +211,15 @@ public void setDefaultFileDirectory(String path) { postChange(); } + public Optional getMetadataVersion() { + return Optional.ofNullable(metadataVersion); + } + + public void setMetadataVersion(String version) { + metadataVersion = Objects.requireNonNull(version).trim(); + postChange(); + } + public Optional getUserFileDirectory(String user) { return Optional.ofNullable(userFileDirectory.get(user)); } From 479b300a3e2bd119df0cc13f3cc9e78fd54181cf Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 03/75] Update methods checkBaseIntegrity and setUP --- .../jabref/logic/shared/DBMSProcessor.java | 2 +- .../jabref/logic/shared/MySQLProcessor.java | 49 +++++++++++++++++-- .../jabref/logic/shared/OracleProcessor.java | 11 +++++ .../logic/shared/PostgreSQLProcessor.java | 36 +++++++++++++- 4 files changed, 92 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 4952c4f4a85..0e33baea4aa 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -80,7 +80,7 @@ public boolean databaseIsAtMostJabRef35() throws SQLException { * @param tableNames Table names to be checked * @return true if all given tables are present, else false. */ - private boolean checkTableAvailability(String... tableNames) throws SQLException { + protected boolean checkTableAvailability(String... tableNames) throws SQLException { List requiredTables = new ArrayList<>(); for (String name : tableNames) { requiredTables.add(name.toUpperCase(Locale.ENGLISH)); diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index bdac07e5fa0..2432ff2ccb3 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -1,6 +1,9 @@ package org.jabref.logic.shared; import java.sql.SQLException; +import java.util.Map; + +import org.jabref.model.metadata.MetaData; /** * Processes all incoming or outgoing bib data to MySQL Database and manages its structure. @@ -19,26 +22,64 @@ public MySQLProcessor(DatabaseConnection connection) { @Override public void setUp() throws SQLException { connection.createStatement().executeUpdate( - "CREATE TABLE IF NOT EXISTS `ENTRY` (" + + "CREATE TABLE IF NOT EXISTS `JABREF_ENTRY` (" + "`SHARED_ID` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, " + "`TYPE` VARCHAR(255) NOT NULL, " + "`VERSION` INT(11) DEFAULT 1)"); connection.createStatement().executeUpdate( - "CREATE TABLE IF NOT EXISTS `FIELD` (" + + "CREATE TABLE IF NOT EXISTS `JABREF_FIELD` (" + "`ENTRY_SHARED_ID` INT(11) NOT NULL, " + "`NAME` VARCHAR(255) NOT NULL, " + "`VALUE` TEXT DEFAULT NULL, " + - "FOREIGN KEY (`ENTRY_SHARED_ID`) REFERENCES `ENTRY`(`SHARED_ID`) ON DELETE CASCADE)"); + "FOREIGN KEY (`ENTRY_SHARED_ID`) REFERENCES `JABREF_ENTRY`(`SHARED_ID`) ON DELETE CASCADE)"); connection.createStatement().executeUpdate( - "CREATE TABLE IF NOT EXISTS `METADATA` (" + + "CREATE TABLE IF NOT EXISTS `JABREF_METADATA` (" + "`KEY` varchar(255) NOT NULL," + "`VALUE` text NOT NULL)"); + + Map metadata = getSharedMetaData(); + metadata.put(MetaData.METADATA_VERSION, "1"); + setSharedMetaData(metadata); + } + + /** + * Scans the database for required tables. + * + * @return true if the structure matches the requirements, false if not. + * @throws SQLException + */ + @Override + public boolean checkBaseIntegrity() throws SQLException { + boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + + if(value){ + Map metadata = getSharedMetaData(); + if(metadata.get(MetaData.METADATA_VERSION) == null){ + value = false; + }else{ + try { + int METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + if(METADATA_VERSION < 1){ + value = false; + } + } catch (Exception e) { + // TODO: handle exception + value = false; + } + } + } + return value; } @Override String escape(String expression) { return "`" + expression + "`"; } + + @Override + String escape_Table(String expression) { + return escape("JABREF_"+expression); + } } diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index b4a0e471915..e96ea8a5987 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -6,11 +6,13 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; import org.jabref.logic.shared.listener.OracleNotificationListener; import org.jabref.model.entry.BibEntry; +import org.jabref.model.metadata.MetaData; import org.jabref.model.entry.field.Field; import oracle.jdbc.OracleConnection; @@ -63,6 +65,10 @@ public void setUp() throws SQLException { "CREATE TABLE \"METADATA\" (" + "\"KEY\" VARCHAR2(255) NULL," + "\"VALUE\" CLOB NOT NULL)"); + + Map metadata = getSharedMetaData(); + metadata.put(MetaData.METADATA_VERSION, "0"); + setSharedMetaData(metadata); } @Override @@ -70,6 +76,11 @@ String escape(String expression) { return expression; } + @Override + String escape_Table(String expression) { + return escape(expression); + } + @Override public void startNotificationListener(DBMSSynchronizer dbmsSynchronizer) { this.listener = new OracleNotificationListener(dbmsSynchronizer); diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index 0c536c6b63d..e9ec216ac6d 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -5,11 +5,12 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.List; +import java.util.Map; import org.jabref.gui.JabRefExecutorService; import org.jabref.logic.shared.listener.PostgresSQLNotificationListener; import org.jabref.model.entry.BibEntry; - +import org.jabref.model.metadata.MetaData; import org.postgresql.PGConnection; /** @@ -48,6 +49,39 @@ public void setUp() throws SQLException { "CREATE TABLE IF NOT EXISTS " + escape_Table("METADATA") + " (" + "\"KEY\" VARCHAR," + "\"VALUE\" TEXT)"); + + Map metadata = getSharedMetaData(); + metadata.put(MetaData.METADATA_VERSION, "1"); + setSharedMetaData(metadata); + } + + /** + * Scans the database for required tables. + * + * @return true if the structure matches the requirements, false if not. + * @throws SQLException + */ + @Override + public boolean checkBaseIntegrity() throws SQLException { + boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + + if(value){ + Map metadata = getSharedMetaData(); + if(metadata.get(MetaData.METADATA_VERSION) == null){ + value = false; + }else{ + try { + int METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + if(METADATA_VERSION < 1){ + value = false; + } + } catch (Exception e) { + // TODO: handle exception + value = false; + } + } + } + return value; } @Override From 0d406bee67e65ecc00a5a59bc9babc2b2c6dc9c0 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 04/75] Fix escape_Table --- .../java/org/jabref/logic/shared/OracleProcessor.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index e96ea8a5987..a00629d6fc1 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -99,9 +99,9 @@ public void startNotificationListener(DBMSSynchronizer dbmsSynchronizer) { ((OracleStatement) statement).setDatabaseChangeRegistration(databaseChangeRegistration); StringBuilder selectQuery = new StringBuilder() .append("SELECT 1 FROM ") - .append(escape("ENTRY")) + .append(escape_Table("ENTRY")) .append(", ") - .append(escape("METADATA")); + .append(escape_Table("METADATA")); // this execution registers all tables mentioned in selectQuery statement.executeQuery(selectQuery.toString()); } @@ -116,7 +116,7 @@ protected void insertIntoEntryTable(List entries) { for (BibEntry entry : entries) { String insertIntoEntryQuery = "INSERT INTO " + - escape("ENTRY") + + escape_Table("ENTRY") + "(" + escape("TYPE") + ") VALUES(?)"; @@ -154,7 +154,7 @@ protected void insertIntoFieldTable(List bibEntries) { } for (int i = 0; i < numFields; i++) { insertFieldQuery.append(" INTO ") - .append(escape("FIELD")) + .append(escape_Table("FIELD")) .append(" (") .append(escape("ENTRY_SHARED_ID")) .append(", ") From c76e2dc99904eea9029b5229accda12e1d0a2d96 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 05/75] Update TestManager and DBMSProcessorTest --- .../java/org/jabref/logic/shared/DBMSProcessorTest.java | 8 ++++++-- src/test/java/org/jabref/logic/shared/TestManager.java | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java index abc597cb186..aa313c4267f 100644 --- a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java +++ b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java @@ -423,7 +423,7 @@ void testInsertMultipleEntries() throws SQLException { private ResultSet selectFrom(String table, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) { try { - return dbmsConnection.getConnection().createStatement().executeQuery("SELECT * FROM " + escape(table, dbmsProcessor)); + return dbmsConnection.getConnection().createStatement().executeQuery("SELECT * FROM " + escape_Table(table, dbmsProcessor)); } catch (SQLException e) { fail(e.getMessage()); return null; @@ -434,7 +434,7 @@ private ResultSet selectFrom(String table, DBMSConnection dbmsConnection, DBMSPr // Therefore this function was defined to improve the readability and to keep the code short. private void insertMetaData(String key, String value, DBMSConnection dbmsConnection, DBMSProcessor dbmsProcessor) { try { - dbmsConnection.getConnection().createStatement().executeUpdate("INSERT INTO " + escape("METADATA", dbmsProcessor) + "(" + dbmsConnection.getConnection().createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA", dbmsProcessor) + "(" + escape("KEY", dbmsProcessor) + ", " + escape("VALUE", dbmsProcessor) + ") VALUES(" + escapeValue(key) + ", " + escapeValue(value) + ")"); } catch (SQLException e) { @@ -446,6 +446,10 @@ private static String escape(String expression, DBMSProcessor dbmsProcessor) { return dbmsProcessor.escape(expression); } + private static String escape_Table(String expression, DBMSProcessor dbmsProcessor) { + return dbmsProcessor.escape_Table(expression); + } + private static String escapeValue(String value) { return "'" + value + "'"; } diff --git a/src/test/java/org/jabref/logic/shared/TestManager.java b/src/test/java/org/jabref/logic/shared/TestManager.java index 48012830211..8a5ddf28cf8 100644 --- a/src/test/java/org/jabref/logic/shared/TestManager.java +++ b/src/test/java/org/jabref/logic/shared/TestManager.java @@ -24,10 +24,17 @@ public static void clearTables(DBMSConnection dbmsConnection) throws SQLExceptio dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `FIELD`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `ENTRY`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `METADATA`"); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_FIELD`"); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_ENTRY`"); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_METADATA`"); } else if (dbmsType == DBMSType.POSTGRESQL) { dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"FIELD\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"ENTRY\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"METADATA\""); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"FIELD\""); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"ENTRY\""); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"METADATA\""); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP SCHEMA IF EXISTS jabref"); } else if (dbmsType == DBMSType.ORACLE) { dbmsConnection.getConnection().createStatement() .executeUpdate("BEGIN\n" From b30ae83b95d965970bc45c8347080bb08c3fc7cb Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 06/75] first implementation of migration (pgsql) --- .../logic/shared/PostgreSQLProcessor.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index e9ec216ac6d..1a6fe261372 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -19,6 +19,7 @@ public class PostgreSQLProcessor extends DBMSProcessor { private PostgresSQLNotificationListener listener; + private Integer METADATA_CURRENT_VERSION = 1; public PostgreSQLProcessor(DatabaseConnection connection) { super(connection); @@ -51,8 +52,31 @@ public void setUp() throws SQLException { + "\"VALUE\" TEXT)"); Map metadata = getSharedMetaData(); - metadata.put(MetaData.METADATA_VERSION, "1"); - setSharedMetaData(metadata); + + Integer METADATA_VERSION = 0; + + if(metadata.get(MetaData.METADATA_VERSION) != null){ + try { + METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + } catch (Exception e) { + // TODO: handle exception + } + } + + if(METADATA_VERSION < METADATA_CURRENT_VERSION){ + //We can to migrate from old table in new table + if(METADATA_VERSION==0 && METADATA_CURRENT_VERSION == 1 && checkTableAvailability(escape("ENTRY"), escape("FIELD"), escape("METADATA"))){ + connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); + connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); + connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM \"METADATA\""); + metadata = getSharedMetaData(); + } + + metadata.put(MetaData.METADATA_VERSION, METADATA_CURRENT_VERSION.toString()); + setSharedMetaData(metadata); + } + + } /** @@ -72,8 +96,9 @@ public boolean checkBaseIntegrity() throws SQLException { }else{ try { int METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); - if(METADATA_VERSION < 1){ + if(METADATA_VERSION < METADATA_CURRENT_VERSION){ value = false; + //We can to migrate from old table in new table } } catch (Exception e) { // TODO: handle exception From 39246e17ccae538d810ff3f97f10376faa00dbd9 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 07/75] Fix Migration pgsql, mysql --- .../jabref/logic/shared/DBMSProcessor.java | 2 + .../jabref/logic/shared/MySQLProcessor.java | 38 +++++++++++++++---- .../logic/shared/PostgreSQLProcessor.java | 11 +++--- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 0e33baea4aa..f19065f59da 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -43,6 +43,8 @@ public abstract class DBMSProcessor { protected DatabaseConnectionProperties connectionProperties; + protected Integer METADATA_VERSION = -1; + protected DBMSProcessor(DatabaseConnection dbmsConnection) { this.connection = dbmsConnection.getConnection(); this.connectionProperties = dbmsConnection.getProperties(); diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index 2432ff2ccb3..317cf85ba37 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -10,6 +10,8 @@ */ public class MySQLProcessor extends DBMSProcessor { + private Integer METADATA_CURRENT_VERSION = 1; + public MySQLProcessor(DatabaseConnection connection) { super(connection); } @@ -39,9 +41,31 @@ public void setUp() throws SQLException { "`KEY` varchar(255) NOT NULL," + "`VALUE` text NOT NULL)"); - Map metadata = getSharedMetaData(); - metadata.put(MetaData.METADATA_VERSION, "1"); - setSharedMetaData(metadata); + Map metadata = getSharedMetaData(); + + if(metadata.get(MetaData.METADATA_VERSION) != null){ + try { + METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + } catch (Exception e) { + // TODO: handle exception + LOGGER.error("[METADATA_VERSION] not Integer!"); + } + }else{ + LOGGER.error("[METADATA_VERSION] not Exists!"); + } + + if(METADATA_VERSION < METADATA_CURRENT_VERSION){ + //We can to migrate from old table in new table + if(METADATA_VERSION==-1 && METADATA_CURRENT_VERSION == 1){ + connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM `ENTRY`"); + connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM `FIELD`"); + connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM `METADATA`"); + metadata = getSharedMetaData(); + } + + metadata.put(MetaData.METADATA_VERSION, METADATA_CURRENT_VERSION.toString()); + setSharedMetaData(metadata); + } } /** @@ -52,16 +76,16 @@ public void setUp() throws SQLException { */ @Override public boolean checkBaseIntegrity() throws SQLException { - boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); - + // boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + boolean value = true; if(value){ Map metadata = getSharedMetaData(); if(metadata.get(MetaData.METADATA_VERSION) == null){ value = false; }else{ try { - int METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); - if(METADATA_VERSION < 1){ + METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + if(METADATA_VERSION < METADATA_CURRENT_VERSION){ value = false; } } catch (Exception e) { diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index 1a6fe261372..01b57dc5a3d 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -53,19 +53,18 @@ public void setUp() throws SQLException { Map metadata = getSharedMetaData(); - Integer METADATA_VERSION = 0; - if(metadata.get(MetaData.METADATA_VERSION) != null){ try { METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); } catch (Exception e) { // TODO: handle exception + LOGGER.error("[METADATA_VERSION] not Integer!"); } } if(METADATA_VERSION < METADATA_CURRENT_VERSION){ //We can to migrate from old table in new table - if(METADATA_VERSION==0 && METADATA_CURRENT_VERSION == 1 && checkTableAvailability(escape("ENTRY"), escape("FIELD"), escape("METADATA"))){ + if(METADATA_VERSION==-1 && METADATA_CURRENT_VERSION == 1){ connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM \"METADATA\""); @@ -87,15 +86,15 @@ public void setUp() throws SQLException { */ @Override public boolean checkBaseIntegrity() throws SQLException { - boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); - + // boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + boolean value = true; if(value){ Map metadata = getSharedMetaData(); if(metadata.get(MetaData.METADATA_VERSION) == null){ value = false; }else{ try { - int METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); if(METADATA_VERSION < METADATA_CURRENT_VERSION){ value = false; //We can to migrate from old table in new table From 80b0cda5f32363116a93dacf0e48f7ba1809120b Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:11 +0100 Subject: [PATCH 08/75] Rename all function e variable --- .../logic/importer/util/MetaDataParser.java | 4 ++-- .../jabref/logic/shared/DBMSProcessor.java | 2 +- .../jabref/logic/shared/MySQLProcessor.java | 22 +++++++++---------- .../jabref/logic/shared/OracleProcessor.java | 4 +++- .../logic/shared/PostgreSQLProcessor.java | 20 ++++++++--------- .../org/jabref/model/metadata/MetaData.java | 12 +++++----- 6 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java b/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java index 18a4a85cb7b..9cea48589c9 100644 --- a/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java +++ b/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java @@ -90,8 +90,8 @@ public MetaData parse(MetaData metaData, Map data, Character key metaData.setSaveOrderConfig(SaveOrderConfig.parse(value)); } else if (entry.getKey().equals(MetaData.GROUPSTREE) || entry.getKey().equals(MetaData.GROUPSTREE_LEGACY)) { metaData.setGroups(GroupsParser.importGroups(value, keywordSeparator, fileMonitor, metaData)); - } else if (entry.getKey().equals(MetaData.METADATA_VERSION)) { - metaData.setMetadataVersion(getSingleItem(value)); + } else if (entry.getKey().equals(MetaData.VERSION_DB_STRUCT)) { + metaData.setVersionDBStructure(getSingleItem(value)); } else { // Keep meta data items that we do not know in the file metaData.putUnknownMetaDataItem(entry.getKey(), value); diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index f19065f59da..91b9eab3ef9 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -43,7 +43,7 @@ public abstract class DBMSProcessor { protected DatabaseConnectionProperties connectionProperties; - protected Integer METADATA_VERSION = -1; + protected Integer VERSION_DB_STRUCT_DEFALUT = -1; protected DBMSProcessor(DatabaseConnection dbmsConnection) { this.connection = dbmsConnection.getConnection(); diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index 317cf85ba37..58aef46c73d 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -10,7 +10,7 @@ */ public class MySQLProcessor extends DBMSProcessor { - private Integer METADATA_CURRENT_VERSION = 1; + private Integer CURRENT_VERSION_DB_STRUCT = 1; public MySQLProcessor(DatabaseConnection connection) { super(connection); @@ -43,27 +43,27 @@ public void setUp() throws SQLException { Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.METADATA_VERSION) != null){ + if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ try { - METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + VERSION_DB_STRUCT_DEFALUT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { // TODO: handle exception - LOGGER.error("[METADATA_VERSION] not Integer!"); + LOGGER.error("[VERSION_DB_STRUCT_DEFALUT] not Integer!"); } }else{ - LOGGER.error("[METADATA_VERSION] not Exists!"); + LOGGER.error("[VERSION_DB_STRUCT_DEFALUT] not Exists!"); } - if(METADATA_VERSION < METADATA_CURRENT_VERSION){ + if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ //We can to migrate from old table in new table - if(METADATA_VERSION==-1 && METADATA_CURRENT_VERSION == 1){ + if(VERSION_DB_STRUCT_DEFALUT==-1 && CURRENT_VERSION_DB_STRUCT == 1){ connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM `ENTRY`"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM `FIELD`"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM `METADATA`"); metadata = getSharedMetaData(); } - metadata.put(MetaData.METADATA_VERSION, METADATA_CURRENT_VERSION.toString()); + metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); setSharedMetaData(metadata); } } @@ -80,12 +80,12 @@ public boolean checkBaseIntegrity() throws SQLException { boolean value = true; if(value){ Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.METADATA_VERSION) == null){ + if(metadata.get(MetaData.VERSION_DB_STRUCT) == null){ value = false; }else{ try { - METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); - if(METADATA_VERSION < METADATA_CURRENT_VERSION){ + VERSION_DB_STRUCT_DEFALUT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ value = false; } } catch (Exception e) { diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index a00629d6fc1..37339816785 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -30,6 +30,8 @@ public class OracleProcessor extends DBMSProcessor { private DatabaseChangeRegistration databaseChangeRegistration; + private Integer CURRENT_VERSION_DB_STRUCT = 0; + public OracleProcessor(DatabaseConnection connection) { super(connection); } @@ -67,7 +69,7 @@ public void setUp() throws SQLException { "\"VALUE\" CLOB NOT NULL)"); Map metadata = getSharedMetaData(); - metadata.put(MetaData.METADATA_VERSION, "0"); + metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); setSharedMetaData(metadata); } diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index 01b57dc5a3d..ea6332cf77e 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -19,7 +19,7 @@ public class PostgreSQLProcessor extends DBMSProcessor { private PostgresSQLNotificationListener listener; - private Integer METADATA_CURRENT_VERSION = 1; + private Integer CURRENT_VERSION_DB_STRUCT = 1; public PostgreSQLProcessor(DatabaseConnection connection) { super(connection); @@ -53,25 +53,25 @@ public void setUp() throws SQLException { Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.METADATA_VERSION) != null){ + if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ try { - METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); + VERSION_DB_STRUCT_DEFALUT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { // TODO: handle exception - LOGGER.error("[METADATA_VERSION] not Integer!"); + LOGGER.error("[VERSION_DB_STRUCT_DEFALUT] not Integer!"); } } - if(METADATA_VERSION < METADATA_CURRENT_VERSION){ + if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ //We can to migrate from old table in new table - if(METADATA_VERSION==-1 && METADATA_CURRENT_VERSION == 1){ + if(VERSION_DB_STRUCT_DEFALUT==-1 && CURRENT_VERSION_DB_STRUCT == 1){ connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM \"METADATA\""); metadata = getSharedMetaData(); } - metadata.put(MetaData.METADATA_VERSION, METADATA_CURRENT_VERSION.toString()); + metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); setSharedMetaData(metadata); } @@ -90,12 +90,12 @@ public boolean checkBaseIntegrity() throws SQLException { boolean value = true; if(value){ Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.METADATA_VERSION) == null){ + if(metadata.get(MetaData.VERSION_DB_STRUCT) == null){ value = false; }else{ try { - METADATA_VERSION = Integer.valueOf(metadata.get(MetaData.METADATA_VERSION)); - if(METADATA_VERSION < METADATA_CURRENT_VERSION){ + CURRENT_VERSION_DB_STRUCT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ value = false; //We can to migrate from old table in new table } diff --git a/src/main/java/org/jabref/model/metadata/MetaData.java b/src/main/java/org/jabref/model/metadata/MetaData.java index bcffa913f2e..2014dad6f21 100644 --- a/src/main/java/org/jabref/model/metadata/MetaData.java +++ b/src/main/java/org/jabref/model/metadata/MetaData.java @@ -40,7 +40,7 @@ public class MetaData { public static final String PREFIX_KEYPATTERN = "keypattern_"; public static final String KEYPATTERNDEFAULT = "keypatterndefault"; public static final String DATABASE_TYPE = "databaseType"; - public static final String METADATA_VERSION = "metadataVersion"; + public static final String VERSION_DB_STRUCT = "VersionDBStructure"; public static final String GROUPSTREE = "grouping"; public static final String GROUPSTREE_LEGACY = "groupstree"; public static final String FILE_DIRECTORY = "fileDirectory"; @@ -70,7 +70,7 @@ public class MetaData { private final Map> unknownMetaData = new HashMap<>(); private boolean isEventPropagationEnabled = true; private boolean encodingExplicitlySupplied; - private String metadataVersion; + private String VersionDBStructure; /** * Constructs an empty metadata. @@ -211,12 +211,12 @@ public void setDefaultFileDirectory(String path) { postChange(); } - public Optional getMetadataVersion() { - return Optional.ofNullable(metadataVersion); + public Optional getVersionDBStructure() { + return Optional.ofNullable(VersionDBStructure); } - public void setMetadataVersion(String version) { - metadataVersion = Objects.requireNonNull(version).trim(); + public void setVersionDBStructure(String version) { + VersionDBStructure = Objects.requireNonNull(version).trim(); postChange(); } From dca9f889c4e901876ab5212a661d8fc49e33ca51 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 14:33:12 +0100 Subject: [PATCH 09/75] Correction of typos and optimizations --- .../jabref/logic/shared/DBMSProcessor.java | 26 ++++++++++- .../jabref/logic/shared/MySQLProcessor.java | 44 +++--------------- .../jabref/logic/shared/OracleProcessor.java | 23 +++++++--- .../logic/shared/PostgreSQLProcessor.java | 45 ++++--------------- 4 files changed, 57 insertions(+), 81 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 91b9eab3ef9..1cf68a3a81f 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -20,6 +20,7 @@ import org.jabref.logic.shared.exception.OfflineLockException; import org.jabref.model.entry.BibEntry; +import org.jabref.model.metadata.MetaData; import org.jabref.model.entry.SharedBibEntryData; import org.jabref.model.entry.event.EntriesEventSource; import org.jabref.model.entry.field.Field; @@ -43,7 +44,8 @@ public abstract class DBMSProcessor { protected DatabaseConnectionProperties connectionProperties; - protected Integer VERSION_DB_STRUCT_DEFALUT = -1; + protected Integer VERSION_DB_STRUCT_DEFAULT = -1; + protected Integer CURRENT_VERSION_DB_STRUCT = 0; protected DBMSProcessor(DatabaseConnection dbmsConnection) { this.connection = dbmsConnection.getConnection(); @@ -57,7 +59,27 @@ protected DBMSProcessor(DatabaseConnection dbmsConnection) { * @throws SQLException */ public boolean checkBaseIntegrity() throws SQLException { - return checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + DBMSType type = connectionProperties.getType(); + if (type == DBMSType.MYSQL || type == DBMSType.POSTGRESQL) { + boolean value = true; + Map metadata = getSharedMetaData(); + if(metadata.get(MetaData.VERSION_DB_STRUCT) == null){ + value = false; + }else{ + try { + CURRENT_VERSION_DB_STRUCT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ + value = false; + //We can to migrate from old table in new table + } + } catch (Exception e) { + value = false; + } + } + return value; + }else{ + return checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + } } /** diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index 58aef46c73d..d139cd4aa5f 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -10,10 +10,9 @@ */ public class MySQLProcessor extends DBMSProcessor { - private Integer CURRENT_VERSION_DB_STRUCT = 1; - public MySQLProcessor(DatabaseConnection connection) { super(connection); + CURRENT_VERSION_DB_STRUCT = 1; } /** @@ -45,18 +44,18 @@ public void setUp() throws SQLException { if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ try { - VERSION_DB_STRUCT_DEFALUT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + VERSION_DB_STRUCT_DEFAULT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { - // TODO: handle exception - LOGGER.error("[VERSION_DB_STRUCT_DEFALUT] not Integer!"); + LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Integer!"); } }else{ - LOGGER.error("[VERSION_DB_STRUCT_DEFALUT] not Exists!"); + LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Exist!"); } - if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ + if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ //We can to migrate from old table in new table - if(VERSION_DB_STRUCT_DEFALUT==-1 && CURRENT_VERSION_DB_STRUCT == 1){ + if(CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")){ + LOGGER.info("Migrating from VersionDBStructure == 0"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM `ENTRY`"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM `FIELD`"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM `METADATA`"); @@ -68,35 +67,6 @@ public void setUp() throws SQLException { } } - /** - * Scans the database for required tables. - * - * @return true if the structure matches the requirements, false if not. - * @throws SQLException - */ - @Override - public boolean checkBaseIntegrity() throws SQLException { - // boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); - boolean value = true; - if(value){ - Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.VERSION_DB_STRUCT) == null){ - value = false; - }else{ - try { - VERSION_DB_STRUCT_DEFALUT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); - if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ - value = false; - } - } catch (Exception e) { - // TODO: handle exception - value = false; - } - } - } - return value; - } - @Override String escape(String expression) { return "`" + expression + "`"; diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index 37339816785..2368d5a11db 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -30,10 +30,9 @@ public class OracleProcessor extends DBMSProcessor { private DatabaseChangeRegistration databaseChangeRegistration; - private Integer CURRENT_VERSION_DB_STRUCT = 0; - public OracleProcessor(DatabaseConnection connection) { super(connection); + CURRENT_VERSION_DB_STRUCT = 0; } /** @@ -68,9 +67,23 @@ public void setUp() throws SQLException { "\"KEY\" VARCHAR2(255) NULL," + "\"VALUE\" CLOB NOT NULL)"); - Map metadata = getSharedMetaData(); - metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); - setSharedMetaData(metadata); + Map metadata = getSharedMetaData(); + + if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ + try { + VERSION_DB_STRUCT_DEFAULT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + } catch (Exception e) { + LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Integer!"); + } + }else{ + LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Exist!"); + } + + if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ + //We can to migrate from old table in new table + metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); + setSharedMetaData(metadata); + } } @Override diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index ea6332cf77e..c290bb1be54 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -19,10 +19,10 @@ public class PostgreSQLProcessor extends DBMSProcessor { private PostgresSQLNotificationListener listener; - private Integer CURRENT_VERSION_DB_STRUCT = 1; public PostgreSQLProcessor(DatabaseConnection connection) { super(connection); + CURRENT_VERSION_DB_STRUCT = 1; } /** @@ -55,16 +55,18 @@ public void setUp() throws SQLException { if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ try { - VERSION_DB_STRUCT_DEFALUT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + VERSION_DB_STRUCT_DEFAULT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { - // TODO: handle exception - LOGGER.error("[VERSION_DB_STRUCT_DEFALUT] not Integer!"); + LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Integer!"); } + }else{ + LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Exist!"); } - if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ + if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ //We can to migrate from old table in new table - if(VERSION_DB_STRUCT_DEFALUT==-1 && CURRENT_VERSION_DB_STRUCT == 1){ + if(CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")){ + LOGGER.info("Migrating from VersionDBStructure == 0"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM \"METADATA\""); @@ -75,37 +77,6 @@ public void setUp() throws SQLException { setSharedMetaData(metadata); } - - } - - /** - * Scans the database for required tables. - * - * @return true if the structure matches the requirements, false if not. - * @throws SQLException - */ - @Override - public boolean checkBaseIntegrity() throws SQLException { - // boolean value = checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); - boolean value = true; - if(value){ - Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.VERSION_DB_STRUCT) == null){ - value = false; - }else{ - try { - CURRENT_VERSION_DB_STRUCT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); - if(VERSION_DB_STRUCT_DEFALUT < CURRENT_VERSION_DB_STRUCT){ - value = false; - //We can to migrate from old table in new table - } - } catch (Exception e) { - // TODO: handle exception - value = false; - } - } - } - return value; } @Override From f9223cbb6f1f72adb3ee1c59bdcabaffa742ee10 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 19:23:58 +0100 Subject: [PATCH 10/75] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3f63e95f24..f78610902fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added HTML and Markdown files to Find Unlinked Files and removed BibTeX.[koppor#547](https://github.com/koppor/jabref/issues/547) - We changed the messages after importing unlinked local files to past tense. [koppor#548](https://github.com/koppor/jabref/issues/548) - We fixed an issue where the wrong icon for a successful import of a bib entry was shown [#9308](https://github.com/JabRef/jabref/pull/9308) +- We changed database structure: in MySQL/MariaDB we renamed tables by adding a `JABREF_` prefix, and in PGSQL we moved tables in `jabref` schema. We added `VersionDBStructure` variable in `METADATA` table to indicate current version of structure, this variable is needed for automatic migration [#9312](https://github.com/JabRef/jabref/issues/9312) ### Fixed From ec2cecb22bbb651033b3a2a681ac923887a33914 Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 21:02:46 +0100 Subject: [PATCH 11/75] Fix for style check --- .../org/jabref/logic/shared/DBMSProcessor.java | 16 ++++++++-------- .../org/jabref/logic/shared/MySQLProcessor.java | 12 ++++++------ .../org/jabref/logic/shared/OracleProcessor.java | 10 +++++----- .../jabref/logic/shared/PostgreSQLProcessor.java | 16 ++++++++-------- .../java/org/jabref/model/metadata/MetaData.java | 4 ++-- .../jabref/logic/shared/DBMSProcessorTest.java | 2 +- .../org/jabref/logic/shared/TestManager.java | 4 ++-- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 1cf68a3a81f..c8b38b60cc6 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -63,21 +63,21 @@ public boolean checkBaseIntegrity() throws SQLException { if (type == DBMSType.MYSQL || type == DBMSType.POSTGRESQL) { boolean value = true; Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.VERSION_DB_STRUCT) == null){ + if (metadata.get(MetaData.VERSION_DB_STRUCT) == null) { value = false; - }else{ + } else { try { CURRENT_VERSION_DB_STRUCT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); - if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ + if (VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT) { value = false; - //We can to migrate from old table in new table + // We can to migrate from old table in new table } } catch (Exception e) { value = false; } } return value; - }else{ + } else { return checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); } } @@ -154,9 +154,9 @@ public void setupSharedDatabase() throws SQLException { */ abstract String escape(String expression); - String escape_Table(String expression) { - return escape(expression); - } + String escape_Table(String expression) { + return escape(expression); + } /** * For use in test only. Inserts the BibEntry into the shared database. diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index d139cd4aa5f..56a5b978583 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -42,19 +42,19 @@ public void setUp() throws SQLException { Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ + if (metadata.get(MetaData.VERSION_DB_STRUCT) != null) { try { VERSION_DB_STRUCT_DEFAULT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Integer!"); } - }else{ + } else { LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Exist!"); } - if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ - //We can to migrate from old table in new table - if(CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")){ + if (VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT) { + // We can to migrate from old table in new table + if (CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")) { LOGGER.info("Migrating from VersionDBStructure == 0"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM `ENTRY`"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM `FIELD`"); @@ -72,7 +72,7 @@ String escape(String expression) { return "`" + expression + "`"; } - @Override + @Override String escape_Table(String expression) { return escape("JABREF_"+expression); } diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index 2368d5a11db..c2e500982c1 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -69,18 +69,18 @@ public void setUp() throws SQLException { Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ + if (metadata.get(MetaData.VERSION_DB_STRUCT) != null) { try { VERSION_DB_STRUCT_DEFAULT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Integer!"); } - }else{ + } else { LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Exist!"); } - if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ - //We can to migrate from old table in new table + if (VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT) { + // We can to migrate from old table in new table metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); setSharedMetaData(metadata); } @@ -91,7 +91,7 @@ String escape(String expression) { return expression; } - @Override + @Override String escape_Table(String expression) { return escape(expression); } diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index c290bb1be54..52923d2b1c6 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -32,7 +32,7 @@ public PostgreSQLProcessor(DatabaseConnection connection) { */ @Override public void setUp() throws SQLException { - connection.createStatement().executeUpdate("CREATE SCHEMA IF NOT EXISTS jabref"); + connection.createStatement().executeUpdate("CREATE SCHEMA IF NOT EXISTS jabref"); connection.createStatement().executeUpdate( "CREATE TABLE IF NOT EXISTS " + escape_Table("ENTRY") + " (" + @@ -51,21 +51,21 @@ public void setUp() throws SQLException { + "\"KEY\" VARCHAR," + "\"VALUE\" TEXT)"); - Map metadata = getSharedMetaData(); + Map metadata = getSharedMetaData(); - if(metadata.get(MetaData.VERSION_DB_STRUCT) != null){ + if (metadata.get(MetaData.VERSION_DB_STRUCT) != null) { try { VERSION_DB_STRUCT_DEFAULT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); } catch (Exception e) { LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Integer!"); } - }else{ + } else { LOGGER.warn("[VERSION_DB_STRUCT_DEFAULT] not Exist!"); } - if(VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT){ - //We can to migrate from old table in new table - if(CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")){ + if (VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT) { + // We can to migrate from old table in new table + if (CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")) { LOGGER.info("Migrating from VersionDBStructure == 0"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); @@ -119,7 +119,7 @@ String escape(String expression) { return "\"" + expression + "\""; } - @Override + @Override String escape_Table(String expression) { return "jabref." + escape(expression); } diff --git a/src/main/java/org/jabref/model/metadata/MetaData.java b/src/main/java/org/jabref/model/metadata/MetaData.java index 2014dad6f21..4f200897ded 100644 --- a/src/main/java/org/jabref/model/metadata/MetaData.java +++ b/src/main/java/org/jabref/model/metadata/MetaData.java @@ -70,7 +70,7 @@ public class MetaData { private final Map> unknownMetaData = new HashMap<>(); private boolean isEventPropagationEnabled = true; private boolean encodingExplicitlySupplied; - private String VersionDBStructure; + private String VersionDBStructure; /** * Constructs an empty metadata. @@ -211,7 +211,7 @@ public void setDefaultFileDirectory(String path) { postChange(); } - public Optional getVersionDBStructure() { + public Optional getVersionDBStructure() { return Optional.ofNullable(VersionDBStructure); } diff --git a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java index aa313c4267f..a647bf95240 100644 --- a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java +++ b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java @@ -446,7 +446,7 @@ private static String escape(String expression, DBMSProcessor dbmsProcessor) { return dbmsProcessor.escape(expression); } - private static String escape_Table(String expression, DBMSProcessor dbmsProcessor) { + private static String escape_Table(String expression, DBMSProcessor dbmsProcessor) { return dbmsProcessor.escape_Table(expression); } diff --git a/src/test/java/org/jabref/logic/shared/TestManager.java b/src/test/java/org/jabref/logic/shared/TestManager.java index 8a5ddf28cf8..dcb4832cd63 100644 --- a/src/test/java/org/jabref/logic/shared/TestManager.java +++ b/src/test/java/org/jabref/logic/shared/TestManager.java @@ -24,14 +24,14 @@ public static void clearTables(DBMSConnection dbmsConnection) throws SQLExceptio dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `FIELD`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `ENTRY`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `METADATA`"); - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_FIELD`"); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_FIELD`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_ENTRY`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_METADATA`"); } else if (dbmsType == DBMSType.POSTGRESQL) { dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"FIELD\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"ENTRY\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"METADATA\""); - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"FIELD\""); + dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"FIELD\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"ENTRY\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"METADATA\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP SCHEMA IF EXISTS jabref"); From ddab7b3e227ef25dfae8aac6b82012a12a4f56ed Mon Sep 17 00:00:00 2001 From: robyquin Date: Thu, 3 Nov 2022 21:34:14 +0100 Subject: [PATCH 12/75] fix checkstyle gradle --- src/main/java/org/jabref/logic/shared/DBMSProcessor.java | 2 +- src/main/java/org/jabref/logic/shared/MySQLProcessor.java | 2 +- src/main/java/org/jabref/logic/shared/OracleProcessor.java | 2 +- src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index c8b38b60cc6..025e861523f 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -20,12 +20,12 @@ import org.jabref.logic.shared.exception.OfflineLockException; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; import org.jabref.model.entry.SharedBibEntryData; import org.jabref.model.entry.event.EntriesEventSource; import org.jabref.model.entry.field.Field; import org.jabref.model.entry.field.FieldFactory; import org.jabref.model.entry.types.EntryTypeFactory; +import org.jabref.model.metadata.MetaData; import com.google.common.collect.Lists; import org.slf4j.Logger; diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index 56a5b978583..6f4aa62bddc 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -74,6 +74,6 @@ String escape(String expression) { @Override String escape_Table(String expression) { - return escape("JABREF_"+expression); + return escape("JABREF_" + expression); } } diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index c2e500982c1..085df5d33d9 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -12,8 +12,8 @@ import org.jabref.logic.shared.listener.OracleNotificationListener; import org.jabref.model.entry.BibEntry; -import org.jabref.model.metadata.MetaData; import org.jabref.model.entry.field.Field; +import org.jabref.model.metadata.MetaData; import oracle.jdbc.OracleConnection; import oracle.jdbc.OracleStatement; diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index 52923d2b1c6..f04e49818b5 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -11,6 +11,7 @@ import org.jabref.logic.shared.listener.PostgresSQLNotificationListener; import org.jabref.model.entry.BibEntry; import org.jabref.model.metadata.MetaData; + import org.postgresql.PGConnection; /** @@ -76,7 +77,6 @@ public void setUp() throws SQLException { metadata.put(MetaData.VERSION_DB_STRUCT, CURRENT_VERSION_DB_STRUCT.toString()); setSharedMetaData(metadata); } - } @Override From 361ec9914538d212a1bf1de2d2d797915f5262f3 Mon Sep 17 00:00:00 2001 From: robyquin Date: Fri, 4 Nov 2022 09:43:28 +0100 Subject: [PATCH 13/75] Fix abstract String escape_Table --- src/main/java/org/jabref/logic/shared/DBMSProcessor.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 025e861523f..0ba708681f8 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -154,9 +154,7 @@ public void setupSharedDatabase() throws SQLException { */ abstract String escape(String expression); - String escape_Table(String expression) { - return escape(expression); - } + abstract String escape_Table(String expression); /** * For use in test only. Inserts the BibEntry into the shared database. From a5c587a7443a5dcf6529095ab4cb77905ad7b219 Mon Sep 17 00:00:00 2001 From: robyquin Date: Fri, 4 Nov 2022 09:46:51 +0100 Subject: [PATCH 14/75] Fix issue: checkTableAvailability doesn't distinguish if same table name exists in different schemas --- .../org/jabref/logic/shared/PostgreSQLProcessor.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index f04e49818b5..3fadd462d77 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -33,6 +33,13 @@ public PostgreSQLProcessor(DatabaseConnection connection) { */ @Override public void setUp() throws SQLException { + + if (CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")) { + // checkTableAvailability does not distinguish if same table name exists in different schemas + // VERSION_DB_STRUCT_DEFAULT must be forced + VERSION_DB_STRUCT_DEFAULT = 0; + } + connection.createStatement().executeUpdate("CREATE SCHEMA IF NOT EXISTS jabref"); connection.createStatement().executeUpdate( @@ -66,7 +73,7 @@ public void setUp() throws SQLException { if (VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT) { // We can to migrate from old table in new table - if (CURRENT_VERSION_DB_STRUCT == 1 && checkTableAvailability("ENTRY", "FIELD", "METADATA")) { + if (VERSION_DB_STRUCT_DEFAULT == 0 && CURRENT_VERSION_DB_STRUCT == 1) { LOGGER.info("Migrating from VersionDBStructure == 0"); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); From 4222c86f0ff330923efe26146a31f4c323db85c0 Mon Sep 17 00:00:00 2001 From: robyquin Date: Fri, 4 Nov 2022 10:45:54 +0100 Subject: [PATCH 15/75] Update 'equals' in MetaData class --- src/main/java/org/jabref/model/metadata/MetaData.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/model/metadata/MetaData.java b/src/main/java/org/jabref/model/metadata/MetaData.java index 4f200897ded..540d1a03086 100644 --- a/src/main/java/org/jabref/model/metadata/MetaData.java +++ b/src/main/java/org/jabref/model/metadata/MetaData.java @@ -381,7 +381,8 @@ public boolean equals(Object o) { && Objects.equals(saveActions, metaData.saveActions) && (mode == metaData.mode) && Objects.equals(defaultFileDirectory, metaData.defaultFileDirectory) - && Objects.equals(contentSelectors, metaData.contentSelectors); + && Objects.equals(contentSelectors, metaData.contentSelectors) + && Objects.equals(VersionDBStructure, metaData.VersionDBStructure); } @Override From 7f356ee1567c0a7e3762023af9c8e4469462bea7 Mon Sep 17 00:00:00 2001 From: robyquin Date: Fri, 4 Nov 2022 10:47:49 +0100 Subject: [PATCH 16/75] Update testGetSharedMetaData, getMetaDataExample --- src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java index a647bf95240..ab62bb164a2 100644 --- a/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java +++ b/src/test/java/org/jabref/logic/shared/DBMSProcessorTest.java @@ -308,6 +308,7 @@ void testGetSharedMetaData() { insertMetaData("protectedFlag", "true;", dbmsConnection, dbmsProcessor); insertMetaData("saveActions", "enabled;\nauthor[capitalize,html_to_latex]\ntitle[title_case]\n;", dbmsConnection, dbmsProcessor); insertMetaData("saveOrderConfig", "specified;author;false;title;false;year;true;", dbmsConnection, dbmsProcessor); + insertMetaData("VersionDBStructure", "1", dbmsConnection, dbmsProcessor); Map expectedMetaData = getMetaDataExample(); Map actualMetaData = dbmsProcessor.getSharedMetaData(); @@ -332,6 +333,7 @@ private static Map getMetaDataExample() { expectedMetaData.put("protectedFlag", "true;"); expectedMetaData.put("saveActions", "enabled;\nauthor[capitalize,html_to_latex]\ntitle[title_case]\n;"); expectedMetaData.put("saveOrderConfig", "specified;author;false;title;false;year;true;"); + expectedMetaData.put("VersionDBStructure", "1"); return expectedMetaData; } From 50e9511c7f2f1bca4196fc75340a72a7f94f14eb Mon Sep 17 00:00:00 2001 From: robyquin Date: Fri, 4 Nov 2022 15:55:21 +0100 Subject: [PATCH 17/75] Update test on checkBaseIntegrity --- .../logic/exporter/MetaDataSerializer.java | 2 ++ .../jabref/logic/shared/DBMSProcessor.java | 35 ++++++++----------- .../jabref/logic/shared/MySQLProcessor.java | 9 ++++- .../jabref/logic/shared/OracleProcessor.java | 9 ++++- .../logic/shared/PostgreSQLProcessor.java | 9 ++++- .../org/jabref/model/metadata/MetaData.java | 4 +-- .../logic/shared/DBMSSynchronizerTest.java | 1 + .../org/jabref/logic/shared/TestManager.java | 6 ---- 8 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java b/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java index b43af7288f2..6b1a13e6757 100644 --- a/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java +++ b/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java @@ -46,6 +46,8 @@ public static Map getSerializedStringMap(MetaData metaData, .put(MetaData.FILE_DIRECTORY + '-' + user, Collections.singletonList(path.trim()))); metaData.getLatexFileDirectories().forEach((user, path) -> stringyMetaData .put(MetaData.FILE_DIRECTORY + "Latex-" + user, Collections.singletonList(path.toString().trim()))); + metaData.getVersionDBStructure().ifPresent( + VersionDBStructure -> stringyMetaData.put(MetaData.VERSION_DB_STRUCT, Collections.singletonList(VersionDBStructure.trim()))); for (ContentSelector selector : metaData.getContentSelectorList()) { stringyMetaData.put(MetaData.SELECTOR_META_PREFIX + selector.getField().getName(), selector.getValues()); diff --git a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java index 0ba708681f8..f1b44ffb824 100644 --- a/src/main/java/org/jabref/logic/shared/DBMSProcessor.java +++ b/src/main/java/org/jabref/logic/shared/DBMSProcessor.java @@ -44,9 +44,6 @@ public abstract class DBMSProcessor { protected DatabaseConnectionProperties connectionProperties; - protected Integer VERSION_DB_STRUCT_DEFAULT = -1; - protected Integer CURRENT_VERSION_DB_STRUCT = 0; - protected DBMSProcessor(DatabaseConnection dbmsConnection) { this.connection = dbmsConnection.getConnection(); this.connectionProperties = dbmsConnection.getProperties(); @@ -59,27 +56,23 @@ protected DBMSProcessor(DatabaseConnection dbmsConnection) { * @throws SQLException */ public boolean checkBaseIntegrity() throws SQLException { - DBMSType type = connectionProperties.getType(); - if (type == DBMSType.MYSQL || type == DBMSType.POSTGRESQL) { - boolean value = true; - Map metadata = getSharedMetaData(); - if (metadata.get(MetaData.VERSION_DB_STRUCT) == null) { - value = false; - } else { - try { - CURRENT_VERSION_DB_STRUCT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); - if (VERSION_DB_STRUCT_DEFAULT < CURRENT_VERSION_DB_STRUCT) { - value = false; - // We can to migrate from old table in new table - } - } catch (Exception e) { - value = false; + boolean value; + value = false; + DBMSType type = this.connectionProperties.getType(); + Map metadata = getSharedMetaData(); + if (type == DBMSType.POSTGRESQL || type == DBMSType.MYSQL) { + try { + Integer VERSION_DB_STRUCT = Integer.valueOf(metadata.get(MetaData.VERSION_DB_STRUCT)); + if (VERSION_DB_STRUCT == getCURRENT_VERSION_DB_STRUCT()) { + value = true; } + } catch (Exception e) { + value = false; } - return value; } else { - return checkTableAvailability(escape_Table("ENTRY"), escape_Table("FIELD"), escape_Table("METADATA")); + value = checkTableAvailability("ENTRY", "FIELD", "METADATA"); } + return value; } /** @@ -156,6 +149,8 @@ public void setupSharedDatabase() throws SQLException { abstract String escape_Table(String expression); + abstract Integer getCURRENT_VERSION_DB_STRUCT(); + /** * For use in test only. Inserts the BibEntry into the shared database. * diff --git a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java index 6f4aa62bddc..906fbaf50e8 100644 --- a/src/main/java/org/jabref/logic/shared/MySQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/MySQLProcessor.java @@ -10,9 +10,11 @@ */ public class MySQLProcessor extends DBMSProcessor { + private Integer VERSION_DB_STRUCT_DEFAULT = -1; + private Integer CURRENT_VERSION_DB_STRUCT = 1; + public MySQLProcessor(DatabaseConnection connection) { super(connection); - CURRENT_VERSION_DB_STRUCT = 1; } /** @@ -76,4 +78,9 @@ String escape(String expression) { String escape_Table(String expression) { return escape("JABREF_" + expression); } + + @Override + Integer getCURRENT_VERSION_DB_STRUCT() { + return CURRENT_VERSION_DB_STRUCT; + } } diff --git a/src/main/java/org/jabref/logic/shared/OracleProcessor.java b/src/main/java/org/jabref/logic/shared/OracleProcessor.java index 085df5d33d9..2bd792b2e55 100644 --- a/src/main/java/org/jabref/logic/shared/OracleProcessor.java +++ b/src/main/java/org/jabref/logic/shared/OracleProcessor.java @@ -30,9 +30,11 @@ public class OracleProcessor extends DBMSProcessor { private DatabaseChangeRegistration databaseChangeRegistration; + private Integer VERSION_DB_STRUCT_DEFAULT = -1; + private Integer CURRENT_VERSION_DB_STRUCT = 0; + public OracleProcessor(DatabaseConnection connection) { super(connection); - CURRENT_VERSION_DB_STRUCT = 0; } /** @@ -96,6 +98,11 @@ String escape_Table(String expression) { return escape(expression); } + @Override + Integer getCURRENT_VERSION_DB_STRUCT() { + return CURRENT_VERSION_DB_STRUCT; + } + @Override public void startNotificationListener(DBMSSynchronizer dbmsSynchronizer) { this.listener = new OracleNotificationListener(dbmsSynchronizer); diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index 3fadd462d77..ec72839bb35 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -21,9 +21,11 @@ public class PostgreSQLProcessor extends DBMSProcessor { private PostgresSQLNotificationListener listener; + private Integer VERSION_DB_STRUCT_DEFAULT = -1; + private Integer CURRENT_VERSION_DB_STRUCT = 1; + public PostgreSQLProcessor(DatabaseConnection connection) { super(connection); - CURRENT_VERSION_DB_STRUCT = 1; } /** @@ -131,6 +133,11 @@ String escape_Table(String expression) { return "jabref." + escape(expression); } + @Override + Integer getCURRENT_VERSION_DB_STRUCT() { + return CURRENT_VERSION_DB_STRUCT; + } + @Override public void startNotificationListener(DBMSSynchronizer dbmsSynchronizer) { // Disable cleanup output of ThreadedHousekeeper diff --git a/src/main/java/org/jabref/model/metadata/MetaData.java b/src/main/java/org/jabref/model/metadata/MetaData.java index 540d1a03086..1b878d2a58c 100644 --- a/src/main/java/org/jabref/model/metadata/MetaData.java +++ b/src/main/java/org/jabref/model/metadata/MetaData.java @@ -388,11 +388,11 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash(isProtected, groupsRoot.getValue(), encoding, encodingExplicitlySupplied, saveOrderConfig, citeKeyPatterns, userFileDirectory, - laTexFileDirectory, defaultCiteKeyPattern, saveActions, mode, defaultFileDirectory, contentSelectors); + laTexFileDirectory, defaultCiteKeyPattern, saveActions, mode, defaultFileDirectory, contentSelectors, VersionDBStructure); } @Override public String toString() { - return "MetaData [citeKeyPatterns=" + citeKeyPatterns + ", userFileDirectory=" + userFileDirectory + ", laTexFileDirectory=" + laTexFileDirectory + ", groupsRoot=" + groupsRoot + ", encoding=" + encoding + ", saveOrderConfig=" + saveOrderConfig + ", defaultCiteKeyPattern=" + defaultCiteKeyPattern + ", saveActions=" + saveActions + ", mode=" + mode + ", isProtected=" + isProtected + ", defaultFileDirectory=" + defaultFileDirectory + ", contentSelectors=" + contentSelectors + ", encodingExplicitlySupplied=" + encodingExplicitlySupplied + "]"; + return "MetaData [citeKeyPatterns=" + citeKeyPatterns + ", userFileDirectory=" + userFileDirectory + ", laTexFileDirectory=" + laTexFileDirectory + ", groupsRoot=" + groupsRoot + ", encoding=" + encoding + ", saveOrderConfig=" + saveOrderConfig + ", defaultCiteKeyPattern=" + defaultCiteKeyPattern + ", saveActions=" + saveActions + ", mode=" + mode + ", isProtected=" + isProtected + ", defaultFileDirectory=" + defaultFileDirectory + ", contentSelectors=" + contentSelectors + ", encodingExplicitlySupplied=" + encodingExplicitlySupplied + ", VersionDBStructure=" + VersionDBStructure + "]"; } } diff --git a/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java b/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java index 11fa69ad521..1abee86e643 100644 --- a/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java +++ b/src/test/java/org/jabref/logic/shared/DBMSSynchronizerTest.java @@ -148,6 +148,7 @@ public void testMetaDataChangedEventListener() throws Exception { Map expectedMap = MetaDataSerializer.getSerializedStringMap(testMetaData, pattern); Map actualMap = dbmsProcessor.getSharedMetaData(); + actualMap.remove("VersionDBStructure"); assertEquals(expectedMap, actualMap); } diff --git a/src/test/java/org/jabref/logic/shared/TestManager.java b/src/test/java/org/jabref/logic/shared/TestManager.java index dcb4832cd63..7a7022555f8 100644 --- a/src/test/java/org/jabref/logic/shared/TestManager.java +++ b/src/test/java/org/jabref/logic/shared/TestManager.java @@ -21,16 +21,10 @@ public static void clearTables(DBMSConnection dbmsConnection) throws SQLExceptio DBMSType dbmsType = dbmsConnection.getProperties().getType(); if (dbmsType == DBMSType.MYSQL) { - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `FIELD`"); - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `ENTRY`"); - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `METADATA`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_FIELD`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_ENTRY`"); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS `JABREF_METADATA`"); } else if (dbmsType == DBMSType.POSTGRESQL) { - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"FIELD\""); - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"ENTRY\""); - dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS \"METADATA\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"FIELD\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"ENTRY\""); dbmsConnection.getConnection().createStatement().executeUpdate("DROP TABLE IF EXISTS jabref.\"METADATA\""); From 0ee2534b1c7df01438a9d99835db87c378a5ef7e Mon Sep 17 00:00:00 2001 From: robyquin Date: Mon, 7 Nov 2022 15:56:01 +0100 Subject: [PATCH 18/75] Fix: set VersionDBStructure without semicolon --- .../java/org/jabref/logic/exporter/MetaDataSerializer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java b/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java index 6b1a13e6757..60045cf1130 100644 --- a/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java +++ b/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java @@ -79,7 +79,11 @@ private static Map serializeMetaData(Map> s for (Map.Entry> metaItem : stringyMetaData.entrySet()) { StringBuilder stringBuilder = new StringBuilder(); for (String dataItem : metaItem.getValue()) { - stringBuilder.append(StringUtil.quote(dataItem, MetaData.SEPARATOR_STRING, MetaData.ESCAPE_CHARACTER)).append(MetaData.SEPARATOR_STRING); + if (!metaItem.getKey().equals(MetaData.VERSION_DB_STRUCT)) { + stringBuilder.append(StringUtil.quote(dataItem, MetaData.SEPARATOR_STRING, MetaData.ESCAPE_CHARACTER)).append(MetaData.SEPARATOR_STRING); + } else { + stringBuilder.append(StringUtil.quote(dataItem, MetaData.SEPARATOR_STRING, MetaData.ESCAPE_CHARACTER)); + } // in case of save actions, add an additional newline after the enabled flag if (metaItem.getKey().equals(MetaData.SAVE_ACTIONS) From 4ae4cd949460c5a9bcd1d278560a1f27fd29bdd0 Mon Sep 17 00:00:00 2001 From: robyquin Date: Wed, 16 Nov 2022 17:12:19 +0100 Subject: [PATCH 19/75] Fix: After migration set current value of ENTRY_SHARED_ID_seq [PgSQL] --- src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java index ec72839bb35..599402b477a 100644 --- a/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java +++ b/src/main/java/org/jabref/logic/shared/PostgreSQLProcessor.java @@ -80,6 +80,7 @@ public void setUp() throws SQLException { connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("ENTRY") + " SELECT * FROM \"ENTRY\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("FIELD") + " SELECT * FROM \"FIELD\""); connection.createStatement().executeUpdate("INSERT INTO " + escape_Table("METADATA") + " SELECT * FROM \"METADATA\""); + connection.createStatement().execute("SELECT setval(\'jabref.\"ENTRY_SHARED_ID_seq\"\', (select max(\"SHARED_ID\") from jabref.\"ENTRY\"))"); metadata = getSharedMetaData(); } From 1cfb568cebe4e2cc5c8ffd5a6ae6d2dcfa25f7f7 Mon Sep 17 00:00:00 2001 From: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Date: Tue, 6 Dec 2022 20:28:35 +0100 Subject: [PATCH 20/75] Refactored prefs migrations --- src/main/java/org/jabref/cli/Launcher.java | 2 +- .../PreferencesDialogViewModel.java | 13 +-- .../migrations/PreferencesMigrations.java | 97 +++++++++++-------- 3 files changed, 63 insertions(+), 49 deletions(-) diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 871ccf46b86..fb49340b5a7 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -53,7 +53,7 @@ public static void main(String[] args) { // Init preferences final JabRefPreferences preferences = JabRefPreferences.getInstance(); Globals.prefs = preferences; - PreferencesMigrations.runMigrations(); + PreferencesMigrations.runMigrations(preferences); // Early exit in case another instance is already running if (!handleMultipleAppInstances(args, preferences)) { diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java index ddb7057aff3..b566932c3f3 100644 --- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java +++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java @@ -36,12 +36,10 @@ import org.jabref.gui.util.FileDialogConfiguration; import org.jabref.logic.JabRefException; import org.jabref.logic.exporter.ExporterFactory; -import org.jabref.logic.exporter.SavePreferences; import org.jabref.logic.exporter.TemplateExporter; import org.jabref.logic.l10n.Localization; import org.jabref.logic.layout.LayoutFormatterPreferences; import org.jabref.logic.util.StandardFileType; -import org.jabref.logic.xmp.XmpPreferences; import org.jabref.preferences.PreferencesFilter; import org.jabref.preferences.PreferencesService; @@ -169,10 +167,13 @@ private void updateAfterPreferenceChanges() { List customExporters = preferences.getCustomExportFormats(Globals.journalAbbreviationRepository); LayoutFormatterPreferences layoutPreferences = preferences.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository); - SavePreferences savePreferences = preferences.getSavePreferencesForExport(); - XmpPreferences xmpPreferences = preferences.getXmpPreferences(); - Globals.exportFactory = ExporterFactory.create(customExporters, layoutPreferences, savePreferences, - xmpPreferences, preferences.getGeneralPreferences().getDefaultBibDatabaseMode(), Globals.entryTypesManager); + Globals.exportFactory = ExporterFactory.create( + customExporters, + layoutPreferences, + preferences.getSavePreferencesForExport(), + preferences.getXmpPreferences(), + preferences.getGeneralPreferences().getDefaultBibDatabaseMode(), + Globals.entryTypesManager); frame.getLibraryTabs().forEach(panel -> panel.getMainTable().getTableModel().refresh()); } diff --git a/src/main/java/org/jabref/migrations/PreferencesMigrations.java b/src/main/java/org/jabref/migrations/PreferencesMigrations.java index 5f35870fb29..38b185c7143 100644 --- a/src/main/java/org/jabref/migrations/PreferencesMigrations.java +++ b/src/main/java/org/jabref/migrations/PreferencesMigrations.java @@ -16,7 +16,6 @@ import javafx.scene.control.TableColumn; -import org.jabref.gui.Globals; import org.jabref.gui.maintable.ColumnPreferences; import org.jabref.gui.maintable.MainTableColumnModel; import org.jabref.logic.citationkeypattern.GlobalCitationKeyPattern; @@ -42,26 +41,26 @@ private PreferencesMigrations() { /** * Perform checks and changes for users with a preference set from an older JabRef version. */ - public static void runMigrations() { + public static void runMigrations(JabRefPreferences preferences) { Preferences mainPrefsNode = Preferences.userRoot().node("/org/jabref"); upgradePrefsToOrgJabRef(mainPrefsNode); - upgradeSortOrder(Globals.prefs); - upgradeFaultyEncodingStrings(Globals.prefs); - upgradeLabelPatternToCitationKeyPattern(Globals.prefs); - upgradeImportFileAndDirePatterns(Globals.prefs, mainPrefsNode); - upgradeStoredBibEntryTypes(Globals.prefs, mainPrefsNode); - upgradeKeyBindingsToJavaFX(Globals.prefs); - addCrossRefRelatedFieldsForAutoComplete(Globals.prefs); - upgradePreviewStyleFromReviewToComment(Globals.prefs); + upgradeSortOrder(preferences); + upgradeFaultyEncodingStrings(preferences); + upgradeLabelPatternToCitationKeyPattern(preferences, mainPrefsNode); + upgradeImportFileAndDirePatterns(preferences, mainPrefsNode); + upgradeStoredBibEntryTypes(preferences, mainPrefsNode); + upgradeKeyBindingsToJavaFX(preferences); + addCrossRefRelatedFieldsForAutoComplete(preferences); + upgradePreviewStyleFromReviewToComment(preferences); // changeColumnVariableNamesFor51 needs to be run before upgradeColumnPre50Preferences to ensure // backwardcompatibility, as it copies the old values to new variable names and keeps th old sored with the old // variable names. However, the variables from 5.0 need to be copied to the new variable name too. - changeColumnVariableNamesFor51(Globals.prefs); - upgradeColumnPreferences(Globals.prefs); - restoreVariablesForBackwardCompatibility(Globals.prefs); - upgradePreviewStyleAllowMarkdown(Globals.prefs); - upgradeCleanups(Globals.prefs); + changeColumnVariableNamesFor51(preferences); + upgradeColumnPreferences(preferences); + restoreVariablesForBackwardCompatibility(preferences); + upgradePreviewStyleAllowMarkdown(preferences); + upgradeCleanups(preferences); } /** @@ -183,34 +182,40 @@ private static void upgradeStoredBibEntryTypes(JabRefPreferences prefs, Preferen } /** - * Migrate LabelPattern configuration from versions <=3.5 to new CitationKeyPatterns + * Migrate LabelPattern configuration from versions <=3.5 to new CitationKeyPatterns. + *

+ * Introduced in #1704 */ - private static void upgradeLabelPatternToCitationKeyPattern(JabRefPreferences prefs) { - try { - Preferences mainPrefsNode = Preferences.userRoot().node("/org/jabref"); + private static void upgradeLabelPatternToCitationKeyPattern(JabRefPreferences prefs, Preferences mainPrefsNode) { + final String V3_6_DEFAULT_BIBTEX_KEYPATTERN = "defaultBibtexKeyPattern"; + final String V3_6_BIBTEX_KEYPATTERN_NODE = "bibtexkeypatterns"; + final String V3_3_DEFAULT_LABELPATTERN = "defaultLabelPattern"; + final String V3_3_LOGIC_LABELPATTERN = "logic/labelpattern"; // version 3.3 - 3.5, mind the case + final String V3_0_LOGIC_LABELPATTERN = "logic/labelPattern"; // node used for version 3.0 - 3.2 + final String LEGACY_LABELPATTERN = "labelPattern"; // version <3.0 + try { // Migrate default pattern - if (mainPrefsNode.get(JabRefPreferences.DEFAULT_CITATION_KEY_PATTERN, null) == null) { + if (mainPrefsNode.get(V3_6_DEFAULT_BIBTEX_KEYPATTERN, null) == null) { // Check whether old defaultLabelPattern is set - String oldDefault = mainPrefsNode.get("defaultLabelPattern", null); + String oldDefault = mainPrefsNode.get(V3_3_DEFAULT_LABELPATTERN, null); if (oldDefault != null) { - prefs.put(JabRefPreferences.DEFAULT_CITATION_KEY_PATTERN, oldDefault); - LOGGER.info("Upgraded old default key generator pattern '" + oldDefault + "' to new version."); + prefs.put(V3_6_DEFAULT_BIBTEX_KEYPATTERN, oldDefault); + LOGGER.info("Upgraded old default key generator pattern '{}' to new version.", oldDefault); } } // Pref node already exists do not migrate from previous version - if (mainPrefsNode.nodeExists(JabRefPreferences.CITATION_KEY_PATTERNS_NODE)) { + if (mainPrefsNode.nodeExists(V3_6_BIBTEX_KEYPATTERN_NODE)) { return; } // Migrate type specific patterns - // Check for prefs node for Version 3.3-3.5 - if (mainPrefsNode.nodeExists("logic/labelpattern")) { - migrateTypedKeyPrefs(prefs, mainPrefsNode.node("logic/labelpattern")); - } else if (mainPrefsNode.nodeExists("logic/labelPattern")) { // node used for version 3.0-3.2 - migrateTypedKeyPrefs(prefs, mainPrefsNode.node("logic/labelPattern")); - } else if (mainPrefsNode.nodeExists("labelPattern")) { // node used for version <3.0 - migrateTypedKeyPrefs(prefs, mainPrefsNode.node("labelPattern")); + if (mainPrefsNode.nodeExists(V3_3_LOGIC_LABELPATTERN)) { + migrateTypedKeyPrefs(prefs, mainPrefsNode.node(V3_3_LOGIC_LABELPATTERN)); + } else if (mainPrefsNode.nodeExists(V3_0_LOGIC_LABELPATTERN)) { + migrateTypedKeyPrefs(prefs, mainPrefsNode.node(V3_0_LOGIC_LABELPATTERN)); + } else if (mainPrefsNode.nodeExists(LEGACY_LABELPATTERN)) { + migrateTypedKeyPrefs(prefs, mainPrefsNode.node(LEGACY_LABELPATTERN)); } } catch (BackingStoreException e) { LOGGER.error("Migrating old bibtexKeyPatterns failed.", e); @@ -326,16 +331,15 @@ static void upgradePreviewStyleAllowMarkdown(JabRefPreferences prefs) { * the preferences store the type of the column too, so that the formerly hardwired columns like the graphic groups * column or the other icon columns can be reordered in the main table and behave like any other field column * ("groups;linked_id;field:author;special:readstatus;extrafile:pdf;..."). - * + *

* Simple strings are by default parsed as a FieldColumn, so there is nothing to do there, but the formerly hard * wired columns need to be added. - * + *

* In 5.1 variable names in JabRefPreferences have changed to offer backward compatibility with pre 5.0 releases * Pre 5.1: columnNames, columnWidths, columnSortTypes, columnSortOrder * Since 5.1: mainTableColumnNames, mainTableColumnWidths, mainTableColumnSortTypes, mainTableColumnSortOrder */ static void upgradeColumnPreferences(JabRefPreferences preferences) { - // Variable names have to be hardcoded here, since they are already changed in JabRefPreferences List columnNames = preferences.getStringList(JabRefPreferences.COLUMN_NAMES); List columnWidths = preferences.getStringList(JabRefPreferences.COLUMN_WIDTHS) .stream() @@ -345,8 +349,7 @@ static void upgradeColumnPreferences(JabRefPreferences preferences) { } catch (NumberFormatException e) { return ColumnPreferences.DEFAULT_COLUMN_WIDTH; } - }) - .collect(Collectors.toList()); + }).toList(); // "field:" String normalFieldTypeString = MainTableColumnModel.Type.NORMALFIELD.getName() + MainTableColumnModel.COLUMNS_QUALIFIER_DELIMITER; @@ -395,13 +398,23 @@ static void upgradeColumnPreferences(JabRefPreferences preferences) { static void changeColumnVariableNamesFor51(JabRefPreferences preferences) { // The variable names have to be hardcoded, because they have changed between 5.0 and 5.1 - List oldColumnNames = preferences.getStringList("columnNames"); - List columnNames = preferences.getStringList(JabRefPreferences.COLUMN_NAMES); + final String V5_0_COLUMN_NAMES = "columnNames"; + final String V5_0_COLUMN_WIDTHS = "columnWidths"; + final String V5_0_COLUMN_SORT_TYPES = "columnSortTypes"; + final String V5_0_COLUMN_SORT_ORDER = "columnSortOrder"; + + final String V5_1_COLUMN_NAMES = "mainTableColumnNames"; + final String V5_1_COLUMN_WIDTHS = "mainTableColumnWidths"; + final String V5_1_COLUMN_SORT_TYPES = "mainTableColumnSortTypes"; + final String V5_1_COLUMN_SORT_ORDER = "mainTableColumnSortOrder"; + + List oldColumnNames = preferences.getStringList(V5_0_COLUMN_NAMES); + List columnNames = preferences.getStringList(V5_1_COLUMN_NAMES); if (!oldColumnNames.isEmpty() && columnNames.isEmpty()) { - preferences.putStringList(JabRefPreferences.COLUMN_NAMES, preferences.getStringList("columnNames")); - preferences.putStringList(JabRefPreferences.COLUMN_WIDTHS, preferences.getStringList("columnWidths")); - preferences.putStringList(JabRefPreferences.COLUMN_SORT_TYPES, preferences.getStringList("columnSortTypes")); - preferences.putStringList(JabRefPreferences.COLUMN_SORT_ORDER, preferences.getStringList("columnSortOrder")); + preferences.putStringList(V5_1_COLUMN_NAMES, preferences.getStringList(V5_0_COLUMN_NAMES)); + preferences.putStringList(V5_1_COLUMN_WIDTHS, preferences.getStringList(V5_0_COLUMN_WIDTHS)); + preferences.putStringList(V5_1_COLUMN_SORT_TYPES, preferences.getStringList(V5_0_COLUMN_SORT_TYPES)); + preferences.putStringList(V5_1_COLUMN_SORT_ORDER, preferences.getStringList(V5_0_COLUMN_SORT_ORDER)); } } From 4772a3bd7fe24885d3daf88ae2aea49a58fa463d Mon Sep 17 00:00:00 2001 From: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Date: Tue, 6 Dec 2022 22:28:19 +0100 Subject: [PATCH 21/75] Removed deprecated unused ExportComparator --- .../org/jabref/preferences/ExportComparator.java | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/main/java/org/jabref/preferences/ExportComparator.java diff --git a/src/main/java/org/jabref/preferences/ExportComparator.java b/src/main/java/org/jabref/preferences/ExportComparator.java deleted file mode 100644 index 07a205d0d75..00000000000 --- a/src/main/java/org/jabref/preferences/ExportComparator.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.jabref.preferences; - -import java.util.Comparator; -import java.util.List; - -public class ExportComparator implements Comparator> { - - @Override - public int compare(List s1, List s2) { - return s1.get(0).compareTo(s2.get(0)); - } -} From 82db9900857c30ccc6c1b0102267966481155258 Mon Sep 17 00:00:00 2001 From: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Date: Tue, 6 Dec 2022 23:55:48 +0100 Subject: [PATCH 22/75] Extracted KeywordSeparator from GroupsPreferences and created new PreferencesTab EntryTab --- .../jabref/gui/groups/GroupsPreferences.java | 17 +--- .../newmergedialog/ThreeWayMergeView.java | 2 +- .../fieldsmerger/KeywordMerger.java | 2 +- .../PreferencesDialogViewModel.java | 2 + .../gui/preferences/entry/EntryTab.fxml | 35 ++++++++ .../gui/preferences/entry/EntryTab.java | 65 +++++++++++++++ .../preferences/entry/EntryTabViewModel.java | 83 +++++++++++++++++++ .../gui/preferences/general/GeneralTab.fxml | 20 ----- .../gui/preferences/general/GeneralTab.java | 32 +------ .../general/GeneralTabViewModel.java | 78 ++--------------- .../gui/preferences/groups/GroupsTab.fxml | 7 -- .../gui/preferences/groups/GroupsTab.java | 5 +- .../groups/GroupsTabViewModel.java | 14 +--- .../importer/ImportFormatPreferences.java | 24 +++++- .../importer/fileformat/BibtexParser.java | 4 +- .../preferences/BibEntryPreferences.java | 24 ++++++ .../preferences/InternalPreferences.java | 16 +--- .../jabref/preferences/JabRefPreferences.java | 31 +++++-- .../preferences/PreferencesService.java | 2 + .../gui/groups/GroupNodeViewModelTest.java | 4 +- 20 files changed, 270 insertions(+), 197 deletions(-) create mode 100644 src/main/java/org/jabref/gui/preferences/entry/EntryTab.fxml create mode 100644 src/main/java/org/jabref/gui/preferences/entry/EntryTab.java create mode 100644 src/main/java/org/jabref/gui/preferences/entry/EntryTabViewModel.java create mode 100644 src/main/java/org/jabref/preferences/BibEntryPreferences.java diff --git a/src/main/java/org/jabref/gui/groups/GroupsPreferences.java b/src/main/java/org/jabref/gui/groups/GroupsPreferences.java index a6bf6f67641..849f7dc808a 100644 --- a/src/main/java/org/jabref/gui/groups/GroupsPreferences.java +++ b/src/main/java/org/jabref/gui/groups/GroupsPreferences.java @@ -10,17 +10,14 @@ public class GroupsPreferences { private final ObjectProperty groupViewMode; private final BooleanProperty shouldAutoAssignGroup; private final BooleanProperty shouldDisplayGroupCount; - private final ObjectProperty keywordSeparator; public GroupsPreferences(GroupViewMode groupViewMode, boolean shouldAutoAssignGroup, - boolean shouldDisplayGroupCount, - ObjectProperty keywordSeparator) { + boolean shouldDisplayGroupCount) { this.groupViewMode = new SimpleObjectProperty<>(groupViewMode); this.shouldAutoAssignGroup = new SimpleBooleanProperty(shouldAutoAssignGroup); this.shouldDisplayGroupCount = new SimpleBooleanProperty(shouldDisplayGroupCount); - this.keywordSeparator = keywordSeparator; } public GroupViewMode getGroupViewMode() { @@ -58,16 +55,4 @@ public BooleanProperty displayGroupCountProperty() { public void setDisplayGroupCount(boolean shouldDisplayGroupCount) { this.shouldDisplayGroupCount.set(shouldDisplayGroupCount); } - - public Character getKeywordSeparator() { - return keywordSeparator.getValue(); - } - - public ObjectProperty keywordSeparatorProperty() { - return keywordSeparator; - } - - public void setKeywordSeparator(Character keywordSeparator) { - this.keywordSeparator.set(keywordSeparator); - } } diff --git a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java index 766b46185f3..fea132e99ca 100644 --- a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java +++ b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/ThreeWayMergeView.java @@ -44,7 +44,7 @@ public ThreeWayMergeView(BibEntry leftEntry, BibEntry rightEntry, String leftHea getStylesheets().add(ThreeWayMergeView.class.getResource("ThreeWayMergeView.css").toExternalForm()); viewModel = new ThreeWayMergeViewModel((BibEntry) leftEntry.clone(), (BibEntry) rightEntry.clone(), leftHeader, rightHeader); this.fieldMergerFactory = new FieldMergerFactory(preferencesService); - this.keywordSeparator = preferencesService.getGroupsPreferences().getKeywordSeparator().toString(); + this.keywordSeparator = preferencesService.getBibEntryPreferences().getKeywordSeparator().toString(); mergeGridPane = new GridPane(); scrollPane = new ScrollPane(); diff --git a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/fieldsmerger/KeywordMerger.java b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/fieldsmerger/KeywordMerger.java index 3947a185b53..9a4021a47ca 100644 --- a/src/main/java/org/jabref/gui/mergeentries/newmergedialog/fieldsmerger/KeywordMerger.java +++ b/src/main/java/org/jabref/gui/mergeentries/newmergedialog/fieldsmerger/KeywordMerger.java @@ -19,7 +19,7 @@ public KeywordMerger(PreferencesService preferencesService) { @Override public String merge(String keywordsA, String keywordsB) { - Character delimiter = preferencesService.getGroupsPreferences().getKeywordSeparator(); + Character delimiter = preferencesService.getBibEntryPreferences().getKeywordSeparator(); return KeywordList.merge(keywordsA, keywordsB, delimiter).getAsString(delimiter); } } diff --git a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java index b566932c3f3..0e5f2f7155f 100644 --- a/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java +++ b/src/main/java/org/jabref/gui/preferences/PreferencesDialogViewModel.java @@ -16,6 +16,7 @@ import org.jabref.gui.preferences.citationkeypattern.CitationKeyPatternTab; import org.jabref.gui.preferences.customexporter.CustomExporterTab; import org.jabref.gui.preferences.customimporter.CustomImporterTab; +import org.jabref.gui.preferences.entry.EntryTab; import org.jabref.gui.preferences.entryeditor.EntryEditorTab; import org.jabref.gui.preferences.entryeditortabs.CustomEditorFieldsTab; import org.jabref.gui.preferences.external.ExternalTab; @@ -64,6 +65,7 @@ public PreferencesDialogViewModel(DialogService dialogService, PreferencesServic new GeneralTab(), new KeyBindingsTab(), new FileTab(), + new EntryTab(), new TableTab(), new PreviewTab(), new ProtectedTermsTab(), diff --git a/src/main/java/org/jabref/gui/preferences/entry/EntryTab.fxml b/src/main/java/org/jabref/gui/preferences/entry/EntryTab.fxml new file mode 100644 index 00000000000..81028a987d1 --- /dev/null +++ b/src/main/java/org/jabref/gui/preferences/entry/EntryTab.fxml @@ -0,0 +1,35 @@ + + + + + + + + + + +