hikvision-sync-service/Data/MySqlRepositories.cs

299 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
namespace HikvisionAttendanceService.Data;
internal sealed class MySqlAttendanceMachineRepository : IAttendanceMachineRepository
{
private readonly IHrmsDbConnectionFactory _factory;
public MySqlAttendanceMachineRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
public List<AttendanceMachineRow> GetActiveMachines(string? machineTypeFilter, out string error)
{
error = "";
var rows = new List<AttendanceMachineRow>();
if (!_factory.TryBuildConnectionString(out var cs, out error))
return rows;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
string sql = "SELECT machine_id,machine_ip,port_number,machine_name,site_id,machine_status,machine_type,status,last_sync_date,total_users " +
"FROM attendance_machine WHERE (machine_status='active' OR machine_status='1' OR machine_status=1)";
if (!string.IsNullOrWhiteSpace(machineTypeFilter))
sql += " AND machine_type=@machineType";
using var cmd = new MySqlCommand(sql, conn);
if (!string.IsNullOrWhiteSpace(machineTypeFilter))
cmd.Parameters.AddWithValue("@machineType", machineTypeFilter);
using var rd = cmd.ExecuteReader();
while (rd.Read())
{
rows.Add(new AttendanceMachineRow
{
MachineId = rd["machine_id"]?.ToString() ?? "",
MachineIp = rd["machine_ip"]?.ToString() ?? "",
PortNumber = rd["port_number"] == DBNull.Value ? 8000 : Convert.ToInt32(rd["port_number"]),
MachineName = rd["machine_name"]?.ToString() ?? "",
SiteId = rd["site_id"] == DBNull.Value ? (int?)null : Convert.ToInt32(rd["site_id"]),
MachineStatus = rd["machine_status"]?.ToString() ?? "",
MachineType = rd["machine_type"]?.ToString() ?? "",
Status = rd["status"]?.ToString() ?? "",
LastSyncDate = rd["last_sync_date"] == DBNull.Value ? (DateTime?)null : Convert.ToDateTime(rd["last_sync_date"]),
TotalUsers = rd["total_users"] == DBNull.Value ? 0 : Convert.ToInt32(rd["total_users"])
});
}
}
catch (Exception ex) { error = ex.Message; }
return rows;
}
public void UpdateMachineSyncState(string machineIp, string status, DateTime? lastSyncDate, int? totalUsers, out string error)
{
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"UPDATE attendance_machine SET status=@status,last_sync_date=COALESCE(@last_sync_date,last_sync_date),total_users=COALESCE(@total_users,total_users) WHERE machine_ip=@machine_ip",
conn);
cmd.Parameters.AddWithValue("@status", status ?? "");
cmd.Parameters.AddWithValue("@last_sync_date", (object?)lastSyncDate ?? DBNull.Value);
cmd.Parameters.AddWithValue("@total_users", (object?)totalUsers ?? DBNull.Value);
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
cmd.ExecuteNonQuery();
}
catch (Exception ex) { error = ex.Message; }
}
public bool TryGetMachineLastSyncDate(string machineIp, out DateTime? lastSyncDate, out string error)
{
lastSyncDate = null;
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"SELECT last_sync_date FROM attendance_machine WHERE machine_ip=@machine_ip LIMIT 1",
conn);
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
var obj = cmd.ExecuteScalar();
if (obj == null || obj == DBNull.Value)
return true;
lastSyncDate = Convert.ToDateTime(obj);
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
public bool UpdateMachineLastSyncDate(string machineIp, DateTime lastSyncDate, out string error)
{
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"UPDATE attendance_machine SET last_sync_date=@last_sync_date WHERE machine_ip=@machine_ip",
conn);
cmd.Parameters.AddWithValue("@last_sync_date", lastSyncDate);
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
}
internal sealed class MySqlAttendanceLogRepository : IAttendanceLogRepository
{
private readonly IHrmsDbConnectionFactory _factory;
public MySqlAttendanceLogRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
public bool UpsertAttendance(string acNo, DateTime checkTime, int processed, string machineId, int inOutTypeId, string machineIp, DateTime dateOnly, out string error)
{
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"REPLACE INTO attendance_log (ac_no,checktime,processed,machine_id,in_out_type_id,machine_ip,date) " +
"VALUES (@ac_no,@checktime,@processed,@machine_id,@in_out_type_id,@machine_ip,@date)",
conn);
cmd.Parameters.AddWithValue("@ac_no", acNo ?? "");
cmd.Parameters.AddWithValue("@checktime", checkTime);
cmd.Parameters.AddWithValue("@processed", processed);
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
cmd.Parameters.AddWithValue("@in_out_type_id", inOutTypeId);
cmd.Parameters.AddWithValue("@machine_ip", machineIp ?? "");
cmd.Parameters.AddWithValue("@date", dateOnly.Date);
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex) { error = ex.Message; return false; }
}
}
internal sealed class MySqlAttendanceMachineUserRepository : IAttendanceMachineUserRepository
{
private readonly IHrmsDbConnectionFactory _factory;
public MySqlAttendanceMachineUserRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
public List<AttendanceMachineUserRow> GetActiveUsersByMachine(string machineId, out string error) =>
QueryUsers(machineId, false, out error);
public List<AttendanceMachineUserRow> GetPendingDeletionUsersByMachine(string machineId, out string error) =>
QueryUsers(machineId, true, out error);
private List<AttendanceMachineUserRow> QueryUsers(string machineId, bool deletionRequested, out string error)
{
error = "";
var rows = new List<AttendanceMachineUserRow>();
if (!_factory.TryBuildConnectionString(out var cs, out error))
return rows;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"SELECT machine_id,serial_number,employee_name,is_deleted,is_deletion_requested FROM attendance_machine_user " +
"WHERE machine_id=@machine_id AND is_deleted=0 AND is_deletion_requested=@is_deletion_requested",
conn);
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
cmd.Parameters.AddWithValue("@is_deletion_requested", deletionRequested ? 1 : 0);
using var rd = cmd.ExecuteReader();
while (rd.Read())
{
rows.Add(new AttendanceMachineUserRow
{
MachineId = rd["machine_id"]?.ToString() ?? "",
SerialNumber = rd["serial_number"]?.ToString() ?? "",
EmployeeName = rd["employee_name"]?.ToString() ?? "",
IsDeleted = Convert.ToInt32(rd["is_deleted"]) != 0,
IsDeletionRequested = Convert.ToInt32(rd["is_deletion_requested"]) != 0
});
}
}
catch (Exception ex) { error = ex.Message; }
return rows;
}
public bool UpsertMachineUser(string machineId, string serialNumber, string employeeName, out string error)
{
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"REPLACE INTO attendance_machine_user (machine_id,serial_number,employee_name,is_deleted,is_deletion_requested,updated_at) " +
"VALUES (@machine_id,@serial_number,@employee_name,0,0,NOW())", conn);
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
cmd.Parameters.AddWithValue("@serial_number", serialNumber ?? "");
cmd.Parameters.AddWithValue("@employee_name", employeeName ?? "");
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex) { error = ex.Message; return false; }
}
public bool MarkDeleted(string machineId, string serialNumber, string updatedBy, out string error)
{
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"UPDATE attendance_machine_user SET is_deleted=1,is_deletion_requested=0,updated_by=@updated_by,updated_at=NOW() " +
"WHERE machine_id=@machine_id AND serial_number=@serial_number", conn);
cmd.Parameters.AddWithValue("@updated_by", updatedBy ?? "hikvision-service");
cmd.Parameters.AddWithValue("@machine_id", machineId ?? "");
cmd.Parameters.AddWithValue("@serial_number", serialNumber ?? "");
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex) { error = ex.Message; return false; }
}
}
internal sealed class MySqlAttendanceMachineFaceTemplateRepository : IAttendanceMachineFaceTemplateRepository
{
private readonly IHrmsDbConnectionFactory _factory;
public MySqlAttendanceMachineFaceTemplateRepository(IHrmsDbConnectionFactory factory) { _factory = factory; }
public bool UpsertFaceTemplate(string serialNo, byte[] template, DateTime createdDate, bool isActive, out string error)
{
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"REPLACE INTO attendance_machine_face_templates (serial_no,template,created_date,is_active) " +
"VALUES (@serial_no,@template,@created_date,@is_active)", conn);
cmd.Parameters.AddWithValue("@serial_no", serialNo ?? "");
cmd.Parameters.Add("@template", MySqlDbType.Blob).Value = (object?)template ?? Array.Empty<byte>();
cmd.Parameters.AddWithValue("@created_date", createdDate);
cmd.Parameters.AddWithValue("@is_active", isActive ? 1 : 0);
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex) { error = ex.Message; return false; }
}
public bool TryGetActiveFaceTemplateBySerial(string serialNo, out AttendanceMachineFaceTemplateRow? row, out string error)
{
row = null;
error = "";
if (!_factory.TryBuildConnectionString(out var cs, out error))
return false;
try
{
using var conn = new MySqlConnection(cs);
conn.Open();
using var cmd = new MySqlCommand(
"SELECT serial_no,template,created_date,is_active FROM attendance_machine_face_templates " +
"WHERE serial_no=@serial_no AND is_active=1 ORDER BY created_date DESC LIMIT 1", conn);
cmd.Parameters.AddWithValue("@serial_no", serialNo ?? "");
using var rd = cmd.ExecuteReader();
if (!rd.Read())
return false;
row = new AttendanceMachineFaceTemplateRow
{
SerialNo = rd["serial_no"]?.ToString() ?? "",
Template = rd["template"] == DBNull.Value ? Array.Empty<byte>() : (byte[])rd["template"],
CreatedDate = rd["created_date"] == DBNull.Value ? DateTime.MinValue : Convert.ToDateTime(rd["created_date"]),
IsActive = rd["is_active"] != DBNull.Value && Convert.ToInt32(rd["is_active"]) != 0
};
return true;
}
catch (Exception ex) { error = ex.Message; return false; }
}
}