using Microsoft.EntityFrameworkCore; using LocationTrackerApp.Models; namespace LocationTrackerApp.Data; /// /// Entity Framework DbContext for managing location data in SQLite database /// public class LocationDbContext : DbContext { /// /// Database path for SQLite storage /// public string DatabasePath { get; } /// /// DbSet for LocationData entities /// public DbSet LocationData { get; set; } = null!; /// /// Initializes a new instance of LocationDbContext /// /// Path to the SQLite database file public LocationDbContext(string databasePath) { DatabasePath = databasePath; } /// /// Configures the database connection and options /// /// Options builder for configuring the database protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite($"Data Source={DatabasePath}"); // Enable sensitive data logging for development (remove in production) #if DEBUG optionsBuilder.EnableSensitiveDataLogging(); #endif } /// /// Configures entity relationships and constraints /// /// Model builder for configuring entities protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Configure LocationData entity modelBuilder.Entity(entity => { // Set primary key entity.HasKey(e => e.Id); // Configure indexes for better query performance entity.HasIndex(e => e.Timestamp) .HasDatabaseName("IX_LocationData_Timestamp"); entity.HasIndex(e => e.SessionId) .HasDatabaseName("IX_LocationData_SessionId"); entity.HasIndex(e => new { e.Latitude, e.Longitude }) .HasDatabaseName("IX_LocationData_Coordinates"); // Configure column types and constraints entity.Property(e => e.Latitude) .HasColumnType("REAL") .IsRequired(); entity.Property(e => e.Longitude) .HasColumnType("REAL") .IsRequired(); entity.Property(e => e.Accuracy) .HasColumnType("REAL") .HasDefaultValue(0.0); entity.Property(e => e.Altitude) .HasColumnType("REAL"); entity.Property(e => e.Speed) .HasColumnType("REAL"); entity.Property(e => e.Timestamp) .HasColumnType("TEXT") .IsRequired(); entity.Property(e => e.SessionId) .HasColumnType("TEXT") .HasMaxLength(100); entity.Property(e => e.Notes) .HasColumnType("TEXT") .HasMaxLength(500); }); } /// /// Ensures the database is created and up to date /// public async Task EnsureDatabaseCreatedAsync() { await Database.EnsureCreatedAsync(); } /// /// Clears all location data from the database /// public async Task ClearAllLocationDataAsync() { await Database.ExecuteSqlRawAsync("DELETE FROM LocationData"); } /// /// Gets location data within a specified time range /// /// Start time for the query /// End time for the query /// List of location data within the time range public async Task> GetLocationDataInTimeRangeAsync(DateTime startTime, DateTime endTime) { return await LocationData .Where(l => l.Timestamp >= startTime && l.Timestamp <= endTime) .OrderBy(l => l.Timestamp) .ToListAsync(); } /// /// Gets location data for a specific session /// /// Session identifier /// List of location data for the session public async Task> GetLocationDataBySessionAsync(string sessionId) { return await LocationData .Where(l => l.SessionId == sessionId) .OrderBy(l => l.Timestamp) .ToListAsync(); } }