Skip to content

Commit

Permalink
Fixed Importer bug with 2.0 databases.
Browse files Browse the repository at this point in the history
Worked in 3.0.9 but then broke because version check was introduced in 3.0.10 to prevent old versions from being opened. As an unintended side-effect, it also prevented 2.0 databases from being opened in the batch importer.
  • Loading branch information
leifeld committed Jan 1, 2024
1 parent 1906b0c commit ea103cb
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 86 deletions.
2 changes: 1 addition & 1 deletion dna/src/main/java/dna/Dna.java
Expand Up @@ -17,7 +17,7 @@ public class Dna {
public static Dna dna;
public static Logger logger;
public static Sql sql;
public static final String date = "2023-10-21";
public static final String date = "2024-01-01";
public static final String version = "3.0.11";
public static final String operatingSystem = System.getProperty("os.name");
public static File workingDirectory = null;
Expand Down
21 changes: 15 additions & 6 deletions dna/src/main/java/dna/HeadlessDna.java
Expand Up @@ -110,13 +110,22 @@ public boolean openDatabase(int coderId, String coderPassword, String type, Stri
ConnectionProfile cp = new ConnectionProfile(type, databaseUrl, databaseName, databasePort, databaseUser, databasePassword);
Sql testSql = new Sql(cp, true);
boolean success = testSql.authenticate(coderId, coderPassword);
String version = testSql.getVersion();
if (success) {
Dna.sql.setConnectionProfile(cp, false);
Dna.sql.selectCoder(coderId);
LogEvent l = new LogEvent(Logger.MESSAGE,
"Coder " + Dna.sql.getActiveCoder().getId() + " (" + Dna.sql.getActiveCoder().getName() + ") successfully authenticated.",
"Coder " + Dna.sql.getActiveCoder().getId() + " (" + Dna.sql.getActiveCoder().getName() + ") successfully authenticated. You can now use the functions available to this user.");
Dna.logger.log(l);
if (version.startsWith("3.0")) {
Dna.sql.setConnectionProfile(cp, false);
Dna.sql.selectCoder(coderId);
LogEvent l = new LogEvent(Logger.MESSAGE,
"Coder " + Dna.sql.getActiveCoder().getId() + " (" + Dna.sql.getActiveCoder().getName() + ") successfully authenticated.",
"Coder " + Dna.sql.getActiveCoder().getId() + " (" + Dna.sql.getActiveCoder().getName() + ") successfully authenticated. You can now use the functions available to this user.");
Dna.logger.log(l);
} else {
LogEvent l = new LogEvent(Logger.ERROR,
"Tried to open an incompatible database version.",
"You tried to open a DNA database with version \" + version + \", but you can only open databases with version 3.0. Data from version 2 databases can also be imported into a new or existing DNA 3 database using the importer in the Documents menu.");
Dna.logger.log(l);
}

printDatabaseDetails();
} else {
LogEvent l = new LogEvent(Logger.ERROR,
Expand Down
34 changes: 20 additions & 14 deletions dna/src/main/java/gui/MainWindow.java
Expand Up @@ -1534,7 +1534,13 @@ public ActionOpenDatabase(String text, ImageIcon icon, String desc, Integer mnem
public void actionPerformed(ActionEvent e) {
NewDatabaseDialog n = new NewDatabaseDialog(MainWindow.this, true);
ConnectionProfile cp = n.getConnectionProfile();
if (cp != null) {
String version = new Sql(cp, false).getVersion();
if (!version.startsWith("3.0")) {
LogEvent le = new LogEvent(Logger.ERROR,
"[GUI] Tried to open an incompatible database version.",
"You tried to open a DNA database with version " + version + ", but you can only open databases with version 3.0. Data from version 2 databases can also be imported into a new or existing DNA 3 database using the importer in the Documents menu.");
Dna.logger.log(le);
} else if (cp != null) {
Dna.sql.setConnectionProfile(cp, false);
refreshDocumentTable();
refreshStatementTable(new int[0]);
Expand All @@ -1547,19 +1553,19 @@ public void actionPerformed(ActionEvent e) {
statementPanel.adjustToChangedConnection();
menuBar.adjustToChangedCoder();
coderSelectionPanel.changeCoderBadge();
}

if (cp == null) {
LogEvent l = new LogEvent(Logger.MESSAGE,
"[GUI] Action executed: could not open database.",
"Started opening a database connection from the GUI, but the connection was not established.");
Dna.logger.log(l);
} else {
Dna.sql.setConnectionProfile(cp, false); // not a connection test, so false
LogEvent l = new LogEvent(Logger.MESSAGE,
"[GUI] Action executed: opened database.",
"Opened a database connection from the GUI.");
Dna.logger.log(l);

if (cp == null) {
LogEvent l = new LogEvent(Logger.MESSAGE,
"[GUI] Action executed: could not open database.",
"Started opening a database connection from the GUI, but the connection was not established.");
Dna.logger.log(l);
} else {
Dna.sql.setConnectionProfile(cp, false); // not a connection test, so false
LogEvent l = new LogEvent(Logger.MESSAGE,
"[GUI] Action executed: opened database.",
"Opened a database connection from the GUI.");
Dna.logger.log(l);
}
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions dna/src/main/java/gui/NewDatabaseDialog.java
Expand Up @@ -19,7 +19,6 @@
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
Expand All @@ -34,7 +33,6 @@
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;

import org.jasypt.util.password.StrongPasswordEncryptor;

Expand Down
77 changes: 14 additions & 63 deletions dna/src/main/java/sql/Sql.java
Expand Up @@ -118,14 +118,12 @@ public boolean setConnectionProfile(ConnectionProfile cp, boolean test) {
SQLiteDataSource sqds = new SQLiteDataSource();
sqds.setUrl("jdbc:sqlite:" + cp.getUrl());
sqds.setEnforceForeignKeys(true); // if this is not set, ON DELETE CASCADE won't work
if (checkDatabaseVersion(sqds)) {
ds = sqds;
success = true;
LogEvent l = new LogEvent(Logger.MESSAGE,
"[SQL] An SQLite DNA database has been opened as a data source.",
"An SQLite DNA database has been opened as a data source.");
Dna.logger.log(l);
}
ds = sqds;
success = true;
LogEvent l = new LogEvent(Logger.MESSAGE,
"[SQL] An SQLite DNA database has been opened as a data source.",
"An SQLite DNA database has been opened as a data source.");
Dna.logger.log(l);
} else if (cp.getType().equals("mysql") || cp.getType().equals("postgresql")) {
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(30);
Expand All @@ -140,18 +138,16 @@ public boolean setConnectionProfile(ConnectionProfile cp, boolean test) {
}
try {
HikariDataSource dsTest = new HikariDataSource(config);
if (checkDatabaseVersion(dsTest)) {
ds = dsTest;
success = true;
LogEvent l = new LogEvent(Logger.MESSAGE,
"[SQL] A " + cp.getType() + " DNA database has been opened as a data source.",
"A " + cp.getType() + " DNA database has been opened as a data source.");
Dna.logger.log(l);
}
ds = dsTest;
success = true;
LogEvent l = new LogEvent(Logger.MESSAGE,
"[SQL] A " + cp.getType() + " DNA database has been opened as a data source.",
"A " + cp.getType() + " DNA database has been opened as a data source.");
Dna.logger.log(l);
} catch (PoolInitializationException e) {
LogEvent l = new LogEvent(Logger.ERROR,
"[SQL] Database access denied. Failed to initialize connection pool.",
"Database access denied. Failed to initialize connection pool.",
"[SQL] Database access denied. Failed to initialize connection pool.",
"Database access denied. Failed to initialize connection pool.",
e);
Dna.logger.log(l);
}
Expand All @@ -178,51 +174,6 @@ public boolean hasDataSource() {
return this.ds != null;
}

/**
* Check if a data source is compatible with the current DNA version by inspecting the version number saved in the
* SETTINGS table.
*
* @param dataSource The data source to be used and checked for compatibility.
* @return True if the database version is compatible with the current DNA version. False if it needs to be updated.
*/
private boolean checkDatabaseVersion(DataSource dataSource) {
boolean compatible = true;
try (Connection conn = dataSource.getConnection();
PreparedStatement s1 = conn.prepareStatement("SELECT * FROM SETTINGS WHERE Property IN ('version', 'date');")) {
ResultSet rs = s1.executeQuery();
String property, version = "", date = "";
while (rs.next()) {
property = rs.getString("Property");
if (property.equals("version")) {
version = rs.getString("Value");
} else if (property.equals("date")) {
date = rs.getString("Value");
}
}
if (version.startsWith("1") || version.startsWith("2")) {
compatible = false;
String msg = "";
if (version.startsWith("1")) {
msg = "Contents from databases that were created with DNA 1 can only be imported into the old DNA 2. See the release page online for old DNA 2 versions.";

} else if (version.startsWith("2")) {
msg = "Contents from databases that were created with DNA 2 can be imported into the current DNA version. To do so, create a new database, create coders that correspond to the coders in the old database (if required), and use the \"Import from DNA database\" dialog in the \"Documents\" menu.";
}
LogEvent l = new LogEvent(Logger.ERROR,
"[SQL] Wrong database version.",
"You tried to open a database that was created with version " + version + " of DNA (release date: " + date + "). You are currently using DNA " + Dna.version + " (release date: " + Dna.date + "). The database version is incompatible with the DNA version. " + msg);
Dna.logger.log(l);
}
} catch (SQLException e) {
LogEvent l = new LogEvent(Logger.WARNING,
"[SQL] Failed to determine database version.",
"Attempted to check if the database version is compatible with the DNA version, but failed to do so. If you do not see any other warnings or errors, you can probably ignore this message. If it happens often, consider filing an issue on GitHub.",
e);
Dna.logger.log(l);
}
return compatible;
}

/**
* Get the active coder.
*
Expand Down

0 comments on commit ea103cb

Please sign in to comment.