package org.gcube.data.access.accounting.summary.access.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Date; import org.gcube.data.access.accounting.summary.access.impl.DBStructure.CONTEXTS; import org.gcube.data.access.accounting.summary.access.impl.DBStructure.DIMENSIONS; import org.gcube.data.access.accounting.summary.access.impl.DBStructure.Measure; import org.gcube.data.access.accounting.summary.access.model.MeasureResolution; import org.gcube.data.access.accounting.summary.access.model.ScopeDescriptor; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j @RequiredArgsConstructor public class Queries { @NonNull private Connection conn; public ResultSet listDimensions() throws SQLException { return conn.createStatement().executeQuery("Select * from "+DIMENSIONS.TABLENAME+" order by "+DIMENSIONS.LABEL); } public ResultSet listContexts() throws SQLException { return conn.createStatement().executeQuery("Select * from "+CONTEXTS.TABLENAME+" order by "+CONTEXTS.LABEL); } /** * Returned parameters order is * Context, Dimension, Time, Measure, Measure * * NB : Measure is replicated in order to manage update on conflict * * @return PS with parameters * @throws SQLException */ public PreparedStatement getMeasureInsertionPreparedStatement() throws SQLException { String query=String.format("INSERT INTO %1$s (%2$s,%3$s,%4$s,%5$s) values (?,?,?,?)" +" ON CONFLICT ON CONSTRAINT "+Measure.TABLENAME+"_pKey DO UPDATE SET "+Measure.MEASURE+"=?", Measure.TABLENAME,Measure.CONTEXT,Measure.DIMENSION,Measure.TIME,Measure.MEASURE); return conn.prepareStatement(query); } /** * Returned parameters order is * ID,LABEL,GROUP,AGGREGATED_MEASURE * * * @return * @throws SQLException */ public PreparedStatement getDimensionInsertionPreparedStatement() throws SQLException { String query=String.format("INSERT INTO %1$s (%2$s,%3$s,%4$s,%5$s) values (?,?,?,?)", DIMENSIONS.TABLENAME,DIMENSIONS.ID,DIMENSIONS.LABEL,DIMENSIONS.GROUP,DIMENSIONS.AGGREGATED_MEASURE); return conn.prepareStatement(query); } /** * Returned parameters order is * ID,LABEL * * * @return * @throws SQLException */ public PreparedStatement getContextInsertionPreparedStatement() throws SQLException { String query=String.format("INSERT INTO %1$s (%2$s,%3$s) values (?,?)", CONTEXTS.TABLENAME,CONTEXTS.ID,CONTEXTS.LABEL); return conn.prepareStatement(query); } /** * Returns Dimensions.* fields * * @param from * @param to * @param scope * @param resolution * @return * @throws SQLException */ public ResultSet getAvailableDimensions(Date from, Date to, ScopeDescriptor scope,MeasureResolution resolution) throws SQLException{ String query= String.format("Select * from %1$s where %2$s in (Select distinct(%3$s) from %4$s where %5$s AND %6$s)", DIMENSIONS.TABLENAME, DIMENSIONS.ID, Measure.DIMENSION,Measure.TABLENAME, Measure.TIME+">=? AND "+Measure.TIME+"<=?", Measure.CONTEXT+" IN "+asIDSet(scope)); PreparedStatement toReturn= conn.prepareStatement(query); toReturn.setLong(1, from.getTime()); toReturn.setLong(2, to.getTime()); log.debug("Performing query {} with params {} and {} ",query,from.getTime(),to.getTime()); return toReturn.executeQuery(); } /** * Prepares a statement for Getting Dim=? in time interval for the scope set * * PS params : * 1- long from * 2- long to * 3- String dimension * * * @param from * @param to * @param scope * @param resolution * @return * @throws SQLException */ public PreparedStatement prepareMeasuresByDimension(ScopeDescriptor scope, MeasureResolution resolution) throws SQLException{ //single scope // "Select measure from measures where context=? and time ok and measure.id=? order by time ASC"; // multi scope return conn.prepareStatement(String.format("Select sum(%1$s) as %1$s from %2$s where %3$s AND %4$s AND %5$s=? group by %6$s order by %7$s", Measure.MEASURE,Measure.TABLENAME, Measure.CONTEXT+" IN "+asIDSet(scope), //context ok Measure.TIME+">=? AND "+Measure.TIME+"<=?", // time ok, PS Parameter Measure.DIMENSION, // dimension ok, PS parameter Measure.TIME, // group by (time) Measure.TIME)); // order by time } public static final String asIDSet(ScopeDescriptor desc){ return "("+scopeList(desc)+")"; } private static final String scopeList(ScopeDescriptor desc) { StringBuilder setBuilder=new StringBuilder(); setBuilder.append("'"+desc.getId()+"'"+","); if(desc.hasChildren()) { for(ScopeDescriptor child : desc.getChildren()) setBuilder.append(scopeList(child)+","); } String toReturn=setBuilder.toString(); return toReturn.substring(0, toReturn.lastIndexOf(",")); } }