Upsert monsterbook cards instead of delete -> insert
Also use existing connection during character saving for proper rollback.
This commit is contained in:
@@ -8464,7 +8464,7 @@ public class Character extends AbstractCharacterObject {
|
||||
ps.setInt(i + 31, getSlots(i));
|
||||
}
|
||||
|
||||
monsterbook.saveCards(getId());
|
||||
monsterbook.saveCards(con, id);
|
||||
|
||||
ps.setInt(36, bookCover);
|
||||
ps.setInt(37, vanquisherStage);
|
||||
|
||||
@@ -32,12 +32,9 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
public final class MonsterBook {
|
||||
private static final Semaphore semaphore = new Semaphore(10);
|
||||
|
||||
private int specialCard = 0;
|
||||
private int normalCard = 0;
|
||||
private int bookLevel = 1;
|
||||
@@ -180,61 +177,27 @@ public final class MonsterBook {
|
||||
calculateLevel();
|
||||
}
|
||||
|
||||
private static int saveStringConcat(char[] data, int pos, Integer i) {
|
||||
return saveStringConcat(data, pos, i.toString());
|
||||
}
|
||||
public void saveCards(Connection con, int chrId) throws SQLException {
|
||||
final String query = """
|
||||
INSERT INTO monsterbook (charid, cardid, level)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE level = ?;
|
||||
""";
|
||||
try (final PreparedStatement ps = con.prepareStatement(query)) {
|
||||
for (Map.Entry<Integer, Integer> cardAndLevel : cards.entrySet()) {
|
||||
final int card = cardAndLevel.getKey();
|
||||
final int level = cardAndLevel.getValue();
|
||||
// insert
|
||||
ps.setInt(1, chrId);
|
||||
ps.setInt(2, card);
|
||||
ps.setInt(3, level);
|
||||
|
||||
private static int saveStringConcat(char[] data, int pos, String s) {
|
||||
int len = s.length();
|
||||
for (int j = 0; j < len; j++) {
|
||||
data[pos + j] = s.charAt(j);
|
||||
}
|
||||
// update
|
||||
ps.setInt(4, level);
|
||||
|
||||
return pos + len;
|
||||
}
|
||||
|
||||
private static String getSaveString(Integer charid, Set<Entry<Integer, Integer>> cardSet) {
|
||||
semaphore.acquireUninterruptibly();
|
||||
try {
|
||||
char[] save = new char[400000]; // 500 * 10 * 10 * 8
|
||||
int i = 0;
|
||||
|
||||
i = saveStringConcat(save, i, "INSERT INTO monsterbook VALUES ");
|
||||
|
||||
for (Entry<Integer, Integer> all : cardSet) { // assuming maxsize 500 unique cards
|
||||
i = saveStringConcat(save, i, "(");
|
||||
i = saveStringConcat(save, i, charid); //10 chars
|
||||
i = saveStringConcat(save, i, ", ");
|
||||
i = saveStringConcat(save, i, all.getKey()); //10 chars
|
||||
i = saveStringConcat(save, i, ", ");
|
||||
i = saveStringConcat(save, i, all.getValue()); //1 char due to being 0 ~ 5
|
||||
i = saveStringConcat(save, i, "),");
|
||||
ps.addBatch();
|
||||
}
|
||||
|
||||
return new String(save, 0, i - 1);
|
||||
} finally {
|
||||
semaphore.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveCards(final int charid) {
|
||||
Set<Entry<Integer, Integer>> cardSet = getCardSet();
|
||||
|
||||
if (cardSet.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM monsterbook WHERE charid = ?")) {
|
||||
ps.setInt(1, charid);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
|
||||
try (PreparedStatement ps = con.prepareStatement(getSaveString(charid, cardSet))) {
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user