|  | @@ -0,0 +1,120 @@
 | 
	
		
			
				|  |  | +package db;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import java.lang.reflect.Field;
 | 
	
		
			
				|  |  | +import java.lang.reflect.InvocationTargetException;
 | 
	
		
			
				|  |  | +import java.sql.SQLException;
 | 
	
		
			
				|  |  | +import java.util.HashMap;
 | 
	
		
			
				|  |  | +import java.util.Map;
 | 
	
		
			
				|  |  | +import java.util.Optional;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import db.annotation.DbField;
 | 
	
		
			
				|  |  | +import db.annotation.DbId;
 | 
	
		
			
				|  |  | +import db.annotation.DbTable;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +public abstract class Table<T extends Persistable> {
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	protected Map<Long, T> cacheMap = new HashMap<>();
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	public Optional<T> findById(long id) {
 | 
	
		
			
				|  |  | +		if (cacheMap.containsKey(id)) {
 | 
	
		
			
				|  |  | +			return Optional.of(cacheMap.get(id));
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		Optional<T> obj = getFromDb(id);
 | 
	
		
			
				|  |  | +		if(obj.isPresent()) {
 | 
	
		
			
				|  |  | +			cache(obj.get());
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return obj;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	public T refresh(long id) {
 | 
	
		
			
				|  |  | +		if (!cacheMap.containsKey(id)) {
 | 
	
		
			
				|  |  | +			throw new IllegalArgumentException("Entity is not load, can't refresh");
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		Optional<T> optObj = getFromDb(id);
 | 
	
		
			
				|  |  | +		if(optObj.isEmpty()) {
 | 
	
		
			
				|  |  | +			throw new IllegalStateException("Unable to find entity in the database");
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		T obj = optObj.get();
 | 
	
		
			
				|  |  | +		cache(obj);
 | 
	
		
			
				|  |  | +		return obj;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	public T refresh(T obj) {
 | 
	
		
			
				|  |  | +		return refresh(obj.getId());
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	public void save(T obj) {
 | 
	
		
			
				|  |  | +		if (cacheMap.containsKey(obj.getId())) {
 | 
	
		
			
				|  |  | +			update(obj);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			insert(obj);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	public final void delete(long id) {
 | 
	
		
			
				|  |  | +		
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	public void delete(T obj) {
 | 
	
		
			
				|  |  | +		delete(obj.getId());
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	private void cache(T obj) {
 | 
	
		
			
				|  |  | +		if (cacheMap.containsKey(obj.getId())) {
 | 
	
		
			
				|  |  | +			cacheMap.replace(obj.getId(), obj);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			cacheMap.put(obj.getId(), obj);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	private Optional<T> getFromDb(long id) {
 | 
	
		
			
				|  |  | +		Class<?> clazz = this.getClass();
 | 
	
		
			
				|  |  | +		// Recupération info anotation DbTable
 | 
	
		
			
				|  |  | +		if (!clazz.isAnnotationPresent(DbTable.class)) {
 | 
	
		
			
				|  |  | +			throw new IllegalStateException("Unable ton find DbTable annotation");
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		DbTable dbTable = clazz.getAnnotation(DbTable.class);
 | 
	
		
			
				|  |  | +		// Cherche l'id
 | 
	
		
			
				|  |  | +		String idField = null;
 | 
	
		
			
				|  |  | +		for(Field field : dbTable.entity().getFields()) {
 | 
	
		
			
				|  |  | +			if(field.isAnnotationPresent(DbId.class)) {
 | 
	
		
			
				|  |  | +				if(field.isAnnotationPresent(DbField.class)) {
 | 
	
		
			
				|  |  | +					idField = field.getAnnotation(DbField.class).name();
 | 
	
		
			
				|  |  | +				} else {
 | 
	
		
			
				|  |  | +					throw new IllegalStateException("Unable to find DbField annotation on id");
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		if (idField == null) {
 | 
	
		
			
				|  |  | +			throw new IllegalStateException("Unable to find find DbField annotation");
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		// Requete sql
 | 
	
		
			
				|  |  | +		String sql = "Select * From " + dbTable.name() + " Where " + idField + " = " + id;
 | 
	
		
			
				|  |  | +		Optional<T> result = Database.query(sql, rs -> {
 | 
	
		
			
				|  |  | +			try {
 | 
	
		
			
				|  |  | +				T obj = (T) dbTable.entity().getConstructor().newInstance();
 | 
	
		
			
				|  |  | +				rs.next();
 | 
	
		
			
				|  |  | +				for(Field field : dbTable.entity().getFields()) {
 | 
	
		
			
				|  |  | +					if(!field.isAnnotationPresent(DbField.class)) {
 | 
	
		
			
				|  |  | +						continue;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +					obj.getClass().getField(field.getName()).set(obj, rs.getObject(field.getAnnotation(DbField.class).name()));
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				return obj;
 | 
	
		
			
				|  |  | +			} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException | SQLException e) {
 | 
	
		
			
				|  |  | +				throw new IllegalStateException("Unable to map value to the entity");
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		});
 | 
	
		
			
				|  |  | +		// Return
 | 
	
		
			
				|  |  | +		return result;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	private void insert(T obj) {
 | 
	
		
			
				|  |  | +		
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	private void update(T obj) {
 | 
	
		
			
				|  |  | +		
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |