Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alex
2019-06-03 00:33:51 -04:00
16 changed files with 280 additions and 110 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ public class CommandBoop extends Command
{ {
super(level, rating); super(level, rating);
boopTracker = new BoopTracker(); boopTracker = new BoopTracker();
DatabaseManager.instance.Register(boopTracker); DatabaseManager.instance.globalRegister(boopTracker);
} }
@Override @Override
+1 -1
View File
@@ -24,7 +24,7 @@ public class CommandDBFlush extends Command
@Override @Override
public void OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res) public void OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res)
{ {
int numUpdated = DatabaseManager.instance.Upkeep(); int numUpdated = DatabaseManager.instance.upkeep();
KittyEmbed embed = new KittyEmbed(); KittyEmbed embed = new KittyEmbed();
embed.title = "Database queue flushed"; embed.title = "Database queue flushed";
+2 -2
View File
@@ -33,9 +33,9 @@ public class CommandDBStats extends Command
{ {
KittyEmbed embed = new KittyEmbed(); KittyEmbed embed = new KittyEmbed();
embed.title = "Database Info"; embed.title = "Database Info";
embed.descriptionText = "**Tracked Items:** " + DatabaseManager.instance.GetTrackedObjectsSize(); embed.descriptionText = "**Tracked Items:** " + DatabaseManager.instance.getTrackedObjectsSize();
embed.descriptionText += "\n"; embed.descriptionText += "\n";
embed.descriptionText += "**Last Upkeep:** " + dateFormat.format(DatabaseManager.instance.GetLastUpkeep()) + " UTC-7"; embed.descriptionText += "**Last Upkeep:** " + dateFormat.format(DatabaseManager.instance.getLastUpkeep()) + " UTC-7";
embed.color = new Color(7*16, 8*16, 9*16); embed.color = new Color(7*16, 8*16, 9*16);
res.CallEmbed(embed); res.CallEmbed(embed);
+1 -1
View File
@@ -47,7 +47,7 @@ public class CommandShutdown extends Command
{ {
// Force upkeep, this works so long as upkeep is on the main thread. // Force upkeep, this works so long as upkeep is on the main thread.
res.CallImmediate(LocStrings.Stub("ShutdownSafe")); res.CallImmediate(LocStrings.Stub("ShutdownSafe"));
DatabaseManager.instance.Upkeep(); DatabaseManager.instance.upkeep();
GlobalLog.Warn(LogFilter.Command, LocStrings.Lookup("ShutdownSafe")); GlobalLog.Warn(LogFilter.Command, LocStrings.Lookup("ShutdownSafe"));
System.exit(0); System.exit(0);
@@ -13,19 +13,21 @@ import utils.LogFilter;
// This is where we put everything and swap out the moving parts, // This is where we put everything and swap out the moving parts,
// ie MySQL, PostgreSQL, SQLite, etc... // ie MySQL, PostgreSQL, SQLite, etc...
// //
// Right now this can be messed up with SQL injection stuff if users // This isn't overly flexible though,
// are allowed to directly touch data. Leaving it like this temporarily, public class DatabaseDriverKeyValue
// and is for prototyping only!
public class DatabaseDriver
{ {
// Config and local varaibles // Config and local varaibles
private JDBCDriver driver; private JDBCDriver driver;
private final String globalTableName = "kitty_globals"; private final String tableName; // Table name
private final String globalKeyName = "GlobalKey"; private final String keyColumnName; // Column name for the key
private final String globalValueName = "GlobalValue"; private final String valueColumnName; // Column name for the value
public DatabaseDriver() public DatabaseDriverKeyValue(String tableName, String keyColumnName, String valueColumnName)
{ {
this.tableName = tableName;
this.keyColumnName = keyColumnName;
this.valueColumnName = valueColumnName;
driver = null; driver = null;
} }
@@ -47,7 +49,7 @@ public class DatabaseDriver
} }
// Verify tables we want to use exist // Verify tables we want to use exist
EnsureTableExists(globalTableName, globalKeyName, globalValueName); // General table. Do not remove. EnsureTableExists(tableName, keyColumnName, valueColumnName); // General table. Do not remove.
return true; return true;
} }
@@ -87,7 +89,7 @@ public class DatabaseDriver
// Prototype formatting for key updating // Prototype formatting for key updating
private void UpdateKey(String key, String value) private void UpdateKey(String key, String value)
{ {
String command = "UPDATE " + globalTableName + " SET " + globalValueName + " = ? WHERE " + globalKeyName + " = ?"; String command = "UPDATE " + tableName + " SET " + valueColumnName + " = ? WHERE " + keyColumnName + " = ?";
boolean status = driver.ExecuteStatement(JDBCStatementType.Update, command, new String[] { value, key }); boolean status = driver.ExecuteStatement(JDBCStatementType.Update, command, new String[] { value, key });
GlobalLog.Log(LogFilter.Database, "UpdateKey status: " + status); GlobalLog.Log(LogFilter.Database, "UpdateKey status: " + status);
} }
@@ -95,7 +97,7 @@ public class DatabaseDriver
// Protoype updating for seeing if a key exists // Protoype updating for seeing if a key exists
private boolean HasKey(String key) private boolean HasKey(String key)
{ {
String command = "SELECT COUNT(1) as count FROM " + globalTableName + " WHERE " + globalKeyName + " = ?"; String command = "SELECT COUNT(1) as count FROM " + tableName + " WHERE " + keyColumnName + " = ?";
ResultSet set = driver.ExecuteReturningStatement(JDBCStatementType.Select, command, new String[] { key }); ResultSet set = driver.ExecuteReturningStatement(JDBCStatementType.Select, command, new String[] { key });
String out = ResultAsString(set, "count"); String out = ResultAsString(set, "count");
return out.charAt(0) == '1'; return out.charAt(0) == '1';
@@ -104,7 +106,7 @@ public class DatabaseDriver
// Prototype for getting a key // Prototype for getting a key
private String GetKey(String key) private String GetKey(String key)
{ {
String command = "SELECT " + globalValueName + " as searchedKey FROM " + globalTableName +" WHERE " + globalKeyName + " = ?"; String command = "SELECT " + valueColumnName + " as searchedKey FROM " + tableName +" WHERE " + keyColumnName + " = ?";
ResultSet set = driver.ExecuteReturningStatement(JDBCStatementType.Select, command, new String[] { key }); ResultSet set = driver.ExecuteReturningStatement(JDBCStatementType.Select, command, new String[] { key });
return ResultAsString(set, "searchedKey"); return ResultAsString(set, "searchedKey");
} }
@@ -112,7 +114,7 @@ public class DatabaseDriver
// Prototype for creating a key // Prototype for creating a key
private void CreateKey(String key, String value) private void CreateKey(String key, String value)
{ {
String command = "INSERT INTO " + globalTableName + " (GlobalKey, GlobalValue) VALUES (?, ?)"; String command = "INSERT INTO " + tableName + " (GlobalKey, GlobalValue) VALUES (?, ?)";
boolean status = driver.ExecuteStatement(JDBCStatementType.Insert, command, new String[] { key, value }); boolean status = driver.ExecuteStatement(JDBCStatementType.Insert, command, new String[] { key, value });
GlobalLog.Log(LogFilter.Database, "CreateKey status: " + status); GlobalLog.Log(LogFilter.Database, "CreateKey status: " + status);
} }
+124 -25
View File
@@ -5,16 +5,33 @@ import java.util.Vector;
import utils.GlobalLog; import utils.GlobalLog;
import utils.LogFilter; import utils.LogFilter;
// This wrangles all of the differentiated storage systems. Internally, these may be tables,
// different databases, etc -- the goal is that it's abstracted away.
//
// TODO: Implement intermediate structure on account of duplicate patterns showing up.
public class DatabaseManager public class DatabaseManager
{ {
// Singleton accessor // Singleton accessor
public static DatabaseManager instance = null; public static DatabaseManager instance = null;
// Database names and configs
private final String globalTableName = "kitty_globals"; // Table name
private final String globalKeyColumnName = "GlobalKey"; // Column name for the key
private final String globalValueColumnName = "GlobalValue"; // Column name for the value
private final String characterTableName = "kitty_characters"; // Table name
private final String characterKeyColumnName = "CharacterKey"; // Column name for the key
private final String characterValueColumnName = "CharacterValue"; // Column name for the value
// Private internal variables // Private internal variables
private Vector<DatabaseTrackedObject> trackedObjects; private Vector<DatabaseTrackedObject> globalDataTrackedObjects;
private DatabaseDriver driver; private Vector<DatabaseTrackedObject> characterDataTrackedObjects;
private DatabaseDriverKeyValue globalDataDriver;
private DatabaseDriverKeyValue characterDataDriver;
private Date lastUpkeep; private Date lastUpkeep;
// Constructor to enforce singleton.
public DatabaseManager() public DatabaseManager()
{ {
GlobalLog.Log(LogFilter.Database, "Creating database manager"); GlobalLog.Log(LogFilter.Database, "Creating database manager");
@@ -29,75 +46,157 @@ public class DatabaseManager
return; return;
} }
// Initialize variables
lastUpkeep = new Date(); lastUpkeep = new Date();
trackedObjects = new Vector<DatabaseTrackedObject>(); globalDataTrackedObjects = new Vector<DatabaseTrackedObject>();
driver = new DatabaseDriver(); characterDataTrackedObjects = new Vector<DatabaseTrackedObject>();
if(driver.Connect() == false) // Initialize data sets
globalDataDriver = new DatabaseDriverKeyValue(globalTableName, globalKeyColumnName, globalValueColumnName);
characterDataDriver = new DatabaseDriverKeyValue(characterTableName, characterKeyColumnName, characterValueColumnName);
// Connect data sets
if(globalDataDriver.Connect() == false)
{ {
GlobalLog.Error("Database failed to connect. Currently, without the DB, this bot can not run."); GlobalLog.Error("Global database failed to connect. Without this DB, this bot can not run.");
System.exit(1);
}
if(characterDataDriver.Connect() == false)
{
GlobalLog.Error("Character database failed to connect. Without this DB, this bot can not run.");
System.exit(1); System.exit(1);
} }
} }
// Thumbs through registered objects and syncs them with the database. // Thumbs through registered objects and syncs them with the database.
// Consider moving this operation to a separate thread. // Consider moving this operation to a separate thread.
public int Upkeep() public int upkeep()
{ {
synchronized(trackedObjects) int total = 0;
total += globalDataUpkeep();
total += characterDataUpkeep();
lastUpkeep = new Date();
return total;
}
// Global data management and updating, returns how many items were updated.
private int globalDataUpkeep()
{
synchronized(globalDataTrackedObjects)
{ {
int numUpdated = 0; int numUpdated = 0;
for(int i = 0 ; i < trackedObjects.size(); ++i) for(int i = 0; i < globalDataTrackedObjects.size(); ++i)
{ {
DatabaseTrackedObject dto = trackedObjects.get(i); DatabaseTrackedObject dto = globalDataTrackedObjects.get(i);
if(dto.IsDirty()) if(dto.IsDirty())
{ {
SetRemoteValue(dto.identifier, dto.Serialize()); globalSetRemoteValue(dto.identifier, dto.Serialize());
dto.Resolve(); dto.Resolve();
++numUpdated; ++numUpdated;
} }
} }
lastUpkeep = new Date(); return numUpdated;
}
}
// Character data management and updating, returns how many items were updated.
private int characterDataUpkeep()
{
synchronized(characterDataTrackedObjects)
{
int numUpdated = 0;
for(int i = 0; i < characterDataTrackedObjects.size(); ++i)
{
DatabaseTrackedObject dto = characterDataTrackedObjects.get(i);
if(dto.IsDirty())
{
characterSetRemoteValue(dto.identifier, dto.Serialize());
dto.Resolve();
++numUpdated;
}
}
return numUpdated; return numUpdated;
} }
} }
public void Register(DatabaseTrackedObject tracked)
/////////////////
// Global Data //
/////////////////
public void globalRegister(DatabaseTrackedObject tracked)
{ {
synchronized(trackedObjects) synchronized(globalDataTrackedObjects)
{ {
trackedObjects.add(tracked); globalDataTrackedObjects.add(tracked);
tracked.DeSerialzie(GetRemoteValue(tracked.identifier)); tracked.DeSerialzie(globalGetRemoteValue(tracked.identifier));
} }
} }
public String GetRemoteValue(String key) private String globalGetRemoteValue(String key)
{ {
synchronized(driver) synchronized(globalDataDriver)
{ {
return driver.CreateGetKey(key); return globalDataDriver.CreateGetKey(key);
} }
} }
public void SetRemoteValue(String key, String value) private void globalSetRemoteValue(String key, String value)
{ {
synchronized(driver) synchronized(globalDataDriver)
{ {
driver.CreateSetKey(key, value); globalDataDriver.CreateSetKey(key, value);
} }
} }
public Date GetLastUpkeep()
////////////////////
// Character Data //
////////////////////
public void characterRegister(DatabaseTrackedObject tracked)
{
synchronized(characterDataTrackedObjects)
{
characterDataTrackedObjects.add(tracked);
tracked.DeSerialzie(characterGetRemoteValue(tracked.identifier));
}
}
private String characterGetRemoteValue(String key)
{
synchronized(characterDataDriver)
{
return characterDataDriver.CreateGetKey(key);
}
}
private void characterSetRemoteValue(String key, String value)
{
synchronized(characterDataDriver)
{
characterDataDriver.CreateSetKey(key, value);
}
}
///////////////////////
// Utility functions //
///////////////////////
public Date getLastUpkeep()
{ {
return lastUpkeep; return lastUpkeep;
} }
public int GetTrackedObjectsSize() public int getTrackedObjectsSize()
{ {
return trackedObjects.size(); return globalDataTrackedObjects.size();
} }
} }
+13 -4
View File
@@ -4,7 +4,7 @@ package core;
// have their data populated from database entries. // have their data populated from database entries.
public abstract class DatabaseTrackedObject public abstract class DatabaseTrackedObject
{ {
private boolean isDirty; private Boolean isDirty;
public final String identifier; public final String identifier;
public DatabaseTrackedObject(String identifier) public DatabaseTrackedObject(String identifier)
@@ -15,17 +15,26 @@ public abstract class DatabaseTrackedObject
public final boolean IsDirty() public final boolean IsDirty()
{ {
return isDirty; synchronized(isDirty)
{
return isDirty;
}
} }
public final void MarkDirty() public final void MarkDirty()
{ {
isDirty = true; synchronized(isDirty)
{
isDirty = true;
}
} }
public final void Resolve() public final void Resolve()
{ {
isDirty = false; synchronized(isDirty)
{
isDirty = false;
}
} }
// Consider an object factory instead of dedicated serialization methods // Consider an object factory instead of dedicated serialization methods
+3 -3
View File
@@ -131,7 +131,7 @@ public class ObjectBuilderFactory
{ {
// Construct a new guild with defaults // Construct a new guild with defaults
guild = new KittyGuild(uid, new AdminControl(event.getGuild()), emotesString); guild = new KittyGuild(uid, new AdminControl(event.getGuild()), emotesString);
DatabaseManager.instance.Register(guild); DatabaseManager.instance.globalRegister(guild);
guildCache.put(uid, guild); guildCache.put(uid, guild);
} }
} }
@@ -241,7 +241,7 @@ public class ObjectBuilderFactory
String discordID = event.getMember().getUser().getId(); String discordID = event.getMember().getUser().getId();
String avatarID = event.getAuthor().getAvatarUrl(); String avatarID = event.getAuthor().getAvatarUrl();
user = new KittyUser(name, guild, role, uid, avatarID, discordID); user = new KittyUser(name, guild, role, uid, avatarID, discordID);
DatabaseManager.instance.Register(user); DatabaseManager.instance.globalRegister(user);
userCache.put(uid, user); userCache.put(uid, user);
} }
} }
@@ -285,7 +285,7 @@ public class ObjectBuilderFactory
KittyRole role = KittyRole.General; KittyRole role = KittyRole.General;
KittyGuild guild = guildCache.get(guildID); KittyGuild guild = guildCache.get(guildID);
user = new KittyUser(name, guild, role, uid, avatarID, discordID); user = new KittyUser(name, guild, role, uid, avatarID, discordID);
DatabaseManager.instance.Register(user); DatabaseManager.instance.globalRegister(user);
userCache.put(uid, user); userCache.put(uid, user);
} }
} }
+2 -2
View File
@@ -35,8 +35,8 @@ public class KittyGuild extends DatabaseTrackedObject
private void RegisterTrackedObjects() private void RegisterTrackedObjects()
{ {
DatabaseManager.instance.Register(roleList); DatabaseManager.instance.globalRegister(roleList);
DatabaseManager.instance.Register(beans); DatabaseManager.instance.globalRegister(beans);
} }
// Default content for a guild // Default content for a guild
+2 -4
View File
@@ -17,8 +17,7 @@ import utils.LogFilter;
// //
public class KittyTrackedLong extends DatabaseTrackedObject public class KittyTrackedLong extends DatabaseTrackedObject
{ {
private long tracked; // Tracked value private long tracked; // Tracked value
private final String databaseID; // in-database ID of this value
// Config // Config
private final static String differentiator = "long-"; private final static String differentiator = "long-";
@@ -26,7 +25,6 @@ public class KittyTrackedLong extends DatabaseTrackedObject
public KittyTrackedLong(String readableName, String UniqueID) public KittyTrackedLong(String readableName, String UniqueID)
{ {
super(differentiator + readableName + UniqueID); super(differentiator + readableName + UniqueID);
databaseID = differentiator + readableName + UniqueID;
} }
public long Add(long toAdd) public long Add(long toAdd)
@@ -73,7 +71,7 @@ public class KittyTrackedLong extends DatabaseTrackedObject
catch(Exception e) catch(Exception e)
{ {
tracked = 0; tracked = 0;
GlobalLog.Error(LogFilter.Core, "Falling back to default of 0 due to failure to deserialize long with database ID " + databaseID); GlobalLog.Error(LogFilter.Core, "Falling back to default of 0 due to failure to deserialize long with database ID " + identifier);
} }
} }
else else
@@ -0,0 +1,58 @@
package dataStructures;
import core.DatabaseTrackedObject;
import utils.GlobalLog;
import utils.LogFilter;
public class KittyTrackedString extends DatabaseTrackedObject
{
private String trackedString; // This is the string tracked in the database
private final static String differentiator = "string-"; // Lends a very slightly human-readable label to the database key
// Constructor with unique id and readable name
public KittyTrackedString(String readableName, String UniqueID)
{
super(differentiator + readableName + UniqueID);
}
// Sets the value of the string and marks it as dirty
public void set(String newValue)
{
synchronized(trackedString)
{
trackedString = newValue;
MarkDirty();
}
}
// Returns string. The string is copied because it is immutable.
public String get()
{
synchronized(trackedString)
{
return trackedString;
}
}
@Override
public String Serialize()
{
return trackedString;
}
@Override
public void DeSerialzie(String string)
{
if(string != null && !string.isEmpty())
{
trackedString = string;
}
else
{
GlobalLog.Log(LogFilter.Database, "String had null or empty value with identifier: " + identifier);
string = "";
MarkDirty();
}
}
}
+11 -15
View File
@@ -5,13 +5,10 @@ import java.util.Vector;
import core.DatabaseTrackedObject; import core.DatabaseTrackedObject;
// Acts as a proxy of sorts for the allowedRole arraylist, keeping it tracked for a specific guild.
@SuppressWarnings("unused")
public class KittyTrackedVector extends DatabaseTrackedObject public class KittyTrackedVector extends DatabaseTrackedObject
{ {
// Variables // Variables
private Vector<String> allowedRole = new Vector<String>(); private Vector<String> trackedVector = new Vector<String>();
private final String databaseID; // in-database ID of this value
private final static String delimiter = "\n"; private final static String delimiter = "\n";
private final static String split = "\\n"; private final static String split = "\\n";
@@ -21,14 +18,13 @@ public class KittyTrackedVector extends DatabaseTrackedObject
public KittyTrackedVector(String readableName, String UniqueID) public KittyTrackedVector(String readableName, String UniqueID)
{ {
super(differentiator + readableName + UniqueID); super(differentiator + readableName + UniqueID);
databaseID = differentiator + readableName + UniqueID;
} }
// See if the string is contined in the vector, regardless of case. // See if the string is contined in the vector, regardless of case.
public boolean containsIgnoreCase(String str) public boolean containsIgnoreCase(String str)
{ {
Iterator<String> value = allowedRole.iterator(); Iterator<String> value = trackedVector.iterator();
while (value.hasNext()) while (value.hasNext())
{ {
@@ -42,33 +38,33 @@ public class KittyTrackedVector extends DatabaseTrackedObject
// Mirrored behavior // Mirrored behavior
public boolean contains(String str) public boolean contains(String str)
{ {
return allowedRole.contains(str); return trackedVector.contains(str);
} }
public void add(String str) public void add(String str)
{ {
allowedRole.add(str); trackedVector.add(str);
this.MarkDirty(); this.MarkDirty();
} }
public boolean isEmpty() public boolean isEmpty()
{ {
return allowedRole.isEmpty(); return trackedVector.isEmpty();
} }
public int size() public int size()
{ {
return allowedRole.size(); return trackedVector.size();
} }
public String get(int index) public String get(int index)
{ {
return allowedRole.get(index); return trackedVector.get(index);
} }
public void remove(String str) public void remove(String str)
{ {
allowedRole.remove(str); trackedVector.remove(str);
this.MarkDirty(); this.MarkDirty();
} }
@@ -78,12 +74,12 @@ public class KittyTrackedVector extends DatabaseTrackedObject
{ {
String toSerialize = ""; String toSerialize = "";
for(int i = 0; i < allowedRole.size(); ++i) for(int i = 0; i < trackedVector.size(); ++i)
{ {
if(i != 0) if(i != 0)
toSerialize += delimiter; toSerialize += delimiter;
toSerialize += allowedRole.get(i); toSerialize += trackedVector.get(i);
} }
return toSerialize; return toSerialize;
@@ -100,7 +96,7 @@ public class KittyTrackedVector extends DatabaseTrackedObject
String[] rolesSplit = string.split(split); String[] rolesSplit = string.split(split);
for(int i = 0; i < rolesSplit.length; ++i) for(int i = 0; i < rolesSplit.length; ++i)
allowedRole.add(rolesSplit[i]); trackedVector.add(rolesSplit[i]);
} }
} }
} }
+7 -7
View File
@@ -9,13 +9,13 @@ import utils.LogFilter;
// two unique user objects associated with them. // two unique user objects associated with them.
public class KittyUser extends DatabaseTrackedObject public class KittyUser extends DatabaseTrackedObject
{ {
public KittyGuild guild; public KittyGuild guild; // The guild this user is associated with. A KittyUser can not be associated with more than one guild.
public String name; public String name; // The 'friendly name' of the user (readable name).
public String uniqueID; public String uniqueID; // The combination of the guild ID that discord uses and the user-specific ID discord uses. (A discord account has one user per server).
public String discordID; public String discordID; // The user-specific ID only. This is the ID associated with the discord account.
public String avatarID; public String avatarID; // The searchable ID of the current avatar image for the user.
private KittyRole role; private KittyRole role; // The command permissions role this user has for issuing bot commands for this bot.
private long beans; private long beans; // A value incremented each time a user sends a message in a server they're in.
// Explicit Constructor // Explicit Constructor
public KittyUser(String name, KittyGuild guild, KittyRole role, String uniqueID, String avatarID, String discordID) public KittyUser(String name, KittyGuild guild, KittyRole role, String uniqueID, String avatarID, String discordID)
+9 -10
View File
@@ -99,18 +99,17 @@ public class Main extends ListenerAdapter
if(pluginOutput != null && pluginOutput.size() > 0) if(pluginOutput != null && pluginOutput.size() > 0)
{ {
for(int i = 0; i < pluginOutput.size(); ++i) for(int i = 0; i < pluginOutput.size(); ++i)
{
if(pluginOutput.get(i).startsWith("!"))
{ {
if(pluginOutput.get(i).startsWith("!")) commandManager.InvokeOnNewThread(guild, channel, user, new UserInput(pluginOutput.get(i).substring(1), guild), response);
{
commandManager.InvokeOnNewThread(guild, channel, user, new UserInput(pluginOutput.get(i).substring(1), guild), response);
}
else
{
response.Call(pluginOutput.get(i));
}
} }
else
{
response.Call(pluginOutput.get(i));
}
}
} }
} }
+1 -1
View File
@@ -92,7 +92,7 @@ public class Superintendent
// Upkeep database lazily on occasion // Upkeep database lazily on occasion
if(delayTimerCurrent.decrementAndGet() < 0) if(delayTimerCurrent.decrementAndGet() < 0)
{ {
databaseManager.Upkeep(); databaseManager.upkeep();
delayTimerCurrent.set(delayTimerReset); delayTimerCurrent.set(delayTimerReset);
} }
+30 -21
View File
@@ -13,34 +13,41 @@ import utils.LogFilter;
// Only to be called by the generic driver. // Only to be called by the generic driver.
public class JDBCDriverSQLite extends JDBCDriver public class JDBCDriverSQLite extends JDBCDriver
{ {
Connection connection = null; private static Connection connection = null;
String databaseFolder = "db/"; public static final String databaseFolder = "db/";
String databaseName = "catfood"; public static final String databaseName = "catfood";
@Override @Override
public boolean Connect() public boolean Connect()
{ {
try if(connection == null)
{ {
{ // Scope to discard file... try
File f = new File(databaseFolder); {
if(!f.exists() || !f.isDirectory()) { // Scope to discard file...
{ File f = new File(databaseFolder);
f.mkdir(); if(!f.exists() || !f.isDirectory())
{
f.mkdir();
}
} }
// db parameters
String url = "jdbc:sqlite:" + databaseFolder + databaseName + ".db";
// create a connection to the database
connection = DriverManager.getConnection(url);
GlobalLog.Log(LogFilter.Database, "Connection to SQLite has been established.");
}
catch (SQLException e)
{
GlobalLog.Error(e.getMessage());
} }
}
// db parameters else
String url = "jdbc:sqlite:db/" + databaseName + ".db";
// create a connection to the database
connection = DriverManager.getConnection(url);
GlobalLog.Log(LogFilter.Database, "Connection to SQLite has been established.");
}
catch (SQLException e)
{ {
GlobalLog.Error(e.getMessage()); GlobalLog.Log(LogFilter.Database, "SQLite database asked to connect a second time. This is perfectly fine as this app has all its data tied together.");
} }
return connection != null; return connection != null;
@@ -52,7 +59,9 @@ public class JDBCDriverSQLite extends JDBCDriver
try try
{ {
if (connection != null) if (connection != null)
{
connection.close(); connection.close();
}
return true; return true;
} }