/**
* Copyright (C) 2013-2014 Project-Vethrfolnir
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.vethrfolnir.game.services.dao;
import java.sql.Connection;
import java.util.concurrent.*;
import com.vethrfolnir.database.DatabaseFactory;
import com.vethrfolnir.game.services.DatabaseService;
import com.vethrfolnir.logging.MuLogger;
import com.vethrfolnir.services.threads.CorvusThreadPool;
import corvus.corax.Corax;
import corvus.corax.inject.Inject;
/**
* @author Vlad
*
* TODO: We need to megrate to Corvus Engine 5, this DAO thingie is really bad :(
*/
public abstract class DAO {
protected static final MuLogger log = MuLogger.getLogger(DAO.class);
@Inject
protected DatabaseService service;
@Inject
private DatabaseFactory factory;
@SuppressWarnings("unchecked")
protected <T> T as(Object obj) {
return (T)obj;
}
@SuppressWarnings("unchecked")
protected <T> T as(Object obj, Class<T> type) {
return (T)obj;
}
/**
* Returning null means failed execution
* @param proc
* @param buff
* @return
*/
@SuppressWarnings("unchecked")
protected <T> T execute(final Procedure<?> proc, final Object... buff) {
try (Connection con = factory.getConnection()) {
return (T) proc.perform(con, proc, buff);
}
catch (Exception e) {
log.fatal("Failed enqueue!", e);
}
return null;
}
protected Future<?> enqueue(final VoidProcedure proc, final Object... buff) {
ThreadPoolExecutor exec = Corax.fetch(CorvusThreadPool.class).getImidiatExecutor();
Future<?> f = exec.submit(new Callable<Object>() {
@Override
public Object call() {
try (Connection con = factory.getConnection()) {
proc.perform(con, buff);
}
catch (Exception e) {
log.fatal("Failed enqueue!", e);
}
return null;
}
});
return f;
}
/**
* @param proc
* @param parallel
* @return
*/
protected Future<?> enqueue(final Procedure<?> proc, final Object... buff) {
ThreadPoolExecutor exec = Corax.fetch(CorvusThreadPool.class).getImidiatExecutor();
Future<?> f = exec.submit(new Callable<Object>() {
@Override
public Object call() {
return execute(proc, buff);
}
});
return f;
}
protected Future<?> enqueueVoid(final VoidProcedure proc, final Object... buff) {
return enqueue(proc, buff);
}
protected <T> T enqueueAndWait(final Procedure<T> proc, final Object... buff) {
return awaitFuture(enqueue(proc, buff));
}
protected <T> T enqueueVoidAndWait(final VoidProcedure proc, final Object... buff) {
return awaitFuture(enqueue(proc, buff));
}
/**
* @param future
* @return
*/
protected <T> T awaitFuture(Future<?> future) {
return awaitFuture(future, null);
}
/**
* @param future
* @param type
* @return
*/
@SuppressWarnings("unchecked")
protected <T> T awaitFuture(Future<?> future, Class<T> type) {
try {
return (T) future.get(5, TimeUnit.SECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutException e) {
log.fatal("Failed awaiting future!", e);
}
return null;
}
protected interface VoidProcedure {
void perform(Connection con, Object... buff) throws Exception;
}
protected interface Procedure<V> {
public V perform(Connection con, Procedure<?> proc, Object... buff) throws Exception;
}
}