diff --git a/src/main/java/me/axeno/hommr/managers/DatabaseManager.java b/src/main/java/me/axeno/hommr/managers/DatabaseManager.java index 9a4ca6a..da74dc7 100644 --- a/src/main/java/me/axeno/hommr/managers/DatabaseManager.java +++ b/src/main/java/me/axeno/hommr/managers/DatabaseManager.java @@ -2,18 +2,17 @@ import com.j256.ormlite.dao.Dao; import com.j256.ormlite.dao.DaoManager; -import com.j256.ormlite.jdbc.JdbcConnectionSource; +import com.j256.ormlite.jdbc.JdbcPooledConnectionSource; import com.j256.ormlite.misc.TransactionManager; import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.table.TableUtils; import lombok.Getter; import me.axeno.hommr.Hommr; import me.axeno.hommr.models.Home; +import org.bukkit.configuration.file.FileConfiguration; -import java.io.File; import java.sql.SQLException; import java.util.List; -import java.util.concurrent.Callable; public class DatabaseManager { @@ -21,46 +20,27 @@ public class DatabaseManager { @Getter private Dao homeDao; - /** - * Set up the database connection and DAO for Home entities based on configuration. - * - * Initializes the plugin data folder if necessary, creates a JDBC connection source - * (MySQL when `database.type` is `"mysql"`, otherwise SQLite using a `homes.db` file), - * and creates a Dao for accessing Home records. Ensures the Home table - * exists in the database; failures during folder creation, table creation, or overall - * initialization are logged. - */ - public void init() { - try { - File dataFolder = Hommr.getInstance().getDataFolder(); - if (!dataFolder.exists()) { - boolean created = dataFolder.mkdirs(); - if (!created) { - Hommr.getInstance().getLogger().warning("Could not create plugin data folder: " + dataFolder.getAbsolutePath()); - } - } - - String type = Hommr.getInstance().getConfig().getString("database.type", "sqlite").toLowerCase(); - String databaseUrl; - String username = null; - String password = null; + public void init(String dbUrl, String dbUser, String dbPassword) { + if (dbUrl == null || dbUrl.isEmpty()) { + throw new IllegalStateException("Database URL is not configured. Please set 'database.connection.url' in config.yml"); + } - if (type.equals("mysql")) { - databaseUrl = Hommr.getInstance().getConfig().getString("database.connection.url"); - username = Hommr.getInstance().getConfig().getString("database.connection.username"); - password = Hommr.getInstance().getConfig().getString("database.connection.password"); - if (databaseUrl == null || databaseUrl.isEmpty()) { - throw new IllegalArgumentException("MySQL database URL is required but not configured. Please check your config.yml."); - } - connectionSource = new JdbcConnectionSource(databaseUrl, username, password); - } else { - databaseUrl = "jdbc:sqlite:" + new File(dataFolder, "homes.db").getAbsolutePath(); - connectionSource = new JdbcConnectionSource(databaseUrl); + if (dbUrl.startsWith("jbdc:mysql:")) { + try { + Class.forName("com.mysql.cj.jdbc.Driver"); + } catch (ClassNotFoundException e) { + Hommr.getInstance().getSLF4JLogger().error("MySQL database driver not found. Please ensure the MySQL driver is included in the classpath."); + throw new RuntimeException(e); } + } - homeDao = DaoManager.createDao(connectionSource, Home.class); + try { + connectionSource = new JdbcPooledConnectionSource(dbUrl, dbUser, dbPassword); - TableUtils.createTableIfNotExists(connectionSource, Home.class); + homeDao = DaoManager.createDao(connectionSource, Home.class); + if (!homeDao.isTableExists()) { + TableUtils.createTableIfNotExists(connectionSource, Home.class); + } } catch (SQLException e) { Hommr.getInstance().getLogger().log(java.util.logging.Level.SEVERE, "Failed to initialize database", e); @@ -68,10 +48,27 @@ public void init() { } } + /** + * Set up the database connection and DAO for Home entities based on configuration. + *

+ * Initializes the plugin data folder if necessary, creates a JDBC connection source + * and creates a Dao for accessing Home records. Ensures the Home table + * exists in the database; failures during folder creation, table creation, or overall + * initialization are logged. + */ + public void init() { + FileConfiguration config = Hommr.getInstance().getConfig(); + String dbUrl = config.getString("database.connection.url"); + String dbUser = config.getString("database.connection.username", ""); + String dbPassword = config.getString("database.connection.password", ""); + + init(dbUrl, dbUser, dbPassword); + } + /** * Closes the underlying database connection source and releases related resources. - * - * If an error occurs while closing, the exception is caught and a warning is logged. + *

+ * If an error occurs while closing, the exception is caught and a warning is logged. */ public void close() { if (connectionSource != null) { @@ -96,7 +93,7 @@ public List getAllHomes() throws SQLException { /** * Replaces all stored Home records with the provided list. - * + *

* Clears the Home table and inserts the given homes in a single batch operation. * * @param homes the list of Home objects to persist (may be empty) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5af7390..1210533 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,12 +1,6 @@ # Hommr Configuration database: - # Database type to use for storage. - # Available options: - # - sqlite: Stores data in a local file (homes.db) within the plugin folder. No extra setup required. - # - mysql: Stores data in an external MySQL database. Requires connection details below. - type: sqlite - connection: # JDBC URL for the database connection (Required for MySQL). # Format for MySQL: jdbc:mysql://:/ diff --git a/src/test/java/me/axeno/hommr/managers/DatabaseManagerTest.java b/src/test/java/me/axeno/hommr/managers/DatabaseManagerTest.java index 0738e78..af05c58 100644 --- a/src/test/java/me/axeno/hommr/managers/DatabaseManagerTest.java +++ b/src/test/java/me/axeno/hommr/managers/DatabaseManagerTest.java @@ -1,11 +1,8 @@ package me.axeno.hommr.managers; -import com.j256.ormlite.dao.Dao; -import com.j256.ormlite.support.ConnectionSource; import me.axeno.hommr.Hommr; import me.axeno.hommr.models.Home; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.PluginDescriptionFile; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -15,7 +12,6 @@ import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; -import java.io.File; import java.nio.file.Path; import java.sql.SQLException; import java.util.ArrayList; @@ -45,8 +41,10 @@ class DatabaseManagerTest { private MockedStatic hommrMockedStatic; @BeforeEach - void setUp() { + void setUp() throws SQLException { + // Use SQLite in-memory database for testing databaseManager = new DatabaseManager(); + databaseManager.init("jdbc:sqlite::memory:", "", ""); hommrMockedStatic = mockStatic(Hommr.class); hommrMockedStatic.when(Hommr::getInstance).thenReturn(mockPlugin); @@ -54,7 +52,6 @@ void setUp() { lenient().when(mockPlugin.getDataFolder()).thenReturn(tempDir.toFile()); lenient().when(mockPlugin.getConfig()).thenReturn(mockConfig); lenient().when(mockPlugin.getLogger()).thenReturn(mockLogger); - lenient().when(mockConfig.getString("database.type", "sqlite")).thenReturn("sqlite"); } @AfterEach @@ -69,17 +66,11 @@ void tearDown() { @Test void testInitWithSQLiteCreatesDatabase() { - databaseManager.init(); - assertNotNull(databaseManager.getHomeDao()); - File dbFile = new File(tempDir.toFile(), "homes.db"); - assertTrue(dbFile.exists()); } @Test void testSaveAndGetAllHomes() throws SQLException { - databaseManager.init(); - List homesToSave = new ArrayList<>(); homesToSave.add(createTestHome(UUID.randomUUID(), "home1")); homesToSave.add(createTestHome(UUID.randomUUID(), "home2")); @@ -94,8 +85,6 @@ void testSaveAndGetAllHomes() throws SQLException { @Test void testSaveAllHomesClearsExistingHomes() throws SQLException { - databaseManager.init(); - List firstBatch = new ArrayList<>(); firstBatch.add(createTestHome(UUID.randomUUID(), "home1")); firstBatch.add(createTestHome(UUID.randomUUID(), "home2")); @@ -108,13 +97,11 @@ void testSaveAllHomesClearsExistingHomes() throws SQLException { List retrievedHomes = databaseManager.getAllHomes(); assertEquals(1, retrievedHomes.size()); - assertEquals("home3", retrievedHomes.get(0).getName()); + assertEquals("home3", retrievedHomes.getFirst().getName()); } @Test void testSaveAllHomesPreservesHomeData() throws SQLException { - databaseManager.init(); - UUID ownerId = UUID.randomUUID(); Home originalHome = new Home( 0, @@ -133,7 +120,7 @@ void testSaveAllHomesPreservesHomeData() throws SQLException { List retrievedHomes = databaseManager.getAllHomes(); assertEquals(1, retrievedHomes.size()); - Home retrievedHome = retrievedHomes.get(0); + Home retrievedHome = retrievedHomes.getFirst(); assertEquals(ownerId, retrievedHome.getOwner()); assertEquals("testHome", retrievedHome.getName()); assertEquals("world", retrievedHome.getWorld()); @@ -146,8 +133,6 @@ void testSaveAllHomesPreservesHomeData() throws SQLException { @Test void testCloseDoesNotThrowException() { - databaseManager.init(); - assertDoesNotThrow(() -> databaseManager.close()); }