|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object soc.server.database.SOCDBHelper
public class SOCDBHelper
This class contains methods for connecting to a database and for manipulating the data stored there.
Based on jdbc code found at www.javaworld.com
This code assumes that you're using mySQL as your database,
but allows you to use other database types.
The default URL is "jdbc:mysql://localhost/socdata".
The default driver is "com.mysql.jdbc.Driver".
These can be changed by supplying properties to initialize(String, String, Properties)
for PROP_JSETTLERS_DB_URL
and PROP_JSETTLERS_DB_DRIVER
.
It uses a database created with the following commands:
(See src/bin/sql/jsettlers-tables.sql)
CREATE DATABASE socdata;
USE socdata;
CREATE TABLE users (nickname VARCHAR(20), host VARCHAR(50), password VARCHAR(20), email VARCHAR(50), lastlogin DATE);
CREATE TABLE logins (nickname VARCHAR(20), host VARCHAR(50), lastlogin DATE);
CREATE TABLE games (gamename VARCHAR(20), player1 VARCHAR(20), player2 VARCHAR(20), player3 VARCHAR(20), player4 VARCHAR(20), score1 TINYINT, score2 TINYINT, score3 TINYINT, score4 TINYINT, starttime TIMESTAMP);
CREATE TABLE robotparams (robotname VARCHAR(20), maxgamelength INT, maxeta INT, etabonusfactor FLOAT, adversarialfactor FLOAT, leaderadversarialfactor FLOAT, devcardmultiplier FLOAT, threatmultiplier FLOAT, strategytype INT, starttime TIMESTAMP, endtime TIMESTAMP, gameswon INT, gameslost INT, tradeFlag BOOL);
Field Summary | |
---|---|
private static java.sql.Connection |
connection
db connection, or null if never initialized or if cleaned up for shutdown. |
private static java.lang.String |
CREATE_ACCOUNT_COMMAND
|
private static java.sql.PreparedStatement |
createAccountCommand
Create a new account in users : CREATE_ACCOUNT_COMMAND |
private static java.lang.String |
dbURL
Retain the URL (default, or passed via props to initialize(String, String, Properties) ). |
private static java.lang.String |
driverclass
The db driver used, or null if none. |
private static java.sql.Driver |
driverinstance
The db driver instance, if we dynamically loaded its JAR. |
private static boolean |
errorCondition
This flag indicates that the connection should be valid, yet the last operation failed. |
private static java.lang.String |
HOST_QUERY
|
private static java.sql.PreparedStatement |
hostQuery
|
private static boolean |
initialized
True if we successfully completed initialize(String, String, Properties)
without throwing an exception. |
private static java.lang.String |
LASTLOGIN_UPDATE
|
private static java.sql.PreparedStatement |
lastloginUpdate
|
private static java.lang.String |
password
Cached password used when reconnecting on error |
private static java.lang.String |
PASSWORD_UPDATE
|
private static java.sql.PreparedStatement |
passwordUpdate
User password update in users : PASSWORD_UPDATE |
static java.lang.String |
PROP_IMPL_JSETTLERS_PW_RESET
Internal property name used to hold the --pw-reset command line argument's username. |
static java.lang.String |
PROP_JSETTLERS_DB_DRIVER
Property jsettlers.db.driver to specify the server's JDBC driver class. |
static java.lang.String |
PROP_JSETTLERS_DB_JAR
Property jsettlers.db.jar to specify the JAR filename for the server's JDBC driver. |
static java.lang.String |
PROP_JSETTLERS_DB_PASS
Property jsettlers.db.pass to specify the server's SQL database password. |
static java.lang.String |
PROP_JSETTLERS_DB_SAVE_GAMES
Property jsettlers.db.save.games to ask to save all game results in the database. |
static java.lang.String |
PROP_JSETTLERS_DB_SCRIPT_SETUP
Property jsettlers.db.script.setup to run a SQL setup script at server startup, then exit. |
static java.lang.String |
PROP_JSETTLERS_DB_URL
Property jsettlers.db.url to specify the server's URL. |
static java.lang.String |
PROP_JSETTLERS_DB_USER
Property jsettlers.db.user to specify the server's SQL database username. |
private static java.lang.String |
RECORD_LOGIN_COMMAND
|
private static java.sql.PreparedStatement |
recordLoginCommand
|
private static java.lang.String |
ROBOT_PARAMS_QUERY
|
private static java.sql.PreparedStatement |
robotParamsQuery
Query all robot parameters for a bot name; ROBOT_PARAMS_QUERY . |
private static java.lang.String |
SAVE_GAME_COMMAND
|
private static java.sql.PreparedStatement |
saveGameCommand
Completed-game info insert into games : SAVE_GAME_COMMAND |
private static java.lang.String |
USER_COUNT_QUERY
|
private static java.lang.String |
USER_EXISTS_QUERY
|
private static java.lang.String |
USER_PASSWORD_QUERY
|
private static java.sql.PreparedStatement |
userCountQuery
Query how many users, if any, exist in the users table: USER_COUNT_QUERY . |
private static java.sql.PreparedStatement |
userExistsQuery
Query whether a user nickname exists in users : USER_EXISTS_QUERY |
private static java.lang.String |
userName
Cached username used when reconnecting on error |
private static java.sql.PreparedStatement |
userPasswordQuery
|
Constructor Summary | |
---|---|
SOCDBHelper()
|
Method Summary | |
---|---|
private static boolean |
checkConnection()
Checks if connection is supposed to be present and attempts to reconnect if there was previously an error. |
static void |
cleanup(boolean isForShutdown)
Close out and shut down the database connection. |
private static boolean |
connect(java.lang.String user,
java.lang.String pswd,
java.lang.String setupScriptPath)
Opens a new connection and initializes the prepared statements. |
static int |
countUsers()
Count the number of users, if any, currently in the users table. |
static boolean |
createAccount(java.lang.String userName,
java.lang.String host,
java.lang.String password,
java.lang.String email,
long time)
Attempt to create a new account with a unique userName in the users table. |
(package private) static void |
dispResultSet(java.sql.ResultSet rs)
|
static boolean |
doesTableColumnExist(java.lang.String tabname,
java.lang.String colname)
Query to see if a column exists in a table. |
static boolean |
doesUserExist(java.lang.String userName)
Does this user (nickname) exist in the database? |
static java.lang.String |
getUserFromHost(java.lang.String host)
DOCUMENT ME! |
static java.lang.String |
getUserPassword(java.lang.String sUserName)
Verify that this user exists, and retrieve their password from the database. |
static void |
initialize(java.lang.String user,
java.lang.String pswd,
java.util.Properties props)
This makes a connection to the database and initializes the prepared statements. |
static boolean |
isInitialized()
Were we able to initialize(String, String, Properties)
and connect to the database?
True if db is connected and available; false if never initialized,
or if cleanup(boolean) was called. |
static boolean |
recordLogin(java.lang.String userName,
java.lang.String host,
long time)
Record this user's login host and time. |
static SOCRobotParameters |
retrieveRobotParams(java.lang.String robotName)
Get this robot's specialized parameters from the database, if it has an entry there. |
private static void |
runSetupScript(java.lang.String setupScriptPath)
Load and run a SQL script. |
private static void |
saveGameScores_fit6pInto4(SOCGame ga,
java.lang.String[] names,
short[] scores)
Try and fit names and scores of player 5 and/or player 6 into the 4 db slots, for backwards-compatibility. |
static boolean |
saveGameScores(SOCGame ga,
long gameLengthSeconds)
Record this game's time, players, and scores in the database. |
static boolean |
updateLastlogin(java.lang.String userName,
long time)
DOCUMENT ME! |
static boolean |
updateUserPassword(java.lang.String userName,
java.lang.String newPassword)
Update a user's password if the user is in the database. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final java.lang.String PROP_JSETTLERS_DB_USER
public static final java.lang.String PROP_JSETTLERS_DB_PASS
public static final java.lang.String PROP_JSETTLERS_DB_JAR
Default is blank (no driver jar file), since the filename varies when used.
public static final java.lang.String PROP_JSETTLERS_DB_DRIVER
URL
begins with "jdbc:postgresql:",
the driver will be "org.postgresql.Driver".
If the URL begins with "jdbc:sqlite:",
the driver will be "org.sqlite.JDBC".
public static final java.lang.String PROP_JSETTLERS_DB_URL
public static final java.lang.String PROP_JSETTLERS_DB_SCRIPT_SETUP
To implement this, the SOCServer constructor connects to the db and runs the setup script,
then signals success by throwing an EOFException
which is
caught by main(..)
. Errors throw SQLException
instead.
public static final java.lang.String PROP_JSETTLERS_DB_SAVE_GAMES
public static final java.lang.String PROP_IMPL_JSETTLERS_PW_RESET
This is a Utility Mode parameter; not for use in property files, because the program always exits after trying to change the password.
private static java.lang.String driverclass
driverinstance
!= null, use that to connect instead of driverclass;
we still need to remember driverclass to detect various db-specific behaviors.
Set in initialize(String, String, Properties)
.
private static java.sql.Driver driverinstance
dbURL
to connect instead.
Used because DriverManager.registerDriver(Driver)
won't work
if the classloader is different, which it will be for dynamic loading.
Set in initialize(String, String, Properties)
.
Used in connect(String, String, String)
.
private static java.sql.Connection connection
checkConnection()
.
Set in connect(String, String, String)
, based on the dbURL
from initialize(String, String, Properties)
.
Cleared in cleanup(true)
.
private static java.lang.String dbURL
initialize(String, String, Properties)
).
Used in connect(String, String, String)
.
If driverinstance
!= null, go through it to connect to dbURL.
private static boolean errorCondition
private static boolean initialized
initialize(String, String, Properties)
without throwing an exception.
Set false in cleanup(boolean)
.
private static java.lang.String userName
private static java.lang.String password
private static java.lang.String CREATE_ACCOUNT_COMMAND
private static java.lang.String RECORD_LOGIN_COMMAND
private static java.lang.String USER_PASSWORD_QUERY
private static java.lang.String HOST_QUERY
private static java.lang.String LASTLOGIN_UPDATE
private static final java.lang.String PASSWORD_UPDATE
private static java.lang.String SAVE_GAME_COMMAND
private static java.lang.String ROBOT_PARAMS_QUERY
private static final java.lang.String USER_COUNT_QUERY
private static final java.lang.String USER_EXISTS_QUERY
private static java.sql.PreparedStatement createAccountCommand
users
: CREATE_ACCOUNT_COMMAND
private static java.sql.PreparedStatement recordLoginCommand
private static java.sql.PreparedStatement userExistsQuery
users
: USER_EXISTS_QUERY
private static java.sql.PreparedStatement userPasswordQuery
private static java.sql.PreparedStatement hostQuery
private static java.sql.PreparedStatement lastloginUpdate
private static java.sql.PreparedStatement passwordUpdate
users
: PASSWORD_UPDATE
private static java.sql.PreparedStatement saveGameCommand
games
: SAVE_GAME_COMMAND
private static java.sql.PreparedStatement robotParamsQuery
ROBOT_PARAMS_QUERY
.
Used in retrieveRobotParams(String)
.
private static java.sql.PreparedStatement userCountQuery
users
table: USER_COUNT_QUERY
.
Constructor Detail |
---|
public SOCDBHelper()
Method Detail |
---|
public static void initialize(java.lang.String user, java.lang.String pswd, java.util.Properties props) throws java.sql.SQLException, java.io.IOException
PROP_JSETTLERS_DB_SCRIPT_SETUP
,
runs that script before the prepared statements.)
Sets isInitialized()
.
The default URL is "jdbc:mysql://localhost/socdata".
The default driver is "com.mysql.jdbc.Driver".
These can be changed by supplying props
.
user
- the user name for accessing the databasepswd
- the password for the user, or ""props
- null, or properties containing PROP_JSETTLERS_DB_DRIVER
,
PROP_JSETTLERS_DB_URL
, and any other desired properties.
Ignores PROP_JSETTLERS_DB_USER
and PROP_JSETTLERS_DB_PASS
if present,
uses the user
and pswd
parameters instead.
java.sql.SQLException
- if an SQL command fails, or the db couldn't be
initialized;
or if the PROP_JSETTLERS_DB_DRIVER
property is not mysql, not sqlite, not postgres,
but the PROP_JSETTLERS_DB_URL
property is not provided.
java.io.IOException
- if props includes PROP_JSETTLERS_DB_SCRIPT_SETUP
but
the SQL file wasn't found, or if any other IO error occurs reading the scriptpublic static boolean isInitialized()
initialize(String, String, Properties)
and connect to the database?
True if db is connected and available; false if never initialized,
or if cleanup(boolean)
was called.
private static boolean checkConnection() throws java.sql.SQLException
connection
, opens a new one, and re-initializes the prepared statements.
java.sql.SQLException
private static boolean connect(java.lang.String user, java.lang.String pswd, java.lang.String setupScriptPath) throws java.sql.SQLException, java.io.IOException
initialize(String, String, Properties)
and checkConnection()
use this to get ready.
Uses dbURL
and driverinstance
.
If setupScriptPath != null, it will be ran before preparing statements. That way, it can create tables used by the statements.
user
- DB usernamepswd
- DB user password, or ""setupScriptPath
- Full path or relative path to SQL script to run at connect, or null;
typically from PROP_JSETTLERS_DB_SCRIPT_SETUP
java.io.IOException
- if setupScriptPath wasn't found, or if any other IO error occurs reading the script
java.sql.SQLException
- if any connect error, missing table, or SQL error occursprivate static void runSetupScript(java.lang.String setupScriptPath) throws java.io.FileNotFoundException, java.io.IOException, java.sql.SQLException
setupScriptPath
- Full path or relative path to the SQL script filename
java.io.FileNotFoundException
- if file not found
java.io.IOException
- if any other IO error occurs
java.sql.SQLException
- if any unexpected database problempublic static boolean doesUserExist(java.lang.String userName) throws java.lang.IllegalArgumentException, java.sql.SQLException
userName
- User nickname to check
java.lang.IllegalArgumentException
- if userName
is null
java.sql.SQLException
- if any unexpected database problemgetUserPassword(String)
public static java.lang.String getUserPassword(java.lang.String sUserName) throws java.sql.SQLException
sUserName
- Username who needs password
java.sql.SQLException
- if any unexpected database problemdoesUserExist(String)
public static java.lang.String getUserFromHost(java.lang.String host) throws java.sql.SQLException
host
- DOCUMENT ME!
java.sql.SQLException
- DOCUMENT ME!public static boolean createAccount(java.lang.String userName, java.lang.String host, java.lang.String password, java.lang.String email, long time) throws java.sql.SQLException
userName
in the users
table.
Before calling, validate the user doesn't already exist
by calling doesUserExist(userName)
or getUserPassword(userName)
.
This method doesn't verify that the user is a unique new user before creating the record.
userName
- New user name (nickname) to createhost
- Client hostname or IP requesting new accountpassword
- New user's initial passwordemail
- Optional email address to contact this usertime
- Created-at time, same format as System.currentTimeMillis()
and Date.Date(long)
java.sql.SQLException
- if any unexpected database problem occurspublic static boolean recordLogin(java.lang.String userName, java.lang.String host, long time) throws java.sql.SQLException
userName
- User name (nickname)host
- Login is from this client hostname or IPtime
- Login time, same format as System.currentTimeMillis()
java.sql.SQLException
- if any unexpected database problempublic static boolean updateLastlogin(java.lang.String userName, long time) throws java.sql.SQLException
userName
- DOCUMENT ME!time
- DOCUMENT ME!
java.sql.SQLException
- if any unexpected database problempublic static boolean updateUserPassword(java.lang.String userName, java.lang.String newPassword) throws java.lang.IllegalArgumentException, java.sql.SQLException
userName
- Username to update. Does not validate this user exists: Call doesUserExist(String)
first to do so.newPassword
- New password (length can be 1 to 20)
userName
, will nonetheless return true.
java.lang.IllegalArgumentException
- If user or password are null, or password is too short or too long
java.sql.SQLException
- if an error occurspublic static boolean saveGameScores(SOCGame ga, long gameLengthSeconds) throws java.sql.SQLException
ga
- Game that's just completedgameLengthSeconds
- Duration of game
java.sql.SQLException
- DOCUMENT ME!private static void saveGameScores_fit6pInto4(SOCGame ga, java.lang.String[] names, short[] scores)
ga.isSeatVacant(pn)
and ga.getPlayer(pn).isRobot()
for the first 4 player numbers, and copies player 5 and 6's
data to those positions in names[] and scores[].
v1.1.15: Copy to vacant slots among first 4 players.
v1.1.19: Copy to vacant slots or robot slots among first 4; if human player 5 or 6 won, overwrite the lowest-scoring non-winner slot if necessary.
ga
- Game that's overnames
- Player names for player number 0-5; contents of 0-3 may be changedscores
- Player scores for player number 0-5; contents of 0-3 may be changedpublic static SOCRobotParameters retrieveRobotParams(java.lang.String robotName) throws java.sql.SQLException
robotName
- Name of robot for db lookup
java.sql.SQLException
- if unexpected problem retrieving the paramspublic static int countUsers() throws java.sql.SQLException
java.sql.SQLException
- if unexpected problem counting the userspublic static boolean doesTableColumnExist(java.lang.String tabname, java.lang.String colname) throws java.lang.IllegalStateException
tabname
- Table name to check colname within; case-sensitive in some db typescolname
- Column name to check; case-sensitive in some db types.
The jsettlers standard is to always use lowercase names when creating tables and columns.
java.lang.IllegalStateException
- If not connected and if checkConnection()
failspublic static void cleanup(boolean isForShutdown) throws java.sql.SQLException
isForShutdown
- If true, set connection = null
so we won't try to reconnect later.
java.sql.SQLException
static void dispResultSet(java.sql.ResultSet rs) throws java.sql.SQLException
java.sql.SQLException
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |