From d193fe303f56659b31a1effea690a5137aa06fc2 Mon Sep 17 00:00:00 2001 From: Craig Schardt Date: Thu, 21 Dec 2023 15:49:42 -0600 Subject: [PATCH] refactor to use constants in DatabaseSchema --- .../configuration/SqlConfigProvider.java | 122 +++++++++++------- 1 file changed, 75 insertions(+), 47 deletions(-) diff --git a/photon-core/src/main/java/org/photonvision/common/configuration/SqlConfigProvider.java b/photon-core/src/main/java/org/photonvision/common/configuration/SqlConfigProvider.java index 7b0132ef48..3c2d1b7b50 100644 --- a/photon-core/src/main/java/org/photonvision/common/configuration/SqlConfigProvider.java +++ b/photon-core/src/main/java/org/photonvision/common/configuration/SqlConfigProvider.java @@ -30,6 +30,8 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import org.photonvision.common.configuration.DatabaseSchema.Columns; +import org.photonvision.common.configuration.DatabaseSchema.Tables; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.Logger; import org.photonvision.common.util.file.JacksonUtils; @@ -47,13 +49,7 @@ public class SqlConfigProvider extends ConfigProvider { private static final Logger logger = new Logger(SqlConfigProvider.class, LogGroup.Config); - static class TableKeys { - static final String CAM_UNIQUE_NAME = "unique_name"; - static final String CONFIG_JSON = "config_json"; - static final String DRIVERMODE_JSON = "drivermode_json"; - static final String OTHERPATHS_JSON = "otherpaths_json"; - static final String PIPELINE_JSONS = "pipeline_jsons"; - + static class GlobalKeys { static final String NETWORK_CONFIG = "networkConfig"; static final String HARDWARE_CONFIG = "hardwareConfig"; static final String HARDWARE_SETTINGS = "hardwareSettings"; @@ -150,7 +146,7 @@ private void doMigration(int index) throws SQLException { logger.debug("Running migration step " + index); try (Connection conn = createConn(); Statement stmt = conn.createStatement()) { - for (String sql : SqlMigrations.SQL[index].split(";")) { + for (String sql : DatabaseSchema.migrations[index].split(";")) { stmt.addBatch(sql); } stmt.executeBatch(); @@ -158,20 +154,18 @@ private void doMigration(int index) throws SQLException { setUserVersion(conn, index + 1); tryCommit(conn); } catch (SQLException e) { - logger.error("Err with migration step " + index, e); + logger.error("Error with migration step " + index, e); throw e; } } private void initDatabase() { int userVersion = getUserVersion(); + int expectedVersion = DatabaseSchema.migrations.length; - if (userVersion > SqlMigrations.SQL.length) { - // database must be from a newer version, so warn - logger.warn( - "This database is from a newer version of PhotonVision. Check that you are running the right version."); - } else if (userVersion < SqlMigrations.SQL.length) { + if (userVersion < expectedVersion) { // older database, run migrations + // first, check to see if this is one of the ones from 2024 beta that need special handling if (userVersion == 0 && getSchemaVersion() > 0) { String sql = @@ -189,23 +183,41 @@ private void initDatabase() { setUserVersion(conn, userVersion); } catch (SQLException e) { logger.error( - "Could not determine the version of the database. Delete " + "Could not determine the version of the database. Try deleting " + dbName + "and restart photonvision.", e); } } - logger.debug("Older database version. Updating schema ... "); + logger.debug("Older database version. Migrating ... "); try { - for (int index = userVersion; index < SqlMigrations.SQL.length; index++) { + for (int index = userVersion; index < expectedVersion; index++) { doMigration(index); } - logger.debug("Database migration succeded. Now on version: " + getUserVersion()); + logger.debug("Database migration complete"); } catch (SQLException e) { - logger.error("Err with migration", e); + logger.error("Error with database migration", e); } } + + // Warn if the database still isn't at the correct version + userVersion = getUserVersion(); + if (userVersion > expectedVersion) { + // database must be from a newer version, so warn + logger.warn( + "This database is from a newer version of PhotonVision. Check that you are running the right version of PhotonVision."); + } else if (userVersion < expectedVersion) { + // migration didn't work, so warn + logger.warn( + "This database migration failed. Expected version: " + + expectedVersion + + ", got version: " + + userVersion); + } else { + // migration worked + logger.info("Using correct database version: " + userVersion); + } } @Override @@ -252,7 +264,7 @@ public void load() { try { hardwareConfig = JacksonUtils.deserialize( - getOneConfigFile(conn, TableKeys.HARDWARE_CONFIG), HardwareConfig.class); + getOneConfigFile(conn, GlobalKeys.HARDWARE_CONFIG), HardwareConfig.class); } catch (IOException e) { logger.error("Could not deserialize hardware config! Loading defaults"); hardwareConfig = new HardwareConfig(); @@ -261,7 +273,7 @@ public void load() { try { hardwareSettings = JacksonUtils.deserialize( - getOneConfigFile(conn, TableKeys.HARDWARE_SETTINGS), HardwareSettings.class); + getOneConfigFile(conn, GlobalKeys.HARDWARE_SETTINGS), HardwareSettings.class); } catch (IOException e) { logger.error("Could not deserialize hardware settings! Loading defaults"); hardwareSettings = new HardwareSettings(); @@ -270,7 +282,7 @@ public void load() { try { networkConfig = JacksonUtils.deserialize( - getOneConfigFile(conn, TableKeys.NETWORK_CONFIG), NetworkConfig.class); + getOneConfigFile(conn, GlobalKeys.NETWORK_CONFIG), NetworkConfig.class); } catch (IOException e) { logger.error("Could not deserialize network config! Loading defaults"); networkConfig = new NetworkConfig(); @@ -279,7 +291,7 @@ public void load() { try { atfl = JacksonUtils.deserialize( - getOneConfigFile(conn, TableKeys.ATFL_CONFIG_FILE), AprilTagFieldLayout.class); + getOneConfigFile(conn, GlobalKeys.ATFL_CONFIG_FILE), AprilTagFieldLayout.class); } catch (IOException e) { logger.error("Could not deserialize apriltag layout! Loading defaults"); try { @@ -313,12 +325,15 @@ private String getOneConfigFile(Connection conn, String filename) { PreparedStatement query = null; try { query = - conn.prepareStatement("SELECT contents FROM global where filename=\"" + filename + "\""); + conn.prepareStatement( + String.format( + "SELECT %s FROM %s WHERE %s = \"%s\"", + Columns.GLB_CONTENTS, Tables.GLOBAL, Columns.GLB_FILENAME, filename)); var result = query.executeQuery(); while (result.next()) { - return result.getString("contents"); + return result.getString(Columns.GLB_CONTENTS); } } catch (SQLException e) { logger.error("SQL Err getting file " + filename, e); @@ -337,8 +352,14 @@ private void saveCameras(Connection conn) { try { // Replace this camera's row with the new settings var sqlString = - "REPLACE INTO cameras (unique_name, config_json, drivermode_json, otherpaths_json, pipeline_jsons) VALUES " - + "(?,?,?,?,?);"; + String.format( + "REPLACE INTO %s (%s, %s, %s, %s, %s) VALUES (?,?,?,?,?);", + Tables.CAMERAS, + Columns.CAM_UNIQUE_NAME, + Columns.CAM_CONFIG_JSON, + Columns.CAM_DRIVERMODE_JSON, + Columns.CAM_OTHERPATHS_JSON, + Columns.CAM_PIPELINE_JSONS); for (var c : config.getCameraConfigurations().entrySet()) { PreparedStatement statement = conn.prepareStatement(sqlString); @@ -389,19 +410,22 @@ private void saveGlobal(Connection conn) { PreparedStatement statement3 = null; try { // Replace this camera's row with the new settings - var sqlString = "REPLACE INTO global (filename, contents) VALUES " + "(?,?);"; + var sqlString = + String.format( + "REPLACE INTO %s (%s, %s) VALUES (?,?);", + Tables.GLOBAL, Columns.GLB_FILENAME, Columns.GLB_CONTENTS); statement1 = conn.prepareStatement(sqlString); addFile( statement1, - TableKeys.HARDWARE_SETTINGS, + GlobalKeys.HARDWARE_SETTINGS, JacksonUtils.serializeToString(config.getHardwareSettings())); statement1.executeUpdate(); statement2 = conn.prepareStatement(sqlString); addFile( statement2, - TableKeys.NETWORK_CONFIG, + GlobalKeys.NETWORK_CONFIG, JacksonUtils.serializeToString(config.getNetworkConfig())); statement2.executeUpdate(); statement2.close(); @@ -409,7 +433,7 @@ private void saveGlobal(Connection conn) { statement3 = conn.prepareStatement(sqlString); addFile( statement3, - TableKeys.HARDWARE_CONFIG, + GlobalKeys.HARDWARE_CONFIG, JacksonUtils.serializeToString(config.getHardwareConfig())); statement3.executeUpdate(); statement3.close(); @@ -443,7 +467,10 @@ private boolean saveOneFile(String fname, Path path) { } // Replace this camera's row with the new settings - var sqlString = "REPLACE INTO global (filename, contents) VALUES " + "(?,?);"; + var sqlString = + String.format( + "REPLACE INTO %s (%s, %s) VALUES (?,?);", + Tables.GLOBAL, Columns.GLB_FILENAME, Columns.GLB_CONTENTS); statement1 = conn.prepareStatement(sqlString); addFile(statement1, fname, Files.readString(path)); @@ -471,22 +498,22 @@ private boolean saveOneFile(String fname, Path path) { @Override public boolean saveUploadedHardwareConfig(Path uploadPath) { - return saveOneFile(TableKeys.HARDWARE_CONFIG, uploadPath); + return saveOneFile(GlobalKeys.HARDWARE_CONFIG, uploadPath); } @Override public boolean saveUploadedHardwareSettings(Path uploadPath) { - return saveOneFile(TableKeys.HARDWARE_SETTINGS, uploadPath); + return saveOneFile(GlobalKeys.HARDWARE_SETTINGS, uploadPath); } @Override public boolean saveUploadedNetworkConfig(Path uploadPath) { - return saveOneFile(TableKeys.NETWORK_CONFIG, uploadPath); + return saveOneFile(GlobalKeys.NETWORK_CONFIG, uploadPath); } @Override public boolean saveUploadedAprilTagFieldLayout(Path uploadPath) { - return saveOneFile(TableKeys.ATFL_CONFIG_FILE, uploadPath); + return saveOneFile(GlobalKeys.ATFL_CONFIG_FILE, uploadPath); } private HashMap loadCameraConfigs(Connection conn) { @@ -498,12 +525,13 @@ private HashMap loadCameraConfigs(Connection conn) query = conn.prepareStatement( String.format( - "SELECT %s, %s, %s, %s, %s FROM cameras", - TableKeys.CAM_UNIQUE_NAME, - TableKeys.CONFIG_JSON, - TableKeys.DRIVERMODE_JSON, - TableKeys.OTHERPATHS_JSON, - TableKeys.PIPELINE_JSONS)); + "SELECT %s, %s, %s, %s, %s FROM %s", + Columns.CAM_UNIQUE_NAME, + Columns.CAM_CONFIG_JSON, + Columns.CAM_DRIVERMODE_JSON, + Columns.CAM_OTHERPATHS_JSON, + Columns.CAM_PIPELINE_JSONS, + Tables.CAMERAS)); var result = query.executeQuery(); @@ -511,18 +539,18 @@ private HashMap loadCameraConfigs(Connection conn) while (result.next()) { List dummyList = new ArrayList<>(); - var uniqueName = result.getString(TableKeys.CAM_UNIQUE_NAME); + var uniqueName = result.getString(Columns.CAM_UNIQUE_NAME); var config = JacksonUtils.deserialize( - result.getString(TableKeys.CONFIG_JSON), CameraConfiguration.class); + result.getString(Columns.CAM_CONFIG_JSON), CameraConfiguration.class); var driverMode = JacksonUtils.deserialize( - result.getString(TableKeys.DRIVERMODE_JSON), DriverModePipelineSettings.class); + result.getString(Columns.CAM_DRIVERMODE_JSON), DriverModePipelineSettings.class); var otherPaths = - JacksonUtils.deserialize(result.getString(TableKeys.OTHERPATHS_JSON), String[].class); + JacksonUtils.deserialize(result.getString(Columns.CAM_OTHERPATHS_JSON), String[].class); List pipelineSettings = JacksonUtils.deserialize( - result.getString(TableKeys.PIPELINE_JSONS), dummyList.getClass()); + result.getString(Columns.CAM_PIPELINE_JSONS), dummyList.getClass()); List loadedSettings = new ArrayList<>(); for (var str : pipelineSettings) {