diff --git a/pom.xml b/pom.xml index b0ed9b5..bce0f0f 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,11 @@ protobuf-java 4.32.0 + + org.xerial + sqlite-jdbc + 3.44.1.0 + diff --git a/src/main/java/com/mediamanager/MediaManagerApplication.java b/src/main/java/com/mediamanager/MediaManagerApplication.java index bc04be1..b9579dc 100644 --- a/src/main/java/com/mediamanager/MediaManagerApplication.java +++ b/src/main/java/com/mediamanager/MediaManagerApplication.java @@ -1,5 +1,6 @@ package com.mediamanager; +import com.mediamanager.service.database.DatabaseManager; import com.mediamanager.service.delegate.DelegateActionManager; import com.mediamanager.service.ipc.IPCManager; import org.apache.logging.log4j.LogManager; @@ -9,7 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import com.mediamanager.service.database.DatabaseManager; +import com.mediamanager.service.database.SqliteDatabaseManager; public class MediaManagerApplication { private static final Logger logger = LogManager.getLogger(MediaManagerApplication.class); @@ -18,13 +19,46 @@ public class MediaManagerApplication { private static DelegateActionManager actionManager; private static IPCManager ipcManager; + public enum ApplicationMode { + LOCAL("local"), + SERVER("server"); + + private final String value; + + ApplicationMode(String value) { + this.value = value; + } + } + public static void main(String[] args) { logger.info("Starting MediaManager Core Application..."); try { // Load configuration loadConfiguration(); - databaseManager = new DatabaseManager(config); + String runTypeString = config.getProperty("runtype","local"); + ApplicationMode mode = null; + + for (ApplicationMode am : ApplicationMode.values()) { + if (am.value.equalsIgnoreCase(runTypeString)) { + mode = am; + break; + } + } + if (mode == null) { + logger.error("Invalid run type: {}", runTypeString); + throw new Exception("Invalid run type: " + runTypeString); + } + logger.info("Run type: {}", mode); + switch (mode) { + case LOCAL: + logger.info("Starting local database..."); + databaseManager = new SqliteDatabaseManager(config); + break; + case SERVER: + throw new Exception("Server mode not yet implemented"); + default: + } databaseManager.init(); actionManager = new DelegateActionManager(); actionManager.start(); @@ -102,4 +136,4 @@ public class MediaManagerApplication { public static Properties getConfig() { return config; } -} +} \ No newline at end of file diff --git a/src/main/java/com/mediamanager/service/database/DatabaseManager.java b/src/main/java/com/mediamanager/service/database/DatabaseManager.java index eeabc69..34f09d5 100644 --- a/src/main/java/com/mediamanager/service/database/DatabaseManager.java +++ b/src/main/java/com/mediamanager/service/database/DatabaseManager.java @@ -1,55 +1,28 @@ package com.mediamanager.service.database; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; +public abstract class DatabaseManager { + protected final Properties configuration; + protected Connection connection; + protected static final Logger logger = LogManager.getLogger(DatabaseManager.class); -public class DatabaseManager { - private final Properties configuration; - private Connection connection; - private static final Logger logger = LogManager.getLogger(DatabaseManager.class); public DatabaseManager(Properties config) { this.configuration = config; logger.debug("DatabaseManager created with configuration:"); - } - public void init() throws Exception { - logger.info("Initializing database connection..."); - validateConfiguration(); + public abstract void init() throws Exception; - String databaseType = configuration.getProperty("database.type"); - String databaseUrl = configuration.getProperty("database.url"); - String databaseUsername = configuration.getProperty("database.username"); - String databasePassword = configuration.getProperty("database.password"); - String databasePort = configuration.getProperty("database.port"); - String databaseName = configuration.getProperty("database.name"); + protected abstract Connection createConnection() throws Exception; - - String connectionString = String.format("jdbc:postgresql://%s:%s/%s", databaseUrl, databasePort, databaseName); - logger.debug("Attempting to connect to: {}", connectionString); - try { - connection = DriverManager.getConnection(connectionString, databaseUsername, databasePassword); - logger.info("Database connection established successfully"); - - performSanityChecks(); - logger.info("Database sanity checks passed successfully"); - - - } catch (SQLException e) { - logger.error("Failed to connect to database", e); - throw new Exception("Database connection failed: " + e.getMessage(), e); - } - - - - } - private void performSanityChecks() throws SQLException { + protected void performSanityChecks() throws SQLException { logger.debug("Performing sanity checks..."); try (Statement stmt = connection.createStatement()) { stmt.execute("SELECT 1"); @@ -59,27 +32,6 @@ public class DatabaseManager { String databaseProductVersion = connection.getMetaData().getDatabaseProductVersion(); logger.info("Connected to database: {} v{}", databaseProductName, databaseProductVersion); } - private void validateConfiguration() throws Exception { - String[] requiredProperties = { - "database.url", - "database.username", - "database.password", - "database.port", - "database.name" - }; - - for (String property : requiredProperties) { - if (configuration.getProperty(property) == null || - configuration.getProperty(property).trim().isEmpty()) { - throw new Exception("Required database configuration missing: " + property); - } - } - - logger.debug("Database configuration validated successfully"); - - } - - public Connection getConnection() { return connection; @@ -98,4 +50,13 @@ public class DatabaseManager { logger.debug("No database connection to close"); } } -} + protected boolean testConnection() { + try (Statement stmt = connection.createStatement()) { + stmt.execute("SELECT 1"); + return true; + } catch (SQLException e) { + logger.error("Connection test failed", e); + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/mediamanager/service/database/SqliteDatabaseManager.java b/src/main/java/com/mediamanager/service/database/SqliteDatabaseManager.java new file mode 100644 index 0000000..02d3ecc --- /dev/null +++ b/src/main/java/com/mediamanager/service/database/SqliteDatabaseManager.java @@ -0,0 +1,97 @@ +package com.mediamanager.service.database; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +public class SqliteDatabaseManager extends DatabaseManager { + private static final Logger logger = LogManager.getLogger(SqliteDatabaseManager.class); + + + private String connectionUrl; + + public SqliteDatabaseManager(Properties config) { + super(config); + } + + @Override + public void init() throws Exception { + + logger.info("Initializing SQLite database..."); + String dataDir = configuration.getProperty("database.dir", + System.getProperty("user.home") + "/.mediamanager/db"); + String dbFilename = configuration.getProperty("database.filename", "mediamanager.db"); + String driverClassName = configuration.getProperty("database.driver", "org.sqlite.JDBC"); + try { + Class.forName(driverClassName); + }catch(ClassNotFoundException e) { + logger.error("Failed to load SQLite driver", e); + throw e; + } + Path dataPath = Paths.get(dataDir); + if (!Files.exists(dataPath)) { + Files.createDirectories(dataPath); + logger.debug("Created database directory: {}", dataDir); + } + Path dbFile = dataPath.resolve(dbFilename); + this.connectionUrl = "jdbc:sqlite:" + dbFile.toAbsolutePath().toString(); + logger.info("Database file path: {}", dbFile); + logger.info("Connection URL: {}", this.connectionUrl); + this.connection = createConnection(); + configurePerformancePragmas(); + performSanityChecks(); + ensureSchemaExists(); + logger.info("SQLite database initialized successfully"); + + } + + @Override + protected Connection createConnection() throws Exception { + try { + // O driver org.xerial.sqlite-jdbc é carregado automaticamente aqui + Connection conn = DriverManager.getConnection(this.connectionUrl); + logger.debug("Got connection to SQLite file"); + return conn; + } catch (SQLException e) { + logger.error("Failed to create SQLite connection", e); + throw new Exception("SQLite connection failed: " + e.getMessage(), e); + } + } + + + private void configurePerformancePragmas() throws SQLException { + try (Statement stmt = connection.createStatement()) { + + stmt.execute("PRAGMA journal_mode=WAL;"); + + + stmt.execute("PRAGMA foreign_keys=ON;"); + + + stmt.execute("PRAGMA synchronous=NORMAL;"); + + stmt.execute("PRAGMA busy_timeout=5000;"); + + logger.debug("SQLite performance PRAGMAs applied (WAL, Synchronous, ForeignKeys)."); + } + } + + private void ensureSchemaExists() throws SQLException { + + } + + @Override + public void close() { + + super.close(); + logger.info("SQLite resources released."); + } +} \ No newline at end of file diff --git a/src/main/resources/config.properties.example b/src/main/resources/config.properties.example index 095d75c..0991905 100644 --- a/src/main/resources/config.properties.example +++ b/src/main/resources/config.properties.example @@ -21,6 +21,8 @@ hibernate.format_sql=true ipc.pipe.name=mediamanager-pipe ipc.pipe.path=/tmp/mediamanager ipc.buffer.size=8192 - +runtype=local ipc.socket.path=/tmp/mediamanager + +