package de.tud.kom.socom.database.user; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import java.util.LinkedList; import java.util.List; import de.tud.kom.socom.GlobalConfig; import de.tud.kom.socom.database.HSQLDatabase; import de.tud.kom.socom.util.datatypes.JournalEntry; import de.tud.kom.socom.util.datatypes.SimpleGameContext; import de.tud.kom.socom.util.exceptions.ContextNotFoundException; import de.tud.kom.socom.util.exceptions.CurrentContextNotFoundException; public class HSQLUserGameInfoDatabase extends HSQLDatabase implements UserGameInfoDatabase { private static UserGameInfoDatabase instance = new HSQLUserGameInfoDatabase(); private HSQLUserGameInfoDatabase() { super(); } public static UserGameInfoDatabase getInstance() { return instance; } @Override public void setCurrentContext(long uid, long oldContext, long newContext) throws SQLException, ContextNotFoundException { // PreparedStatement statement = db.getPreparedStatement("SELECT uid FROM userprogress WHERE uid = ? AND scnid = ?"); // statement.setLong(1, uid); // statement.setLong(2, newContext); //// String selectQuery = "SELECT uid FROM userprogress WHERE uid = '" + uid + "' AND scnid = '" + newContext + "'"; // ResultSet rs = statement.executeQuery(); // if (!rs.next()) { // Insert PreparedStatement statement = db.getPreparedStatement("INSERT INTO userprogress (uid, scnid, playtime, time) VALUES (?, ?, '0', NOW());"); statement.setLong(1, uid); statement.setLong(2, newContext); statement.executeUpdate(); // } else { // // Update time // statement = db.getPreparedStatement("UPDATE userprogress SET time = NOW() WHERE uid = ? AND scnid = ?;"); // statement.setLong(1, uid); // statement.setLong(2, newContext); // statement.executeUpdate(); // } statement = db.getPreparedStatement("UPDATE gamecontextrelations SET timesused = timesused + 1 WHERE parentid = ? AND childid = ?;"); statement.setLong(1, oldContext); statement.setLong(2, newContext); statement.executeUpdate(); } @Override public long getCurrentContext(long userId, long gameInstanceId) throws SQLException, CurrentContextNotFoundException { PreparedStatement statement = db.getPreparedStatement("SELECT userprogress.scnid " + "FROM ((userprogress " + "INNER JOIN gamecontexts ON userprogress.scnid = gamecontexts.id) " + "INNER JOIN gameinstances ON gamecontexts.gameinstid = gameinstances.id) " + "INNER JOIN users ON gameinstances.id = users.currentgameinst " + "WHERE uid = ? AND currentgameinst = ? " + "ORDER BY userprogress.time DESC " + "LIMIT 0,1"); statement.setLong(1, userId); statement.setLong(2, gameInstanceId); ResultSet rs = statement.executeQuery(); if (!rs.next()) throw new CurrentContextNotFoundException(userId); return rs.getLong("scnid"); } @Override public void addTimePlayed(long uid, long contextId, long timeInS) throws SQLException { PreparedStatement statement = db.getPreparedStatement("UPDATE userprogress SET playtime = playtime + ? WHERE uid = ? AND scnid = ?"); statement.setLong(1, timeInS); statement.setLong(2, uid); statement.setLong(3, contextId); statement.executeUpdate(); } @Override public void setTimePlayed(long uid, long contextId, long timeInS) throws SQLException { PreparedStatement statement = db.getPreparedStatement("UPDATE userprogress SET playtime = ? WHERE uid = ? AND scnid = ?"); statement.setLong(1, timeInS); statement.setLong(2, uid); statement.setLong(3, contextId); statement.executeUpdate(); } @Override public void addJournalEntry(long uid, long gameInstId, JournalEntry log) throws SQLException { long typeId = lazyInsert("userlogtypes", log.getType()); PreparedStatement statement = db.getPreparedStatement("INSERT INTO " + "userlogs (" + "uid, " + "gameinstid, " + "typeid," + "content," + "time, " + "visibility) " + "VALUES (?,?,?,?,NOW(),?);"); statement.setLong(1, uid); statement.setLong(2, gameInstId); statement.setLong(3, typeId); statement.setString(4, log.getMessage()); statement.setInt(5, log.getVisibility()); statement.executeUpdate(); } @Override public List<JournalEntry> getUserJournal(long uid, long gameInstId, int limit, int offset, String type, boolean game) throws SQLException { List<JournalEntry> result = new LinkedList<JournalEntry>(); String typeSelect = type.equals("all") ? "" : " AND name = UPPER(?) "; String visibilitySelect = " AND " + (game ? "visibility = " + GlobalConfig.VISIBILITY_NON_USER: "visibility < " + GlobalConfig.VISIBILITY_NON_USER); //FIXME make journal entries accessable for other players if visibility allows so PreparedStatement statement = db.getPreparedStatement("SELECT name, content, time, visibility " + "FROM (userlogs INNER JOIN userlogtypes ON userlogs.typeid = userlogtypes.id) " + "WHERE uid = ? " + typeSelect + visibilitySelect + " AND gameinstid = ? AND deleted = 0" + " ORDER BY time DESC LIMIT ? OFFSET ?;"); statement.setLong(1, uid); boolean withtype = typeSelect.length() > 0; if(withtype) statement.setString(2, type); statement.setLong(withtype?3:2, gameInstId); statement.setInt(withtype?4:3, limit); statement.setInt(withtype?5:4, offset); ResultSet rs = statement.executeQuery(); while(rs.next()){ JournalEntry log = new JournalEntry(rs.getString("name"), rs.getString("content"), rs.getInt("visibility")); log.setTime(new Date(rs.getTimestamp("time").getTime())); result.add(log); } return result; } @Override public long getTimePlayed(long uid, long contextId) throws SQLException { PreparedStatement statement = db.getPreparedStatement("SELECT playtime FROM userprogress WHERE uid = ? AND scnid = ?;"); statement.setLong(1, uid); statement.setLong(2, contextId); ResultSet rs = statement.executeQuery(); if(!rs.next()) return -1; return rs.getLong(1); } @Override public List<SimpleGameContext> getVisitedContexts(long uid, long gameInst) throws SQLException { List<SimpleGameContext> result = new LinkedList<SimpleGameContext>(); PreparedStatement statement = db.getPreparedStatement("SELECT " + "playtime, time, externalid, name " + "FROM " + "userprogress JOIN gamecontexts ON userprogress.scnid = gamecontexts.id " + "WHERE " + "userprogress.uid = ? AND gamecontexts.gameinstid = ?;"); statement.setLong(1, uid); statement.setLong(2, gameInst); ResultSet rs = statement.executeQuery(); while(rs.next()){ result.add(new SimpleGameContext(rs.getString("externalid"), rs.getTimestamp("time"), rs.getLong("playtime"), rs.getString("name"))); } return result; } }