NounsPicker/src/main/java/wtf/beatrice/nounspicker/utils/DatabaseManager.java

370 lines
11 KiB
Java

package wtf.beatrice.nounspicker.utils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class DatabaseManager
{
private final static String sqliteURL = "jdbc:sqlite:%path%";
private Connection dbConnection = null;
private ConsoleLogger logger;
private final String dbPath;
public DatabaseManager(String dbPath)
{
this.dbPath = dbPath;
logger = new ConsoleLogger(getClass());
}
public boolean connect()
{
String url = sqliteURL.replace("%path%", dbPath);
if(!close()) return false;
try {
dbConnection = DriverManager.getConnection(url);
logger.log("Database connection established!");
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public boolean close()
{
if (dbConnection != null)
{
try {
if(!dbConnection.isClosed())
{
dbConnection.close();
}
} catch (SQLException e) {
e.printStackTrace();
return false;
}
dbConnection = null;
}
return true;
}
public boolean initDb()
{
List<String> newTables = new ArrayList<>();
newTables.add("CREATE TABLE IF NOT EXISTS players (" +
"player TEXT NOT NULL," +
"main_pronoun_id INTEGER DEFAULT -1," +
"secondary_pronoun_id INTEGER DEFAULT -1" +
");");
newTables.add("CREATE TABLE IF NOT EXISTS pronouns (" +
"pronoun TEXT," +
"format TEXT," +
"id INTEGER" +
");");
for(String sql : newTables)
{
try (Statement stmt = dbConnection.createStatement()) {
// execute the statement
stmt.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
return true;
}
/**
* DB STRUCTURE
* TABLE 1: PLAYERS
* -----------------------------------------------------------------
* | name | main_pronoun_id | secondary_pronoun_id |
* -----------------------------------------------------------------
* | AstroBea | 1 | 2 |
* | Notch | 3 | 1 |
* -----------------------------------------------------------------
*
*
* TABLE 2: PRONOUNS
* --------------------------------------
* | pronoun | id | format |
* --------------------------------------
* | she | 1 | She |
* | her | 2 | Her |
* | he | 3 | He |
* --------------------------------------
*
*/
public int getPronounId(String pronoun) {
String query = "SELECT id " +
"FROM pronouns " +
"WHERE pronoun = ? " +
"LIMIT 1;";
try (PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setString(1, pronoun);
ResultSet resultSet = pStatement.executeQuery();
while(resultSet.next())
{
return resultSet.getInt("id");
}
} catch (SQLException e)
{
e.printStackTrace();
}
return -1;
}
public boolean isPronounValid(String pronoun) {
return getPronounId(pronoun) >= 0;
}
public boolean addNewPronoun(String pronoun, String format) {
String query = "INSERT INTO pronouns " +
"( pronoun, format, id) VALUES " +
" (?, ?, ?);";
int pronounId = getHighestPronounId() + 1;
try (PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setString(1, pronoun);
pStatement.setString(2, format);
pStatement.setInt(3, pronounId);
pStatement.executeUpdate();
// add to cache
Cache.pronouns.add(pronoun);
// announce success
return true;
} catch (SQLException e)
{
e.printStackTrace();
}
return false;
}
public int getHighestPronounId() {
String query = "SELECT id " +
"FROM pronouns " +
"ORDER BY id DESC " +
"LIMIT 1";
try (Statement stmt = dbConnection.createStatement()) {
ResultSet rSet = stmt.executeQuery(query);
if(rSet.isClosed()) return -1;
return rSet.getInt("id");
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
public boolean deletePronoun(String pronoun) {
// get the pronoun id (so we can remove it from users)
int pronounId = getPronounId(pronoun);
// delete it from the list of pronouns
String query = "DELETE FROM pronouns " +
"WHERE pronoun = ?;";
try (PreparedStatement preparedStatement = dbConnection.prepareStatement(query)) {
preparedStatement.setString(1, pronoun);
preparedStatement.execute();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
// set players who had this pronoun to -1, which means no pronoun
List<String> queries = new ArrayList<>();
queries.add("UPDATE players " +
"SET main_pronoun_id = -1 " +
"WHERE main_pronoun_id = " + pronounId + ";");
queries.add("UPDATE players " +
"SET secondary_pronoun_id = -1 " +
"WHERE secondary_pronoun_id = " + pronounId + ";");
for(String q : queries) {
try(Statement stmt = dbConnection.createStatement()) {
stmt.executeUpdate(q);
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
// remove from cache
Cache.pronouns.remove(pronoun);
// announce success
return true;
}
public boolean setPlayerPronouns(String playerName, String mainPronoun, String secondaryPronoun) {
// if the player is not in the table, add them
if(!isInTable(playerName))
{
String query = "INSERT INTO players (player) VALUES (?);";
try(PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setString(1, playerName);
pStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
// get pronouns ids
int mainPronounId = getPronounId(mainPronoun);
int secondaryPronounId = getPronounId(secondaryPronoun);
// update player values in the table
String query = "UPDATE players " +
"SET (main_pronoun_id, secondary_pronoun_id) = (?,?) " +
"WHERE player = ?;";
try(PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setInt(1, mainPronounId);
pStatement.setInt(2, secondaryPronounId);
pStatement.setString(3, playerName);
pStatement.executeUpdate();
return true;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public String getPronounFormat(int pronounId) {
String query = "SELECT format FROM pronouns " +
"WHERE id = " + pronounId + " " +
"LIMIT 1;";
try (Statement stmt = dbConnection.createStatement())
{
ResultSet rSet = stmt.executeQuery(query);
return rSet.getString("format");
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public boolean isInTable(String playerName) {
String query = "SELECT player FROM players " +
"WHERE player = ? " +
"LIMIT 1;";
try (PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setString(1, playerName);
ResultSet rSet = pStatement.executeQuery();
if(rSet.isClosed()) return false;
while(rSet.next())
{
if(rSet.getString("player").equals(playerName)) return true;
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public boolean updatePronounFormat(int pronounId, String newFormat) {
String query = "UPDATE pronouns SET format=? " +
"WHERE id=?;";
try(PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setString(1, newFormat);
pStatement.setInt(2, pronounId);
pStatement.executeUpdate();
return true;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public List<String> getAllPronouns() {
String query = "SELECT pronoun FROM pronouns;";
List<String> allPronouns = new ArrayList<>();
try(Statement stmt = dbConnection.createStatement()) {
ResultSet rSet = stmt.executeQuery(query);
if(rSet.isClosed()) return allPronouns;
while(rSet.next()) {
allPronouns.add(rSet.getString("pronoun"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return allPronouns;
}
public int getPlayerPronounId(String playerName, int priority) {
if(!isInTable(playerName)) return -1;
String query = "SELECT ? FROM players " +
"WHERE player = ? " +
"LIMIT 1";
// instead of making two separate methods for main and secondary pronouns (copying a lot of code),
// we just set up a priority value that decides whether to pick the main or secondary pronoun.
// this also helps in case we want to allow for more than two pronouns in the future.
String priorityStr = "";
if(priority == 0) priorityStr = "main_pronoun_id";
else if(priority == 1) priorityStr = "secondary_pronoun_id";
try(PreparedStatement pStatement = dbConnection.prepareStatement(query)) {
pStatement.setString(1, priorityStr);
pStatement.setString(2, playerName);
ResultSet rSet = pStatement.executeQuery();
if(rSet.isClosed()) return -1;
while(rSet.next()) return rSet.getInt(priorityStr);
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
}