server: database improves:

- fixed broken database in some use cases (example: AI and choose name dialog, related to #11285);
- added docs and debug tools for sql queries, caches and memory analyse (see DebugUtil);
- refactor code to use shared settings;
- deleted outdated and un-used code (db logs, stats, etc);
This commit is contained in:
Oleg Agafonov 2024-07-18 21:22:10 +04:00
parent c448612c97
commit bf3f26ccc1
18 changed files with 376 additions and 394 deletions

View file

@ -5,9 +5,8 @@ import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import mage.cards.repository.DatabaseUtils;
import mage.db.model.Feedback;
import mage.db.model.Log;
import mage.utils.properties.PropertiesUtil;
import java.io.File;
import java.sql.SQLException;
@ -21,20 +20,15 @@ public enum EntityManager {
instance;
private Dao<Log, Object> logDao;
private Dao<Feedback, Object> feedbackDao;
private EntityManager() {
EntityManager() {
File file = new File("db");
if (!file.exists()) {
file.mkdirs();
}
try {
ConnectionSource logConnectionSource = new JdbcConnectionSource(PropertiesUtil.getDBLogUrl());
TableUtils.createTableIfNotExists(logConnectionSource, Log.class);
logDao = DaoManager.createDao(logConnectionSource, Log.class);
ConnectionSource feedbackConnectionSource = new JdbcConnectionSource(PropertiesUtil.getDBFeedbackUrl());
ConnectionSource feedbackConnectionSource = new JdbcConnectionSource(DatabaseUtils.prepareH2Connection(DatabaseUtils.DB_NAME_FEEDBACK, false));
TableUtils.createTableIfNotExists(feedbackConnectionSource, Feedback.class);
feedbackDao = DaoManager.createDao(feedbackConnectionSource, Feedback.class);
} catch (SQLException ex) {
@ -42,22 +36,6 @@ public enum EntityManager {
}
}
public void insertLog(String key, java.util.Date date, String... args) throws SQLException {
Log logEntity = new Log(key, date);
logEntity.setArguments(args);
logDao.create(logEntity);
}
public List<Log> getAllLogs() {
List<Log> logs = new ArrayList<>();
try {
logs = logDao.queryForAll();
} catch (SQLException ex) {
}
return logs;
}
public void insertFeedback(String username, String title, String type, String message, String email, String host, java.util.Date created) throws SQLException {
Feedback feedback = new Feedback(username, title, type, message, email, host, created, "new");
feedbackDao.create(feedback);

View file

@ -12,26 +12,7 @@ import java.util.List;
*/
public final class EntityManagerTest {
private static DateFormat timeFormatter = SimpleDateFormat.getTimeInstance(SimpleDateFormat.FULL);
public static void main(String[] args) throws Exception {
List<Log> logs = EntityManager.instance.getAllLogs();
System.out.println("logs found: " + logs.size());
for (Log log : logs) {
System.out.println(" key=" + log.getKey());
System.out.println(" date=" + timeFormatter.format(log.getCreatedDate()));
System.out.print(" arguments=[ ");
if (log.getArguments() != null) {
for (String argument : log.getArguments()) {
System.out.print("arg=" + argument + ' ');
}
}
System.out.println("]");
System.out.println(" --------------");
}
System.out.println("********************************");
List<Feedback> feedbackList = EntityManager.instance.getAllFeedbacks();
System.out.println("feedbacks found: " + feedbackList.size());
int count = 1;

View file

@ -1,113 +0,0 @@
package mage.db;
import mage.db.model.Log;
import java.util.*;
/**
* @author noxx
*/
public final class Statistics {
public static void main(String[] args) throws Exception {
List<Log> logs = EntityManager.instance.getAllLogs();
System.out.println("logs found: " + logs.size());
Map<String, Integer> nicknames = displayCommonNumbers(logs);
List<Integer> games = displayTop3(nicknames);
displayPlayedOnlyOnce(games);
System.out.println("Done");
}
private static void displayPlayedOnlyOnce(List<Integer> games) {
Integer oneGame = 0;
for (Integer numberOfGames : games) {
if (numberOfGames == 1) {
oneGame++;
}
}
System.out.println("Number of players played only one game: " + oneGame);
}
private static List<Integer> displayTop3(Map<String, Integer> nicknames) {
Collection<Integer> values = nicknames.values();
List<Integer> games = new ArrayList<>();
games.addAll(values);
Collections.sort(games, new Comparator<Integer>() {
@Override
public int compare(Integer i1, Integer i2) {
return i2.compareTo(i1);
}
});
// Top-3
List<Integer> numbersToFind = new ArrayList<>();
for (Integer numberOfGames : games) {
numbersToFind.add(numberOfGames);
if (numbersToFind.size() == 3) {
break;
}
}
Map<Integer, String> players = new LinkedHashMap<>();
for (Map.Entry<String, Integer> entry : nicknames.entrySet()) {
if (check(numbersToFind, entry.getValue())) {
players.put(entry.getValue(), entry.getKey());
}
if (players.size() == 3) {
break;
}
}
System.out.println("Top-3");
for (Map.Entry<Integer, String> entry : players.entrySet()) {
System.out.println(" " + entry.getValue() + ": " + entry.getKey());
}
return games;
}
private static Map<String, Integer> displayCommonNumbers(List<Log> logs) {
int count = 0;
Map<String, Integer> nicknames = new HashMap<>();
for (Log log : logs) {
if (log.getKey().equals("gameStarted")) {
if (log.getArguments() != null) {
int index = 0;
for (String argument : log.getArguments()) {
if (index > 0) {
inc(nicknames, argument);
}
index++;
}
}
count++;
}
}
System.out.println("********************************");
System.out.println("Games played: " + count);
System.out.println("Number of players: " + nicknames.size());
return nicknames;
}
public static void inc(Map<String, Integer> map, String player) {
if (map.containsKey(player)) {
Integer count = map.get(player);
count++;
map.put(player, count);
} else {
map.put(player, 1);
}
}
public static boolean check(List<Integer> numbers, Integer value) {
for (Integer number : numbers) {
if (number.equals(value)) {
return true;
}
}
return false;
}
}

View file

@ -1,59 +0,0 @@
package mage.utils.properties;
import org.apache.log4j.Logger;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author noxx
*/
public final class PropertiesUtil {
private static final Logger logger = Logger.getLogger(PropertiesUtil.class);
private static final String LOG_JDBC_URL = "jdbc:h2:file:./db/mage.h2;AUTO_SERVER=TRUE";
private static final String FEEDBACK_JDBC_URL = "jdbc:h2:file:./db/feedback.h2;AUTO_SERVER=TRUE";
private static Properties properties = new Properties();
static {
try (InputStream in = PropertiesUtil.class.getResourceAsStream("/xmage.properties")) {
if(in != null) {
properties.load(in);
} else {
logger.warn("No xmage.properties were found");
}
} catch (FileNotFoundException fnfe) {
logger.warn("No xmage.properties were found on classpath");
} catch (IOException e) {
logger.error("Couldn't load properties");
e.printStackTrace();
}
}
/**
* Hide constructor
*/
private PropertiesUtil() {
}
public static String getDBLogUrl () {
String url = properties.getProperty(PropertyKeys.KEY_DB_LOG_URL, LOG_JDBC_URL);
if (url != null) {
return url.trim();
}
return null;
}
public static String getDBFeedbackUrl () {
String url = properties.getProperty(PropertyKeys.KEY_DB_FEEDBACK_URL, FEEDBACK_JDBC_URL);
if (url != null) {
return url.trim();
}
return null;
}
}

View file

@ -1,10 +0,0 @@
package mage.utils.properties;
/**
* @author noxx
*/
public final class PropertyKeys {
public static final String KEY_DB_LOG_URL = "db.log.url";
public static final String KEY_DB_FEEDBACK_URL = "db.feedback.url";
}