package art.servers.gost.access.controller;
|
|
import art.library.interop.serialization.Serialization;
|
import art.library.model.devices.Device;
|
import art.library.model.devices.gost.access.AccessEnforcement;
|
import art.library.model.devices.gost.access.AccessEnforcementInformation;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection_State;
|
import art.library.utils.licence.Licence;
|
import art.servers.controller.ControllerDevice;
|
import art.servers.gost.access.Shared;
|
import art.servers.gost.access.types.DatabasePoolConnection;
|
import art.servers.gost.access.utils.ZIP;
|
import java.io.File;
|
import java.sql.Connection;
|
import java.sql.PreparedStatement;
|
import java.sql.ResultSet;
|
import java.sql.Timestamp;
|
import java.sql.Types;
|
import java.text.SimpleDateFormat;
|
import java.util.Calendar;
|
import org.postgresql.util.PGobject;
|
|
|
public class Controller_ACCESS extends ControllerDevice
|
{
|
protected DatabasePoolConnection database = null;
|
|
|
public Controller_ACCESS(Device device, DatabasePoolConnection database)
|
{
|
super(device);
|
this.database = database;
|
}
|
|
|
|
protected void initialise()
|
{
|
// Database
|
|
Connection connection = null;
|
|
try
|
{
|
connection = database.getConnection(true);
|
|
database.executeUpdate(connection, "CREATE TABLE IF NOT EXISTS detections(number BIGSERIAL, datetime TIMESTAMP, "
|
+ "device TEXT, type TEXT, plate TEXT NOT NULL, state SMALLINT, record TEXT, value JSONB, "
|
+ "PRIMARY KEY (datetime, device, plate)) "
|
+ "PARTITION BY RANGE (datetime)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_1 ON detections (number)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_2 ON detections (datetime)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_3 ON detections (datetime, device)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_4 ON detections (datetime, type)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_6 ON detections (datetime, state)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_7 ON detections (datetime, plate)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_8 ON detections (datetime, record");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_9 ON detections (record)");
|
database.executeUpdate(connection, "CREATE INDEX IF NOT EXISTS detections_index_10 ON detections (state)");
|
|
|
// Partitioned table
|
|
SimpleDateFormat formato1 = new SimpleDateFormat("yyyy_MM");
|
SimpleDateFormat formato2 = new SimpleDateFormat("yyyy-MM-dd");
|
|
Calendar calendar1 = Calendar.getInstance();
|
calendar1.setTimeInMillis(System.currentTimeMillis());
|
calendar1.set(Calendar.DATE, 1);
|
calendar1.set(Calendar.HOUR_OF_DAY, 0);
|
calendar1.set(Calendar.MINUTE, 0);
|
calendar1.set(Calendar.SECOND, 0);
|
calendar1.set(Calendar.MILLISECOND, 0);
|
calendar1.add(Calendar.MONTH, -24);
|
|
Calendar calendar2 = Calendar.getInstance();
|
calendar2.setTimeInMillis(calendar1.getTimeInMillis());
|
calendar2.add(Calendar.MONTH, 1);
|
|
for (int i=0; i<48; i++)
|
{
|
String tablename = "detections_" + formato1.format(calendar1.getTimeInMillis());
|
String month1 = formato2.format(calendar1.getTimeInMillis());
|
String month2 = formato2.format(calendar2.getTimeInMillis());
|
|
database.executeUpdate(connection, "CREATE TABLE IF NOT EXISTS " + tablename + " PARTITION OF detections FOR VALUES FROM ('" + month1 + "') TO ('" + month2 + "')");
|
|
calendar1.add(Calendar.MONTH, 1);
|
calendar2.add(Calendar.MONTH, 1);
|
}
|
|
|
database.vacuum("detections", connection);
|
|
}
|
catch (Exception exception)
|
{
|
// Shared.printstack(getName(), exception);
|
Shared.traceError(getName(),Shared.getMessage("Initialise"), exception);
|
}
|
finally
|
{
|
database.releaseConnection(connection);
|
}
|
}
|
|
|
|
|
protected int updateDatabaseDetection(AccessEnforcementInformation deviceInformation, AccessEnforcement_Detection detection) throws Exception
|
{
|
Connection connection = null;
|
PreparedStatement statement = null;
|
ResultSet resultset = null;
|
|
try
|
{
|
connection = database.getConnection(true);
|
|
// Exists
|
{
|
String command = "SELECT EXISTS(SELECT 1 FROM detections WHERE datetime = ? AND device = ?)";
|
statement = connection.prepareStatement(command);
|
statement.setTimestamp(1, new Timestamp(detection.timestamp));
|
statement.setString(2, deviceInformation.getIdentifier());
|
resultset = statement.executeQuery();
|
resultset.next();
|
if (resultset.getBoolean(1) == true) return 0;
|
}
|
|
|
// Save images
|
|
ZIP.zip(detection, Licence.decrypt(deviceInformation.storage.storagePassword), deviceInformation.storage.storageFolder);
|
|
// Remove images, we don't want store in database
|
|
detection.images = null;
|
|
AccessEnforcement_Detection_State detectionState = detection.getLastState();
|
if (detectionState.vehicle.plate != null) detectionState.vehicle.plate = detectionState.vehicle.plate.replaceAll("\\s+","");
|
|
// Insert
|
{
|
String command = "INSERT INTO detections (datetime, device, type, plate, state, record , value) VALUES (?,?,?,?,?,?,?) ON CONFLICT DO NOTHING";
|
statement = connection.prepareStatement(command);
|
PGobject jsonObject = new PGobject();
|
jsonObject.setType("json");
|
jsonObject.setValue(Serialization.toString(detection));
|
|
statement.setTimestamp(1, new Timestamp(detection.timestamp));
|
statement.setString(2, deviceInformation.getIdentifier());
|
statement.setString(3, AccessEnforcement.class.getName());
|
statement.setString(4, detectionState.vehicle.getPlate());
|
statement.setShort(5, detectionState.state);
|
|
if ((detectionState.violation != null) && (detectionState.violation.record != null))
|
{
|
statement.setString(6, detectionState.violation.record);
|
}
|
else
|
{
|
statement.setNull(6, Types.VARCHAR);
|
}
|
|
statement.setObject(7, jsonObject);
|
int result = statement.executeUpdate();
|
database.close(statement);
|
return result;
|
}
|
}
|
finally
|
{
|
database.releaseConnection(connection, statement);
|
}
|
|
}
|
|
|
|
|
|
|
protected void delete(File folder)
|
{
|
for (File file : folder.listFiles())
|
{
|
if (file.isDirectory() == true)
|
{
|
delete(file);
|
}
|
else
|
{
|
file.delete();
|
}
|
}
|
|
folder.delete();
|
}
|
|
}
|