Fix communities queries having the ability to lock the server mysql connections due to nesting, improve RepositoryBase by allowing all the methods to be passed a Connection object to reuse it, and fix duplicate invites throwing an sql error

This commit is contained in:
AlexTheCoder 2016-12-17 00:06:23 -05:00 committed by cnr
parent cc3842f019
commit 1190d4a427
3 changed files with 208 additions and 132 deletions

View File

@ -470,7 +470,10 @@ public class CommunityManager extends MiniDbClientPlugin<CommunityMemberData>
{
if (_repo.deleteInviteToCommunity(community.getId(), target))
{
UtilPlayer.message(sender, F.main(getName(), "You have revoked " + F.name(target) + "'s invitation to join " + F.name(community.getName()) + "!"));
if (!community.getMembers().containsKey(sender.getUniqueId()))
{
UtilPlayer.message(sender, F.main(getName(), "You have revoked " + F.name(target) + "'s invitation to join " + F.name(community.getName()) + "!"));
}
new CommunityUnInvite(community.getId(), sender.getName(), target, Managers.get(CoreClientManager.class).loadUUIDFromDB(target).toString(), true).publish();
}
else

View File

@ -40,7 +40,7 @@ public class CommunityRepository extends MinecraftRepository
private static final String ADD_TO_COMMUNITY = "INSERT INTO communityMembers (accountId, communityId, communityRole, readingChat) VALUES (?, ?, ?, true);";
private static final String UPDATE_COMMUNITY_SETTING = "INSERT INTO communitySettings (settingId, communityId, settingValue) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE settingValue=VALUES(settingValue);";
private static final String UPDATE_COMMUNITY_NAME = "UPDATE communities SET name=? WHERE id=?;";
private static final String INVITE_TO_COMMUNITY = "INSERT INTO communityInvites (accountId, communityId) SELECT a.id AS accountId, ? FROM accounts as a WHERE a.name = ? ORDER BY a.lastLogin DESC LIMIT 1;";
private static final String INVITE_TO_COMMUNITY = "INSERT INTO communityInvites (accountId, communityId) SELECT a.id AS accountId, ? FROM accounts as a WHERE a.name = ? ORDER BY a.lastLogin DESC LIMIT 1 ON DUPLICATE KEY UPDATE communityInvites.id=communityInvites.id;";
private static final String DELETE_INVITE_TO_COMMUNITY = "DELETE i FROM communityInvites AS i INNER JOIN accounts as a ON i.accountId = a.id WHERE a.name = ? AND i.communityId=?;";
private static final String ADD_JOIN_REQUEST = "INSERT INTO communityJoinRequests (accountId, communityId) VALUES (?, ?);";
private static final String REMOVE_JOIN_REQUEST = "DELETE FROM communityJoinRequests WHERE accountId=? AND communityId=?;";
@ -62,136 +62,150 @@ public class CommunityRepository extends MinecraftRepository
public void loadCommunity(int communityId, final Map<Integer, Community> communityMap)
{
executeQuery(GET_COMMUNITY_BY_ID, resultSet ->
try (Connection connection = getConnection())
{
if (resultSet.next())
executeQuery(connection, GET_COMMUNITY_BY_ID, resultSet ->
{
final int id = resultSet.getInt("id");
final String cName = resultSet.getString("name");
final Community community = new Community(id, cName);
executeQuery(GET_COMMUNITY_MEMBERS, memberSet ->
if (resultSet.next())
{
while (memberSet.next())
final int id = resultSet.getInt("id");
final String cName = resultSet.getString("name");
final Community community = new Community(id, cName);
executeQuery(connection, GET_COMMUNITY_MEMBERS, memberSet ->
{
final int accountId = memberSet.getInt("accountId");
final String name = memberSet.getString("name");
final UUID uuid = UUID.fromString(memberSet.getString("uuid"));
final CommunityRole role = CommunityRole.parseRole(memberSet.getString("communityRole"));
final long timeSinceOnline = memberSet.getTimestamp(6).getTime() - memberSet.getTimestamp(5).getTime();
boolean readingChat = memberSet.getBoolean("readingChat");
final int owns = memberSet.getInt(8);
CommunityMemberInfo info = new CommunityMemberInfo(name, uuid, accountId, role, timeSinceOnline);
PlayerStatus status = _repo.getElement(name);
if (status != null)
while (memberSet.next())
{
info.update(name, role, timeSinceOnline, true, status.getServer());
final int accountId = memberSet.getInt("accountId");
final String name = memberSet.getString("name");
final UUID uuid = UUID.fromString(memberSet.getString("uuid"));
final CommunityRole role = CommunityRole.parseRole(memberSet.getString("communityRole"));
final long timeSinceOnline = memberSet.getTimestamp(6).getTime() - memberSet.getTimestamp(5).getTime();
boolean readingChat = memberSet.getBoolean("readingChat");
final int owns = memberSet.getInt(8);
CommunityMemberInfo info = new CommunityMemberInfo(name, uuid, accountId, role, timeSinceOnline);
PlayerStatus status = _repo.getElement(name);
if (status != null)
{
info.update(name, role, timeSinceOnline, true, status.getServer());
}
info.ReadingChat = readingChat;
info.OwnsCommunity = owns > 0;
community.getMembers().put(info.UUID, info);
}
info.ReadingChat = readingChat;
info.OwnsCommunity = owns > 0;
community.getMembers().put(info.UUID, info);
}
}, new ColumnInt("communityId", community.getId()));
}, new ColumnInt("communityId", community.getId()));
executeQuery(GET_COMMUNITY_JOIN_REQUESTS, requestSet ->
{
while (requestSet.next())
executeQuery(connection, GET_COMMUNITY_JOIN_REQUESTS, requestSet ->
{
final int accountId = requestSet.getInt("accountId");
final UUID uuid = UUID.fromString(requestSet.getString("uuid"));
final String name = requestSet.getString("name");
community.getJoinRequests().put(uuid, new CommunityJoinRequestInfo(name, uuid, accountId));
}
}, new ColumnInt("communityId", community.getId()));
executeQuery(GET_COMMUNITY_SETTINGS, settingSet ->
{
while (settingSet.next())
{
final int settingId = settingSet.getInt("settingId");
final String value = settingSet.getString("settingValue");
CommunitySetting setting = CommunitySetting.getSetting(settingId);
if (setting != null)
while (requestSet.next())
{
setting.parseValueInto(value, community);
}
}
}, new ColumnInt("communityId", community.getId()));
final int accountId = requestSet.getInt("accountId");
final UUID uuid = UUID.fromString(requestSet.getString("uuid"));
final String name = requestSet.getString("name");
communityMap.put(community.getId(), community);
}
}, new ColumnInt("id", communityId));
community.getJoinRequests().put(uuid, new CommunityJoinRequestInfo(name, uuid, accountId));
}
}, new ColumnInt("communityId", community.getId()));
executeQuery(connection, GET_COMMUNITY_SETTINGS, settingSet ->
{
while (settingSet.next())
{
final int settingId = settingSet.getInt("settingId");
final String value = settingSet.getString("settingValue");
CommunitySetting setting = CommunitySetting.getSetting(settingId);
if (setting != null)
{
setting.parseValueInto(value, community);
}
}
}, new ColumnInt("communityId", community.getId()));
communityMap.put(community.getId(), community);
}
}, new ColumnInt("id", communityId));
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void loadCommunities(final Map<Integer, Community> communityMap)
{
executeQuery(GET_ALL_COMMUNITIES, resultSet ->
try (Connection connection = getConnection())
{
Map<Integer, Community> resultant = new HashMap<>();
while (resultSet.next())
executeQuery(connection, GET_ALL_COMMUNITIES, resultSet ->
{
final int id = resultSet.getInt("id");
final String cName = resultSet.getString("name");
final Community community = new Community(id, cName);
executeQuery(GET_COMMUNITY_MEMBERS, memberSet ->
Map<Integer, Community> resultant = new HashMap<>();
while (resultSet.next())
{
while (memberSet.next())
final int id = resultSet.getInt("id");
final String cName = resultSet.getString("name");
final Community community = new Community(id, cName);
executeQuery(connection, GET_COMMUNITY_MEMBERS, memberSet ->
{
final int accountId = memberSet.getInt("accountId");
final String name = memberSet.getString("name");
final UUID uuid = UUID.fromString(memberSet.getString("uuid"));
final CommunityRole role = CommunityRole.parseRole(memberSet.getString("communityRole"));
final long timeSinceOnline = memberSet.getTimestamp(6).getTime() - memberSet.getTimestamp(5).getTime();
boolean readingChat = memberSet.getBoolean("readingChat");
final int owns = memberSet.getInt(8);
CommunityMemberInfo info = new CommunityMemberInfo(name, uuid, accountId, role, timeSinceOnline);
PlayerStatus status = _repo.getElement(name);
if (status != null)
while (memberSet.next())
{
info.update(name, role, timeSinceOnline, true, status.getServer());
final int accountId = memberSet.getInt("accountId");
final String name = memberSet.getString("name");
final UUID uuid = UUID.fromString(memberSet.getString("uuid"));
final CommunityRole role = CommunityRole.parseRole(memberSet.getString("communityRole"));
final long timeSinceOnline = memberSet.getTimestamp(6).getTime() - memberSet.getTimestamp(5).getTime();
boolean readingChat = memberSet.getBoolean("readingChat");
final int owns = memberSet.getInt(8);
CommunityMemberInfo info = new CommunityMemberInfo(name, uuid, accountId, role, timeSinceOnline);
PlayerStatus status = _repo.getElement(name);
if (status != null)
{
info.update(name, role, timeSinceOnline, true, status.getServer());
}
info.ReadingChat = readingChat;
info.OwnsCommunity = owns > 0;
community.getMembers().put(info.UUID, info);
}
info.ReadingChat = readingChat;
info.OwnsCommunity = owns > 0;
community.getMembers().put(info.UUID, info);
}
}, new ColumnInt("communityId", community.getId()));
}, new ColumnInt("communityId", community.getId()));
executeQuery(GET_COMMUNITY_JOIN_REQUESTS, requestSet ->
{
while (requestSet.next())
executeQuery(connection, GET_COMMUNITY_JOIN_REQUESTS, requestSet ->
{
final int accountId = requestSet.getInt("accountId");
final UUID uuid = UUID.fromString(requestSet.getString("uuid"));
final String name = requestSet.getString("name");
community.getJoinRequests().put(uuid, new CommunityJoinRequestInfo(name, uuid, accountId));
}
}, new ColumnInt("communityId", community.getId()));
executeQuery(GET_COMMUNITY_SETTINGS, settingSet ->
{
while (settingSet.next())
{
final int settingId = settingSet.getInt("settingId");
final String value = settingSet.getString("settingValue");
CommunitySetting setting = CommunitySetting.getSetting(settingId);
if (setting != null)
while (requestSet.next())
{
setting.parseValueInto(value, community);
final int accountId = requestSet.getInt("accountId");
final UUID uuid = UUID.fromString(requestSet.getString("uuid"));
final String name = requestSet.getString("name");
community.getJoinRequests().put(uuid, new CommunityJoinRequestInfo(name, uuid, accountId));
}
}
}, new ColumnInt("communityId", community.getId()));
}, new ColumnInt("communityId", community.getId()));
resultant.put(community.getId(), community);
}
executeQuery(connection, GET_COMMUNITY_SETTINGS, settingSet ->
{
while (settingSet.next())
{
final int settingId = settingSet.getInt("settingId");
final String value = settingSet.getString("settingValue");
communityMap.clear();
communityMap.putAll(resultant);
}, new ColumnVarChar("region", 5, _us ? "US" : "EU"));
CommunitySetting setting = CommunitySetting.getSetting(settingId);
if (setting != null)
{
setting.parseValueInto(value, community);
}
}
}, new ColumnInt("communityId", community.getId()));
resultant.put(community.getId(), community);
}
communityMap.clear();
communityMap.putAll(resultant);
}, new ColumnVarChar("region", 5, _us ? "US" : "EU"));
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void updateMembersAndJoinRequests(LinkedList<Community> communities)
@ -372,28 +386,42 @@ public class CommunityRepository extends MinecraftRepository
public void createCommunity(String name, int leaderAccount, Callback<Integer> idCallback)
{
executeInsert(CREATE_COMMUNITY, resultSet ->
try (Connection connection = getConnection())
{
if (resultSet.next())
executeInsert(connection, CREATE_COMMUNITY, resultSet ->
{
int id = resultSet.getInt(1);
executeUpdate(ADD_TO_COMMUNITY, new ColumnInt("accountId", leaderAccount), new ColumnInt("communityId", id), new ColumnVarChar("communityRole", 20, CommunityRole.LEADER.toString()));
idCallback.run(id);
}
else
{
idCallback.run(-1);
}
}, new ColumnVarChar("name", 15, name), new ColumnVarChar("region", 5, _us ? "US" : "EU"));
if (resultSet.next())
{
int id = resultSet.getInt(1);
executeUpdate(connection, ADD_TO_COMMUNITY, new ColumnInt("accountId", leaderAccount), new ColumnInt("communityId", id), new ColumnVarChar("communityRole", 20, CommunityRole.LEADER.toString()));
idCallback.run(id);
}
else
{
idCallback.run(-1);
}
}, new ColumnVarChar("name", 15, name), new ColumnVarChar("region", 5, _us ? "US" : "EU"));
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void deleteCommunity(int communityId)
{
executeUpdate("DELETE FROM communities WHERE id=?;", new ColumnInt("id", communityId));
executeUpdate("DELETE FROM communitySettings WHERE communityId=?;", new ColumnInt("communityId", communityId));
executeUpdate("DELETE FROM communityMembers WHERE communityId=?;", new ColumnInt("communityId", communityId));
executeUpdate("DELETE FROM communityInvites WHERE communityId=?;", new ColumnInt("communityId", communityId));
executeUpdate("DELETE FROM communityJoinRequests WHERE communityId=?", new ColumnInt("communityId", communityId));
try (Connection connection = getConnection())
{
executeUpdate(connection, "DELETE FROM communities WHERE id=?;", new ColumnInt("id", communityId));
executeUpdate(connection, "DELETE FROM communitySettings WHERE communityId=?;", new ColumnInt("communityId", communityId));
executeUpdate(connection, "DELETE FROM communityMembers WHERE communityId=?;", new ColumnInt("communityId", communityId));
executeUpdate(connection, "DELETE FROM communityInvites WHERE communityId=?;", new ColumnInt("communityId", communityId));
executeUpdate(connection, "DELETE FROM communityJoinRequests WHERE communityId=?", new ColumnInt("communityId", communityId));
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void setReadingChat(int accountId, int communityId, boolean reading)

View File

@ -76,6 +76,11 @@ public abstract class RepositoryBase
}
}
protected int executeUpdate(Connection connection, String query, Column<?>...columns)
{
return executeInsert(connection, query, null, columns);
}
/**
* Execute a query against the repository.
* @param query - the concatenated query to execute in string form.
@ -87,13 +92,12 @@ public abstract class RepositoryBase
return executeInsert(query, null, columns);
}
protected int executeInsert(String query, ResultSetCallable callable, Column<?>...columns)
protected int executeInsert(Connection connection, String query, ResultSetCallable callable, Column<?>...columns)
{
int affectedRows = 0;
// Automatic resource management for handling/closing objects.
try (
Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)
)
{
@ -121,6 +125,29 @@ public abstract class RepositoryBase
return affectedRows;
}
protected int executeInsert(String query, ResultSetCallable callable, Column<?>...columns)
{
int affectedRows = 0;
// Automatic resource management for handling/closing objects.
try (
Connection connection = getConnection();
)
{
affectedRows = executeInsert(connection, query, callable, columns);
}
catch (SQLException exception)
{
exception.printStackTrace();
}
catch (Exception exception)
{
exception.printStackTrace();
}
return affectedRows;
}
protected void executeQuery(PreparedStatement statement, ResultSetCallable callable, Column<?>...columns)
{
try
@ -148,11 +175,10 @@ public abstract class RepositoryBase
}
}
protected void executeQuery(String query, ResultSetCallable callable, Column<?>...columns)
protected void executeQuery(Connection connection, String query, ResultSetCallable callable, Column<?>...columns)
{
// Automatic resource management for handling/closing objects.
try (
Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(query)
)
{
@ -167,4 +193,23 @@ public abstract class RepositoryBase
exception.printStackTrace();
}
}
protected void executeQuery(String query, ResultSetCallable callable, Column<?>...columns)
{
// Automatic resource management for handling/closing objects.
try (
Connection connection = getConnection();
)
{
executeQuery(connection, query, callable, columns);
}
catch (SQLException exception)
{
exception.printStackTrace();
}
catch (Exception exception)
{
exception.printStackTrace();
}
}
}