From 159cbe52aff88ae08ff37dfcaefa28c613ff96dc Mon Sep 17 00:00:00 2001 From: Marc Baloup Date: Fri, 8 Jul 2016 11:33:22 +0200 Subject: [PATCH] Nouvelle version ORM Java --- .../pandacube/java/util/db2/SQLContact.java | 43 ++ .../java/util/db2/SQLForumCategorie.java | 20 + .../java/util/db2/SQLForumForum.java | 31 ++ .../pandacube/java/util/db2/SQLForumPost.java | 38 ++ .../java/util/db2/SQLForumThread.java | 43 ++ .../java/util/db2/SQLLoginHistory.java | 48 +++ .../pandacube/java/util/db2/SQLMPGroup.java | 19 + .../java/util/db2/SQLMPGroupUser.java | 37 ++ .../pandacube/java/util/db2/SQLMPMessage.java | 56 +++ .../java/util/db2/SQLModoHistory.java | 59 +++ .../java/util/db2/SQLOnlineshopHistory.java | 71 ++++ src/fr/pandacube/java/util/db2/SQLPlayer.java | 81 ++++ .../java/util/db2/SQLPlayerIgnore.java | 48 +++ .../pandacube/java/util/db2/SQLShopStock.java | 23 + .../java/util/db2/SQLStaffTicket.java | 49 +++ .../java/util/db2/SQLStaticPages.java | 24 ++ .../java/util/db2/sql_tools/DBConnection.java | 54 +++ .../java/util/db2/sql_tools/ORM.java | 297 +++++++++++++ .../java/util/db2/sql_tools/SQLElement.java | 392 ++++++++++++++++++ .../util/db2/sql_tools/SQLElementList.java | 165 ++++++++ .../java/util/db2/sql_tools/SQLField.java | 86 ++++ .../java/util/db2/sql_tools/SQLOrderBy.java | 54 +++ .../java/util/db2/sql_tools/SQLType.java | 83 ++++ .../java/util/db2/sql_tools/SQLWhere.java | 21 + .../util/db2/sql_tools/SQLWhereChain.java | 60 +++ .../java/util/db2/sql_tools/SQLWhereComp.java | 62 +++ .../java/util/db2/sql_tools/SQLWhereLike.java | 35 ++ .../java/util/db2/sql_tools/SQLWhereNull.java | 37 ++ 28 files changed, 2036 insertions(+) create mode 100644 src/fr/pandacube/java/util/db2/SQLContact.java create mode 100644 src/fr/pandacube/java/util/db2/SQLForumCategorie.java create mode 100644 src/fr/pandacube/java/util/db2/SQLForumForum.java create mode 100644 src/fr/pandacube/java/util/db2/SQLForumPost.java create mode 100644 src/fr/pandacube/java/util/db2/SQLForumThread.java create mode 100644 src/fr/pandacube/java/util/db2/SQLLoginHistory.java create mode 100644 src/fr/pandacube/java/util/db2/SQLMPGroup.java create mode 100644 src/fr/pandacube/java/util/db2/SQLMPGroupUser.java create mode 100644 src/fr/pandacube/java/util/db2/SQLMPMessage.java create mode 100644 src/fr/pandacube/java/util/db2/SQLModoHistory.java create mode 100644 src/fr/pandacube/java/util/db2/SQLOnlineshopHistory.java create mode 100644 src/fr/pandacube/java/util/db2/SQLPlayer.java create mode 100644 src/fr/pandacube/java/util/db2/SQLPlayerIgnore.java create mode 100644 src/fr/pandacube/java/util/db2/SQLShopStock.java create mode 100644 src/fr/pandacube/java/util/db2/SQLStaffTicket.java create mode 100644 src/fr/pandacube/java/util/db2/SQLStaticPages.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/DBConnection.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/ORM.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLElement.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLElementList.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLField.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLOrderBy.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLType.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLWhere.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLWhereChain.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLWhereComp.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLWhereLike.java create mode 100644 src/fr/pandacube/java/util/db2/sql_tools/SQLWhereNull.java diff --git a/src/fr/pandacube/java/util/db2/SQLContact.java b/src/fr/pandacube/java/util/db2/SQLContact.java new file mode 100644 index 0000000..65517dd --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLContact.java @@ -0,0 +1,43 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLContact extends SQLElement { + + public SQLContact() { super(); } + public SQLContact(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_contact"; } + + + + + + public static final SQLField time = new SQLField<>("time", SQLType.INT, false); + public static final SQLField playerId = new SQLField<>("playerId", SQLType.CHAR(36), true); + public static final SQLField userName = new SQLField<>("userName", SQLType.VARCHAR(50), true); + public static final SQLField userMail = new SQLField<>("userMail", SQLType.VARCHAR(50), true); + public static final SQLField titre = new SQLField<>("titre", SQLType.VARCHAR(100), false); + public static final SQLField texte = new SQLField<>("texte", SQLType.TEXT, false); + public static final SQLField hidden = new SQLField<>("hidden", SQLType.BOOLEAN, false, (Boolean)false); + + + + public UUID getPlayerId() { + String id = (String)get(playerId); + return (id == null) ? null : UUID.fromString(id); + } + + + public void setPlayerId(UUID pName) { + set(playerId, (pName == null) ? (String)null : pName.toString()); + } + + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLForumCategorie.java b/src/fr/pandacube/java/util/db2/SQLForumCategorie.java new file mode 100644 index 0000000..7174bcc --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLForumCategorie.java @@ -0,0 +1,20 @@ +package fr.pandacube.java.util.db2; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLForumCategorie extends SQLElement { + + public SQLForumCategorie() { super(); } + public SQLForumCategorie(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_forum_categorie"; } + + + public static final SQLField nom = new SQLField<>("nom", SQLType.VARCHAR(100), false); + public static final SQLField ordre = new SQLField<>("ordre", SQLType.INT, false); + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLForumForum.java b/src/fr/pandacube/java/util/db2/SQLForumForum.java new file mode 100644 index 0000000..d503500 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLForumForum.java @@ -0,0 +1,31 @@ +package fr.pandacube.java.util.db2; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLForumForum extends SQLElement { + + + public SQLForumForum() { super(); } + public SQLForumForum(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_forum_forum"; } + + + public static final SQLField catId = new SQLField<>("catId", SQLType.INT, false); + public static final SQLField nom = new SQLField<>("nom", SQLType.VARCHAR(100), false); + public static final SQLField description = new SQLField<>("description", SQLType.TEXT, false); + public static final SQLField ordre = new SQLField<>("ordre", SQLType.INT, false); + public static final SQLField authView = new SQLField<>("authView", SQLType.INT, false); + public static final SQLField authPost = new SQLField<>("authPost", SQLType.INT, false); + public static final SQLField authThread = new SQLField<>("authThread", SQLType.INT, false); + public static final SQLField authAnchored = new SQLField<>("authAnchored", SQLType.INT, false); + public static final SQLField authModo = new SQLField<>("authModo", SQLType.INT, false); + public static final SQLField nbThreads = new SQLField<>("nbThreads", SQLType.INT, false); + public static final SQLField nbMessages = new SQLField<>("nbMessages", SQLType.INT, false); + + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLForumPost.java b/src/fr/pandacube/java/util/db2/SQLForumPost.java new file mode 100644 index 0000000..3fb1d76 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLForumPost.java @@ -0,0 +1,38 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLForumPost extends SQLElement { + + + public SQLForumPost() { super(); } + public SQLForumPost(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_forum_post"; } + + + public static final SQLField createur = new SQLField<>("createur", SQLType.CHAR(36), false); + public static final SQLField texte = new SQLField<>("texte", SQLType.TEXT, false); + public static final SQLField time = new SQLField<>("time", SQLType.INT, false); + public static final SQLField threadId = new SQLField<>("threadId", SQLType.INT, false); + public static final SQLField moderated = new SQLField<>("moderated", SQLType.BOOLEAN, false); + + + + public UUID getCreateurId() { + String id = (String)get(createur); + return (id == null) ? null : UUID.fromString(id); + } + + + public void setCreateurId(UUID pName) { + set(createur, (pName == null) ? (String)null : pName.toString()); + } + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLForumThread.java b/src/fr/pandacube/java/util/db2/SQLForumThread.java new file mode 100644 index 0000000..9cbe19c --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLForumThread.java @@ -0,0 +1,43 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLForumThread extends SQLElement { + + + public SQLForumThread() { super(); } + public SQLForumThread(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_forum_thread"; } + + + public static final SQLField forumId = new SQLField<>("forumId", SQLType.INT, false); + public static final SQLField titre = new SQLField<>("titre", SQLType.VARCHAR(60), false); + public static final SQLField createur = new SQLField<>("createur", SQLType.CHAR(36), false); + public static final SQLField vu = new SQLField<>("vu", SQLType.INT, false); + public static final SQLField time = new SQLField<>("time", SQLType.BIGINT, false); + public static final SQLField anchored = new SQLField<>("anchored", SQLType.BOOLEAN, false); + public static final SQLField locked = new SQLField<>("locked", SQLType.BOOLEAN, false); + public static final SQLField nbMessages = new SQLField<>("nbMessages", SQLType.INT, false); + + + + public UUID getCreateurId() { + String id = (String)get(createur); + return (id == null) ? null : UUID.fromString(id); + } + + + public void setCreateurId(UUID pName) { + set(createur, (pName == null) ? (String)null : pName.toString()); + } + + + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLLoginHistory.java b/src/fr/pandacube/java/util/db2/SQLLoginHistory.java new file mode 100644 index 0000000..ba28148 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLLoginHistory.java @@ -0,0 +1,48 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLLoginHistory extends SQLElement { + + + public SQLLoginHistory() { super(); } + public SQLLoginHistory(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_login_history"; } + + + public static final SQLField time = new SQLField<>("time", SQLType.BIGINT, false); + public static final SQLField playerId = new SQLField<>("playerId", SQLType.CHAR(36), false); + public static final SQLField ip = new SQLField<>("ip", SQLType.VARCHAR(128), true); + public static final SQLField actionType = new SQLField<>("actionType", SQLType.ENUM(ActionType.class), false); + public static final SQLField nbOnline = new SQLField<>("nbOnline", SQLType.INT, false); + public static final SQLField playerName = new SQLField<>("playerName", SQLType.VARCHAR(16), true); + public static final SQLField minecraftVersion = new SQLField<>("minecraftVersion", SQLType.INT, false, 0); + + + + + + public UUID getPlayerId() { + String id = (String)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 + } +} diff --git a/src/fr/pandacube/java/util/db2/SQLMPGroup.java b/src/fr/pandacube/java/util/db2/SQLMPGroup.java new file mode 100644 index 0000000..7cd47b5 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLMPGroup.java @@ -0,0 +1,19 @@ +package fr.pandacube.java.util.db2; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLMPGroup extends SQLElement { + + + public SQLMPGroup() { super(); } + public SQLMPGroup(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_mp_group"; } + + + public static final SQLField groupName = new SQLField<>("groupName", SQLType.VARCHAR(16), false); + +} diff --git a/src/fr/pandacube/java/util/db2/SQLMPGroupUser.java b/src/fr/pandacube/java/util/db2/SQLMPGroupUser.java new file mode 100644 index 0000000..7eb12fa --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLMPGroupUser.java @@ -0,0 +1,37 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLMPGroupUser extends SQLElement { + + + public SQLMPGroupUser() { super(); } + public SQLMPGroupUser(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_mp_group_user"; } + + + public static final SQLField groupId = new SQLField<>("groupId", SQLType.INT, false); + public static final SQLField playerId = new SQLField<>("playerId", SQLType.CHAR(36), false); + + // 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()); + } + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLMPMessage.java b/src/fr/pandacube/java/util/db2/SQLMPMessage.java new file mode 100644 index 0000000..abb4480 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLMPMessage.java @@ -0,0 +1,56 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLMPMessage extends SQLElement { + + + public SQLMPMessage() { super(); } + public SQLMPMessage(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_mp_message"; } + + + public static final SQLField time = new SQLField<>("time", SQLType.BIGINT, false); + public static final SQLField securityKey = new SQLField<>("securityKey", SQLType.INT, false); + public static final SQLField viewerId = new SQLField<>("viewerId", SQLType.CHAR(36), false); + public static final SQLField sourceId = new SQLField<>("sourceId", SQLType.CHAR(36), true); + public static final SQLField destId = new SQLField<>("destId", SQLType.CHAR(36), true); + public static final SQLField destGroup = new SQLField<>("destGroup", SQLType.INT, true); + public static final SQLField message = new SQLField<>("message", SQLType.VARCHAR(512), false); + public static final SQLField wasRead = new SQLField<>("wasRead", SQLType.BOOLEAN, false); + public static final SQLField deleted = new SQLField<>("deleted", SQLType.BOOLEAN, false); + public static final SQLField 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()); + } +} diff --git a/src/fr/pandacube/java/util/db2/SQLModoHistory.java b/src/fr/pandacube/java/util/db2/SQLModoHistory.java new file mode 100644 index 0000000..a80fb3a --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLModoHistory.java @@ -0,0 +1,59 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLModoHistory extends SQLElement { + + + public SQLModoHistory() { super(); } + public SQLModoHistory(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_modo_history"; } + + + public static final SQLField modoId = new SQLField<>("modoId", SQLType.CHAR(36), true); + public static final SQLField actionType = new SQLField<>("actionType", SQLType.ENUM(ActionType.class), false); + public static final SQLField time = new SQLField<>("time", SQLType.BIGINT, false); + public static final SQLField playerId = new SQLField<>("playerId", SQLType.CHAR(36), false); + public static final SQLField value = new SQLField<>("value", SQLType.BIGINT, true); + public static final SQLField message = new SQLField<>("message", SQLType.VARCHAR(512), false); + + + + + public UUID getModoId() { + String id = (String)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 = (String)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 + } + +} diff --git a/src/fr/pandacube/java/util/db2/SQLOnlineshopHistory.java b/src/fr/pandacube/java/util/db2/SQLOnlineshopHistory.java new file mode 100644 index 0000000..6b654df --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLOnlineshopHistory.java @@ -0,0 +1,71 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLOnlineshopHistory extends SQLElement { + + + public SQLOnlineshopHistory() { super(); } + public SQLOnlineshopHistory(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_onlineshop_history"; } + + + public static final SQLField time = new SQLField<>("time", SQLType.BIGINT, false); + public static final SQLField transactionId = new SQLField<>("transactionId", SQLType.VARCHAR(255), true); + public static final SQLField sourceType = new SQLField<>("sourceType", SQLType.ENUM(SourceType.class), false); + public static final SQLField sourcePlayerId = new SQLField<>("sourcePlayerId", SQLType.CHAR(36), true); + public static final SQLField sourceQuantity = new SQLField<>("sourceQuantity", SQLType.DOUBLE, false); + public static final SQLField sourceName = new SQLField<>("sourceName", SQLType.VARCHAR(64), false); + public static final SQLField destType = new SQLField<>("destType", SQLType.ENUM(DestType.class), false); + public static final SQLField destPlayerId = new SQLField<>("destPlayerId", SQLType.CHAR(36), false); + public static final SQLField destQuantity = new SQLField<>("destQuantity", SQLType.DOUBLE, false); + public static final SQLField destName = new SQLField<>("destName", SQLType.VARCHAR(64), false); + + + + + + public UUID getSourcePlayerId() { + String id = (String)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 = (String)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 + } + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLPlayer.java b/src/fr/pandacube/java/util/db2/SQLPlayer.java new file mode 100644 index 0000000..a626fc8 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLPlayer.java @@ -0,0 +1,81 @@ +package fr.pandacube.java.util.db2; + +import java.sql.Date; +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + + +public class SQLPlayer extends SQLElement { + + 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 playerId = new SQLField<>("playerId", SQLType.CHAR(36), false); + public static final SQLField token = new SQLField<>("token", SQLType.CHAR(36), true); + public static final SQLField mailCheck = new SQLField<>("mailCheck", SQLType.VARCHAR(255), true); + public static final SQLField password = new SQLField<>("password", SQLType.VARCHAR(255), true); + public static final SQLField mail = new SQLField<>("mail", SQLType.VARCHAR(255), true); + public static final SQLField playerDisplayName = new SQLField<>("playerDisplayName", SQLType.VARCHAR(255), false); + public static final SQLField firstTimeInGame = new SQLField<>("firstTimeInGame", SQLType.BIGINT, false); + public static final SQLField timeWebRegister = new SQLField<>("timeWebRegister", SQLType.BIGINT, true); + public static final SQLField lastTimeInGame = new SQLField<>("lastTimeInGame", SQLType.BIGINT, true); + public static final SQLField lastWebActivity = new SQLField<>("lastWebActivity", SQLType.BIGINT, false); + public static final SQLField onlineInServer = new SQLField<>("onlineInServer", SQLType.VARCHAR(32), true); + public static final SQLField skinURL = new SQLField<>("skinURL", SQLType.VARCHAR(255), true); + public static final SQLField isVanish = new SQLField<>("isVanish", SQLType.BOOLEAN, false, (Boolean)false); + public static final SQLField birthday = new SQLField<>("birthday", SQLType.DATE, true); + public static final SQLField lastYearCelebBday = new SQLField<>("lastYearCelebratedBirthday", SQLType.INT, false, 0); + public static final SQLField banTimeout = new SQLField<>("banTimeout", SQLType.BIGINT, true); + public static final SQLField muteTimeout = new SQLField<>("muteTimeout", SQLType.BIGINT, true); + public static final SQLField isWhitelisted = new SQLField<>("isWhitelisted", SQLType.BOOLEAN, false, (Boolean)false); + public static final SQLField bambou = new SQLField<>("bambou", SQLType.BIGINT, false, 0L); + public static final SQLField grade = new SQLField<>("grade", SQLType.VARCHAR(36), false, "default"); + + + + + /* + * Getteurs spécifique (encapsulation) + */ + + public UUID getPlayerId() { + String id = (String)get(playerId); + return (id == null) ? null : UUID.fromString(id); + } + public UUID getToken() { + String id = (String)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()); + } + +} diff --git a/src/fr/pandacube/java/util/db2/SQLPlayerIgnore.java b/src/fr/pandacube/java/util/db2/SQLPlayerIgnore.java new file mode 100644 index 0000000..e617f2a --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLPlayerIgnore.java @@ -0,0 +1,48 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLPlayerIgnore extends SQLElement { + + + public SQLPlayerIgnore() { super(); } + public SQLPlayerIgnore(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_player_ignore"; } + + + public static final SQLField ignorer = new SQLField<>("ignorer", SQLType.CHAR(36), false); + public static final SQLField ignored = new SQLField<>("ignored", SQLType.CHAR(36), false); + + + + public UUID getIgnorerId() { + String id = (String)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 = (String)get(ignored); + return (id == null) ? null : UUID.fromString(id); + } + + + public void setIgnoredId(UUID pName) { + set(ignored, (pName == null) ? (String)null : pName.toString()); + } + + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLShopStock.java b/src/fr/pandacube/java/util/db2/SQLShopStock.java new file mode 100644 index 0000000..2e97363 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLShopStock.java @@ -0,0 +1,23 @@ +package fr.pandacube.java.util.db2; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLShopStock extends SQLElement { + + + public SQLShopStock() { super(); } + public SQLShopStock(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_shop_stock"; } + + + public static final SQLField material = new SQLField<>("material", SQLType.VARCHAR(50), false); + public static final SQLField damage = new SQLField<>("damage", SQLType.INT, false, 0); + public static final SQLField quantity = new SQLField<>("quantity", SQLType.DOUBLE, false); + public static final SQLField server = new SQLField<>("server", SQLType.VARCHAR(50), false); + + +} diff --git a/src/fr/pandacube/java/util/db2/SQLStaffTicket.java b/src/fr/pandacube/java/util/db2/SQLStaffTicket.java new file mode 100644 index 0000000..2c70686 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLStaffTicket.java @@ -0,0 +1,49 @@ +package fr.pandacube.java.util.db2; + +import java.util.UUID; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLStaffTicket extends SQLElement { + + + public SQLStaffTicket() { super(); } + public SQLStaffTicket(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_staff_ticket"; } + + + public static final SQLField playerId = new SQLField<>("playerId", SQLType.CHAR(36), false); + public static final SQLField message = new SQLField<>("message", SQLType.VARCHAR(1024), false); + public static final SQLField creationTime = new SQLField<>("creationTime", SQLType.BIGINT, false); + public static final SQLField staffPlayerId = new SQLField<>("staffPlayerId", SQLType.CHAR(36), true); + + + + + 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()); + } + +} diff --git a/src/fr/pandacube/java/util/db2/SQLStaticPages.java b/src/fr/pandacube/java/util/db2/SQLStaticPages.java new file mode 100644 index 0000000..31a6ee3 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/SQLStaticPages.java @@ -0,0 +1,24 @@ +package fr.pandacube.java.util.db2; + +import fr.pandacube.java.util.db2.sql_tools.SQLElement; +import fr.pandacube.java.util.db2.sql_tools.SQLField; +import fr.pandacube.java.util.db2.sql_tools.SQLType; + +public class SQLStaticPages extends SQLElement { + + + public SQLStaticPages() { super(); } + public SQLStaticPages(int id) { super(id); } + + @Override + protected String tableName() { return "pandacube_static_pages"; } + + + public static final SQLField permalink = new SQLField<>("permalink", SQLType.VARCHAR(128), false); + public static final SQLField titreHead = new SQLField<>("titreHead", SQLType.VARCHAR(128), false); + public static final SQLField titreH2 = new SQLField<>("titreH2", SQLType.VARCHAR(255), false); + public static final SQLField texte = new SQLField<>("texte", SQLType.TEXT, false); + public static final SQLField permissions = new SQLField<>("permissions", SQLType.VARCHAR(255), true); + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/DBConnection.java b/src/fr/pandacube/java/util/db2/sql_tools/DBConnection.java new file mode 100644 index 0000000..74dc428 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/DBConnection.java @@ -0,0 +1,54 @@ +package fr.pandacube.java.util.db2.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; + conn = DriverManager.getConnection(url, login, pass); + + + } + + + public void reconnectIfNecessary() throws SQLException + { + try + { + Statement stmt = conn.createStatement(); + stmt.close(); + } + catch(SQLException e) + { + close(); + conn = DriverManager.getConnection(url, login, pass); + } + } + + public Connection getNativeConnection() throws SQLException + { + if (!conn.isValid(1)) + reconnectIfNecessary(); + return conn; + } + + + public void close() { + try { + conn.close(); + } catch (Exception e) { } + + } + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/ORM.java b/src/fr/pandacube/java/util/db2/sql_tools/ORM.java new file mode 100644 index 0000000..a0971fb --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/ORM.java @@ -0,0 +1,297 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.lang.reflect.InvocationTargetException; +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.PandacubeUtil; +import fr.pandacube.java.util.db2.SQLPlayer; +import fr.pandacube.java.util.db2.sql_tools.SQLWhereChain.SQLBoolOp; +import fr.pandacube.java.util.db2.sql_tools.SQLWhereComp.SQLComparator; +import javafx.util.Pair; + +/** + * ORM = Object-Relational Mapping + * @author Marc Baloup + * + */ +public final class ORM { + + private static List> 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 + */ + + initTable(SQLPlayer.class); + + + + } + + + /* package */ static void initTable(Class elemClass) { + if (tables.contains(elemClass)) + return; + try { + T instance = elemClass.newInstance(); + String tableName = instance.tableName(); + if (!tableExist(tableName)) + createTable(instance); + tables.add(elemClass); + } catch (Exception e) { + PandacubeUtil.getMasterLogger().log(Level.SEVERE, "Can't init table " + elemClass.getName(), e); + } + } + + + + + private static void createTable(T elem) throws SQLException { + + String sql = "CREATE TABLE IF NOT EXISTS "+elem.tableName()+" ("; + List params = new ArrayList<>(); + + Collection> tableFields = elem.getFields().values(); + boolean first = true; + for (SQLField f : tableFields) { + Pair> 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 { + System.out.println(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 SQLField getSQLIdField(Class elemClass) { + return (SQLField) SQLElement.fieldsCache.get(elemClass).get("id"); + } + + + public static List getByIds(Class elemClass, Collection ids) throws Exception { + return getByIds(elemClass, ids.toArray(new Integer[ids.size()])); + } + + public static List getByIds(Class elemClass, Integer... ids) throws Exception { + SQLField 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 T getById(Class elemClass, int id) throws Exception { + return getFirst(elemClass, new SQLWhereComp(getSQLIdField(elemClass), SQLComparator.EQ, id), null); + } + + public static T getFirst(Class elemClass, SQLWhere where, SQLOrderBy orderBy) throws Exception { + SQLElementList elts = getAll(elemClass, where, orderBy, 1, null); + return (elts.size() == 0)? null : elts.get(0); + } + + + + public static SQLElementList getAll(Class elemClass) throws Exception { + return getAll(elemClass, null, null, null, null); + } + + public static SQLElementList getAll(Class elemClass, SQLWhere where, SQLOrderBy orderBy, Integer limit, Integer offset) throws Exception { + initTable(elemClass); + String sql = "SELECT * FROM "+elemClass.newInstance().tableName(); + List params = new ArrayList<>(); + + if (where != null) { + Pair> 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 elmts = new SQLElementList(); + + PreparedStatement ps = connection.getNativeConnection().prepareStatement(sql); + + try { + + int i = 1; + for (Object val : params) { + ps.setObject(i++, val); + } + + System.out.println(ps.toString()); + + ResultSet set = ps.executeQuery(); + + try { + while (set.next()) + elmts.add(getElementInstance(set, elemClass)); + } finally { + set.close(); + } + } finally { + ps.close(); + } + + return elmts; + } + + + + + + + + + + + + + + + private static T getElementInstance(ResultSet set, Class elemClass) throws Exception { + try { + T 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 sqlField = (SQLField) instance.getFields().get(fieldName); + instance.set(sqlField, set.getObject(c), false); + } + + return instance; + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + throw new Exception("Can't instanciate " + elemClass.getName(), e); + } catch (SQLException e) { + throw new Exception("Error reading ResultSet for creating instance of " + 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 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) + + + + + } + */ + + + + + + + + + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLElement.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLElement.java new file mode 100644 index 0000000..a3d6870 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLElement.java @@ -0,0 +1,392 @@ +package fr.pandacube.java.util.db2.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 fr.pandacube.java.PandacubeUtil; + +public abstract class SQLElement { + /** cache for fields for each subclass of SQLElement */ + /* package */ static final Map, SQLFieldMap> fieldsCache = new HashMap<>(); + + + + + DBConnection db = ORM.getConnection(); + + private boolean stored = false; + private int id; + + private final String tableName; + private final SQLFieldMap fields; + + private final Map, Object> values; + private final Set modifiedSinceLastSave; + + + public SQLElement() { + tableName = tableName(); + + + if (fieldsCache.get(getClass()) == null) { + fields = new SQLFieldMap(getClass()); + + // le champ id commun à toutes les tables + fields.addField(new SQLField<>("id", SQLType.INT, false, true, 0)); + + generateFields(fields); + fieldsCache.put(getClass(), fields); + } + else { + fields = fieldsCache.get(getClass()); + } + + values = new LinkedHashMap<>(fields.size()); + modifiedSinceLastSave = new HashSet<>(fields.size()); + + initDefaultValues(); + + + } + + + protected SQLElement(int id) { + this(); + @SuppressWarnings("unchecked") + SQLField idField = (SQLField)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 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) { + PandacubeUtil.getMasterLogger().log(Level.SEVERE, "Can't get value of static field "+field.toString(), e); + } + } + + + + + } + + /* package */ Map> getFields() { + return Collections.unmodifiableMap(fields); + } + + + + + public Map, Object> getValues() { + return Collections.unmodifiableMap(values); + } + + + + + + + + + public void set(SQLField field, T value) { + set(field, value, true); + } + + + /* package */ void set(SQLField 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 get(SQLField 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 boolean isValidForSave() { + return values.keySet().containsAll(fields.keySet()); + } + + + + private Map, Object> getOnlyModifiedValues() { + Map, Object> modifiedValues = new LinkedHashMap<>(); + values.forEach((k, v) -> { + if (modifiedSinceLastSave.contains(k)) + modifiedValues.put(k, v); + }); + return modifiedValues; + } + + + + public boolean isModified(SQLField field) { + return modifiedSinceLastSave.contains(field.name); + } + + + + public void save() throws SQLException { + if (!isValidForSave()) + throw new IllegalStateException("this instance of " + getClass().getName() + " has at least one undefined value and can't be saved."); + + ORM.initTable(getClass()); + + 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 + @SuppressWarnings("unchecked") + SQLField idField = (SQLField) fields.get("id"); + values.put(idField, id); + modifiedSinceLastSave.remove("id"); + Map, Object> modifiedValues = getOnlyModifiedValues(); + + + + String sql = ""; + List psValues = new ArrayList<>(); + + for(Map.Entry, Object> entry : modifiedValues.entrySet()) { + sql += entry.getKey() + " = ? ,"; + 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); + } + + 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 psValues = new ArrayList<>(); + + boolean first = true; + for(Map.Entry, Object> entry : values.entrySet()) { + if (!first) { + concat_vals += ","; + concat_fields += ","; + } + first = false; + concat_vals += " ? "; + concat_fields += entry.getKey(); + 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); + } + + ps.executeUpdate(); + + ResultSet rs = ps.getGeneratedKeys(); + try { + if(rs.next()) + { + id = rs.getInt(1); + } + + stored = true; + } finally { + rs.close(); + } + } finally { + ps.close(); + } + + } + + modifiedSinceLastSave.clear(); + + } + + + public boolean isStored() { return stored; } + + public Integer getId() { + return (stored) ? id : null; + } + + @SuppressWarnings("unchecked") + public SQLField getFieldId() { + return (SQLField) getFields().get("id"); + } + + + + + + public void delete() { + + try { + if (stored) + { // supprimer la ligne de la base + PreparedStatement st = db.getNativeConnection().prepareStatement("DELETE FROM "+tableName+" WHERE id="+id); + try { + st.executeUpdate(); + markAsNotStored(); + } finally { + st.close(); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + } + + /** + * 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 extends LinkedHashMap> { + private static final long serialVersionUID = 1L; + + private final Class sqlElemClass; + + private SQLFieldMap(Class elemClass) { + sqlElemClass = elemClass; + } + + private void addField(SQLField f) { + if (f == null) return; + if (containsKey(f.name)) + throw new IllegalArgumentException("SQLField "+f.name+" already exist in "+sqlElemClass.getName()); + f.setSQLElementType(sqlElemClass); + put(f.name, f); + } + + } + + + + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLElementList.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLElementList.java new file mode 100644 index 0000000..52499a8 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLElementList.java @@ -0,0 +1,165 @@ +package fr.pandacube.java.util.db2.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; + +/** + * + * @param + */ +public class SQLElementList extends ArrayList { + private static final long serialVersionUID = 1L; + + private final Map, 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 + * @param field le champs à modifier + * @param value la valeur à lui appliquer + */ + public synchronized void setCommon(SQLField field, T value) { + if (isEmpty()) throw new IllegalStateException("This SQLElementList is empty"); + if (field != null && field.name == "id") + throw new IllegalArgumentException("Can't modify id field in a SQLElementList"); + @SuppressWarnings("unchecked") + Class elemClass = (Class) get(0).getClass(); + 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)}.
+ * 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 storedEl = getStoredEl(); + if (storedEl.isEmpty()) return; + + String sqlSet = ""; + List psValues = new ArrayList<>(); + + for(Map.Entry, Object> entry : modifiedValues.entrySet()) { + sqlSet += entry.getKey().name + " = ? ,"; + 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); + } + + ps.executeUpdate(); + + applyNewValuesToElements(storedEl); + } finally { + ps.close(); + } + } + + @SuppressWarnings("unchecked") + private void applyNewValuesToElements(List 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 getStoredEl() { + List listStored = new ArrayList<>(); + forEach(el -> { + if (el.isStored()) listStored.add(el); + }); + return listStored; + } + + + + public synchronized void removeFromDB() { + List 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 { + st.executeUpdate(); + + for (E el : storedEl) { + el.markAsNotStored(); + } + + } finally { + st.close(); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + + } + + + + + + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLField.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLField.java new file mode 100644 index 0000000..aad7872 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLField.java @@ -0,0 +1,86 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.util.ArrayList; +import java.util.List; + +import javafx.util.Pair; + +public class SQLField { + + private Class sqlElemClass; + public final String name; + public final SQLType type; + public final boolean canBeNull; + public final boolean autoIncrement; + /* package */ final T defaultValue; + + public SQLField(String n, SQLType t, boolean nul, boolean autoIncr, T deflt) { + name = n; + type = t; + canBeNull = nul; + autoIncrement = autoIncr; + defaultValue = deflt; + } + + public SQLField(String n, SQLType t, boolean nul) { + this(n, t, nul, false, null); + } + + public SQLField(String n, SQLType t, boolean nul, boolean autoIncr) { + this(n, t, nul, autoIncr, null); + } + + public SQLField(String n, SQLType t, boolean nul, T deflt) { + this(n, t, nul, false, deflt); + } + + /* package */ Pair> forSQLPreparedStatement() { + List 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 elemClass) { + sqlElemClass = elemClass; + } + + public Class getSQLElementType() { + return sqlElemClass; + } + + + /** + * Don't use this {@link #toString()} method in a SQL query, because + * the default value is not escaped correctly + * @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(); + } + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLOrderBy.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLOrderBy.java new file mode 100644 index 0000000..39675ca --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLOrderBy.java @@ -0,0 +1,54 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.util.ArrayList; +import java.util.List; + +public class SQLOrderBy { + + private List orderByFields = new ArrayList<>(); + + public SQLOrderBy() {} + + public SQLOrderBy addField(SQLField field,Direction d) { + orderByFields.add(new OBField(field, d)); + return this; + } + + 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; + } + + + } + + private enum Direction { + ASC, DESC; + } +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLType.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLType.java new file mode 100644 index 0000000..32eadae --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLType.java @@ -0,0 +1,83 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.sql.Date; + +public class SQLType { + + private final String sqlType; + private final String sqlTypeParam; + private final Class javaTypes; + + public SQLType(String sqlT, String sqlP, Class 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; + } + + + + + + + public static final SQLType BOOLEAN = new SQLType<>("BOOLEAN", "", Boolean.class); + + public static final SQLType TINYINT = new SQLType<>("TINYINT", "", Byte.class); + public static final SQLType BYTE = TINYINT; + + public static final SQLType SMALLINT = new SQLType<>("SMALLINT", "", Short.class); + public static final SQLType SHORT = SMALLINT; + + public static final SQLType INT = new SQLType<>("INT", "", Integer.class); + public static final SQLType INTEGER = INT; + + public static final SQLType BIGINT = new SQLType<>("BIGINT", "", Long.class); + public static final SQLType LONG = BIGINT; + + public static final SQLType DATE = new SQLType<>("DATE", "", Date.class); + + public static final SQLType FLOAT = new SQLType<>("FLOAT", "", Float.class); + + public static final SQLType DOUBLE = new SQLType<>("DOUBLE", "", Double.class); + + public static final SQLType CHAR(int charCount) { + if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive."); + return new SQLType<>("CHAR", "("+charCount+")", String.class); + } + + public static final SQLType VARCHAR(int charCount) { + if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive."); + return new SQLType<>("VARCHAR", "("+charCount+")", String.class); + } + + public static final SQLType TEXT = new SQLType<>("TEXT", "", String.class); + public static final SQLType STRING = TEXT; + + public static final > SQLType ENUM(Class 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); + } + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLWhere.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhere.java new file mode 100644 index 0000000..8e6e93f --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhere.java @@ -0,0 +1,21 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.util.List; + +import javafx.util.Pair; + +public abstract class SQLWhere { + + + + + + public abstract Pair> toSQL(); + + + @Override + public String toString() { + return toSQL().getKey(); + } + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereChain.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereChain.java new file mode 100644 index 0000000..314c940 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereChain.java @@ -0,0 +1,60 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.util.ArrayList; +import java.util.List; + +import javafx.util.Pair; + +public class SQLWhereChain extends SQLWhere { + + private SQLBoolOp operator; + private List 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> toSQL() { + String sql = ""; + List params = new ArrayList<>(); + boolean first = true; + + for (SQLWhere w : conditions) { + if (!first) sql += " " + operator.sql + " "; + first = false; + + Pair> ret = w.toSQL(); + sql += "(" + ret.getKey() + ")"; + params.addAll(ret.getValue()); + } + + return new Pair<>(sql, params); + } + + + enum SQLBoolOp { + /** Equivalent to SQL "AND" */ + AND("AND"), + /** Equivalent to SQL "OR" */ + OR("OR"); + public final String sql; + + private SQLBoolOp(String s) { + sql = s; + } + + } + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereComp.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereComp.java new file mode 100644 index 0000000..61f2b17 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereComp.java @@ -0,0 +1,62 @@ +package fr.pandacube.java.util.db2.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 SQLWhereComp(SQLField 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> toSQL() { + List params = new ArrayList<>(); + params.add(right); + return new Pair<>(left.name + " " + comp.sql + " ? ", params); + } + + + enum SQLComparator { + /** Equivalent to SQL "=" */ + EQ("="), + /** Equivalent to SQL ">" */ + GT(">"), + /** Equivalent to SQL ">=" */ + GEQ(">="), + /** Equivalent to SQL "<" */ + LT("<"), + /** Equivalent to SQL "<=" */ + LEQ("<="), + /** Equivalent to SQL "!=" */ + NEQ("!="); + + public final String sql; + + private SQLComparator(String s) { + sql = s; + } + + } + + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereLike.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereLike.java new file mode 100644 index 0000000..4968442 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereLike.java @@ -0,0 +1,35 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.util.ArrayList; +import java.util.List; + +import javafx.util.Pair; + +public class SQLWhereLike extends SQLWhere { + + + private SQLField field; + private String likeExpr; + + /** + * 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 SQLWhereLike(SQLField 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> toSQL() { + ArrayList params = new ArrayList<>(); + params.add(likeExpr); + return new Pair<>(field.name + " LIKE ? ", params); + } + +} diff --git a/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereNull.java b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereNull.java new file mode 100644 index 0000000..8116120 --- /dev/null +++ b/src/fr/pandacube/java/util/db2/sql_tools/SQLWhereNull.java @@ -0,0 +1,37 @@ +package fr.pandacube.java.util.db2.sql_tools; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import fr.pandacube.java.PandacubeUtil; +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) + PandacubeUtil.getMasterLogger().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> toSQL() { + return new Pair<>(fild.name + " IS" + ((nulll)?" NULL":" NOT NULL"), new ArrayList<>()); + } + + + +}