Просмотр исходного кода

Finalized service for export in crosstab style

Michal Kepka 4 лет назад
Родитель
Сommit
ca49d3c848

+ 118 - 29
src/main/java/cz/hsrs/db/util/ExportUtil.java

@@ -1,9 +1,13 @@
 package cz.hsrs.db.util;
 
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.sql.Types;
 import java.util.List;
 
 import cz.hsrs.db.model.Unit;
+import cz.hsrs.db.pool.SQLExecutor;
 
 /**
  * 
@@ -11,33 +15,118 @@ import cz.hsrs.db.model.Unit;
  *
  */
 public class ExportUtil {
-	public static String getObservationsBySensorByGroupCross(long sensorId, int groupId, String fromTime, String toTime) throws SQLException {
-		List<Unit> unitList = UnitUtil.getUnitsByGroup(groupId);
-		
-		// define Query
-		StringBuilder selectString = new StringBuilder();
-		StringBuilder unitString = new StringBuilder();
-		selectString.append("select time_stamp\n");
-		unitString.append("as ct( \"time_stamp\" text\n");
-		for (int i = 0; i <unitList.size(); i++) {
-			Unit unit = unitList.get(i);
-			selectString.append(", coalesce(\""+unit.getUnitId()+"\", 0) as \""+unit.getUnitId()+"\"\n");
-			unitString.append(",\""+unit.getUnitId()+"\" double precision,\n");
-		}
-		unitString.append(" ) order by time_stamp;");
-		String fromString = "FROM crosstab( $$\r\n" + 
-				" SELECT to_char(time_stamp, 'DD.MM.YYYY HH24:MI:SS'), unit_id, observed_value from observations\r\n" + 
-				" WHERE unit_id IN (SELECT unit_id FROM units_to_groups WHERE group_id = "+groupId+")\r\n" + 
-				" AND sensor_id = "+sensorId+"\r\n" + 
-				" AND time_stamp >= '"+fromTime+"'\r\n" + 
-				" AND time_stamp < '"+toTime+"'\r\n" + 
-				" order by time_stamp, unit_id\r\n" + 
-				"$$)";
-		
-		String query = selectString.toString() + fromString + unitString.toString();
-		
-		//ResultSet res = SQLExecutor.getInstance().executeQuery(query);
-		
-		return query;
-	}
+    
+    /**
+     * Export method for crosstab style 
+     * e.g.: time_stamp;unit1;unit2;...;unitN
+     * @param sensorId
+     * @param groupId
+     * @param fromTime
+     * @param toTime
+     * @return
+     * @throws SQLException
+     */
+    public static String getObservationsBySensorByGroupCross(long sensorId, int groupId, String fromTime, String toTime, boolean nullable) throws SQLException {
+        List<Unit> unitList = UnitUtil.getUnitsBySensorIdByGroup(sensorId, groupId);
+        String CSV = "";
+        // there are some units to export
+        if(!unitList.isEmpty()) {
+            // define Query
+            StringBuilder selectString = new StringBuilder();
+            StringBuilder unitString = new StringBuilder();
+            selectString.append("SELECT time_stamp\n");
+            unitString.append("AS ct( \"time_stamp\" text\n");
+            for (int i = 0; i <unitList.size(); i++) {
+                Unit unit = unitList.get(i);
+                if(nullable == true) {
+                	selectString.append(", \""+unit.getUnitId()+"\"");
+                }
+                else {
+                	selectString.append(", COALESCE(\""+unit.getUnitId()+"\", 0) AS \""+unit.getUnitId()+"\"");
+                }
+                unitString.append(", \""+unit.getUnitId()+"\" double precision");
+            }
+            unitString.append(" ) ORDER BY time_stamp;");
+            StringBuilder fromString = new StringBuilder();
+            fromString.append(" FROM crosstab( $$\r\n" + 
+                    " SELECT to_char(time_stamp, 'DD.MM.YYYY HH24:MI:SS'), unit_id, observed_value FROM observations\r\n" + 
+                    " WHERE unit_id IN (SELECT unit_id FROM units_to_groups WHERE group_id = "+groupId+")\r\n" + 
+                    " AND sensor_id = "+sensorId+"\r\n"); 
+            if(fromTime != null) {
+                fromString.append(" AND time_stamp >= '"+fromTime+"'\r\n");
+            }
+            if(toTime != null) {
+                fromString.append(" AND time_stamp < '"+toTime+"'\r\n");
+            }
+            fromString.append(" ORDER BY time_stamp, unit_id\r\n$$) ");
+            
+            String query = selectString.toString() + fromString + unitString.toString();
+            
+            ResultSet res = SQLExecutor.getInstance().executeQuery(query);
+            if(res != null) {
+                CSV = CSVWriter(res);
+            }
+        }
+        return CSV;
+    }
+    
+    /**
+     * 
+     * @param res
+     * @return
+     */
+    private static String CSVWriter(ResultSet res) {
+        try {
+            String CSV = null;
+            ResultSetMetaData meta = res.getMetaData();
+            // Head
+            StringBuilder CSVhead = new StringBuilder();
+            for (int i = 1; i <= meta.getColumnCount(); i++) {
+                CSVhead.append("\"");
+                CSVhead.append(meta.getColumnName(i));
+                CSVhead.append("\"");
+                if(i != meta.getColumnCount()) {
+                    CSVhead.append(";");
+                }
+                else {
+                    CSVhead.append("\r\n");
+                }
+            }
+            // Data
+            StringBuilder data = new StringBuilder();
+            while(res.next()) {
+                StringBuilder rowCSV = new StringBuilder();
+                for (int i = 1; i <= meta.getColumnCount(); i++) {
+                    int colType = meta.getColumnType(i);
+                    if(colType == Types.DATE || colType == Types.VARCHAR || colType == Types.TIME || colType == Types.TIMESTAMP_WITH_TIMEZONE) {
+                        rowCSV.append("\"");
+                        rowCSV.append(res.getString(i));
+                        rowCSV.append("\"");
+                    }
+                    else {
+                    	double val = res.getDouble(i);
+                    	if (res.wasNull()) {
+                    		rowCSV.append("");
+                    	}
+                    	else {
+                    		rowCSV.append(val);
+                    	}
+                    }
+                    if(i != meta.getColumnCount()) {
+                        rowCSV.append(";");
+                    }
+                    else {
+                        rowCSV.append("\r\n");
+                    }
+                }
+                data.append(rowCSV.toString());
+            }
+            CSV = CSVhead.toString() + data.toString();
+            return CSV;
+        } catch (SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return null;
+        }
+    }
 }

+ 36 - 11
src/main/java/cz/hsrs/db/util/UnitUtil.java

@@ -214,19 +214,44 @@ public class UnitUtil extends DBUtil {
      * @throws SQLException
      */
     public static List<Unit> getUnitsByGroup(int groupId) throws SQLException{
-    	List<Unit> unitList = new LinkedList<Unit>();
-    	String query = "SELECT u.unit_id, u.holder_id, u.description"
-    			+ " FROM units u, units_to_groups utg"
+        List<Unit> unitList = new LinkedList<Unit>();
+        String query = "SELECT u.unit_id, u.holder_id, u.description"
+                + " FROM units u, units_to_groups utg"
                 + " WHERE utg.group_id = "+groupId
                 + " AND utg.unit_id = u.unit_id;";
-    	ResultSet res = SQLExecutor.getInstance().executeQuery(query);
-    	while (res.next()) {
-    		unitList.add(new Unit(
-    				res.getLong("unit_id"), 
-    				res.getInt("holder_id"),
-    				res.getString("description")));
-    	}
-    	return unitList;
+        ResultSet res = SQLExecutor.getInstance().executeQuery(query);
+        while (res.next()) {
+            unitList.add(new Unit(
+                    res.getLong("unit_id"), 
+                    res.getInt("holder_id"),
+                    res.getString("description")));
+        }
+        return unitList;
+    }
+    
+    /**
+     * Method provides list of Units with given sensor connected of particular Group
+     * @param groupId - ID of group
+     * @param sensorId - ID of sensor
+     * @return List of Unit
+     * @throws SQLException
+     */
+    public static List<Unit> getUnitsBySensorIdByGroup(long sensorId, int groupId) throws SQLException{
+        List<Unit> unitList = new LinkedList<Unit>();
+        String query = "SELECT u.unit_id, u.holder_id, u.description"
+                + " FROM units u, units_to_groups utg, units_to_sensors uts"
+                + " WHERE utg.group_id = "+groupId
+                + " AND utg.unit_id = u.unit_id"
+                + " AND uts.unit_id = u.unit_id"
+                + " AND uts.sensor_id = "+sensorId+";";
+        ResultSet res = SQLExecutor.getInstance().executeQuery(query);
+        while (res.next()) {
+            unitList.add(new Unit(
+                    res.getLong("unit_id"), 
+                    res.getInt("holder_id"),
+                    res.getString("description")));
+        }
+        return unitList;
     }
 
     public int getGroupID(long unit_id) throws SQLException {

+ 50 - 44
src/main/java/cz/hsrs/rest/provider/ObservationRest.java

@@ -8,6 +8,7 @@ import java.util.logging.Logger;
 
 import javax.naming.AuthenticationException;
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.QueryParam;
@@ -30,46 +31,47 @@ import cz.hsrs.servlet.security.LoginUser;
  */
 @Path("/observation/")
 public class ObservationRest {
-	
-	public static Logger logger = Logger.getLogger("ObservationRest");
+    
+    public static Logger logger = Logger.getLogger("ObservationRest");
 
-	/**
-	 * Empty constructor
-	 */
-	public ObservationRest() {
-		super();
-	}
-	
-	/**
-	 * 
-	 * @return
-	 * /rest/observation/export?group_id=25&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-31&style=crosstab
-	 */
-	@Path("/export")
-	@GET
-	public Response getObservationsCrossTab(
-			@QueryParam("sensor_id") Long sensorId,
-			@QueryParam("group_id") Integer groupId,
-			@QueryParam("from_time") String fromTime,
-			@QueryParam("to_time") String toTime,
-			@QueryParam("style") String exportStyle,
-			
-			@Context HttpServletRequest req){
-		try {
-            //LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
+    /**
+     * Empty constructor
+     */
+    public ObservationRest() {
+        super();
+    }
+    
+    /**
+     * 
+     * @return
+     * /rest/observation/export?group_id=25&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-31&style=crosstab
+     * /rest/observation/export?group_id=25&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-30+04:00:00&style=crosstab&nullable=false
+     */
+    @Path("/export")
+    @GET
+    public Response getObservationsCrossTab(
+            @QueryParam("sensor_id") Long sensorId,
+            @QueryParam("group_id") Integer groupId,
+            @QueryParam(Params.FROM_TIME) String fromTime,
+            @QueryParam(Params.TO_TIME) String toTime,
+            @QueryParam("style") String exportStyle,
+            @DefaultValue("true") @QueryParam("nullable") Boolean nullable,
+            @Context HttpServletRequest req){
+        try {
+            LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
             if(exportStyle.equalsIgnoreCase(Params.CROSS_TAB_STYLE)) {
-            	if(groupId == null) {
-            		//groupId = UserUtil.getUserGroupId(loggedUser.getUserName());
-            	}
-            	String CSV = ExportUtil.getObservationsBySensorByGroupCross(sensorId, groupId, fromTime, toTime);
-            	return Response.ok()
-            			.entity(CSV)
-            			.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
+                if(groupId == null) {
+                	groupId = UserUtil.getUserGroupId(loggedUser.getUserName());
+                }
+                String CSV = ExportUtil.getObservationsBySensorByGroupCross(sensorId, groupId, fromTime, toTime, nullable);
+                return Response.ok()
+                        .entity(CSV)
+                        .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
                         .build();
             } else {
-            	return Response.ok()
-            			.entity("Empty")
-            			.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
+                return Response.ok()
+                        .entity("Empty")
+                        .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
                         .build();
             }
             
@@ -77,12 +79,16 @@ public class ObservationRest {
             return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
                     .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
                     .build();
-        }
-	}
-	
-	private class Params{
-		protected static final String CROSS_TAB_STYLE = "crosstab";
-		protected static final String FROM_TIME = "from_time";
-		protected static final String TO_TIME = "to_time";
-	}
+        } catch (AuthenticationException e) {
+        	return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
+                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+                    .build();
+		}
+    }
+    
+    private class Params{
+        static final String CROSS_TAB_STYLE = "crosstab";
+        static final String FROM_TIME = "from_time";
+        static final String TO_TIME = "to_time";
+    }
 }