package xyz.veronie.bgg.localdb; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import xyz.veronie.bgg.result.ThingMetaData; public class SqliteController { private static final SqliteController dbcontroller = new SqliteController(); private static Connection connection; public static final String DB_PATH = System.getProperty("user.home") + "/" + "bggtool.db"; static { try { Class.forName("org.sqlite.JDBC"); } catch (ClassNotFoundException e) { System.err.println("Error while loading JDBC driver"); e.printStackTrace(); } } private SqliteController() { initDBConnection(); } public static SqliteController getInstance() { return dbcontroller; } private void initDBConnection() { try { if (connection != null) return; System.out.println("Creating Connection to Database..."); String filename = System.getProperty("user.home") + "/bggtool.db"; connection = DriverManager.getConnection("jdbc:sqlite:" + filename); if (!connection.isClosed()) System.out.println("...Connection established"); } catch (SQLException e) { throw new RuntimeException(e); } Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { if (!connection.isClosed() && connection != null) { connection.close(); if (connection.isClosed()) System.out.println("Connection to Database closed"); } } catch (SQLException e) { e.printStackTrace(); } } }); } public void createSchema() { try { Statement stmt = connection.createStatement(); stmt.executeUpdate("DROP TABLE IF EXISTS Thing;"); stmt.executeUpdate("DROP TABLE IF EXISTS ThingList"); stmt.executeUpdate("DROP TABLE IF EXISTS ThingListToThing"); stmt.executeUpdate("CREATE TABLE Thing (ThingId INTEGER PRIMARY KEY, Name, ImgUrl, ThumbUrl, Comment, NumPlays);"); stmt.executeUpdate("CREATE TABLE ThingList (ListId INTEGER PRIMARY KEY, Name) ON DELETE CASCADE;"); stmt.executeUpdate("CREATE UNIQUE INDEX idx1 ON ThingList(Name)"); stmt.executeUpdate("CREATE TABLE ThingListToThing (ListId, ThingId, FOREIGN KEY (ListId) REFERENCES ThingList(ListId), FOREIGN KEY (ThingId) REFERENCES Thing(ThingId));"); stmt.executeUpdate("CREATE UNIQUE INDEX idx2 ON ThingListToThing(ListId, ThingId)"); } catch (SQLException e) { System.err.println("Couldn't create Schema"); e.printStackTrace(); } } public void openThingList(String name) { try { Statement stmt = connection.createStatement(); // insert new thing list if one with that name does not exist already stmt.executeQuery("INSERT INTO ThingList (name) VALUES ('" + name + "');"); } catch (SQLException e) { System.err.println("Couldn't add to thing list with handle " + name); e.printStackTrace(); } } public void addToThingList(String name, List things) { try { Statement stmt = connection.createStatement(); ResultSet res = stmt.executeQuery("SELECT ListId from ThingList where name = '" + name + "'"); int listId = res.getInt(0); PreparedStatement thingStatement = connection .prepareStatement("INSERT INTO Thing VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT REPLACE;"); PreparedStatement listToThingStatement = connection .prepareStatement("INSERT INTO ThingListToThing VALUES (?, ?)"); for (ThingMetaData thing : things) { thingStatement.setInt(1, thing.getId()); thingStatement.setString(2, thing.getName()); thingStatement.setString(3, thing.getImgURL()); thingStatement.setString(4, thing.getThumbURL()); thingStatement.setString(5, thing.getComment()); thingStatement.setInt(6, thing.getNumPlays()); thingStatement.addBatch(); // get generated id ResultSet keys = thingStatement.getGeneratedKeys(); int thingId = keys.getInt(0); listToThingStatement.setInt(0, listId); listToThingStatement.setInt(1, thingId); listToThingStatement.addBatch(); } connection.setAutoCommit(false); thingStatement.executeBatch(); connection.setAutoCommit(true); } catch (SQLException e) { System.err.println("Couldn't add to thing list with handle " + name); e.printStackTrace(); } } }