Debug, Correction de bug, Classe Log, affichage des distances amélioré
- Ajout d'un mode debuggage utilisé par l'ORM pour afficher les requêtes envoyés au serveur BDD - Corrections de nombreux bugs présent dans le nouvel ORM et dans son utilisation - Meilleure affichage des distances : unité m et km choisi selon distance - Ajout d'une classe Log qui permet de simplifier l'utilisation du logger
This commit is contained in:
parent
b2a19e09c1
commit
c5af1bd213
@ -50,6 +50,25 @@ public class EnumUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de rechercher l'existance d'un élément dans un enum, de façon insensible à la casse
|
||||
* La validité de la classe passé en premier paramètre est vérifiée dynamiquement et non
|
||||
* statiquement. Préférez l'utilisation de {@link #searchEnum(Class, String)} quand c'est possible.
|
||||
* @param enumType la classe correpondant à l'enum à lister
|
||||
* @param search l'élément à rechercher, insensible à la casse
|
||||
* @return l'élément de l'énumération, si elle a été trouvée et si la classe passée en paramètre est un enum, null dans les autres cas
|
||||
*/
|
||||
public static Enum<?> searchUncheckedEnum(Class<?> enumType, String search) {
|
||||
if (!enumType.isEnum())
|
||||
return null;
|
||||
Enum<?>[] elements = (Enum<?>[]) enumType.getEnumConstants();
|
||||
|
||||
for (Enum<?> el : elements)
|
||||
if (el.name().equalsIgnoreCase(search))
|
||||
return el;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +1,22 @@
|
||||
package fr.pandacube.java.util;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Log {
|
||||
|
||||
private static Logger logger;
|
||||
private static AtomicBoolean logDebug = new AtomicBoolean(false);
|
||||
|
||||
public static void setDebugState(boolean newVal) {
|
||||
logDebug.set(newVal);
|
||||
}
|
||||
|
||||
public static boolean getDebugState() {
|
||||
return logDebug.get();
|
||||
}
|
||||
|
||||
|
||||
public static Logger getLogger() {
|
||||
return logger;
|
||||
@ -42,5 +53,20 @@ public class Log {
|
||||
public static void severe(String message) {
|
||||
logger.severe(message);
|
||||
}
|
||||
|
||||
public static void debug(String message, Throwable t) {
|
||||
if (!logDebug.get()) return;
|
||||
logger.log(Level.INFO, message, t);
|
||||
}
|
||||
|
||||
public static void debug(Throwable t) {
|
||||
if (!logDebug.get()) return;
|
||||
logger.log(Level.INFO, "", t);
|
||||
}
|
||||
|
||||
public static void debug(String message) {
|
||||
if (!logDebug.get()) return;
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
package fr.pandacube.java.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MemoryUtil {
|
||||
public static String humanReadableSize(long octet)
|
||||
{
|
||||
DecimalFormat format = new DecimalFormat("#####0.00");
|
||||
double size = octet;
|
||||
if (size < 1024)
|
||||
return size+"o";
|
||||
size /= 1024;
|
||||
if (size < 1024)
|
||||
return format.format(size)+"kio";
|
||||
size /= 1024;
|
||||
if (size < 1024)
|
||||
return format.format(size)+"Mio";
|
||||
size /= 1024;
|
||||
if (size < 1024)
|
||||
return format.format(size)+"Gio";
|
||||
size /= 1024;
|
||||
|
||||
return format.format(size)+"Tio";
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import java.sql.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import fr.pandacube.java.util.db2.sql_tools.ORM;
|
||||
import fr.pandacube.java.util.db2.sql_tools.ORMException;
|
||||
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;
|
||||
@ -90,7 +91,7 @@ public class SQLPlayer extends SQLElement {
|
||||
|
||||
|
||||
|
||||
public static SQLPlayer getPlayerFromUUID(UUID playerId) throws Exception {
|
||||
public static SQLPlayer getPlayerFromUUID(UUID playerId) throws ORMException {
|
||||
return ORM.getFirst(SQLPlayer.class,
|
||||
new SQLWhereComp(SQLPlayer.playerId, SQLComparator.EQ, playerId.toString()),
|
||||
null);
|
||||
|
@ -8,6 +8,7 @@ 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.db2.SQLContact;
|
||||
import fr.pandacube.java.util.db2.SQLForumCategorie;
|
||||
@ -127,7 +128,7 @@ public final class ORM {
|
||||
ps.setObject(i++, val);
|
||||
}
|
||||
try {
|
||||
System.out.println(ps.toString());
|
||||
Log.info("Creating table "+elem.tableName()+":\n"+ps.toString());
|
||||
ps.executeUpdate();
|
||||
} finally {
|
||||
ps.close();
|
||||
@ -222,11 +223,11 @@ public final class ORM {
|
||||
|
||||
int i = 1;
|
||||
for (Object val : params) {
|
||||
if (val instanceof Enum<?>)
|
||||
val = ((Enum<?>)val).name();
|
||||
ps.setObject(i++, val);
|
||||
}
|
||||
|
||||
System.out.println(ps.toString());
|
||||
|
||||
Log.debug(ps.toString());
|
||||
ResultSet set = ps.executeQuery();
|
||||
|
||||
try {
|
||||
@ -259,7 +260,7 @@ public final class ORM {
|
||||
|
||||
|
||||
|
||||
private static <T extends SQLElement> T getElementInstance(ResultSet set, Class<T> elemClass) throws ReflectiveOperationException, SQLException {
|
||||
private static <T extends SQLElement> T getElementInstance(ResultSet set, Class<T> elemClass) throws ORMException {
|
||||
try {
|
||||
T instance = elemClass.getConstructor(int.class).newInstance(set.getInt("id"));
|
||||
|
||||
@ -271,12 +272,37 @@ public final class ORM {
|
||||
continue; // ignore when field is present in database but not handled by SQLElement instance
|
||||
@SuppressWarnings("unchecked")
|
||||
SQLField<Object> sqlField = (SQLField<Object>) instance.getFields().get(fieldName);
|
||||
instance.set(sqlField, set.getObject(c), false);
|
||||
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 e) {
|
||||
throw new ReflectiveOperationException("Can't instanciate " + elemClass.getName(), e);
|
||||
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException | SQLException e) {
|
||||
throw new ORMException("Can't instanciate " + elemClass.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,9 +319,6 @@ public final class ORM {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private ORM() { } // rend la classe non instanciable
|
||||
|
||||
/*
|
||||
|
@ -37,7 +37,7 @@ public abstract class SQLElement {
|
||||
private final SQLFieldMap fields;
|
||||
|
||||
private final Map<SQLField<?>, Object> values;
|
||||
private final Set<String> modifiedSinceLastSave;
|
||||
/* package */ final Set<String> modifiedSinceLastSave;
|
||||
|
||||
|
||||
public SQLElement() {
|
||||
@ -206,7 +206,7 @@ public abstract class SQLElement {
|
||||
|
||||
|
||||
public boolean isValidForSave() {
|
||||
return values.keySet().containsAll(fields.keySet());
|
||||
return values.keySet().containsAll(fields.values());
|
||||
}
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ public abstract class SQLElement {
|
||||
private Map<SQLField<?>, Object> getOnlyModifiedValues() {
|
||||
Map<SQLField<?>, Object> modifiedValues = new LinkedHashMap<>();
|
||||
values.forEach((k, v) -> {
|
||||
if (modifiedSinceLastSave.contains(k))
|
||||
if (modifiedSinceLastSave.contains(k.name))
|
||||
modifiedValues.put(k, v);
|
||||
});
|
||||
return modifiedValues;
|
||||
@ -230,10 +230,10 @@ public abstract class SQLElement {
|
||||
|
||||
public void save() throws ORMException {
|
||||
if (!isValidForSave())
|
||||
throw new IllegalStateException("this instance of " + getClass().getName() + " has at least one undefined value and can't be saved.");
|
||||
throw new IllegalStateException(toString() + " has at least one undefined value and can't be saved.");
|
||||
|
||||
ORM.initTable(getClass());
|
||||
|
||||
String toStringStatement = "";
|
||||
try {
|
||||
|
||||
Connection conn = db.getNativeConnection();
|
||||
@ -249,14 +249,20 @@ public abstract class SQLElement {
|
||||
modifiedSinceLastSave.remove("id");
|
||||
Map<SQLField<?>, Object> modifiedValues = getOnlyModifiedValues();
|
||||
|
||||
|
||||
if (modifiedValues.isEmpty())
|
||||
return;
|
||||
|
||||
String sql = "";
|
||||
List<Object> psValues = new ArrayList<>();
|
||||
|
||||
for(Map.Entry<SQLField<?>, Object> entry : modifiedValues.entrySet()) {
|
||||
sql += entry.getKey() + " = ? ,";
|
||||
psValues.add(entry.getValue());
|
||||
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)
|
||||
@ -270,7 +276,8 @@ public abstract class SQLElement {
|
||||
for (Object val : psValues) {
|
||||
ps.setObject(i++, val);
|
||||
}
|
||||
|
||||
|
||||
toStringStatement = ps.toString();
|
||||
ps.executeUpdate();
|
||||
} finally {
|
||||
ps.close();
|
||||
@ -295,8 +302,13 @@ public abstract class SQLElement {
|
||||
}
|
||||
first = false;
|
||||
concat_vals += " ? ";
|
||||
concat_fields += entry.getKey();
|
||||
psValues.add(entry.getValue());
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@ -307,7 +319,8 @@ public abstract class SQLElement {
|
||||
for (Object val : psValues) {
|
||||
ps.setObject(i++, val);
|
||||
}
|
||||
|
||||
|
||||
toStringStatement = ps.toString();
|
||||
ps.executeUpdate();
|
||||
|
||||
ResultSet rs = ps.getGeneratedKeys();
|
||||
@ -329,8 +342,9 @@ public abstract class SQLElement {
|
||||
|
||||
modifiedSinceLastSave.clear();
|
||||
} catch(SQLException e) {
|
||||
throw new ORMException("Error while saving data in table "+tableName(), e);
|
||||
throw new ORMException("Error while executing SQL statement "+toStringStatement, e);
|
||||
}
|
||||
Log.debug(toStringStatement);
|
||||
}
|
||||
|
||||
|
||||
@ -356,6 +370,7 @@ public abstract class SQLElement {
|
||||
{ // 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 {
|
||||
@ -411,7 +426,7 @@ public abstract class SQLElement {
|
||||
try {
|
||||
b.append(f.name, get(f));
|
||||
} catch(IllegalArgumentException e) {
|
||||
b.append(f.name, "(Must be defined before saving)");
|
||||
b.append(f.name, "(Undefined)");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import fr.pandacube.java.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <E>
|
||||
@ -32,11 +34,11 @@ public class SQLElementList<E extends SQLElement> extends ArrayList<E> {
|
||||
* @param value la valeur à lui appliquer
|
||||
*/
|
||||
public synchronized <T> void setCommon(SQLField<T> 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<E> elemClass = (Class<E>) get(0).getClass();
|
||||
|
||||
Class<E> elemClass = (Class<E>) field.getSQLElementType();
|
||||
try {
|
||||
E emptyElement = elemClass.newInstance();
|
||||
emptyElement.set(field, value, false);
|
||||
@ -71,7 +73,12 @@ public class SQLElementList<E extends SQLElement> extends ArrayList<E> {
|
||||
|
||||
for(Map.Entry<SQLField<?>, Object> entry : modifiedValues.entrySet()) {
|
||||
sqlSet += entry.getKey().name + " = ? ,";
|
||||
psValues.add(entry.getValue());
|
||||
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)
|
||||
@ -93,6 +100,7 @@ public class SQLElementList<E extends SQLElement> extends ArrayList<E> {
|
||||
ps.setObject(i++, val);
|
||||
}
|
||||
|
||||
Log.debug(ps.toString());
|
||||
ps.executeUpdate();
|
||||
|
||||
applyNewValuesToElements(storedEl);
|
||||
@ -140,6 +148,7 @@ public class SQLElementList<E extends SQLElement> extends ArrayList<E> {
|
||||
|
||||
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) {
|
||||
|
@ -6,7 +6,7 @@ public class SQLType<T> {
|
||||
|
||||
private final String sqlType;
|
||||
private final String sqlTypeParam;
|
||||
private final Class<?> javaTypes;
|
||||
private final Class<T> javaTypes;
|
||||
|
||||
public SQLType(String sqlT, String sqlP, Class<T> javaT) {
|
||||
sqlType = sqlT;
|
||||
@ -37,6 +37,10 @@ public class SQLType<T> {
|
||||
return toString().equals(((SQLType<?>)obj).toString());
|
||||
}
|
||||
|
||||
public Class<T> getJavaType() {
|
||||
return javaTypes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
63
src/fr/pandacube/java/util/measurement/DistanceUtil.java
Normal file
63
src/fr/pandacube/java/util/measurement/DistanceUtil.java
Normal file
@ -0,0 +1,63 @@
|
||||
package fr.pandacube.java.util.measurement;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DistanceUtil {
|
||||
|
||||
public static String distanceToString(double meterDist, int precision, DistanceUnit... desiredUnits) {
|
||||
|
||||
|
||||
Arrays.sort(desiredUnits);
|
||||
|
||||
DistanceUnit choosenUnit = desiredUnits[0]; // la plus petite unitée
|
||||
for (DistanceUnit unit : desiredUnits) {
|
||||
if (meterDist / unit.multiplicator < 1)
|
||||
continue;
|
||||
choosenUnit = unit;
|
||||
}
|
||||
|
||||
if (choosenUnit != desiredUnits[0] && precision <= 2)
|
||||
precision = 2;
|
||||
|
||||
|
||||
String precisionFormat = "##0";
|
||||
if (precision > 0)
|
||||
precisionFormat += ".";
|
||||
for (int i=0;i<precision; i++)
|
||||
precisionFormat += "0";
|
||||
DecimalFormat df = new DecimalFormat(precisionFormat);
|
||||
|
||||
double dist = meterDist / choosenUnit.multiplicator;
|
||||
|
||||
return df.format(dist)+choosenUnit.unitStr;
|
||||
}
|
||||
|
||||
public static String distanceToString(double meterDist, int precision) {
|
||||
return distanceToString(meterDist, precision, DistanceUnit.M, DistanceUnit.KM);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public enum DistanceUnit implements Comparable<DistanceUnit> {
|
||||
NM(0.000000001, "nm"),
|
||||
µM(0.000001, "µm"),
|
||||
MM(0.001, "mm"),
|
||||
CM(0.01, "cm"),
|
||||
M(1, "m"),
|
||||
KM(1000, "km");
|
||||
|
||||
|
||||
private final double multiplicator;
|
||||
private final String unitStr;
|
||||
|
||||
private DistanceUnit(double mult, String s) {
|
||||
multiplicator = mult;
|
||||
unitStr = s;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
37
src/fr/pandacube/java/util/measurement/MemoryUtil.java
Normal file
37
src/fr/pandacube/java/util/measurement/MemoryUtil.java
Normal file
@ -0,0 +1,37 @@
|
||||
package fr.pandacube.java.util.measurement;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MemoryUtil {
|
||||
|
||||
private static final DecimalFormat format = new DecimalFormat("#####0.00");
|
||||
|
||||
public static String humanReadableSize(long octet, boolean si)
|
||||
{
|
||||
|
||||
double size = octet;
|
||||
|
||||
int diveBy = si ? 1000 : 1024;
|
||||
|
||||
|
||||
if (size < diveBy)
|
||||
return size+"o";
|
||||
size /= diveBy;
|
||||
if (size < diveBy)
|
||||
return format.format(size) + (si ? "ko" : "kio");
|
||||
size /= diveBy;
|
||||
if (size < diveBy)
|
||||
return format.format(size) + (si ? "Mo" : "Mio");
|
||||
size /= diveBy;
|
||||
if (size < diveBy)
|
||||
return format.format(size) + (si ? "Go" : "Gio");
|
||||
size /= diveBy;
|
||||
|
||||
return format.format(size) + (si ? "To" : "Tio");
|
||||
}
|
||||
|
||||
|
||||
public static String humanReadableSize(long octet) {
|
||||
return humanReadableSize(octet, false);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package fr.pandacube.java.util;
|
||||
package fr.pandacube.java.util.measurement;
|
||||
|
||||
public class TimeUtil {
|
||||
public static String durationToString (long msec_time, boolean dec_seconde)
|
Loading…
Reference in New Issue
Block a user