Ver código fonte

Prepared method for cross_tab export

Michal Kepka 4 anos atrás
pai
commit
608c713124

+ 43 - 0
src/main/java/cz/hsrs/db/util/ExportUtil.java

@@ -0,0 +1,43 @@
+package cz.hsrs.db.util;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import cz.hsrs.db.model.Unit;
+
+/**
+ * 
+ * @author mkepka
+ *
+ */
+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;
+	}
+}

+ 1 - 2
src/main/java/cz/hsrs/db/util/SensorUtil.java

@@ -77,8 +77,7 @@ public class SensorUtil extends TrackUtil {
      * @throws SQLException
      */
     public List<Sensor> getSensorTypes() throws SQLException{
-        String query = "SELECT distinct on(sensor_type) sensor_type, (sensor_id/10000)*10000 as sensor_id"
-        		+ " FROM sensors ORDER BY sensor_type;";
+        String query = "SELECT distinct on ((sensor_id/10000)) sensor_type, (sensor_id/10000)*10000 as sensor_id FROM sensors ORDER BY (sensor_id/10000), sensor_type;";
         ResultSet res = stmt.executeQuery(query);
         List<Sensor> senTypeList = new LinkedList<Sensor>();
         if(res != null) {

+ 376 - 353
src/main/java/cz/hsrs/db/util/UnitUtil.java

@@ -1,354 +1,377 @@
-package cz.hsrs.db.util;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-
-import cz.hsrs.db.model.IgnitionStatus;
-import cz.hsrs.db.model.NoItemFoundException;
-import cz.hsrs.db.model.Unit;
-import cz.hsrs.db.model.UnitDriver;
-import cz.hsrs.db.model.UnitHolder;
-import cz.hsrs.db.model.UnitPosition;
-import cz.hsrs.db.model.composite.LastPosition;
-import cz.hsrs.db.model.custom.DBItemInfo;
-import cz.hsrs.db.pool.SQLExecutor;
-import cz.hsrs.db.util.factory.UnitPositionFactory;
-
-/**
- * @author jezekjan
- */
-public class UnitUtil extends DBUtil {
-    
-    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
-
-    public UnitUtil() {
-        super();
-    }
-
-    public int deleteUnit(long unit_id) throws SQLException {
-        String delete_unit = "DELETE FROM units WHERE unit_id = " + unit_id + ";";
-        return SQLExecutor.executeUpdate(delete_unit);
-    }
-
-    public int deleteHolder(int holder_id) throws SQLException {
-        String delete_unit = "DELETE FROM unit_holders WHERE holder_id =" + holder_id;
-        return SQLExecutor.executeUpdate(delete_unit);
-    }
-
-    public int deleteHolder(String hname) throws SQLException {
-        String delete_unit = "DELETE FROM unit_holders WHERE holder_name = '" + hname + "'";
-        return SQLExecutor.executeUpdate(delete_unit);
-    }
-
-    public int deleteDriver(int driver_id) throws SQLException {
-        String delete_driver = "DELETE FROM unit_drivers WHERE driver_id = '" + driver_id + "'";
-        return SQLExecutor.executeUpdate(delete_driver);
-    }
-    
-    public int deleteDriver(String fname, String lname) throws SQLException {
-        String delete_driver = "DELETE FROM unit_drivers WHERE fname = '" + fname + "' and lname = '" + lname +"'";
-        return SQLExecutor.executeUpdate(delete_driver);
-    }
-
-    public int insertUnit(long unit_id, String description) throws SQLException {
-        String queryConf = "INSERT into units(unit_id, description) values (" + unit_id + ",'" + description + "');";
-        return SQLExecutor.executeUpdate(queryConf);
-    }
-
-    /**
-     * Method pairs given unit to given group
-     * @param unitId of unit
-     * @param groupId of group
-     * @return either (1) the row count for SQL DML statements or (2) 0 for SQL statements that return nothing
-     * @throws SQLException
-     */
-    public int pairUnitToGroup(long unitId, int groupId) throws SQLException{
-        String insUtG = "INSERT INTO units_to_groups(unit_id, group_id) VALUES("+unitId+", "+groupId+");";
-        return SQLExecutor.executeUpdate(insUtG);
-    }
-    
-    public int getUnitConfTimeById(long unit_id) throws SQLException, NoItemFoundException {
-        String queryConf = "select extract(epoch from max_time_span) from units_conf where unit_id =" + unit_id;
-        ResultSet res = stmt.executeQuery(queryConf);
-        if (res.next()) {
-            return res.getInt(1);
-        } else
-            throw new NoItemFoundException("getUnitConfTimeById for " + unit_id + " not found.");
-    }
-
-    public boolean isRunning(long unit_id) throws SQLException {
-        String queryConf = "select unit_id from running_tracks where unit_id =" + unit_id;
-        ResultSet res = stmt.executeQuery(queryConf);
-        return res.next();
-    }
-
-    public UnitPosition getLastUnitPosition(long unit_id) throws SQLException, NoItemFoundException {
-        String queryConf = "select " + UnitPosition.SELECT + "from last_units_positions where unit_id =" + unit_id;
-        ResultSet res = stmt.executeQuery(queryConf);
-        if (res.next()) {
-            return new UnitPosition(res);
-        } else
-            throw new NoItemFoundException("Last position for " + unit_id + " not found.");
-    }
-
-    
-    public UnitPosition getPositionByGid(int gid) throws SQLException, NoItemFoundException {
-        String queryConf = "select " + UnitPosition.SELECT + "from units_positions where gid =" + gid;
-        ResultSet res = stmt.executeQuery(queryConf);
-        if (res.next()) {
-            return new UnitPosition(res);
-        } else
-            throw new NoItemFoundException("Last position for " + gid + " not found.");
-    }
-
-    public int changeUnitsTrackInterval(long unit_id, int milliseconds) throws SQLException {
-        String queryConf = "update units_conf SET max_time_span = interval '" + milliseconds + " milliseconds' where unit_id=" + unit_id;
-        return SQLExecutor.executeUpdate(queryConf);
-    }
-
-    public UnitHolder getUnitHolder(long unit_id) throws SQLException, NoItemFoundException {
-        String queryConf = "SELECT " + UnitHolder.SELECT
-                + "FROM unit_holders, units WHERE units.holder_id = unit_holders.holder_id AND "
-                + "units.unit_id = " + unit_id;
-
-        ResultSet res = stmt.executeQuery(queryConf);
-        if (res.next()) {
-            return new UnitHolder(res);
-        } else
-            throw new NoItemFoundException("getUnitHolder " + unit_id + " not found.");
-    }
-
-    @SuppressWarnings("unchecked")
-    public List<UnitDriver> getUnitDrivers(long unit_id) throws SQLException {
-        String queryObservations = "select * "
-                + " from unit_drivers, units_to_drivers "
-                + "WHERE units_to_drivers.unit_id = " + unit_id
-                + " AND units_to_drivers.driver_id = unit_drivers.driver_id ";
-        ResultSet res = stmt.executeQuery(queryObservations);
-        return (List<UnitDriver>) generateObjectList(new UnitDriver(), res);
-    }
-
-    public LastPosition getLastPositionWithStatus(UnitPosition pos) throws SQLException {
-        UnitPositionFactory pf = new UnitPositionFactory(pos);
-        return pf.getLastPositionWithStatus();
-    }
-
-    public DBItemInfo getUnitInfo(String schema, String tableName, long id, String forigenKeyName) throws NoItemFoundException {
-        return new DBItemInfo(schema, tableName, id, forigenKeyName);
-
-    }
-
-    public void setProvideAlert(long unit_id, boolean provide) throws SQLException, NoItemFoundException{
-        String query = "UPDATE units_conf SET provide_alerts="+provide+" where unit_id = "+unit_id;
-        int i = SQLExecutor.executeUpdate(query);
-        if (i==0){
-            throw new NoItemFoundException(String.valueOf(unit_id));
-        }
-    }
-    
-    /**
-     * Method gets next value for unit_id, confirms if there is not any unit with same id in DB
-     * @return new unit_id if there is not same unit in DB or null if it is not possible o select new unit_id
-     * @throws SQLException
-     */
-    public Long getNextUnitID() throws SQLException{
-        boolean exists = true;
-        Long newId = null;
-        while(exists){
-            try{
-                String selectId = "SELECT nextval('units_unit_id'::regclass);";
-                ResultSet resId = SQLExecutor.getInstance().executeQuery(selectId);
-                if(resId.next()){
-                    newId = resId.getLong(1);
-                } else{
-                    return null;
-                }
-                Unit isSame = getUnit(newId);
-                if(isSame==null){
-                    exists = false;
-                }
-            } catch(SQLException e){
-                throw new SQLException("Unit can't get new ID!");
-            }
-        }
-        return newId;
-    }
-    
-    public Unit getUnit(long unit_id) throws SQLException {
-        String query = "SELECT holder_id, description FROM units WHERE unit_id = "
-                + unit_id;
-        ResultSet res = stmt.executeQuery(query);
-        if (res.next()) {
-            return new Unit(unit_id, res.getInt("holder_id"), res.getString("description"));
-        } else
-            return null;
-    }
-    
-    /**
-     * Method selects unit if there is unit with given unitId paired with given groupId
-     * @param unitId - id of unit
-     * @param groupId - id of group
-     * @return Unit object if there is the unit already in DB, null if there is not
-     * @throws SQLException
-     */
-    public Unit getUnitByGroup(long unitId, int groupId) throws SQLException {
-        String query = "SELECT holder_id, description FROM units u, units_to_groups utg"
-                + " WHERE u.unit_id = "+ unitId
-                + " AND utg.group_id = "+groupId
-                + " AND utg.unit_id = u.unit_id;";
-        ResultSet res = stmt.executeQuery(query);
-        if (res.next()) {
-            return new Unit(unitId, res.getInt("holder_id"), res.getString("description"));
-        } else
-            return null;
-    }
-
-    public int getGroupID(long unit_id) throws SQLException {
-        String query = "SELECT group_id FROM units_to_groups WHERE unit_id= "
-                + unit_id + ";";
-        ResultSet res = stmt.executeQuery(query);
-        res.next();
-        return res.getInt("group_id");
-    }
-
-    /**
-     * function to get last valid ignition status for unit
-     * 
-     * @param unit_id - unit to get status
-     * @return IgnitionStatus valid for unit
-     * @throws SQLException
-     */
-    public IgnitionStatus getValidIgnitionStatus(long unit_id) throws SQLException {
-        String query = "SELECT * FROM last_ignition_status WHERE unit_id = " + unit_id + " ;";
-        ResultSet res = stmt.executeQuery(query);
-        if (res.next()) {
-            return new IgnitionStatus(res);
-        } else {
-            return null;
-        }
-    }
-    
-    public UnitPosition getPositionBefore(long unit_id, Date date)throws SQLException, NoItemFoundException {
-        String dstring = FORMATTER.format(date);
-        String queryConf = "select " + UnitPosition.SELECT
-                + " from units_positions where time_stamp < timestamp with time zone'" + dstring+"' ORDER BY time_stamp DESC LIMIT 1";
-        ResultSet res = stmt.executeQuery(queryConf);
-        if (res.next()) {
-            return new UnitPosition(res);
-        } else
-            throw new NoItemFoundException("getPositionBefore " + unit_id + ", " + dstring + " not found.");
-    }
-
-    /**
-     * Function to get last ignition status from observations before time of
-     * unitPosition
-     * @param pos - UnitPosition
-     * @return IgnitionStatus for unit before time of UnitPosition
-     * @throws SQLException
-     * @throws NoItemFoundException
-     */
-    public IgnitionStatus getLastIgnitionStatus(UnitPosition pos) throws SQLException, NoItemFoundException {
-        String query = "SELECT observation_id, gid, observed_value, time_stamp, unit_id FROM observations"
-                + " WHERE sensor_id = 330040000"
-                + " AND unit_id = "
-                + pos.getUnit_id()
-                + " AND time_stamp < '"
-                + pos.getTime_stamp()
-                + "' "
-                + " ORDER BY time_stamp DESC LIMIT 1 ;";
-        ResultSet res = stmt.executeQuery(query);
-        if (res.next()) {
-            return new IgnitionStatus(res);
-        } else {
-            throw new NoItemFoundException("getLastIgnitionStatus for "
-                    + pos.getUnit_id() + " and " + pos.getTime_stamp() + " does not exist!");
-        }
-    }
-
-    /**
-     * Function to get next ignition status from observations after time of
-     * unitPosition
-     * 
-     * @param pos
-     *            UnitPosition
-     * @return IgnitionStatus for unit after time of UnitPosition
-     * @throws SQLException
-     * @throws NoItemFoundException
-     */
-    public IgnitionStatus getNextIgnitionStatus(UnitPosition pos) throws SQLException, NoItemFoundException {
-        String query = "SELECT observation_id, gid, observed_value, time_stamp, unit_id FROM observations"
-                + " WHERE sensor_id = 330040000"
-                + " AND unit_id = "
-                + pos.getUnit_id()
-                + " AND time_stamp > '"
-                + pos.getTime_stamp() + "' " + " ORDER BY time_stamp LIMIT 1 ;";
-        ResultSet res = stmt.executeQuery(query);
-        if (res.next()) {
-            return new IgnitionStatus(res);
-        } else {
-            throw new NoItemFoundException("getLastIgnitionStatus for "
-                    + pos.getUnit_id() + " and " + pos.getTime_stamp() + " does not exist!");
-        }
-    }
-    
-    /**
-     * Method selects observed value for given unit, sensor and position
-     * @param pos UnitPosition provides gid, unitId
-     * @param sensorId identifier of sensor as long
-     * @return Observed value as double
-     * @throws SQLException
-     */
-    public double getObservationValueOnPosition(UnitPosition pos, long sensorId) throws SQLException{
-        String query = "SELECT observed_value FROM observations"
-                + " WHERE unit_id = "+pos.getUnit_id()
-                + " AND sensor_id = "+sensorId
-                + " AND gid = "+pos.getGid()+";";
-        ResultSet res = stmt.executeQuery(query);
-        if (res != null){
-            return res.next() ? res.getDouble("observed_value") : Double.NaN;
-        } else {
-            throw new SQLException("An Exception occurs when executing SQL command!");
-        }
-    }
-    
-    /**
-     * Method gets last observation for given unit and sensor that not older than configuration time of unit 
-     * @param pos UnitPosition contains unitId and last position timestamp
-     * @param sensorId identifier of particular sensor
-     * @param confTime configuration time of unit
-     * @return last observation value as double if exists, NaN otherwise
-     * @throws SQLException
-     */
-    public double getLastObservationValueInConfTime(UnitPosition pos, long sensorId, int confTime) throws SQLException{
-        String query = "SELECT observed_value, time_stamp FROM observations"
-                +" WHERE sensor_id = "+sensorId+" AND unit_id = "+pos.getUnit_id()
-                +" GROUP BY observed_value, time_stamp"
-                +" HAVING (EXTRACT (epoch FROM (timestamp '"+pos.getTime_stamp()+"' - time_stamp))) < integer '"+confTime+"' "
-                +" ORDER BY time_stamp DESC LIMIT 1;";
-        ResultSet res = stmt.executeQuery(query);
-        if (res != null){
-            return res.next() ? res.getDouble("observed_value") : Double.NaN;
-        } else {
-            throw new SQLException("An Exception occurs when executing SQL command!");
-        }
-    }
-    
-    /**
-     * Method gets description from agricultural machinery table by given identifier  
-     * @param deviceId - identifier of the device
-     * @return description as String
-     * @throws SQLException
-     */
-    public String getDescriptionOfRfid(long deviceId) throws SQLException{
-        String query = "SELECT description_cze FROM agricultural_machinery WHERE id="+deviceId;
-        ResultSet res = stmt.executeQuery(query);
-        if (res != null){
-            return res.next() ? res.getString("description_cze") : "";
-        } else {
-            throw new SQLException("An Exception occurs when executing SQL command!");
-        }
-    }
+package cz.hsrs.db.util;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import cz.hsrs.db.model.IgnitionStatus;
+import cz.hsrs.db.model.NoItemFoundException;
+import cz.hsrs.db.model.Unit;
+import cz.hsrs.db.model.UnitDriver;
+import cz.hsrs.db.model.UnitHolder;
+import cz.hsrs.db.model.UnitPosition;
+import cz.hsrs.db.model.composite.LastPosition;
+import cz.hsrs.db.model.custom.DBItemInfo;
+import cz.hsrs.db.pool.SQLExecutor;
+import cz.hsrs.db.util.factory.UnitPositionFactory;
+
+/**
+ * @author jezekjan
+ */
+public class UnitUtil extends DBUtil {
+    
+    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
+
+    public UnitUtil() {
+        super();
+    }
+
+    public int deleteUnit(long unit_id) throws SQLException {
+        String delete_unit = "DELETE FROM units WHERE unit_id = " + unit_id + ";";
+        return SQLExecutor.executeUpdate(delete_unit);
+    }
+
+    public int deleteHolder(int holder_id) throws SQLException {
+        String delete_unit = "DELETE FROM unit_holders WHERE holder_id =" + holder_id;
+        return SQLExecutor.executeUpdate(delete_unit);
+    }
+
+    public int deleteHolder(String hname) throws SQLException {
+        String delete_unit = "DELETE FROM unit_holders WHERE holder_name = '" + hname + "'";
+        return SQLExecutor.executeUpdate(delete_unit);
+    }
+
+    public int deleteDriver(int driver_id) throws SQLException {
+        String delete_driver = "DELETE FROM unit_drivers WHERE driver_id = '" + driver_id + "'";
+        return SQLExecutor.executeUpdate(delete_driver);
+    }
+    
+    public int deleteDriver(String fname, String lname) throws SQLException {
+        String delete_driver = "DELETE FROM unit_drivers WHERE fname = '" + fname + "' and lname = '" + lname +"'";
+        return SQLExecutor.executeUpdate(delete_driver);
+    }
+
+    public int insertUnit(long unit_id, String description) throws SQLException {
+        String queryConf = "INSERT into units(unit_id, description) values (" + unit_id + ",'" + description + "');";
+        return SQLExecutor.executeUpdate(queryConf);
+    }
+
+    /**
+     * Method pairs given unit to given group
+     * @param unitId of unit
+     * @param groupId of group
+     * @return either (1) the row count for SQL DML statements or (2) 0 for SQL statements that return nothing
+     * @throws SQLException
+     */
+    public int pairUnitToGroup(long unitId, int groupId) throws SQLException{
+        String insUtG = "INSERT INTO units_to_groups(unit_id, group_id) VALUES("+unitId+", "+groupId+");";
+        return SQLExecutor.executeUpdate(insUtG);
+    }
+    
+    public int getUnitConfTimeById(long unit_id) throws SQLException, NoItemFoundException {
+        String queryConf = "select extract(epoch from max_time_span) from units_conf where unit_id =" + unit_id;
+        ResultSet res = stmt.executeQuery(queryConf);
+        if (res.next()) {
+            return res.getInt(1);
+        } else
+            throw new NoItemFoundException("getUnitConfTimeById for " + unit_id + " not found.");
+    }
+
+    public boolean isRunning(long unit_id) throws SQLException {
+        String queryConf = "select unit_id from running_tracks where unit_id =" + unit_id;
+        ResultSet res = stmt.executeQuery(queryConf);
+        return res.next();
+    }
+
+    public UnitPosition getLastUnitPosition(long unit_id) throws SQLException, NoItemFoundException {
+        String queryConf = "select " + UnitPosition.SELECT + "from last_units_positions where unit_id =" + unit_id;
+        ResultSet res = stmt.executeQuery(queryConf);
+        if (res.next()) {
+            return new UnitPosition(res);
+        } else
+            throw new NoItemFoundException("Last position for " + unit_id + " not found.");
+    }
+
+    
+    public UnitPosition getPositionByGid(int gid) throws SQLException, NoItemFoundException {
+        String queryConf = "select " + UnitPosition.SELECT + "from units_positions where gid =" + gid;
+        ResultSet res = stmt.executeQuery(queryConf);
+        if (res.next()) {
+            return new UnitPosition(res);
+        } else
+            throw new NoItemFoundException("Last position for " + gid + " not found.");
+    }
+
+    public int changeUnitsTrackInterval(long unit_id, int milliseconds) throws SQLException {
+        String queryConf = "update units_conf SET max_time_span = interval '" + milliseconds + " milliseconds' where unit_id=" + unit_id;
+        return SQLExecutor.executeUpdate(queryConf);
+    }
+
+    public UnitHolder getUnitHolder(long unit_id) throws SQLException, NoItemFoundException {
+        String queryConf = "SELECT " + UnitHolder.SELECT
+                + "FROM unit_holders, units WHERE units.holder_id = unit_holders.holder_id AND "
+                + "units.unit_id = " + unit_id;
+
+        ResultSet res = stmt.executeQuery(queryConf);
+        if (res.next()) {
+            return new UnitHolder(res);
+        } else
+            throw new NoItemFoundException("getUnitHolder " + unit_id + " not found.");
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<UnitDriver> getUnitDrivers(long unit_id) throws SQLException {
+        String queryObservations = "select * "
+                + " from unit_drivers, units_to_drivers "
+                + "WHERE units_to_drivers.unit_id = " + unit_id
+                + " AND units_to_drivers.driver_id = unit_drivers.driver_id ";
+        ResultSet res = stmt.executeQuery(queryObservations);
+        return (List<UnitDriver>) generateObjectList(new UnitDriver(), res);
+    }
+
+    public LastPosition getLastPositionWithStatus(UnitPosition pos) throws SQLException {
+        UnitPositionFactory pf = new UnitPositionFactory(pos);
+        return pf.getLastPositionWithStatus();
+    }
+
+    public DBItemInfo getUnitInfo(String schema, String tableName, long id, String forigenKeyName) throws NoItemFoundException {
+        return new DBItemInfo(schema, tableName, id, forigenKeyName);
+
+    }
+
+    public void setProvideAlert(long unit_id, boolean provide) throws SQLException, NoItemFoundException{
+        String query = "UPDATE units_conf SET provide_alerts="+provide+" where unit_id = "+unit_id;
+        int i = SQLExecutor.executeUpdate(query);
+        if (i==0){
+            throw new NoItemFoundException(String.valueOf(unit_id));
+        }
+    }
+    
+    /**
+     * Method gets next value for unit_id, confirms if there is not any unit with same id in DB
+     * @return new unit_id if there is not same unit in DB or null if it is not possible o select new unit_id
+     * @throws SQLException
+     */
+    public Long getNextUnitID() throws SQLException{
+        boolean exists = true;
+        Long newId = null;
+        while(exists){
+            try{
+                String selectId = "SELECT nextval('units_unit_id'::regclass);";
+                ResultSet resId = SQLExecutor.getInstance().executeQuery(selectId);
+                if(resId.next()){
+                    newId = resId.getLong(1);
+                } else{
+                    return null;
+                }
+                Unit isSame = getUnit(newId);
+                if(isSame==null){
+                    exists = false;
+                }
+            } catch(SQLException e){
+                throw new SQLException("Unit can't get new ID!");
+            }
+        }
+        return newId;
+    }
+    
+    public Unit getUnit(long unit_id) throws SQLException {
+        String query = "SELECT holder_id, description FROM units WHERE unit_id = "
+                + unit_id;
+        ResultSet res = stmt.executeQuery(query);
+        if (res.next()) {
+            return new Unit(unit_id, res.getInt("holder_id"), res.getString("description"));
+        } else
+            return null;
+    }
+    
+    /**
+     * Method selects unit if there is unit with given unitId paired with given groupId
+     * @param unitId - id of unit
+     * @param groupId - id of group
+     * @return Unit object if there is the unit already in DB, null if there is not
+     * @throws SQLException
+     */
+    public Unit getUnitByGroup(long unitId, int groupId) throws SQLException {
+        String query = "SELECT holder_id, description FROM units u, units_to_groups utg"
+                + " WHERE u.unit_id = "+ unitId
+                + " AND utg.group_id = "+groupId
+                + " AND utg.unit_id = u.unit_id;";
+        ResultSet res = stmt.executeQuery(query);
+        if (res.next()) {
+            return new Unit(unitId, res.getInt("holder_id"), res.getString("description"));
+        } else
+            return null;
+    }
+    
+    /**
+     * Method provides list of Units of particular Group
+     * @param groupId - ID of group
+     * @return List of Unit
+     * @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"
+                + " 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;
+    }
+
+    public int getGroupID(long unit_id) throws SQLException {
+        String query = "SELECT group_id FROM units_to_groups WHERE unit_id= "
+                + unit_id + ";";
+        ResultSet res = stmt.executeQuery(query);
+        res.next();
+        return res.getInt("group_id");
+    }
+
+    /**
+     * function to get last valid ignition status for unit
+     * 
+     * @param unit_id - unit to get status
+     * @return IgnitionStatus valid for unit
+     * @throws SQLException
+     */
+    public IgnitionStatus getValidIgnitionStatus(long unit_id) throws SQLException {
+        String query = "SELECT * FROM last_ignition_status WHERE unit_id = " + unit_id + " ;";
+        ResultSet res = stmt.executeQuery(query);
+        if (res.next()) {
+            return new IgnitionStatus(res);
+        } else {
+            return null;
+        }
+    }
+    
+    public UnitPosition getPositionBefore(long unit_id, Date date)throws SQLException, NoItemFoundException {
+        String dstring = FORMATTER.format(date);
+        String queryConf = "select " + UnitPosition.SELECT
+                + " from units_positions where time_stamp < timestamp with time zone'" + dstring+"' ORDER BY time_stamp DESC LIMIT 1";
+        ResultSet res = stmt.executeQuery(queryConf);
+        if (res.next()) {
+            return new UnitPosition(res);
+        } else
+            throw new NoItemFoundException("getPositionBefore " + unit_id + ", " + dstring + " not found.");
+    }
+
+    /**
+     * Function to get last ignition status from observations before time of
+     * unitPosition
+     * @param pos - UnitPosition
+     * @return IgnitionStatus for unit before time of UnitPosition
+     * @throws SQLException
+     * @throws NoItemFoundException
+     */
+    public IgnitionStatus getLastIgnitionStatus(UnitPosition pos) throws SQLException, NoItemFoundException {
+        String query = "SELECT observation_id, gid, observed_value, time_stamp, unit_id FROM observations"
+                + " WHERE sensor_id = 330040000"
+                + " AND unit_id = "
+                + pos.getUnit_id()
+                + " AND time_stamp < '"
+                + pos.getTime_stamp()
+                + "' "
+                + " ORDER BY time_stamp DESC LIMIT 1 ;";
+        ResultSet res = stmt.executeQuery(query);
+        if (res.next()) {
+            return new IgnitionStatus(res);
+        } else {
+            throw new NoItemFoundException("getLastIgnitionStatus for "
+                    + pos.getUnit_id() + " and " + pos.getTime_stamp() + " does not exist!");
+        }
+    }
+
+    /**
+     * Function to get next ignition status from observations after time of
+     * unitPosition
+     * 
+     * @param pos
+     *            UnitPosition
+     * @return IgnitionStatus for unit after time of UnitPosition
+     * @throws SQLException
+     * @throws NoItemFoundException
+     */
+    public IgnitionStatus getNextIgnitionStatus(UnitPosition pos) throws SQLException, NoItemFoundException {
+        String query = "SELECT observation_id, gid, observed_value, time_stamp, unit_id FROM observations"
+                + " WHERE sensor_id = 330040000"
+                + " AND unit_id = "
+                + pos.getUnit_id()
+                + " AND time_stamp > '"
+                + pos.getTime_stamp() + "' " + " ORDER BY time_stamp LIMIT 1 ;";
+        ResultSet res = stmt.executeQuery(query);
+        if (res.next()) {
+            return new IgnitionStatus(res);
+        } else {
+            throw new NoItemFoundException("getLastIgnitionStatus for "
+                    + pos.getUnit_id() + " and " + pos.getTime_stamp() + " does not exist!");
+        }
+    }
+    
+    /**
+     * Method selects observed value for given unit, sensor and position
+     * @param pos UnitPosition provides gid, unitId
+     * @param sensorId identifier of sensor as long
+     * @return Observed value as double
+     * @throws SQLException
+     */
+    public double getObservationValueOnPosition(UnitPosition pos, long sensorId) throws SQLException{
+        String query = "SELECT observed_value FROM observations"
+                + " WHERE unit_id = "+pos.getUnit_id()
+                + " AND sensor_id = "+sensorId
+                + " AND gid = "+pos.getGid()+";";
+        ResultSet res = stmt.executeQuery(query);
+        if (res != null){
+            return res.next() ? res.getDouble("observed_value") : Double.NaN;
+        } else {
+            throw new SQLException("An Exception occurs when executing SQL command!");
+        }
+    }
+    
+    /**
+     * Method gets last observation for given unit and sensor that not older than configuration time of unit 
+     * @param pos UnitPosition contains unitId and last position timestamp
+     * @param sensorId identifier of particular sensor
+     * @param confTime configuration time of unit
+     * @return last observation value as double if exists, NaN otherwise
+     * @throws SQLException
+     */
+    public double getLastObservationValueInConfTime(UnitPosition pos, long sensorId, int confTime) throws SQLException{
+        String query = "SELECT observed_value, time_stamp FROM observations"
+                +" WHERE sensor_id = "+sensorId+" AND unit_id = "+pos.getUnit_id()
+                +" GROUP BY observed_value, time_stamp"
+                +" HAVING (EXTRACT (epoch FROM (timestamp '"+pos.getTime_stamp()+"' - time_stamp))) < integer '"+confTime+"' "
+                +" ORDER BY time_stamp DESC LIMIT 1;";
+        ResultSet res = stmt.executeQuery(query);
+        if (res != null){
+            return res.next() ? res.getDouble("observed_value") : Double.NaN;
+        } else {
+            throw new SQLException("An Exception occurs when executing SQL command!");
+        }
+    }
+    
+    /**
+     * Method gets description from agricultural machinery table by given identifier  
+     * @param deviceId - identifier of the device
+     * @return description as String
+     * @throws SQLException
+     */
+    public String getDescriptionOfRfid(long deviceId) throws SQLException{
+        String query = "SELECT description_cze FROM agricultural_machinery WHERE id="+deviceId;
+        ResultSet res = stmt.executeQuery(query);
+        if (res != null){
+            return res.next() ? res.getString("description_cze") : "";
+        } else {
+            throw new SQLException("An Exception occurs when executing SQL command!");
+        }
+    }
 }

+ 88 - 0
src/main/java/cz/hsrs/rest/provider/ObservationRest.java

@@ -0,0 +1,88 @@
+/**
+ * 
+ */
+package cz.hsrs.rest.provider;
+
+import java.sql.SQLException;
+import java.util.logging.Logger;
+
+import javax.naming.AuthenticationException;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.mortbay.jetty.HttpStatus;
+
+import cz.hsrs.db.util.ExportUtil;
+import cz.hsrs.db.util.UserUtil;
+import cz.hsrs.rest.beans.ExceptionBean;
+import cz.hsrs.rest.util.AuthUtil;
+import cz.hsrs.servlet.security.LoginUser;
+
+/**
+ * @author mkepka
+ *
+ */
+@Path("/observation/")
+public class 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);
+            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)
+                        .build();
+            } else {
+            	return Response.ok()
+            			.entity("Empty")
+            			.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
+                        .build();
+            }
+            
+        } catch (SQLException e) {
+            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";
+	}
+}