|
1 | 1 | =============================================================================== |
2 | 2 | PROJECT EXPORT |
3 | | -Generated: Tue Jan 20 09:23:22 AM EST 2026 |
| 3 | +Generated: Tue Jan 20 09:26:58 AM EST 2026 |
4 | 4 | Project Path: /home/kushal/src/dotnet/MyBlog |
5 | 5 | =============================================================================== |
6 | 6 |
|
@@ -75,7 +75,8 @@ DIRECTORY STRUCTURE: |
75 | 75 | │ ├── MyBlog.Infrastructure |
76 | 76 | │ │ ├── Data |
77 | 77 | │ │ │ ├── BlogDbContext.cs |
78 | | -│ │ │ └── DatabasePathResolver.cs |
| 78 | +│ │ │ ├── DatabasePathResolver.cs |
| 79 | +│ │ │ └── DatabaseSchemaUpdater.cs |
79 | 80 | │ │ ├── Repositories |
80 | 81 | │ │ │ ├── ImageRepository.cs |
81 | 82 | │ │ │ ├── PostRepository.cs |
@@ -2636,6 +2637,74 @@ public static class DatabasePathResolver |
2636 | 2637 | } |
2637 | 2638 |
|
2638 | 2639 |
|
| 2640 | +================================================================================ |
| 2641 | +FILE: src/MyBlog.Infrastructure/Data/DatabaseSchemaUpdater.cs |
| 2642 | +SIZE: 2.24 KB |
| 2643 | +MODIFIED: 2026-01-20 09:25:48 |
| 2644 | +================================================================================ |
| 2645 | + |
| 2646 | +using Microsoft.EntityFrameworkCore; |
| 2647 | + |
| 2648 | +namespace MyBlog.Infrastructure.Data; |
| 2649 | + |
| 2650 | +/// <summary> |
| 2651 | +/// Handles incremental schema updates for existing databases. |
| 2652 | +/// Since we're not using formal EF Core migrations, this class ensures |
| 2653 | +/// new tables and columns are added to existing databases on deployment. |
| 2654 | +/// </summary> |
| 2655 | +public static class DatabaseSchemaUpdater |
| 2656 | +{ |
| 2657 | + /// <summary> |
| 2658 | + /// Applies any pending schema updates to the database. |
| 2659 | + /// This is safe to run multiple times - it only creates objects that don't exist. |
| 2660 | + /// </summary> |
| 2661 | + public static async Task ApplyUpdatesAsync(BlogDbContext db) |
| 2662 | + { |
| 2663 | + var connection = db.Database.GetDbConnection(); |
| 2664 | + if (connection.State != System.Data.ConnectionState.Open) |
| 2665 | + { |
| 2666 | + await connection.OpenAsync(); |
| 2667 | + } |
| 2668 | + |
| 2669 | + // Check and create ImageDimensionCache table if it doesn't exist |
| 2670 | + await EnsureImageDimensionCacheTableAsync(db); |
| 2671 | + } |
| 2672 | + |
| 2673 | + private static async Task EnsureImageDimensionCacheTableAsync(BlogDbContext db) |
| 2674 | + { |
| 2675 | + var tableExists = await TableExistsAsync(db, "ImageDimensionCache"); |
| 2676 | + if (!tableExists) |
| 2677 | + { |
| 2678 | + // Create the ImageDimensionCache table using raw SQL |
| 2679 | + // This matches the schema defined in BlogDbContext.OnModelCreating |
| 2680 | + await db.Database.ExecuteSqlRawAsync(""" |
| 2681 | + CREATE TABLE IF NOT EXISTS "ImageDimensionCache" ( |
| 2682 | + "Url" TEXT NOT NULL CONSTRAINT "PK_ImageDimensionCache" PRIMARY KEY, |
| 2683 | + "Width" INTEGER NOT NULL, |
| 2684 | + "Height" INTEGER NOT NULL, |
| 2685 | + "LastCheckedUtc" TEXT NOT NULL |
| 2686 | + ) |
| 2687 | + """); |
| 2688 | + } |
| 2689 | + } |
| 2690 | + |
| 2691 | + private static async Task<bool> TableExistsAsync(BlogDbContext db, string tableName) |
| 2692 | + { |
| 2693 | + var connection = db.Database.GetDbConnection(); |
| 2694 | + using var command = connection.CreateCommand(); |
| 2695 | + command.CommandText = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=@tableName"; |
| 2696 | + |
| 2697 | + var parameter = command.CreateParameter(); |
| 2698 | + parameter.ParameterName = "@tableName"; |
| 2699 | + parameter.Value = tableName; |
| 2700 | + command.Parameters.Add(parameter); |
| 2701 | + |
| 2702 | + var result = await command.ExecuteScalarAsync(); |
| 2703 | + return Convert.ToInt64(result) > 0; |
| 2704 | + } |
| 2705 | +} |
| 2706 | + |
| 2707 | + |
2639 | 2708 | ================================================================================ |
2640 | 2709 | FILE: src/MyBlog.Infrastructure/MyBlog.Infrastructure.csproj |
2641 | 2710 | SIZE: .50 KB |
@@ -6902,8 +6971,8 @@ MODIFIED: 2026-01-16 20:29:40 |
6902 | 6971 |
|
6903 | 6972 | ================================================================================ |
6904 | 6973 | FILE: src/MyBlog.Web/Program.cs |
6905 | | -SIZE: 3.82 KB |
6906 | | -MODIFIED: 2026-01-20 09:17:33 |
| 6974 | +SIZE: 4.10 KB |
| 6975 | +MODIFIED: 2026-01-20 09:25:14 |
6907 | 6976 | ================================================================================ |
6908 | 6977 |
|
6909 | 6978 | using Microsoft.AspNetCore.Authentication; |
@@ -6997,7 +7066,13 @@ var app = builder.Build(); |
6997 | 7066 | using (var scope = app.Services.CreateScope()) |
6998 | 7067 | { |
6999 | 7068 | var db = scope.ServiceProvider.GetRequiredService<BlogDbContext>(); |
7000 | | - await db.Database.MigrateAsync(); |
| 7069 | + |
| 7070 | + // EnsureCreated creates the database and all tables if the database doesn't exist. |
| 7071 | + // For existing databases, we need to manually ensure new tables exist. |
| 7072 | + await db.Database.EnsureCreatedAsync(); |
| 7073 | + |
| 7074 | + // Apply any pending schema updates for existing databases |
| 7075 | + await DatabaseSchemaUpdater.ApplyUpdatesAsync(db); |
7001 | 7076 |
|
7002 | 7077 | var authService = scope.ServiceProvider.GetRequiredService<IAuthService>(); |
7003 | 7078 | await authService.EnsureAdminUserAsync(); |
@@ -7562,9 +7637,9 @@ a:hover { |
7562 | 7637 |
|
7563 | 7638 |
|
7564 | 7639 | =============================================================================== |
7565 | | -EXPORT COMPLETED: Tue Jan 20 09:23:23 AM EST 2026 |
7566 | | -Total Files Found: 72 |
7567 | | -Files Exported: 72 |
| 7640 | +EXPORT COMPLETED: Tue Jan 20 09:26:59 AM EST 2026 |
| 7641 | +Total Files Found: 73 |
| 7642 | +Files Exported: 73 |
7568 | 7643 | Files Skipped: 0 (binary or large files) |
7569 | 7644 | Output File: /home/kushal/src/dotnet/MyBlog/docs/llm/dump.txt |
7570 | 7645 | =============================================================================== |
0 commit comments