From c7db74d96cd5ef95dfebc53e245eae904cb7053c Mon Sep 17 00:00:00 2001 From: NovaFox161 Date: Mon, 2 Jan 2017 21:23:38 -0600 Subject: [PATCH] Start integration of MySQL database for storing settings. --- pom.xml | 6 + src/main/java/com/cloudcraftgaming/Main.java | 39 +++++- .../cloudcraftgaming/database/Database.java | 116 ++++++++++++++++++ .../database/DatabaseInfo.java | 33 +++++ .../com/cloudcraftgaming/database/MySQL.java | 83 +++++++++++++ .../com/cloudcraftgaming/database/SQLite.java | 53 ++++++++ .../eventlisteners/MessageListener.java | 17 +++ .../ConsoleCommandExecutor.java | 1 + .../internal/file/ReadFile.java | 75 +++++++++++ 9 files changed, 421 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/cloudcraftgaming/database/Database.java create mode 100644 src/main/java/com/cloudcraftgaming/database/DatabaseInfo.java create mode 100644 src/main/java/com/cloudcraftgaming/database/MySQL.java create mode 100644 src/main/java/com/cloudcraftgaming/database/SQLite.java create mode 100644 src/main/java/com/cloudcraftgaming/eventlisteners/MessageListener.java create mode 100644 src/main/java/com/cloudcraftgaming/internal/file/ReadFile.java diff --git a/pom.xml b/pom.xml index 423caf42..0ea472e6 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,12 @@ google-api-client 1.22.0 + + + mysql + mysql-connector-java + LATEST + diff --git a/src/main/java/com/cloudcraftgaming/Main.java b/src/main/java/com/cloudcraftgaming/Main.java index 7c56bbf3..11ac51f8 100644 --- a/src/main/java/com/cloudcraftgaming/Main.java +++ b/src/main/java/com/cloudcraftgaming/Main.java @@ -1,11 +1,18 @@ package com.cloudcraftgaming; +import com.cloudcraftgaming.database.DatabaseInfo; +import com.cloudcraftgaming.database.MySQL; +import com.cloudcraftgaming.eventlisteners.MessageListener; import com.cloudcraftgaming.internal.consolecommand.ConsoleCommandExecutor; +import com.cloudcraftgaming.internal.file.ReadFile; import sx.blah.discord.api.ClientBuilder; import sx.blah.discord.api.IDiscordClient; import sx.blah.discord.api.events.EventDispatcher; import sx.blah.discord.util.DiscordException; +import java.sql.Connection; +import java.sql.SQLException; + /** * Created by Nova Fox on 1/2/2017. * Website: www.cloudcraftgaming.com @@ -14,17 +21,23 @@ import sx.blah.discord.util.DiscordException; @SuppressWarnings("SameParameterValue") public class Main { public static IDiscordClient client; + public static DatabaseInfo databaseInfo; public static void main(String[] args) { - if (args.length < 1) // Needs a bot token provided - throw new IllegalArgumentException("The Bot Token has not be specified!"); + if (args.length < 2) // Needs a bot token provided + throw new IllegalArgumentException("The Bot Token & MySQL file has not be specified!"); client = createClient(args[0], true); if (client == null) throw new NullPointerException("Failed to log in! Client cannot be null!"); + //Connect to MySQL + MySQL mySQL = ReadFile.readDatabaseSettings(args[1]); + connectToMySQL(mySQL); + //Register events EventDispatcher dispatcher = client.getDispatcher(); + dispatcher.registerListener(new MessageListener()); //Accept commands ConsoleCommandExecutor.init(); @@ -44,4 +57,26 @@ public class Main { } return null; } + + private static void connectToMySQL(MySQL mySQL) { + try { + Connection mySQLConnection = mySQL.openConnection(); + databaseInfo = new DatabaseInfo(mySQL, mySQLConnection, mySQL.getPrefix()); + System.out.println("Connected to MySQL database!"); + } catch (Exception e) { + System.out.println("Failed to connect to MySQL database! Is it properly configured?"); + e.printStackTrace(); + } + } + + public static void disconnectFromMySQL() { + if (databaseInfo != null) { + try { + databaseInfo.getMySQL().closeConnection(); + System.out.println("Successfully disconnected from MySQL Database!"); + } catch (SQLException e) { + System.out.println("MySQL Connection may not have closed properly! Data may be invalidated!"); + } + } + } } \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/database/Database.java b/src/main/java/com/cloudcraftgaming/database/Database.java new file mode 100644 index 00000000..656a9535 --- /dev/null +++ b/src/main/java/com/cloudcraftgaming/database/Database.java @@ -0,0 +1,116 @@ +package com.cloudcraftgaming.database; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * Abstract Database class, serves as a base for any connection method (MySQL, + * SQLite, etc.) + * + * @author -_Husky_- + * @author tips48 + */ +@SuppressWarnings({"unused", "WeakerAccess"}) +public abstract class Database { + protected Connection connection; + + /** + * Creates a new Database + * + */ + protected Database() { + this.connection = null; + } + + /** + * Opens a connection with the database + * + * @return Opened connection + * @throws SQLException + * if the connection can not be opened + * @throws ClassNotFoundException + * if the driver cannot be found + */ + public abstract Connection openConnection() throws SQLException, ClassNotFoundException; + + /** + * Checks if a connection is open with the database + * + * @return true if the connection is open + * @throws SQLException + * if the connection cannot be checked + */ + public boolean checkConnection() throws SQLException { + return connection != null && !connection.isClosed(); + } + + /** + * Gets the connection with the database + * + * @return Connection with the database, null if none + */ + public Connection getConnection() { + return connection; + } + + /** + * Closes the connection with the database + * + * @return true if successful + * @throws SQLException + * if the connection cannot be closed + */ + public boolean closeConnection() throws SQLException { + if (connection == null) { + return false; + } + connection.close(); + return true; + } + + /** + * Executes a SQL Query
+ * + * If the connection is closed, it will be opened + * + * @param query + * Query to be run + * @return the results of the query + * @throws SQLException + * If the query cannot be executed + * @throws ClassNotFoundException + * If the driver cannot be found; see {@link #openConnection()} + */ + public ResultSet querySQL(String query) throws SQLException, ClassNotFoundException { + if (!checkConnection()) { + openConnection(); + } + Statement statement = connection.createStatement(); + + return statement.executeQuery(query); + } + + /** + * Executes an Update SQL Query
+ * See {@link java.sql.Statement#executeUpdate(String)}
+ * If the connection is closed, it will be opened + * + * @param query + * Query to be run + * @return Result Code, see {@link java.sql.Statement#executeUpdate(String)} + * @throws SQLException + * If the query cannot be executed + * @throws ClassNotFoundException + * If the driver cannot be found; see {@link #openConnection()} + */ + public int updateSQL(String query) throws SQLException, ClassNotFoundException { + if (!checkConnection()) { + openConnection(); + } + Statement statement = connection.createStatement(); + + return statement.executeUpdate(query); + } +} \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/database/DatabaseInfo.java b/src/main/java/com/cloudcraftgaming/database/DatabaseInfo.java new file mode 100644 index 00000000..7c134bcd --- /dev/null +++ b/src/main/java/com/cloudcraftgaming/database/DatabaseInfo.java @@ -0,0 +1,33 @@ +package com.cloudcraftgaming.database; + +import java.sql.Connection; + +/** + * Created by Nova Fox on 1/2/2017. + * Website: www.cloudcraftgaming.com + * For Project: DisCal + */ +@SuppressWarnings("unused") +public class DatabaseInfo { + private MySQL mySQL; + private Connection con; + private String prefix; + + public DatabaseInfo(MySQL _mySQL, Connection _con, String _prefix) { + mySQL = _mySQL; + con = _con; + prefix = _prefix; + } + + public MySQL getMySQL() { + return mySQL; + } + + public Connection getConnection() { + return con; + } + + public String getPrefix() { + return prefix; + } +} \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/database/MySQL.java b/src/main/java/com/cloudcraftgaming/database/MySQL.java new file mode 100644 index 00000000..6f992a9d --- /dev/null +++ b/src/main/java/com/cloudcraftgaming/database/MySQL.java @@ -0,0 +1,83 @@ +package com.cloudcraftgaming.database; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * Connects to and uses a MySQL database + * + * @author -_Husky_- + * @author tips48 + */ +@SuppressWarnings({"unused", "WeakerAccess"}) +public class MySQL extends Database { + private final String user; + private final String database; + private final String password; + private final String port; + private final String hostname; + private final String prefix; + + /** + * Creates a new MySQL instance + * + * @param hostname + * Name of the host + * @param port + * Port number + * @param username + * Username + * @param password + * Password + */ + public MySQL(String hostname, String port, String prefix, String username, + String password) { + this(hostname, port, null, prefix, username, password); + } + + /** + * Creates a new MySQL instance for a specific database + * + * @param hostname + * Name of the host + * @param port + * Port number + * @param database + * Database name + * @param username + * Username + * @param password + * Password + */ + public MySQL(String hostname, String port, String database, String prefix, String username, String password) { + this.hostname = hostname; + this.port = port; + this.database = database; + this.user = username; + this.password = password; + this.prefix = prefix; + } + + @Override + public Connection openConnection() throws SQLException, + ClassNotFoundException { + if (checkConnection()) { + return connection; + } + String connectionURL = "jdbc:mysql://" + + this.hostname + ":" + this.port; + if (database != null) { + connectionURL = connectionURL + "/" + this.database + "?autoReconnect=true&useSSL=false"; + } + + Class.forName("com.mysql.jdbc.Driver"); + connection = DriverManager.getConnection(connectionURL, + this.user, this.password); + return connection; + } + + public String getPrefix() { + return prefix; + } +} \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/database/SQLite.java b/src/main/java/com/cloudcraftgaming/database/SQLite.java new file mode 100644 index 00000000..7209a635 --- /dev/null +++ b/src/main/java/com/cloudcraftgaming/database/SQLite.java @@ -0,0 +1,53 @@ +package com.cloudcraftgaming.database; + +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * Connects to and uses a SQLite database + * + * @author tips48 + */ +@SuppressWarnings({"unused", "ResultOfMethodCallIgnored"}) +public class SQLite extends Database { + private final String dbLocation; + + /** + * Creates a new SQLite instance + * + * @param dbLocation Location of the Database (Must end in .db) + */ + public SQLite(String dbLocation) { + this.dbLocation = dbLocation; + } + + @Override + public Connection openConnection() throws SQLException, ClassNotFoundException { + if (checkConnection()) { + return connection; + } + + File dataFolder = new File("sqlite-db/"); + if (!dataFolder.exists()) { + dataFolder.mkdirs(); + } + + File file = new File(dataFolder, dbLocation); + if (!(file.exists())) { + try { + file.createNewFile(); + } catch (IOException e) { + System.out.println("Unable to create database!"); + } + } + Class.forName("org.sqlite.JDBC"); + connection = DriverManager + .getConnection("jdbc:sqlite:" + + dataFolder + "/" + + dbLocation); + return connection; + } +} \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/eventlisteners/MessageListener.java b/src/main/java/com/cloudcraftgaming/eventlisteners/MessageListener.java new file mode 100644 index 00000000..4165cdfc --- /dev/null +++ b/src/main/java/com/cloudcraftgaming/eventlisteners/MessageListener.java @@ -0,0 +1,17 @@ +package com.cloudcraftgaming.eventlisteners; + +import sx.blah.discord.api.events.EventSubscriber; +import sx.blah.discord.handle.impl.events.MessageReceivedEvent; +import sx.blah.discord.handle.obj.IMessage; + +/** + * Created by Nova Fox on 1/2/2017. + * Website: www.cloudcraftgaming.com + * For Project: DisCal + */ +public class MessageListener { + @EventSubscriber + public void onMessageEvent(MessageReceivedEvent event) { + IMessage msg = event.getMessage(); + } +} \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/internal/consolecommand/ConsoleCommandExecutor.java b/src/main/java/com/cloudcraftgaming/internal/consolecommand/ConsoleCommandExecutor.java index 50ec669f..fab797d8 100644 --- a/src/main/java/com/cloudcraftgaming/internal/consolecommand/ConsoleCommandExecutor.java +++ b/src/main/java/com/cloudcraftgaming/internal/consolecommand/ConsoleCommandExecutor.java @@ -53,6 +53,7 @@ public class ConsoleCommandExecutor { } catch (DiscordException e) { //No need to print, exiting anyway. } + Main.disconnectFromMySQL(); System.exit(0); } } \ No newline at end of file diff --git a/src/main/java/com/cloudcraftgaming/internal/file/ReadFile.java b/src/main/java/com/cloudcraftgaming/internal/file/ReadFile.java new file mode 100644 index 00000000..22b5706f --- /dev/null +++ b/src/main/java/com/cloudcraftgaming/internal/file/ReadFile.java @@ -0,0 +1,75 @@ +package com.cloudcraftgaming.internal.file; + +import com.cloudcraftgaming.database.MySQL; + +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.InputStreamReader; + +/** + * Created by Nova Fox on 1/2/2017. + * Website: www.cloudcraftgaming.com + * For Project: DisCal + */ +public class ReadFile { + + /** + * To prevent the highly sensitive data from being hard coded into the .jar. + * This will read a .txt file with the following information encoded in it. + * (In order, one per line): + * Hostname, Port, Database, Prefix, Username, Password + * + * @param fileAndPath the path and file of the file to read from. + */ + public static MySQL readDatabaseSettings(String fileAndPath) { + try { + // Open the file that is the first + // command line parameter + FileInputStream fstream = new FileInputStream(fileAndPath); + // Get the object of DataInputStream + DataInputStream in = new DataInputStream(fstream); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String strLine; + //Read File Line By Line + String hostName = null; + String port = null; + String database = null; + String prefix = null; + String user = null; + String pass = null; + + int line = 0; + while ((strLine = br.readLine()) != null) { + if (line == 0) { + hostName = strLine; + } + if (line == 1) { + port = strLine; + } + if (line == 2) { + database = strLine; + } + if (line == 3) { + prefix = strLine; + } + if (line == 4) { + user = strLine; + } + if (line == 5) { + pass = strLine; + } + line++; + + } + //Close the input stream + in.close(); + + //Return a new MySQL object + return new MySQL(hostName, port, database, prefix, user, pass); + }catch (Exception e){//Catch exception if any + System.err.println("Error: " + e.getMessage()); + } + return null; + } +} \ No newline at end of file