accounting-dashboard-harves.../src/main/java/org/gcube/dataharvest/dao/Dao.java

387 lines
11 KiB
Java

package org.gcube.dataharvest.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.dataharvest.datamodel.HarvestedData;
import org.gcube.dataharvest.utils.DateUtils;
import org.postgresql.util.PSQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Eric Perrone (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*/
public class Dao {
private Connection conn = null;
private static Logger logger = LoggerFactory.getLogger(Dao.class);
/**
* Class constructor. This method must be called before any other class
* method.
*
* @throws DaoException
*/
public void init() throws DaoException {
try {
Class.forName("org.postgresql.Driver");
} catch(ClassNotFoundException ex) {
logger.error(ex.getLocalizedMessage());
throw new DaoException(ex.getLocalizedMessage(), ex.getCause());
}
}
/**
* Connect a database
*
* @param url
* @param user
* @param password
* @throws DaoException
*/
public void connect(String url, String user, String password) throws DaoException {
try {
conn = DriverManager.getConnection(url, user, password);
logger.debug("Connected to: " + url);
} catch(SQLException ex) {
logger.error(ex.getLocalizedMessage());
throw new DaoException(ex.getLocalizedMessage(), ex.getCause());
}
}
/**
* Release a database connection
*
* @throws DaoException
*/
public void disconnect() throws DaoException {
try {
if(conn != null) {
conn.close();
conn = null;
logger.debug("Disconnecting from database");
}
} catch(SQLException ex) {
logger.error(ex.getLocalizedMessage());
throw new DaoException(ex.getLocalizedMessage(), ex.getCause());
}
}
/**
* Check the connection with the database.
*
* @return true|false
*/
public boolean isConnected() {
return (!(conn == null));
}
/**
* Getter for the database connection
*
* @return Connection class
*/
public Connection getConnection() {
return conn;
}
/**
* Read on the database all active VRES
*
* @return
*/
public String[] getActiveVres() {
String query = "select dname from context where dname is not null and dismissed is null";
logger.debug(query);
Statement s = null;
ResultSet rs = null;
ArrayList<String> list = new ArrayList<>();
try {
s = conn.createStatement();
rs = s.executeQuery(query);
while(rs.next()) {
list.add(rs.getString("dname"));
}
return list.toArray(new String[list.size()]);
} catch(Exception ex) {
logger.error(ex.getLocalizedMessage());
return null;
} finally {
if(rs != null) {
try {
rs.close();
} catch(SQLException ex) {
// do nothing
}
}
if(s != null) {
try {
s.close();
} catch(SQLException ex) {
// do nothing
}
}
}
}
/**
* This method insert/update data in the monthly_measure database table.
*
* @param data
* @param from
* @param to
* @throws DaoException
*/
public void insertMonthlyMeasure(List<HarvestedData> data, Date from, Date to, boolean doUpdate)
throws DaoException {
// first of all: check if data of the same type are already in the
// database.
// In this case data will be updated.
Calendar cFrom = DateUtils.dateToCalendar(from);
Calendar cTo = DateUtils.dateToCalendar(to);
int monthFrom = cFrom.get(Calendar.MONTH);
int yearFrom = cFrom.get(Calendar.YEAR);
int monthTo = cTo.get(Calendar.MONTH);
int yearTo = cTo.get(Calendar.YEAR);
if((monthFrom != monthTo) || (yearFrom != yearTo)) {
String err = "Invalid time period. The time period MUST refer one month.";
logger.error(err);
throw new DaoException(err, null);
}
if(data == null || data.size() <= 0) {
String err = "No data passed in input. Aborting operation.";
logger.error(err);
throw new DaoException(err, null);
}
monthFrom++; // because january = 0...
try {
for(HarvestedData harvestedData : data) {
int contextId = getOrInsertContextId(harvestedData.getContext());
String query = "select id from monthly_measure where measure_type_id=" + harvestedData.getDataType()
+ " and context_id=" + contextId + " and month=" + monthFrom + " and year=" + yearFrom;
logger.debug(query);
Statement sel = conn.createStatement();
ResultSet rs = sel.executeQuery(query);
if(rs.next()) {
if(doUpdate) {
// record found: update it
Statement s = conn.createStatement();
int id = rs.getInt("id");
String update = "update monthly_measure set measure=" + harvestedData.getMeasure() + " where id="
+ id;
logger.debug(update);
s.execute(update);
s.close();
} else {
logger.warn("Skipped " + harvestedData.getContext());
}
} else {
// record not found: insert new record
Statement s = conn.createStatement();
String insert = "insert into monthly_measure (year, month, measure, measure_type_id, context_id, day) values (";
insert += yearFrom + "," + monthFrom + "," + harvestedData.getMeasure() + "," + harvestedData.getDataType()
+ ",";
insert += "(select id from context where dname='" + harvestedData.getContext() + "'),";
insert += "'" + yearFrom + "-" + monthFrom + "-01'";
insert += ")";
logger.debug(insert);
s.execute(insert);
s.close();
}
rs.close();
sel.close();
}
} catch(PSQLException x) {
// handled exception: try to iterate...
logger.error(x.getLocalizedMessage());
} catch(Exception x) {
// not handled exception: stop
logger.error(x.getLocalizedMessage());
throw new DaoException(x.getClass().getName() + "::" + x.getLocalizedMessage(), x);
}
}
public enum contextType {
INFRASTRUCTURE, VO, VRE
}
public int getOrInsertContextId(String contextFullName) throws SQLException {
String query = "select id from context where dname='" + contextFullName + "'";
logger.debug(query);
Statement sel = conn.createStatement();
ResultSet rs = sel.executeQuery(query);
if(rs.next()) {
// context found
int id = rs.getInt("id");
logger.debug("Context {} has id {}", contextFullName, id);
return id;
} else {
// context not found: insert new record
int parentId = 0; // The id of D4Science infrastructure as aggregator
int lastIndexOfSlash = contextFullName.lastIndexOf("/");
if(lastIndexOfSlash!=0) {
String parentContextFullName = contextFullName.substring(0, contextFullName.lastIndexOf("/"));
parentId = getOrInsertContextId(parentContextFullName);
}
// It is a new context and we don't know which context type is. Using 0 for ROOT, 1 for VO, 2 for VRE
int contextTypeId = contextType.INFRASTRUCTURE.ordinal();
ScopeBean scopeBean = new ScopeBean(contextFullName);
switch(scopeBean.type()) {
case INFRASTRUCTURE:
contextTypeId = contextType.INFRASTRUCTURE.ordinal();
break;
case VO:
contextTypeId = contextType.VO.ordinal();
break;
case VRE:
contextTypeId = contextType.VRE.ordinal();
break;
default:
break;
}
Statement s = conn.createStatement();
String insert = "insert into context (name, context_id, context_type_id, dname) values ('";
insert += contextFullName + "'," + parentId + "," + contextTypeId + ", '" + contextFullName;
insert += "')";
logger.debug(insert);
s.execute(insert);
s.close();
}
rs.close();
sel.close();
return getOrInsertContextId(contextFullName);
}
public ArrayList<Integer> getSubTree(Integer rootId) throws DaoException {
String queryBase = "select id from context where context_id in (%%)";
ArrayList<Integer> subTree = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
Statement s = null;
ResultSet rs = null;
temp.add(rootId);
subTree.add(rootId);
boolean again = true;
for(int i = 0; (i < 10) && (again); i++) {
try {
String listId = "";
for(Integer id : temp) {
listId += "," + id;
}
listId = listId.substring(1);
String query = queryBase.replace("%%", listId);
s = conn.createStatement();
rs = s.executeQuery(query);
if(rs.next()) {
temp = new ArrayList<>();
Integer dbId = rs.getInt("id");
subTree.add(dbId);
temp.add(dbId);
while(rs.next()) {
dbId = rs.getInt("id");
subTree.add(dbId);
temp.add(dbId);
}
} else {
again = false;
}
rs.close();
s.close();
} catch(Exception x) {
logger.error(x.getLocalizedMessage());
throw new DaoException(x.getClass().getName() + "::" + x.getLocalizedMessage(), x);
}
}
return subTree;
}
public void createSocialReport(int contextId, int orderBy) throws DaoException {
Statement rep = null;
ResultSet rs = null;
try {
String report = "insert into report (context_id, name, orderby, chart_type, x_text, y_text) values ";
report += "(" + contextId + ", \'VRE Social\', " + orderBy
+ ", \'column\', \'Period\', \'Social interaction\')";
logger.debug(report);
rep = conn.createStatement();
rep.execute(report);
String query = "select id from report where name=\'VRE Social\' order by id desc";
rs = rep.executeQuery(query);
if(rs.next()) {
int id = rs.getInt("id");
String reportItem = "insert into report_item (report_id, type_id_1, type_id_1_name) ";
reportItem += "values (" + id + ", 8, \'mt\'), (" + id + ", 9, \'mt\'), (" + id + ", 10, \'mt\')";
rep.execute(reportItem);
} else
throw new DaoException("No report id.", null);
} catch(SQLException ex) {
logger.error(ex.getLocalizedMessage());
throw new DaoException(ex.getLocalizedMessage(), ex.getCause());
} finally {
try {
if(rs != null) {
rs.close();
}
if(rep != null) {
rep.close();
}
} catch(SQLException ex) {
logger.error(ex.getLocalizedMessage());
}
}
}
/**
* Dummy tester
*
* @Deprecated
* @param originator
* @throws DaoException
*
*/
public void dummyTest(String originator) throws DaoException {
String insert = "insert into dummy (now, originator) values(current_timestamp, '" + originator + "')";
logger.debug(insert);
Statement s = null;
try {
s = conn.createStatement();
s.execute(insert);
} catch(SQLException ex) {
logger.error(ex.getLocalizedMessage());
throw new DaoException(ex.getLocalizedMessage(), ex.getCause());
} finally {
if(s != null)
try {
s.close();
} catch(SQLException ex) {
logger.error(ex.getLocalizedMessage());
}
}
}
}