Refactoring de l'ORM : package 'db2' -> 'db' + typage plus précis des SQLField

This commit is contained in:
2016-07-15 02:05:22 +02:00
parent 724e9ecd6c
commit 805ff052d3
47 changed files with 850 additions and 845 deletions

View File

@@ -0,0 +1,43 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLContact extends SQLElement<SQLContact> {
public SQLContact() {
super();
}
public SQLContact(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_contact";
}
public static final SQLField<SQLContact, Integer> time = new SQLField<>("time", SQLType.INT, false);
public static final SQLFKField<SQLContact, String, SQLPlayer> playerId = new SQLFKField<>("playerId", SQLType.CHAR(36), true,
SQLPlayer.playerId);
public static final SQLField<SQLContact, String> userName = new SQLField<>("userName", SQLType.VARCHAR(50), true);
public static final SQLField<SQLContact, String> userMail = new SQLField<>("userMail", SQLType.VARCHAR(50), true);
public static final SQLField<SQLContact, String> titre = new SQLField<>("titre", SQLType.VARCHAR(100), false);
public static final SQLField<SQLContact, String> texte = new SQLField<>("texte", SQLType.TEXT, false);
public static final SQLField<SQLContact, Boolean> hidden = new SQLField<>("hidden", SQLType.BOOLEAN, false, (Boolean) false);
public UUID getPlayerId() {
String id = get(playerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setPlayerId(UUID pName) {
set(playerId, (pName == null) ? (String) null : pName.toString());
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.java.util.db;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLForumCategorie extends SQLElement<SQLForumCategorie> {
public SQLForumCategorie() {
super();
}
public SQLForumCategorie(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_forum_categorie";
}
public static final SQLField<SQLForumCategorie, String> nom = new SQLField<>("nom", SQLType.VARCHAR(100), false);
public static final SQLField<SQLForumCategorie, Integer> ordre = new SQLField<>("ordre", SQLType.INT, false);
}

View File

@@ -0,0 +1,36 @@
package fr.pandacube.java.util.db;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLForumForum extends SQLElement<SQLForumForum> {
public SQLForumForum() {
super();
}
public SQLForumForum(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_forum_forum";
}
public static final SQLFKField<SQLForumForum, Integer, SQLForumCategorie> catId = SQLFKField.idFK("catId", SQLType.INT, false,
SQLForumCategorie.class);
public static final SQLField<SQLForumForum, String> nom = new SQLField<>("nom", SQLType.VARCHAR(100), false);
public static final SQLField<SQLForumForum, String> description = new SQLField<>("description", SQLType.TEXT, false);
public static final SQLField<SQLForumForum, Integer> ordre = new SQLField<>("ordre", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> authView = new SQLField<>("authView", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> authPost = new SQLField<>("authPost", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> authThread = new SQLField<>("authThread", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> authAnchored = new SQLField<>("authAnchored", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> authModo = new SQLField<>("authModo", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> nbThreads = new SQLField<>("nbThreads", SQLType.INT, false);
public static final SQLField<SQLForumForum, Integer> nbMessages = new SQLField<>("nbMessages", SQLType.INT, false);
}

View File

@@ -0,0 +1,41 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLForumPost extends SQLElement<SQLForumPost> {
public SQLForumPost() {
super();
}
public SQLForumPost(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_forum_post";
}
public static final SQLField<SQLForumPost, String> createur = new SQLField<>("createur", SQLType.CHAR(36), false);
public static final SQLField<SQLForumPost, String> texte = new SQLField<>("texte", SQLType.TEXT, false);
public static final SQLField<SQLForumPost, Integer> time = new SQLField<>("time", SQLType.INT, false);
public static final SQLFKField<SQLForumPost, Integer, SQLForumThread> threadId = SQLFKField.idFK("threadId", SQLType.INT, false,
SQLForumThread.class);
public static final SQLField<SQLForumPost, Boolean> moderated = new SQLField<>("moderated", SQLType.BOOLEAN, false);
public UUID getCreateurId() {
String id = get(createur);
return (id == null) ? null : UUID.fromString(id);
}
public void setCreateurId(UUID pName) {
set(createur, (pName == null) ? (String) null : pName.toString());
}
}

View File

@@ -0,0 +1,45 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLForumThread extends SQLElement<SQLForumThread> {
public SQLForumThread() {
super();
}
public SQLForumThread(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_forum_thread";
}
public static final SQLFKField<SQLForumThread, Integer, SQLForumForum> forumId = SQLFKField.idFK("forumId", SQLType.INT, false,
SQLForumForum.class);
public static final SQLField<SQLForumThread, String> titre = new SQLField<>("titre", SQLType.VARCHAR(60), false);
public static final SQLFKField<SQLForumThread, String, SQLPlayer> createur = new SQLFKField<>("createur", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLField<SQLForumThread, Integer> vu = new SQLField<>("vu", SQLType.INT, false);
public static final SQLField<SQLForumThread, Long> time = new SQLField<>("time", SQLType.BIGINT, false);
public static final SQLField<SQLForumThread, Boolean> anchored = new SQLField<>("anchored", SQLType.BOOLEAN, false);
public static final SQLField<SQLForumThread, Boolean> locked = new SQLField<>("locked", SQLType.BOOLEAN, false);
public static final SQLField<SQLForumThread, Integer> nbMessages = new SQLField<>("nbMessages", SQLType.INT, false);
public UUID getCreateurId() {
String id = get(createur);
return (id == null) ? null : UUID.fromString(id);
}
public void setCreateurId(UUID pName) {
set(createur, (pName == null) ? (String) null : pName.toString());
}
}

View File

@@ -0,0 +1,47 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLLoginHistory extends SQLElement<SQLLoginHistory> {
public SQLLoginHistory() {
super();
}
public SQLLoginHistory(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_login_history";
}
public static final SQLField<SQLLoginHistory, Long> time = new SQLField<>("time", SQLType.BIGINT, false);
public static final SQLFKField<SQLLoginHistory, String, SQLPlayer> playerId = new SQLFKField<>("playerId", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLField<SQLLoginHistory, String> ip = new SQLField<>("ip", SQLType.VARCHAR(128), true);
public static final SQLField<SQLLoginHistory, ActionType> actionType = new SQLField<>("actionType", SQLType.ENUM(ActionType.class),
false);
public static final SQLField<SQLLoginHistory, Integer> nbOnline = new SQLField<>("nbOnline", SQLType.INT, false);
public static final SQLField<SQLLoginHistory, String> playerName = new SQLField<>("playerName", SQLType.VARCHAR(16), true);
public static final SQLField<SQLLoginHistory, Integer> minecraftVersion = new SQLField<>("minecraftVersion", SQLType.INT, false, 0);
public UUID getPlayerId() {
String id = get(playerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setPlayerId(UUID pName) {
set(playerId, (pName == null) ? (String) null : pName.toString());
}
public enum ActionType {
LOGIN, LOGOUT
}
}

View File

@@ -0,0 +1,41 @@
package fr.pandacube.java.util.db;
import fr.pandacube.java.util.db.sql_tools.ORM;
import fr.pandacube.java.util.db.sql_tools.ORMException;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLElementList;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLOrderBy;
import fr.pandacube.java.util.db.sql_tools.SQLType;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
public class SQLMPGroup extends SQLElement<SQLMPGroup> {
public SQLMPGroup() {
super();
}
public SQLMPGroup(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_mp_group";
}
public static final SQLField<SQLMPGroup, String> groupName = new SQLField<>("groupName", SQLType.VARCHAR(16), false);
public SQLElementList<SQLMPGroupUser> getGroupUsers() throws ORMException {
return ORM.getAll(SQLMPGroupUser.class, new SQLWhereComp(SQLMPGroupUser.groupId, SQLComparator.EQ, getId()),
new SQLOrderBy().addField(ORM.getSQLIdField(SQLMPGroupUser.class)), null, null);
}
public static SQLMPGroup getByName(String name) throws ORMException {
if (name == null) return null;
return ORM.getFirst(SQLMPGroup.class, new SQLWhereComp(groupName, SQLComparator.EQ, name), null);
}
}

View File

@@ -0,0 +1,63 @@
package fr.pandacube.java.util.db;
import java.sql.SQLException;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.ORM;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain.SQLBoolOp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
public class SQLMPGroupUser extends SQLElement<SQLMPGroupUser> {
public SQLMPGroupUser() {
super();
}
public SQLMPGroupUser(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_mp_group_user";
}
public static final SQLFKField<SQLMPGroupUser, Integer, SQLMPGroup> groupId = SQLFKField.idFK("groupId", SQLType.INT, false,
SQLMPGroup.class);
public static final SQLFKField<SQLMPGroupUser, String, SQLPlayer> playerId = new SQLFKField<>("playerId", SQLType.CHAR(36), false,
SQLPlayer.playerId);
// TODO ajouter un champ qui dit si le joueur est admin du groupe
public UUID getPlayerId() {
String id = get(playerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setPlayerId(UUID id) {
set(playerId, (id == null) ? null : id.toString());
}
/**
* Retourne l'instance de SQLMPGroupUser correcpondant à la présence d'un
* joueur dans un groupe
*
* @param group le groupe concerné, sous forme d'instance de SQLMPGroup
* @param player l'identifiant du joueur
* @return null si la correspondance n'a pas été trouvée
* @throws SQLException
*/
public static SQLMPGroupUser getPlayerInGroup(SQLMPGroup group, UUID player) throws Exception {
if (player == null || group == null) return null;
return ORM.getFirst(SQLMPGroupUser.class,
new SQLWhereChain(SQLBoolOp.AND).add(new SQLWhereComp(groupId, SQLComparator.EQ, group.getId()))
.add(new SQLWhereComp(playerId, SQLComparator.EQ, player.toString())),
null);
}
}

View File

@@ -0,0 +1,137 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.PlayerFinder;
import fr.pandacube.java.util.db.sql_tools.ORM;
import fr.pandacube.java.util.db.sql_tools.ORMException;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLElementList;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLOrderBy;
import fr.pandacube.java.util.db.sql_tools.SQLType;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereLike;
import fr.pandacube.java.util.db.sql_tools.SQLWhereNull;
import fr.pandacube.java.util.db.sql_tools.SQLOrderBy.Direction;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain.SQLBoolOp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
public class SQLMPMessage extends SQLElement<SQLMPMessage> {
public SQLMPMessage() {
super();
}
public SQLMPMessage(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_mp_message";
}
public static final SQLField<SQLMPMessage, Long> time = new SQLField<>("time", SQLType.BIGINT, false);
public static final SQLField<SQLMPMessage, Integer> securityKey = new SQLField<>("securityKey", SQLType.INT, false);
public static final SQLFKField<SQLMPMessage, String, SQLPlayer> viewerId = new SQLFKField<>("viewerId", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLFKField<SQLMPMessage, String, SQLPlayer> sourceId = new SQLFKField<>("sourceId", SQLType.CHAR(36), true,
SQLPlayer.playerId);
public static final SQLFKField<SQLMPMessage, String, SQLPlayer> destId = new SQLFKField<>("destId", SQLType.CHAR(36), true,
SQLPlayer.playerId);
public static final SQLFKField<SQLMPMessage, Integer, SQLMPGroup> destGroup = SQLFKField.idFK("destGroup", SQLType.INT, true,
SQLMPGroup.class);
public static final SQLField<SQLMPMessage, String> message = new SQLField<>("message", SQLType.VARCHAR(512), false);
public static final SQLField<SQLMPMessage, Boolean> wasRead = new SQLField<>("wasRead", SQLType.BOOLEAN, false);
public static final SQLField<SQLMPMessage, Boolean> deleted = new SQLField<>("deleted", SQLType.BOOLEAN, false, (Boolean) false);
public static final SQLField<SQLMPMessage, Boolean> serverSync = new SQLField<>("serverSync", SQLType.BOOLEAN, false);
public UUID getViewerId() {
String id = get(viewerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setViewerId(UUID id) {
set(viewerId, (id == null) ? null : id.toString());
}
public UUID getSourceId() {
String id = get(sourceId);
return (id == null) ? null : UUID.fromString(id);
}
public void setSourceId(UUID id) {
set(sourceId, (id == null) ? null : id.toString());
}
public UUID getDestId() {
String id = get(destId);
return (id == null) ? null : UUID.fromString(id);
}
public void setDestId(UUID id) {
set(destId, (id == null) ? null : id.toString());
}
public static SQLElementList<SQLMPMessage> getAllUnsyncMessage() throws ORMException {
return ORM.getAll(SQLMPMessage.class, new SQLWhereComp(SQLMPMessage.serverSync, SQLComparator.EQ, false),
new SQLOrderBy().addField(SQLMPMessage.time), null, null);
}
public static SQLElementList<SQLMPMessage> getAllUnreadForPlayer(UUID player) throws ORMException {
return getForPlayer(player, true, null, false);
}
public static SQLElementList<SQLMPMessage> getOneDiscussionForPlayer(UUID player, Object discussion,
Integer numberLast, boolean revert) throws ORMException {
if (player == null) return null;
if (discussion != null && !(discussion instanceof String) && !(discussion instanceof UUID)) return null;
if (discussion != null && discussion instanceof String
&& !PlayerFinder.isValidPlayerName(discussion.toString()))
return null;
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.AND)
.add(new SQLWhereComp(SQLMPMessage.viewerId, SQLComparator.EQ, player.toString()));
if (discussion == null) // message de système
where.add(new SQLWhereNull(SQLMPMessage.sourceId, true))
.add(new SQLWhereNull(SQLMPMessage.destGroup, true));
else if (discussion instanceof String) { // message de groupe
SQLMPGroup groupEl = ORM.getFirst(SQLMPGroup.class,
new SQLWhereComp(SQLMPGroup.groupName, SQLComparator.EQ, (String) discussion), null);
if (groupEl == null) return null;
where.add(new SQLWhereComp(SQLMPMessage.destGroup, SQLComparator.EQ, groupEl.getId()));
}
else if (discussion instanceof UUID && discussion.equals(player)) // message
// à
// lui
// même
where.add(new SQLWhereLike(SQLMPMessage.destId, discussion.toString()))
.add(new SQLWhereLike(SQLMPMessage.sourceId, discussion.toString()))
.add(new SQLWhereNull(SQLMPMessage.destGroup, true));
else // discussion instanceof UUID
where.add(new SQLWhereChain(SQLBoolOp.OR).add(new SQLWhereLike(SQLMPMessage.destId, discussion.toString()))
.add(new SQLWhereLike(SQLMPMessage.sourceId, discussion.toString())))
.add(new SQLWhereNull(SQLMPMessage.destGroup, true));
SQLOrderBy orderBy = new SQLOrderBy().addField(SQLMPMessage.time, revert ? Direction.DESC : Direction.ASC);
return ORM.getAll(SQLMPMessage.class, where, orderBy, numberLast, null);
}
public static SQLElementList<SQLMPMessage> getForPlayer(UUID player, boolean onlyUnread, Integer numberLast,
boolean revert) throws ORMException {
if (player == null) return null;
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.AND);
where.add(new SQLWhereComp(SQLMPMessage.viewerId, SQLComparator.EQ, player.toString()));
if (onlyUnread) where.add(new SQLWhereComp(SQLMPMessage.wasRead, SQLComparator.EQ, false));
SQLOrderBy orderBy = new SQLOrderBy().addField(SQLMPMessage.time, revert ? Direction.DESC : Direction.ASC);
return ORM.getAll(SQLMPMessage.class, where, orderBy, numberLast, null);
}
}

View File

@@ -0,0 +1,57 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLModoHistory extends SQLElement<SQLModoHistory> {
public SQLModoHistory() {
super();
}
public SQLModoHistory(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_modo_history";
}
public static final SQLFKField<SQLModoHistory, String, SQLPlayer> modoId = new SQLFKField<>("modoId", SQLType.CHAR(36), true,
SQLPlayer.playerId);
public static final SQLField<SQLModoHistory, ActionType> actionType = new SQLField<>("actionType", SQLType.ENUM(ActionType.class),
false);
public static final SQLField<SQLModoHistory, Long> time = new SQLField<>("time", SQLType.BIGINT, false);
public static final SQLFKField<SQLModoHistory, String, SQLPlayer> playerId = new SQLFKField<>("playerId", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLField<SQLModoHistory, Long> value = new SQLField<>("value", SQLType.BIGINT, true);
public static final SQLField<SQLModoHistory, String> message = new SQLField<>("message", SQLType.VARCHAR(512), false);
public UUID getModoId() {
String id = get(modoId);
return (id == null) ? null : UUID.fromString(id);
}
public void setModoId(UUID pName) {
set(modoId, (pName == null) ? (String) null : pName.toString());
}
public UUID getPlayerId() {
String id = get(playerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setPlayerId(UUID pName) {
set(playerId, (pName == null) ? (String) null : pName.toString());
}
public enum ActionType {
BAN, UNBAN, MUTE, UNMUTE, REPORT, KICK
}
}

View File

@@ -0,0 +1,65 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLOnlineshopHistory extends SQLElement<SQLOnlineshopHistory> {
public SQLOnlineshopHistory() {
super();
}
public SQLOnlineshopHistory(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_onlineshop_history";
}
public static final SQLField<SQLOnlineshopHistory, Long> time = new SQLField<>("time", SQLType.BIGINT, false);
public static final SQLField<SQLOnlineshopHistory, String> transactionId = new SQLField<>("transactionId", SQLType.VARCHAR(255), true);
public static final SQLField<SQLOnlineshopHistory, SourceType> sourceType = new SQLField<>("sourceType", SQLType.ENUM(SourceType.class),
false);
public static final SQLFKField<SQLOnlineshopHistory, String, SQLPlayer> sourcePlayerId = new SQLFKField<>("sourcePlayerId",
SQLType.CHAR(36), true, SQLPlayer.playerId);
public static final SQLField<SQLOnlineshopHistory, Double> sourceQuantity = new SQLField<>("sourceQuantity", SQLType.DOUBLE, false);
public static final SQLField<SQLOnlineshopHistory, String> sourceName = new SQLField<>("sourceName", SQLType.VARCHAR(64), false);
public static final SQLField<SQLOnlineshopHistory, DestType> destType = new SQLField<>("destType", SQLType.ENUM(DestType.class), false);
public static final SQLFKField<SQLOnlineshopHistory, String, SQLPlayer> destPlayerId = new SQLFKField<>("destPlayerId", SQLType.CHAR(36),
false, SQLPlayer.playerId);
public static final SQLField<SQLOnlineshopHistory, Double> destQuantity = new SQLField<>("destQuantity", SQLType.DOUBLE, false);
public static final SQLField<SQLOnlineshopHistory, String> destName = new SQLField<>("destName", SQLType.VARCHAR(64), false);
public UUID getSourcePlayerId() {
String id = get(sourcePlayerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setSourcePlayerId(UUID pName) {
set(sourcePlayerId, (pName == null) ? (String) null : pName.toString());
}
public UUID getDestPlayerId() {
String id = get(destPlayerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setDestPlayerId(UUID pName) {
set(destPlayerId, (pName == null) ? (String) null : pName.toString());
}
public static enum SourceType {
REAL_MONEY, BAMBOU
}
public static enum DestType {
BAMBOU, GRADE
}
}

View File

@@ -0,0 +1,91 @@
package fr.pandacube.java.util.db;
import java.sql.Date;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.ORM;
import fr.pandacube.java.util.db.sql_tools.ORMException;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
public class SQLPlayer extends SQLElement<SQLPlayer> {
public SQLPlayer() {
super();
}
public SQLPlayer(int id) {
super(id);
}
/*
* Nom de la table
*/
@Override
protected String tableName() {
return "pandacube_player";
}
/*
* Champs de la table
*/
public static final SQLField<SQLPlayer, String> playerId = new SQLField<>("playerId", SQLType.CHAR(36), false);
public static final SQLField<SQLPlayer, String> token = new SQLField<>("token", SQLType.CHAR(36), true);
public static final SQLField<SQLPlayer, String> mailCheck = new SQLField<>("mailCheck", SQLType.VARCHAR(255), true);
public static final SQLField<SQLPlayer, String> password = new SQLField<>("password", SQLType.VARCHAR(255), true);
public static final SQLField<SQLPlayer, String> mail = new SQLField<>("mail", SQLType.VARCHAR(255), true);
public static final SQLField<SQLPlayer, String> playerDisplayName = new SQLField<>("playerDisplayName", SQLType.VARCHAR(255),
false);
public static final SQLField<SQLPlayer, Long> firstTimeInGame = new SQLField<>("firstTimeInGame", SQLType.BIGINT, false, 0L);
public static final SQLField<SQLPlayer, Long> timeWebRegister = new SQLField<>("timeWebRegister", SQLType.BIGINT, true);
public static final SQLField<SQLPlayer, Long> lastTimeInGame = new SQLField<>("lastTimeInGame", SQLType.BIGINT, true);
public static final SQLField<SQLPlayer, Long> lastWebActivity = new SQLField<>("lastWebActivity", SQLType.BIGINT, false, 0L);
public static final SQLField<SQLPlayer, String> onlineInServer = new SQLField<>("onlineInServer", SQLType.VARCHAR(32), true);
public static final SQLField<SQLPlayer, String> skinURL = new SQLField<>("skinURL", SQLType.VARCHAR(255), true);
public static final SQLField<SQLPlayer, Boolean> isVanish = new SQLField<>("isVanish", SQLType.BOOLEAN, false,
(Boolean) false);
public static final SQLField<SQLPlayer, Date> birthday = new SQLField<>("birthday", SQLType.DATE, true);
public static final SQLField<SQLPlayer, Integer> lastYearCelebBday = new SQLField<>("lastYearCelebratedBirthday", SQLType.INT,
false, 0);
public static final SQLField<SQLPlayer, Long> banTimeout = new SQLField<>("banTimeout", SQLType.BIGINT, true);
public static final SQLField<SQLPlayer, Long> muteTimeout = new SQLField<>("muteTimeout", SQLType.BIGINT, true);
public static final SQLField<SQLPlayer, Boolean> isWhitelisted = new SQLField<>("isWhitelisted", SQLType.BOOLEAN, false,
(Boolean) false);
public static final SQLField<SQLPlayer, Long> bambou = new SQLField<>("bambou", SQLType.BIGINT, false, 0L);
public static final SQLField<SQLPlayer, String> grade = new SQLField<>("grade", SQLType.VARCHAR(36), false, "default");
/*
* Getteurs spécifique (encapsulation)
*/
public UUID getPlayerId() {
String id = get(playerId);
return (id == null) ? null : UUID.fromString(id);
}
public UUID getToken() {
String id = get(token);
return (id == null) ? null : UUID.fromString(id);
}
/*
* Setteurs spécifique (encapsulation)
*/
public void setPlayerId(UUID pName) {
set(playerId, (pName == null) ? (String) null : pName.toString());
}
public void setToken(UUID t) {
set(token, (t == null) ? (String) null : t.toString());
}
public static SQLPlayer getPlayerFromUUID(UUID playerId) throws ORMException {
return ORM.getFirst(SQLPlayer.class,
new SQLWhereComp(SQLPlayer.playerId, SQLComparator.EQ, playerId.toString()), null);
}
}

View File

@@ -0,0 +1,93 @@
package fr.pandacube.java.util.db;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.ORM;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLOrderBy;
import fr.pandacube.java.util.db.sql_tools.SQLType;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain.SQLBoolOp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
public class SQLPlayerIgnore extends SQLElement<SQLPlayerIgnore> {
public SQLPlayerIgnore() {
super();
}
public SQLPlayerIgnore(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_player_ignore";
}
public static final SQLFKField<SQLPlayerIgnore, String, SQLPlayer> ignorer = new SQLFKField<>("ignorer", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLFKField<SQLPlayerIgnore, String, SQLPlayer> ignored = new SQLFKField<>("ignored", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public UUID getIgnorerId() {
String id = get(ignorer);
return (id == null) ? null : UUID.fromString(id);
}
public void setIgnorerId(UUID pName) {
set(ignorer, (pName == null) ? (String) null : pName.toString());
}
public UUID getIgnoredId() {
String id = get(ignored);
return (id == null) ? null : UUID.fromString(id);
}
public void setIgnoredId(UUID pName) {
set(ignored, (pName == null) ? (String) null : pName.toString());
}
public static SQLPlayerIgnore getPlayerIgnoringPlayer(UUID ignorer, UUID ignored) throws Exception {
return ORM.getFirst(SQLPlayerIgnore.class,
new SQLWhereChain(SQLBoolOp.AND)
.add(new SQLWhereComp(SQLPlayerIgnore.ignorer, SQLComparator.EQ, ignorer.toString()))
.add(new SQLWhereComp(SQLPlayerIgnore.ignored, SQLComparator.EQ, ignored.toString())),
null);
}
public static boolean isPlayerIgnoringPlayer(UUID ignorer, UUID ignored) throws Exception {
return getPlayerIgnoringPlayer(ignorer, ignored) != null;
}
public static void setPlayerIgnorePlayer(UUID ignorer, UUID ignored, boolean newIgnoreState) throws Exception {
SQLPlayerIgnore el = getPlayerIgnoringPlayer(ignorer, ignored);
if (el == null && newIgnoreState) {
el = new SQLPlayerIgnore();
el.setIgnorerId(ignorer);
el.setIgnoredId(ignored);
el.save();
return;
}
if (el != null && !newIgnoreState) {
el.delete();
return;
}
}
public static List<UUID> getListIgnoredPlayer(UUID ignorer) throws Exception {
List<SQLPlayerIgnore> els = ORM.getAll(SQLPlayerIgnore.class,
new SQLWhereComp(SQLPlayerIgnore.ignorer, SQLComparator.EQ, ignorer.toString()),
new SQLOrderBy().addField(ORM.getSQLIdField(SQLPlayerIgnore.class)), null, null);
List<UUID> ret = new ArrayList<>(els.size());
for (SQLPlayerIgnore el : els)
ret.add(el.getIgnoredId());
return ret;
}
}

View File

@@ -0,0 +1,27 @@
package fr.pandacube.java.util.db;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLShopStock extends SQLElement<SQLShopStock> {
public SQLShopStock() {
super();
}
public SQLShopStock(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_shop_stock";
}
public static final SQLField<SQLShopStock, String> material = new SQLField<>("material", SQLType.VARCHAR(50), false);
public static final SQLField<SQLShopStock, Integer> damage = new SQLField<>("damage", SQLType.INT, false, 0);
public static final SQLField<SQLShopStock, Double> quantity = new SQLField<>("quantity", SQLType.DOUBLE, false);
public static final SQLField<SQLShopStock, String> server = new SQLField<>("server", SQLType.VARCHAR(50), false);
}

View File

@@ -0,0 +1,50 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLStaffTicket extends SQLElement<SQLStaffTicket> {
public SQLStaffTicket() {
super();
}
public SQLStaffTicket(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_staff_ticket";
}
public static final SQLFKField<SQLStaffTicket, String, SQLPlayer> playerId = new SQLFKField<>("playerId", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLField<SQLStaffTicket, String> message = new SQLField<>("message", SQLType.VARCHAR(1024), false);
public static final SQLField<SQLStaffTicket, Long> creationTime = new SQLField<>("creationTime", SQLType.BIGINT, false);
public static final SQLFKField<SQLStaffTicket, String, SQLPlayer> staffPlayerId = new SQLFKField<>("staffPlayerId",
SQLType.CHAR(36), true, SQLPlayer.playerId);
public UUID getPlayerId() {
String id = get(playerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setPlayerId(UUID id) {
set(playerId, (id == null) ? null : id.toString());
}
public UUID getstaffPlayerId() {
String id = get(staffPlayerId);
return (id == null) ? null : UUID.fromString(id);
}
public void setstaffPlayerId(UUID id) {
set(staffPlayerId, (id == null) ? null : id.toString());
}
}

View File

@@ -0,0 +1,28 @@
package fr.pandacube.java.util.db;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLStaticPages extends SQLElement<SQLStaticPages> {
public SQLStaticPages() {
super();
}
public SQLStaticPages(int id) {
super(id);
}
@Override
protected String tableName() {
return "pandacube_static_pages";
}
public static final SQLField<SQLStaticPages, String> permalink = new SQLField<>("permalink", SQLType.VARCHAR(128), false);
public static final SQLField<SQLStaticPages, String> titreHead = new SQLField<>("titreHead", SQLType.VARCHAR(128), false);
public static final SQLField<SQLStaticPages, String> titreH2 = new SQLField<>("titreH2", SQLType.VARCHAR(255), false);
public static final SQLField<SQLStaticPages, String> texte = new SQLField<>("texte", SQLType.TEXT, false);
public static final SQLField<SQLStaticPages, String> permissions = new SQLField<>("permissions", SQLType.VARCHAR(255), true);
}

View File

@@ -0,0 +1,38 @@
package fr.pandacube.java.util.db;
import java.util.UUID;
import fr.pandacube.java.util.db.sql_tools.SQLElement;
import fr.pandacube.java.util.db.sql_tools.SQLFKField;
import fr.pandacube.java.util.db.sql_tools.SQLField;
import fr.pandacube.java.util.db.sql_tools.SQLType;
public class SQLUUIDPlayer extends SQLElement<SQLUUIDPlayer> {
public SQLUUIDPlayer() {
super();
}
public SQLUUIDPlayer(int id) {
super(id);
}
@Override
protected String tableName() {
return "bungeeperms_uuidplayer";
}
public static final SQLFKField<SQLUUIDPlayer, String, SQLPlayer> uuid = new SQLFKField<>("uuid", SQLType.CHAR(36), false,
SQLPlayer.playerId);
public static final SQLField<SQLUUIDPlayer, String> player = new SQLField<>("player", SQLType.VARCHAR(16), false);
public UUID getUUID() {
String id = get(uuid);
return (id == null) ? null : UUID.fromString(id);
}
public void setUUID(UUID id) {
set(uuid, (id == null) ? null : id.toString());
}
}

View File

@@ -0,0 +1,51 @@
package fr.pandacube.java.util.db.sql_tools;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class DBConnection {
Connection conn;
String url;
String login;
String pass;
public DBConnection(String host, int port, String dbname, String l, String p)
throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://" + host + ":" + port + "/" + dbname;
login = l;
pass = p;
connect();
}
public void reconnectIfNecessary() throws SQLException {
try {
Statement stmt = conn.createStatement();
stmt.close();
} catch (SQLException e) {
try {
close();
} catch (Exception ex) {}
connect();
}
}
public Connection getNativeConnection() throws SQLException {
if (!conn.isValid(1)) reconnectIfNecessary();
return conn;
}
private void connect() throws SQLException {
conn = DriverManager.getConnection(url, login, pass);
}
public void close() {
try {
conn.close();
} catch (Exception e) {}
}
}

View File

@@ -0,0 +1,289 @@
package fr.pandacube.java.util.db.sql_tools;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import fr.pandacube.java.util.EnumUtil;
import fr.pandacube.java.util.Log;
import fr.pandacube.java.util.db.SQLContact;
import fr.pandacube.java.util.db.SQLForumCategorie;
import fr.pandacube.java.util.db.SQLForumForum;
import fr.pandacube.java.util.db.SQLForumPost;
import fr.pandacube.java.util.db.SQLForumThread;
import fr.pandacube.java.util.db.SQLLoginHistory;
import fr.pandacube.java.util.db.SQLMPGroup;
import fr.pandacube.java.util.db.SQLMPGroupUser;
import fr.pandacube.java.util.db.SQLMPMessage;
import fr.pandacube.java.util.db.SQLModoHistory;
import fr.pandacube.java.util.db.SQLOnlineshopHistory;
import fr.pandacube.java.util.db.SQLPlayer;
import fr.pandacube.java.util.db.SQLPlayerIgnore;
import fr.pandacube.java.util.db.SQLShopStock;
import fr.pandacube.java.util.db.SQLStaffTicket;
import fr.pandacube.java.util.db.SQLStaticPages;
import fr.pandacube.java.util.db.SQLUUIDPlayer;
import fr.pandacube.java.util.db.sql_tools.SQLWhereChain.SQLBoolOp;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
import javafx.util.Pair;
/**
* <b>ORM = Object-Relational Mapping</b>
*
* @author Marc Baloup
*
*/
public final class ORM {
private static List<Class<? extends SQLElement<?>>> tables = new ArrayList<>();
private static DBConnection connection;
public static DBConnection getConnection() {
return connection;
}
public synchronized static void init(DBConnection conn) {
connection = conn;
/*
* Les tables à initialiser
* utile des les initialiser ici, car on peut tout de suite déceler les
* bugs ou erreurs dans la déclaration des SQLFields
*/
try {
initTable(SQLContact.class);
initTable(SQLForumCategorie.class);
initTable(SQLForumForum.class);
initTable(SQLForumPost.class);
initTable(SQLForumThread.class);
initTable(SQLLoginHistory.class);
initTable(SQLModoHistory.class);
initTable(SQLMPGroup.class);
initTable(SQLMPGroupUser.class);
initTable(SQLMPMessage.class);
initTable(SQLOnlineshopHistory.class);
initTable(SQLPlayer.class);
initTable(SQLPlayerIgnore.class);
initTable(SQLShopStock.class);
initTable(SQLStaffTicket.class);
initTable(SQLStaticPages.class);
initTable(SQLUUIDPlayer.class);
} catch (ORMInitTableException e) {
Log.getLogger().log(Level.SEVERE, "Erreur d'initialisation d'une table dans l'ORM", e);
}
}
/* package */ static <E extends SQLElement<E>> void initTable(Class<E> elemClass) throws ORMInitTableException {
if (tables.contains(elemClass)) return;
try {
E instance = elemClass.newInstance();
String tableName = instance.tableName();
if (!tableExist(tableName)) createTable(instance);
tables.add(elemClass);
} catch (Exception e) {
throw new ORMInitTableException(elemClass, e);
}
}
private static <E extends SQLElement<E>> void createTable(E elem) throws SQLException {
String sql = "CREATE TABLE IF NOT EXISTS " + elem.tableName() + " (";
List<Object> params = new ArrayList<>();
Collection<SQLField<E, ?>> tableFields = elem.getFields().values();
boolean first = true;
for (SQLField<E, ?> f : tableFields) {
Pair<String, List<Object>> statementPart = f.forSQLPreparedStatement();
params.addAll(statementPart.getValue());
if (!first) sql += ", ";
first = false;
sql += statementPart.getKey();
}
sql += ", PRIMARY KEY id(id))";
PreparedStatement ps = connection.getNativeConnection().prepareStatement(sql);
int i = 1;
for (Object val : params)
ps.setObject(i++, val);
try {
Log.info("Creating table " + elem.tableName() + ":\n" + ps.toString());
ps.executeUpdate();
} finally {
ps.close();
}
}
private static boolean tableExist(String tableName) throws SQLException {
ResultSet set = null;
boolean exist = false;
try {
set = connection.getNativeConnection().getMetaData().getTables(null, null, tableName, null);
exist = set.next();
} finally {
if (set != null) set.close();
}
return exist;
}
@SuppressWarnings("unchecked")
public static <E extends SQLElement<E>> SQLField<E, Integer> getSQLIdField(Class<E> elemClass)
throws ORMInitTableException {
initTable(elemClass);
return (SQLField<E, Integer>) SQLElement.fieldsCache.get(elemClass).get("id");
}
public static <E extends SQLElement<E>> List<E> getByIds(Class<E> elemClass, Collection<Integer> ids)
throws ORMException {
return getByIds(elemClass, ids.toArray(new Integer[ids.size()]));
}
public static <E extends SQLElement<E>> List<E> getByIds(Class<E> elemClass, Integer... ids) throws ORMException {
SQLField<E, Integer> idField = getSQLIdField(elemClass);
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.OR);
for (Integer id : ids)
if (id != null) where.add(new SQLWhereComp(idField, SQLComparator.EQ, id));
return getAll(elemClass, where, new SQLOrderBy().addField(idField), 1, null);
}
public static <E extends SQLElement<E>> E getById(Class<E> elemClass, int id) throws ORMException {
return getFirst(elemClass, new SQLWhereComp(getSQLIdField(elemClass), SQLComparator.EQ, id), null);
}
public static <E extends SQLElement<E>> E getFirst(Class<E> elemClass, SQLWhere where, SQLOrderBy orderBy)
throws ORMException {
SQLElementList<E> elts = getAll(elemClass, where, orderBy, 1, null);
return (elts.size() == 0) ? null : elts.get(0);
}
public static <E extends SQLElement<E>> SQLElementList<E> getAll(Class<E> elemClass) throws ORMException {
return getAll(elemClass, null, null, null, null);
}
public static <E extends SQLElement<E>> SQLElementList<E> getAll(Class<E> elemClass, SQLWhere where,
SQLOrderBy orderBy, Integer limit, Integer offset) throws ORMException {
initTable(elemClass);
try {
String sql = "SELECT * FROM " + elemClass.newInstance().tableName();
List<Object> params = new ArrayList<>();
if (where != null) {
Pair<String, List<Object>> ret = where.toSQL();
sql += " WHERE " + ret.getKey();
params.addAll(ret.getValue());
}
if (orderBy != null) sql += " ORDER BY " + orderBy.toSQL();
if (limit != null) sql += " LIMIT " + limit;
if (offset != null) sql += " OFFSET " + offset;
sql += ";";
SQLElementList<E> elmts = new SQLElementList<E>();
PreparedStatement ps = connection.getNativeConnection().prepareStatement(sql);
try {
int i = 1;
for (Object val : params) {
if (val instanceof Enum<?>) val = ((Enum<?>) val).name();
ps.setObject(i++, val);
}
Log.debug(ps.toString());
ResultSet set = ps.executeQuery();
try {
while (set.next())
elmts.add(getElementInstance(set, elemClass));
} finally {
set.close();
}
} finally {
ps.close();
}
return elmts;
} catch (ReflectiveOperationException | SQLException e) {
throw new ORMException(e);
}
}
private static <E extends SQLElement<E>> E getElementInstance(ResultSet set, Class<E> elemClass) throws ORMException {
try {
E instance = elemClass.getConstructor(int.class).newInstance(set.getInt("id"));
int fieldCount = set.getMetaData().getColumnCount();
for (int c = 1; c <= fieldCount; c++) {
String fieldName = set.getMetaData().getColumnLabel(c);
if (!instance.getFields().containsKey(fieldName)) continue;
// ignore when field is present in database but not handled by SQLElement instance
@SuppressWarnings("unchecked")
SQLField<E, Object> sqlField = (SQLField<E, Object>) instance.getFields().get(fieldName);
if (sqlField.type.getJavaType().isEnum()) {
// JDBC ne supporte pas les enums
String enumStrValue = set.getString(c);
if (enumStrValue == null || set.wasNull()) instance.set(sqlField, null, false);
else {
Enum<?> enumValue = EnumUtil.searchUncheckedEnum(sqlField.type.getJavaType(), enumStrValue);
if (enumValue == null) throw new ORMException("The enum constant '" + enumStrValue
+ "' is not found in enum class " + sqlField.type.getJavaType().getName());
instance.set(sqlField, enumValue, false);
}
}
else {
Object val = set.getObject(c, sqlField.type.getJavaType());
if (val == null || set.wasNull()) instance.set(sqlField, null, false);
else
instance.set(sqlField, val, false);
}
// la valeur venant de la BDD est marqué comme "non modifié"
// dans l'instance
// car le constructeur de l'instance met tout les champs comme
// modifiés
instance.modifiedSinceLastSave.remove(sqlField.name);
}
if (!instance.isValidForSave()) throw new ORMException(
"This SQLElement representing a database entry is not valid for save : " + instance.toString());
return instance;
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException | SQLException e) {
throw new ORMException("Can't instanciate " + elemClass.getName(), e);
}
}
private ORM() {} // rend la classe non instanciable
/*
* public static void main(String[] args) throws Throwable {
* ORM.init(new DBConnection("localhost", 3306, "pandacube", "pandacube",
* "pandacube"));
* List<SQLPlayer> players = ORM.getAll(SQLPlayer.class,
* new SQLWhereChain(SQLBoolOp.AND)
* .add(new SQLWhereNull(SQLPlayer.banTimeout, true))
* .add(new SQLWhereChain(SQLBoolOp.OR)
* .add(new SQLWhereComp(SQLPlayer.bambou, SQLComparator.EQ, 0L))
* .add(new SQLWhereComp(SQLPlayer.grade, SQLComparator.EQ, "default"))
* ),
* new SQLOrderBy().addField(SQLPlayer.playerDisplayName), null, null);
* for(SQLPlayer p : players) {
* System.out.println(p.get(SQLPlayer.playerDisplayName));
* }
* // TODO LIST
* - Gérer mise à jour relative d'un champ (incrément / décrément)
* }
*/
}

View File

@@ -0,0 +1,18 @@
package fr.pandacube.java.util.db.sql_tools;
public class ORMException extends Exception {
private static final long serialVersionUID = 1L;
public ORMException(Throwable initCause) {
super(initCause);
}
public ORMException(String message, Throwable initCause) {
super(message, initCause);
}
public ORMException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,14 @@
package fr.pandacube.java.util.db.sql_tools;
public class ORMInitTableException extends ORMException {
private static final long serialVersionUID = 1L;
/* package */ <E extends SQLElement<E>> ORMInitTableException(Class<E> tableElem) {
super("Error while initializing table " + tableElem.getName());
}
/* package */ <E extends SQLElement<E>> ORMInitTableException(Class<E> tableElem, Throwable t) {
super("Error while initializing table " + tableElem.getName(), t);
}
}

View File

@@ -0,0 +1,393 @@
package fr.pandacube.java.util.db.sql_tools;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import org.apache.commons.lang.builder.ToStringBuilder;
import fr.pandacube.java.util.Log;
import fr.pandacube.java.util.db.sql_tools.SQLWhereComp.SQLComparator;
public abstract class SQLElement<E extends SQLElement<E>> {
/** cache for fields for each subclass of SQLElement */
/* package */ static final Map<Class<? extends SQLElement<?>>, SQLFieldMap<? extends SQLElement<?>>> fieldsCache = new HashMap<>();
DBConnection db = ORM.getConnection();
private boolean stored = false;
private int id;
private final String tableName;
private final SQLFieldMap<E> fields;
private final Map<SQLField<E, ?>, Object> values;
/* package */ final Set<String> modifiedSinceLastSave;
@SuppressWarnings("unchecked")
public SQLElement() {
tableName = tableName();
if (fieldsCache.get(getClass()) == null) {
fields = new SQLFieldMap<>((Class<E>)getClass());
// le champ id commun à toutes les tables
fields.addField(new SQLField<>("id", SQLType.INT, false, true, 0));
generateFields(fields);
fieldsCache.put((Class<E>)getClass(), fields);
}
else
fields = (SQLFieldMap<E>) fieldsCache.get((Class<E>)getClass());
values = new LinkedHashMap<>(fields.size());
modifiedSinceLastSave = new HashSet<>(fields.size());
initDefaultValues();
}
protected SQLElement(int id) {
this();
@SuppressWarnings("unchecked")
SQLField<E, Integer> idField = (SQLField<E, Integer>) fields.get("id");
set(idField, id, false);
this.id = id;
stored = true;
}
/**
* @return The name of the table in the database.
*/
protected abstract String tableName();
@SuppressWarnings("unchecked")
private void initDefaultValues() {
// remplissage des données par défaut (si peut être null ou si valeur
// par défaut existe)
for (@SuppressWarnings("rawtypes")
SQLField f : fields.values())
if (f.defaultValue != null) set(f, f.defaultValue);
else if (f.canBeNull || (f.autoIncrement && !stored)) set(f, null);
}
protected void generateFields(SQLFieldMap<E> listToFill) {
java.lang.reflect.Field[] declaredFields = getClass().getDeclaredFields();
for (java.lang.reflect.Field field : declaredFields) {
if (!java.lang.reflect.Modifier.isStatic(field.getModifiers())) continue;
try {
Object val = field.get(null);
if (val == null || !(val instanceof SQLField)) continue;
listToFill.addField((SQLField<?, ?>) val);
} catch (IllegalArgumentException | IllegalAccessException e) {
Log.getLogger().log(Level.SEVERE, "Can't get value of static field " + field.toString(), e);
}
}
}
/* package */ Map<String, SQLField<E, ?>> getFields() {
return Collections.unmodifiableMap(fields);
}
public Map<SQLField<E, ?>, Object> getValues() {
return Collections.unmodifiableMap(values);
}
public <T> void set(SQLField<E, T> field, T value) {
set(field, value, true);
}
/* package */ <T> void set(SQLField<E, T> sqlField, T value, boolean setModified) {
if (sqlField == null) throw new IllegalArgumentException("sqlField can't be null");
if (!fields.containsValue(sqlField))
throw new IllegalArgumentException(sqlField.name + " is not a SQLField of " + getClass().getName());
boolean modify = false;
if (value == null) {
if (sqlField.canBeNull || (sqlField.autoIncrement && !stored)) modify = true;
else
throw new IllegalArgumentException(
"SQLField '" + sqlField.name + "' of " + getClass().getName() + " is a NOT NULL field");
}
else if (sqlField.type.isAssignableFrom(value)) modify = true;
else
throw new IllegalArgumentException("SQLField '" + sqlField.name + "' of " + getClass().getName()
+ " type is '" + sqlField.type.toString() + "' and can't accept values of type "
+ value.getClass().getName());
if (modify) if (!values.containsKey(sqlField)) {
values.put(sqlField, value);
if (setModified) modifiedSinceLastSave.add(sqlField.name);
}
else {
Object oldVal = values.get(sqlField);
if (!Objects.equals(oldVal, value)) {
values.put(sqlField, value);
if (setModified) modifiedSinceLastSave.add(sqlField.name);
}
// sinon, rien n'est modifié
}
}
public <T> T get(SQLField<E, T> field) {
if (field == null) throw new IllegalArgumentException("field can't be null");
if (values.containsKey(field)) {
@SuppressWarnings("unchecked")
T val = (T) values.get(field);
return val;
}
throw new IllegalArgumentException("The field '" + field.name + "' in this instance of " + getClass().getName()
+ " does not exist or is not set");
}
public <T, F extends SQLElement<F>> F getForeign(SQLFKField<E, T, F> field) throws ORMException {
T fkValue = get(field);
if (fkValue == null) return null;
return ORM.getFirst(field.getForeignElementClass(),
new SQLWhereComp(field.getForeignField(), SQLComparator.EQ, fkValue), null);
}
public boolean isValidForSave() {
return values.keySet().containsAll(fields.values());
}
private Map<SQLField<E, ?>, Object> getOnlyModifiedValues() {
Map<SQLField<E, ?>, Object> modifiedValues = new LinkedHashMap<>();
values.forEach((k, v) -> {
if (modifiedSinceLastSave.contains(k.name)) modifiedValues.put(k, v);
});
return modifiedValues;
}
public boolean isModified(SQLField<E, ?> field) {
return modifiedSinceLastSave.contains(field.name);
}
@SuppressWarnings("unchecked")
public void save() throws ORMException {
if (!isValidForSave())
throw new IllegalStateException(toString() + " has at least one undefined value and can't be saved.");
ORM.initTable((Class<E>)getClass());
String toStringStatement = "";
try {
Connection conn = db.getNativeConnection();
if (stored) { // mettre à jour les valeurs dans la base
// restaurer l'ID au cas il aurait été changé à la main dans
// values
SQLField<E, Integer> idField = (SQLField<E, Integer>) fields.get("id");
values.put(idField, id);
modifiedSinceLastSave.remove("id");
Map<SQLField<E, ?>, Object> modifiedValues = getOnlyModifiedValues();
if (modifiedValues.isEmpty()) return;
String sql = "";
List<Object> psValues = new ArrayList<>();
for (Map.Entry<SQLField<E, ?>, Object> entry : modifiedValues.entrySet()) {
sql += entry.getKey().name + " = ? ,";
if (entry.getKey().type.getJavaType().isEnum()) // prise en
// charge
// enum (non
// prise en
// charge
// par JDBC)
psValues.add(((Enum<?>) entry.getValue()).name());
else
psValues.add(entry.getValue());
}
if (sql.length() > 0) sql = sql.substring(0, sql.length() - 1);
PreparedStatement ps = conn.prepareStatement("UPDATE " + tableName + " SET " + sql + " WHERE id=" + id);
try {
int i = 1;
for (Object val : psValues)
ps.setObject(i++, val);
toStringStatement = ps.toString();
ps.executeUpdate();
} finally {
ps.close();
}
}
else { // ajouter dans la base
// restaurer l'ID au cas il aurait été changé à la main dans
// values
values.put(fields.get("id"), null);
String concat_vals = "";
String concat_fields = "";
List<Object> psValues = new ArrayList<>();
boolean first = true;
for (Map.Entry<SQLField<E, ?>, Object> entry : values.entrySet()) {
if (!first) {
concat_vals += ",";
concat_fields += ",";
}
first = false;
concat_vals += " ? ";
concat_fields += entry.getKey().name;
if (entry.getKey().type.getJavaType().isEnum()) // prise en
// charge
// enum (non
// prise en
// charge
// par JDBC)
psValues.add(((Enum<?>) entry.getValue()).name());
else
psValues.add(entry.getValue());
}
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO " + tableName + " (" + concat_fields + ") VALUES (" + concat_vals + ")",
Statement.RETURN_GENERATED_KEYS);
try {
int i = 1;
for (Object val : psValues)
ps.setObject(i++, val);
toStringStatement = ps.toString();
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
try {
if (rs.next()) id = rs.getInt(1);
stored = true;
} finally {
rs.close();
}
} finally {
ps.close();
}
}
modifiedSinceLastSave.clear();
} catch (SQLException e) {
throw new ORMException("Error while executing SQL statement " + toStringStatement, e);
}
Log.debug(toStringStatement);
}
public boolean isStored() {
return stored;
}
public Integer getId() {
return (stored) ? id : null;
}
@SuppressWarnings("unchecked")
public SQLField<E, Integer> getFieldId() {
return (SQLField<E, Integer>) fields.get("id");
}
public void delete() throws ORMException {
try {
if (stored) { // supprimer la ligne de la base
PreparedStatement st = db.getNativeConnection()
.prepareStatement("DELETE FROM " + tableName + " WHERE id=" + id);
try {
Log.debug(st.toString());
st.executeUpdate();
markAsNotStored();
} finally {
st.close();
}
}
} catch (SQLException e) {
throw new ORMException(e);
}
}
/**
* Méthode appelée quand l'élément courant est retirée de la base de données
* via une requête externe
*/
/* package */ void markAsNotStored() {
stored = false;
id = 0;
modifiedSinceLastSave.clear();
values.forEach((k, v) -> modifiedSinceLastSave.add(k.name));
}
protected static class SQLFieldMap<E extends SQLElement<E>> extends LinkedHashMap<String, SQLField<E, ?>> {
private static final long serialVersionUID = 1L;
private final Class<E> sqlElemClass;
private SQLFieldMap(Class<E> elemClass) {
sqlElemClass = elemClass;
}
private void addField(SQLField<?, ?> f) {
if (f == null) return;
if (!sqlElemClass.equals(f.getSQLElementType())) return;
if (containsKey(f.name)) throw new IllegalArgumentException(
"SQLField " + f.name + " already exist in " + sqlElemClass.getName());
@SuppressWarnings("unchecked")
SQLField<E, ?> checkedF = (SQLField<E, ?>) f;
checkedF.setSQLElementType(sqlElemClass);
put(checkedF.name, checkedF);
}
}
@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
for (SQLField<E, ?> f : fields.values())
try {
b.append(f.name, get(f));
} catch (IllegalArgumentException e) {
b.append(f.name, "(Undefined)");
}
return b.toString();
}
@Override
public boolean equals(Object o) {
if (o == null || !(getClass().isInstance(o))) return false;
SQLElement<?> oEl = (SQLElement<?>) o;
if (oEl.getId() == null) return false;
return oEl.getId().equals(getId());
}
@Override
public int hashCode() {
return super.hashCode();
}
}

View File

@@ -0,0 +1,166 @@
package fr.pandacube.java.util.db.sql_tools;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import fr.pandacube.java.util.Log;
/**
*
* @param <E>
*/
public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
private static final long serialVersionUID = 1L;
private final Map<SQLField<E, ?>, Object> modifiedValues = new LinkedHashMap<>();
@Override
public synchronized boolean add(E e) {
if (e == null || !e.isStored()) return false;
return super.add(e);
}
/**
* Défini une valeur à un champ qui sera appliquée dans la base de données à
* tous les
* entrées présente dans cette liste lors de l'appel à {@link #saveCommon()}
* .
* Les valeurs stockés dans chaque élément de cette liste ne seront affectés
* que lors de
* l'appel à {@link #saveCommon()}
*
* @param <T>
* @param field le champs à modifier
* @param value la valeur à lui appliquer
*/
public synchronized <T> void setCommon(SQLField<E, T> field, T value) {
if (field != null && field.name == "id")
throw new IllegalArgumentException("Can't modify id field in a SQLElementList");
Class<E> elemClass = (Class<E>) field.getSQLElementType();
try {
E emptyElement = elemClass.newInstance();
emptyElement.set(field, value, false);
} catch (Exception e) {
throw new IllegalArgumentException("Illegal field or value or can't instanciante an empty instance of "
+ elemClass.getName() + ". (the instance is only created to test validity of field and value)", e);
}
// ici, la valeur est bonne
modifiedValues.put(field, value);
}
/**
* Applique toutes les valeurs défini avec
* {@link #setCommon(SQLField, Object)} à toutes
* les entrées dans la base de données correspondants aux entrées de cette
* liste. Les nouvelles
* valeurs sont aussi mises à jour dans les objets contenus dans cette
* liste, si la valeur n'a pas été modifiée individuellement avec
* {@link SQLElement#set(SQLField, Object)}.<br/>
* Les objets de cette liste qui n'ont pas leur données en base de données
* sont ignorées.
*
* @throws SQLException
*/
public synchronized void saveCommon() throws SQLException {
List<E> storedEl = getStoredEl();
if (storedEl.isEmpty()) return;
String sqlSet = "";
List<Object> psValues = new ArrayList<>();
for (Map.Entry<SQLField<E, ?>, Object> entry : modifiedValues.entrySet()) {
sqlSet += entry.getKey().name + " = ? ,";
if (entry.getKey().type.getJavaType().isEnum()) // prise en charge
// enum (non prise
// en charge par
// JDBC)
psValues.add(((Enum<?>) entry.getValue()).name());
else
psValues.add(entry.getValue());
}
if (sqlSet.length() > 0) sqlSet = sqlSet.substring(0, sqlSet.length() - 1);
String sqlWhere = "";
boolean first = true;
for (E el : storedEl) {
if (!first) sqlWhere += " OR ";
first = false;
sqlWhere += "id = " + el.getId();
}
PreparedStatement ps = ORM.getConnection().getNativeConnection()
.prepareStatement("UPDATE " + storedEl.get(0).tableName() + " SET " + sqlSet + " WHERE " + sqlWhere);
try {
int i = 1;
for (Object val : psValues)
ps.setObject(i++, val);
Log.debug(ps.toString());
ps.executeUpdate();
applyNewValuesToElements(storedEl);
} finally {
ps.close();
}
}
@SuppressWarnings("unchecked")
private void applyNewValuesToElements(List<E> storedEl) {
// applique les valeurs dans chaques objets de la liste
for (E el : storedEl)
for (@SuppressWarnings("rawtypes")
SQLField entry : modifiedValues.keySet())
if (!el.isModified(entry)) el.set(entry, modifiedValues.get(entry), false);
}
private List<E> getStoredEl() {
List<E> listStored = new ArrayList<>();
forEach(el -> {
if (el.isStored()) listStored.add(el);
});
return listStored;
}
public synchronized void removeFromDB() {
List<E> storedEl = getStoredEl();
if (storedEl.isEmpty()) return;
try {
String sqlWhere = "";
boolean first = true;
for (E el : storedEl) {
if (!first) sqlWhere += " OR ";
first = false;
sqlWhere += "id = " + el.getId();
}
PreparedStatement st = ORM.getConnection().getNativeConnection()
.prepareStatement("DELETE FROM " + storedEl.get(0).tableName() + " WHERE " + sqlWhere);
try {
Log.debug(st.toString());
st.executeUpdate();
for (E el : storedEl)
el.markAsNotStored();
} finally {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,67 @@
package fr.pandacube.java.util.db.sql_tools;
import fr.pandacube.java.util.Log;
public class SQLFKField<E extends SQLElement<E>, T, F extends SQLElement<F>> extends SQLField<E, T> {
private SQLField<F, T> sqlForeignKeyField;
private Class<F> sqlForeignKeyElemClass;
public SQLFKField(String n, SQLType<T> t, boolean nul, SQLField<F, T> fkF) {
super(n, t, nul);
construct(fkF);
}
public SQLFKField(String n, SQLType<T> t, boolean nul, T deflt, SQLField<F, T> fkF) {
super(n, t, nul, deflt);
construct(fkF);
}
public static <E extends SQLElement<E>, F extends SQLElement<F>> SQLFKField<E, Integer, F> idFK(String n, SQLType<Integer> t, boolean nul,
Class<F> fkEl) {
if (fkEl == null) throw new IllegalArgumentException("foreignKeyElement can't be null");
try {
return new SQLFKField<>(n, t, nul, ORM.getSQLIdField(fkEl));
} catch (ORMInitTableException e) {
Log.severe("Can't create Foreign key Field called '" + n + "'", e);
return null;
}
}
public static <E extends SQLElement<E>, F extends SQLElement<F>> SQLFKField<E, Integer, F> idFKField(String n, SQLType<Integer> t, boolean nul,
Integer deflt, Class<F> fkEl) {
if (fkEl == null) throw new IllegalArgumentException("foreignKeyElement can't be null");
try {
return new SQLFKField<>(n, t, nul, deflt, ORM.getSQLIdField(fkEl));
} catch (ORMInitTableException e) {
Log.severe("Can't create Foreign key Field called '" + n + "'", e);
return null;
}
}
private void construct(SQLField<F, T> fkF) {
if (fkF == null) throw new IllegalArgumentException("foreignKeyField can't be null");
Class<F> fkEl = fkF.getSQLElementType();
try {
ORM.initTable(fkEl);
} catch (ORMInitTableException e) {
Log.severe(e);
return;
}
if (!fkEl.equals(fkF.getSQLElementType()))
throw new IllegalArgumentException("foreignKeyField must be from supplied foreignKeyElement");
if (!type.equals(fkF.type))
throw new IllegalArgumentException("foreignKeyField and current Field must have the same SQLType");
sqlForeignKeyField = fkF;
sqlForeignKeyElemClass = fkEl;
}
public SQLField<F, T> getForeignField() {
return sqlForeignKeyField;
}
public Class<F> getForeignElementClass() {
return sqlForeignKeyElemClass;
}
}

View File

@@ -0,0 +1,80 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SQLField<E extends SQLElement<E>, T> {
private Class<E> sqlElemClass;
public final String name;
public final SQLType<T> type;
public final boolean canBeNull;
public final boolean autoIncrement;
/* package */ final T defaultValue;
public SQLField(String n, SQLType<T> t, boolean nul, boolean autoIncr, T deflt) {
name = n;
type = t;
canBeNull = nul;
autoIncrement = autoIncr;
defaultValue = deflt;
}
public SQLField(String n, SQLType<T> t, boolean nul) {
this(n, t, nul, false, null);
}
public SQLField(String n, SQLType<T> t, boolean nul, boolean autoIncr) {
this(n, t, nul, autoIncr, null);
}
public SQLField(String n, SQLType<T> t, boolean nul, T deflt) {
this(n, t, nul, false, deflt);
}
/* package */ Pair<String, List<Object>> forSQLPreparedStatement() {
List<Object> params = new ArrayList<>(1);
if (defaultValue != null && !autoIncrement) params.add(defaultValue);
return new Pair<>(name + " " + type.toString() + (canBeNull ? " NULL" : " NOT NULL")
+ (autoIncrement ? " AUTO_INCREMENT" : "")
+ ((defaultValue == null || autoIncrement) ? "" : " DEFAULT ?"), params);
}
/* package */ void setSQLElementType(Class<E> elemClass) {
sqlElemClass = elemClass;
}
public Class<E> getSQLElementType() {
return sqlElemClass;
}
/**
* <b>Don't use this {@link #toString()} method in a SQL query, because
* the default value is not escaped correctly</b>
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return forSQLPreparedStatement().getKey().replaceFirst("\\?",
(defaultValue != null && !autoIncrement) ? defaultValue.toString() : "");
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof SQLField)) return false;
SQLField<?, ?> f = (SQLField<?, ?>) obj;
if (!f.name.equals(name)) return false;
if (!f.sqlElemClass.equals(sqlElemClass)) return false;
return true;
}
@Override
public int hashCode() {
return name.hashCode() + sqlElemClass.hashCode();
}
}

View File

@@ -0,0 +1,68 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.ArrayList;
import java.util.List;
public class SQLOrderBy {
private List<OBField> orderByFields = new ArrayList<>();
/**
* Construit une nouvelle clause ORDER BY
*/
public SQLOrderBy() {}
/**
* Ajoute un champ dans la clause ORDER BY en construction
*
* @param field le champ SQL à ordonner
* @param d le sens de tri (croissant ASC ou décroissant DESC)
* @return l'objet courant (permet de chainer les ajouts de champs)
*/
public SQLOrderBy addField(SQLField<?, ?> field, Direction d) {
orderByFields.add(new OBField(field, d));
return this;
}
/**
* Ajoute un champ dans la clause ORDER BY en construction,
* avec comme ordre de tri croissant ASC par défaut
*
* @param field le champ SQL à ordonner dans l'ordre croissant ASC
* @return l'objet courant (permet de chainer les ajouts de champs)
*/
public SQLOrderBy addField(SQLField<?, ?> field) {
return addField(field, Direction.ASC);
}
/* package */ String toSQL() {
String ret = "";
boolean first = true;
for (OBField f : orderByFields) {
if (!first) ret += ", ";
first = false;
ret += f.field.name + " " + f.direction.name();
}
return ret;
}
@Override
public String toString() {
return toSQL();
}
private class OBField {
public final SQLField<?, ?> field;
public final Direction direction;
public OBField(SQLField<?, ?> f, Direction d) {
field = f;
direction = d;
}
}
public enum Direction {
ASC, DESC;
}
}

View File

@@ -0,0 +1,90 @@
package fr.pandacube.java.util.db.sql_tools;
import java.sql.Date;
public class SQLType<T> {
private final String sqlType;
private final String sqlTypeParam;
private final Class<T> javaTypes;
public SQLType(String sqlT, String sqlP, Class<T> javaT) {
sqlType = sqlT;
sqlTypeParam = sqlP;
javaTypes = javaT;
}
@Override
public String toString() {
return sqlType + sqlTypeParam;
}
public boolean isAssignableFrom(Object val) {
if (javaTypes.isInstance(val)) return true;
return false;
}
@Override
public int hashCode() {
return toString().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof SQLType)) return false;
return toString().equals(((SQLType<?>) obj).toString());
}
public Class<T> getJavaType() {
return javaTypes;
}
public static final SQLType<Boolean> BOOLEAN = new SQLType<>("BOOLEAN", "", Boolean.class);
public static final SQLType<Byte> TINYINT = new SQLType<>("TINYINT", "", Byte.class);
public static final SQLType<Byte> BYTE = TINYINT;
public static final SQLType<Short> SMALLINT = new SQLType<>("SMALLINT", "", Short.class);
public static final SQLType<Short> SHORT = SMALLINT;
public static final SQLType<Integer> INT = new SQLType<>("INT", "", Integer.class);
public static final SQLType<Integer> INTEGER = INT;
public static final SQLType<Long> BIGINT = new SQLType<>("BIGINT", "", Long.class);
public static final SQLType<Long> LONG = BIGINT;
public static final SQLType<Date> DATE = new SQLType<>("DATE", "", Date.class);
public static final SQLType<Float> FLOAT = new SQLType<>("FLOAT", "", Float.class);
public static final SQLType<Double> DOUBLE = new SQLType<>("DOUBLE", "", Double.class);
public static final SQLType<String> CHAR(int charCount) {
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
return new SQLType<>("CHAR", "(" + charCount + ")", String.class);
}
public static final SQLType<String> VARCHAR(int charCount) {
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
return new SQLType<>("VARCHAR", "(" + charCount + ")", String.class);
}
public static final SQLType<String> TEXT = new SQLType<>("TEXT", "", String.class);
public static final SQLType<String> STRING = TEXT;
public static final <T extends Enum<T>> SQLType<T> ENUM(Class<T> enumType) {
if (enumType == null) throw new IllegalArgumentException("enumType can't be null.");
String enumStr = "'";
boolean first = true;
for (T el : enumType.getEnumConstants()) {
if (!first) enumStr += "', '";
first = false;
enumStr += el.name();
}
enumStr += "'";
return new SQLType<>("VARCHAR", "(" + enumStr + ")", enumType);
}
}

View File

@@ -0,0 +1,16 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.List;
import javafx.util.Pair;
public abstract class SQLWhere {
public abstract Pair<String, List<Object>> toSQL();
@Override
public String toString() {
return toSQL().getKey();
}
}

View File

@@ -0,0 +1,54 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SQLWhereChain extends SQLWhere {
private SQLBoolOp operator;
private List<SQLWhere> conditions = new ArrayList<>();
public SQLWhereChain(SQLBoolOp op) {
if (op == null) throw new IllegalArgumentException("op can't be null");
operator = op;
}
public SQLWhereChain add(SQLWhere sqlWhere) {
if (sqlWhere == null) throw new IllegalArgumentException("sqlWhere can't be null");
conditions.add(sqlWhere);
return this;
}
@Override
public Pair<String, List<Object>> toSQL() {
String sql = "";
List<Object> params = new ArrayList<>();
boolean first = true;
for (SQLWhere w : conditions) {
if (!first) sql += " " + operator.sql + " ";
first = false;
Pair<String, List<Object>> ret = w.toSQL();
sql += "(" + ret.getKey() + ")";
params.addAll(ret.getValue());
}
return new Pair<>(sql, params);
}
public enum SQLBoolOp {
/** Equivalent to SQL "<code>AND</code>" */
AND("AND"), /** Equivalent to SQL "<code>OR</code>" */
OR("OR");
public final String sql;
private SQLBoolOp(String s) {
sql = s;
}
}
}

View File

@@ -0,0 +1,53 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SQLWhereComp extends SQLWhere {
private SQLField<?, ?> left;
private SQLComparator comp;
private Object right;
/**
* Compare a field with a value
*
* @param l the field at left of the comparison operator. Can't be null
* @param c the comparison operator, can't be null
* @param r the value at right of the comparison operator. Can't be null
*/
public <T> SQLWhereComp(SQLField<?, T> l, SQLComparator c, T r) {
if (l == null || r == null || c == null)
throw new IllegalArgumentException("All arguments for SQLWhereComp constructor can't be null");
left = l;
comp = c;
right = r;
}
@Override
public Pair<String, List<Object>> toSQL() {
List<Object> params = new ArrayList<>();
params.add(right);
return new Pair<>(left.name + " " + comp.sql + " ? ", params);
}
public enum SQLComparator {
/** Equivalent to SQL "<code>=</code>" */
EQ("="), /** Equivalent to SQL "<code>></code>" */
GT(">"), /** Equivalent to SQL "<code>>=</code>" */
GEQ(">="), /** Equivalent to SQL "<code>&lt;</code>" */
LT("<"), /** Equivalent to SQL "<code>&lt;=</code>" */
LEQ("<="), /** Equivalent to SQL "<code>!=</code>" */
NEQ("!=");
public final String sql;
private SQLComparator(String s) {
sql = s;
}
}
}

View File

@@ -0,0 +1,33 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.ArrayList;
import java.util.List;
import javafx.util.Pair;
public class SQLWhereLike extends SQLWhere {
private SQLField<?, String> field;
private String likeExpr;
/**
* Compare a field with a value
*
* @param f the field at left of the LIKE keyword. Can't be null
* @param like the like expression.
*/
public SQLWhereLike(SQLField<?, String> f, String like) {
if (f == null || like == null)
throw new IllegalArgumentException("All arguments for SQLWhereLike constructor can't be null");
field = f;
likeExpr = like;
}
@Override
public Pair<String, List<Object>> toSQL() {
ArrayList<Object> params = new ArrayList<>();
params.add(likeExpr);
return new Pair<>(field.name + " LIKE ? ", params);
}
}

View File

@@ -0,0 +1,36 @@
package fr.pandacube.java.util.db.sql_tools;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import fr.pandacube.java.util.Log;
import javafx.util.Pair;
public class SQLWhereNull extends SQLWhere {
private SQLField<?, ?> fild;
private boolean nulll;
/**
* Init a IS NULL / IS NOT NULL expression for a SQL WHERE condition.
*
* @param field the field to check null / not null state
* @param isNull true if we want to ckeck if "IS NULL", or false to check if
* "IS NOT NULL"
*/
public SQLWhereNull(SQLField<?, ?> field, boolean isNull) {
if (field == null) throw new IllegalArgumentException("field can't be null");
if (!field.canBeNull) Log.getLogger().log(Level.WARNING,
"Useless : Trying to check IS [NOT] NULL on the field " + field.getSQLElementType().getName() + "#"
+ field.name + " which is declared in the ORM as 'can't be null'");
fild = field;
nulll = isNull;
}
@Override
public Pair<String, List<Object>> toSQL() {
return new Pair<>(fild.name + " IS" + ((nulll) ? " NULL" : " NOT NULL"), new ArrayList<>());
}
}