99 lines
3.0 KiB
C#
99 lines
3.0 KiB
C#
using System.Data;
|
|
using System.IO;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using UtopiaCanteenSystem.Models;
|
|
|
|
namespace UtopiaCanteenSystem.Data;
|
|
|
|
/// <summary>
|
|
/// SQLite DbContext for Labour and ScanRecord tables.
|
|
/// Database file is created in application directory on first run.
|
|
/// </summary>
|
|
public class AppDbContext : DbContext
|
|
{
|
|
private static readonly string DbPath = Path.Combine(
|
|
AppDomain.CurrentDomain.BaseDirectory,
|
|
"utopia_canteen.db");
|
|
|
|
public DbSet<Labour> Labour { get; set; }
|
|
public DbSet<ScanRecord> ScanRecords { get; set; }
|
|
|
|
public AppDbContext() { }
|
|
|
|
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
|
|
|
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{
|
|
if (!optionsBuilder.IsConfigured)
|
|
optionsBuilder.UseSqlite($"Data Source={DbPath}");
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
// Labour: CardId should be indexed for lookups.
|
|
modelBuilder.Entity<Labour>(e =>
|
|
{
|
|
e.HasKey(x => x.Id);
|
|
e.HasIndex(x => x.CardId);
|
|
});
|
|
|
|
// ScanRecord: Index for unsynced queries and by ScanTime.
|
|
modelBuilder.Entity<ScanRecord>(e =>
|
|
{
|
|
e.HasKey(x => x.Id);
|
|
e.HasIndex(x => x.IsSynced);
|
|
e.HasIndex(x => x.ScanTime);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensures database exists and is migrated. Call on app startup.
|
|
/// </summary>
|
|
public void EnsureDatabaseCreated()
|
|
{
|
|
Database.EnsureCreated();
|
|
UpgradeScanRecordsSchemaIfNeeded();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lightweight schema upgrade: add SiteId and DeviceId to ScanRecords if missing (no EF migrations).
|
|
/// Does not delete any data.
|
|
/// </summary>
|
|
private void UpgradeScanRecordsSchemaIfNeeded()
|
|
{
|
|
try
|
|
{
|
|
var conn = Database.GetDbConnection();
|
|
if (conn.State != ConnectionState.Open)
|
|
conn.Open();
|
|
|
|
var columns = new List<string>();
|
|
using (var cmd = conn.CreateCommand())
|
|
{
|
|
cmd.CommandText = "SELECT name FROM pragma_table_info('ScanRecords')";
|
|
using var r = cmd.ExecuteReader();
|
|
while (r.Read())
|
|
columns.Add(r.GetString(0));
|
|
}
|
|
|
|
if (!columns.Contains("SiteId", StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "ALTER TABLE ScanRecords ADD COLUMN SiteId TEXT DEFAULT ''";
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
if (!columns.Contains("DeviceId", StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
using var cmd = conn.CreateCommand();
|
|
cmd.CommandText = "ALTER TABLE ScanRecords ADD COLUMN DeviceId TEXT DEFAULT ''";
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// Ignore; existing DB may already have columns or be incompatible
|
|
}
|
|
}
|
|
}
|