diff --git a/docs/02-Database.md b/docs/02-Database.md index 87fef7c58..e7c5ede61 100644 --- a/docs/02-Database.md +++ b/docs/02-Database.md @@ -1,28 +1,74 @@ -### To change Database Provider - -1. Update provider and connection string in the `appsettings.json`: +## To change Database Provider +Update provider and connection string in the `appsettings.json`: +#### SQLite +``` json +"Blogifier": { + "DbProvider": "Sqlite", + "ConnString": "Data Source=App_Data/blogifier.db", + ... +} ``` +It is recommended to put the database file under the App_Data folder. The logs and local pictures in the project will be stored in this path for persistence. + +#### SqlServer +``` json "Blogifier": { - "DbProvider": "SQLite", - "ConnString": "Data Source=Blog.db", + "DbProvider": "SqlServer", + "ConnString": "Data Source=mssql; User Id=sa; Password=Password; Initial Catalog=blogifier;TrustServerCertificate=True", ... } ``` -Valid providers: `SQLite`, `SqlServer`, `Postgres`, `MySql` (you'll need to supply valid connection string) +In the latest version of sql server connection, SqlClient will perform a secure connection by default, and you need to add a server certificate to the system. The example adds TrustServerCertificate=True to ignore this requirement. You can also delete this ignore and enable a secure connection. -2. Remove `Blogifier/Data/Migrations` folder with existing migrations -3. In the Visual Studio, open `Package Manager Console`, set `Blogifier` -as Default project and run these commands: +#### MySql +``` json +"Blogifier": { + "DbProvider": "MySql", + "ConnString": "server=mysql;user=root;password=password;database=blogifier", + ... +} +``` +#### Postgres +``` json +"Blogifier": { + "DbProvider": "Postgres", + "ConnString": "Host=postgres;Username=postgres;Password=password;Database=blogifier;", + ... +} ``` -Add-Migration Init -o Data\Migrations -Update-Database +In the above example, ConnString requires you to fill in the correct database host address username and password to connect normally + + +## When a change to an entity field requires a database migration + +The database migration is stored in the src/Blogifier/Data/Migrations directory. The current project is still under development. When there is a modification, this directory may be deleted for quick migration. After the project is officially released, it is no longer recommended to delete the updated database migrate. + +The following is the way to generate a new migration or delete the previous migration command. Before executing the command, please configure the corresponding DbProvider and ConnString in appsettings.json and then execute the corresponding migration command +``` shell +# Revert Migration Tool +dotnet tool restore + +# Jump to project directory +cd src/Blogifier + +# Sqlite +dotnet ef migrations add Init --context SqliteDbContext --output-dir Data/Migrations/Sqlite +dotnet ef migrations remove --context SqliteDbContext + +# SqlServer +dotnet ef migrations add Init --context SqlServerDbContext --output-dir Data/Migrations/SqlServer +dotnet ef migrations remove --context SqlServerDbContext + +# MySql +dotnet ef migrations add Init --context MySqlDbContext --output-dir Data/Migrations/MySql +dotnet ef migrations remove --context MySqlDbContext -# cil -dotnet ef migrations Init -o Data\Migrations -dotnet ef migrations remove +# Postgres +dotnet ef migrations add Init --context PostgresDbContext --output-dir Data/Migrations/Postgres +dotnet ef migrations remove --context MySqlDbContext ``` -First command should re-generate provider specific code migrations and second will -execute them and create database specified in the connection string. +### Warn +Do not add or delete database migration at will. After the application generates data, random migration may cause data loss. This project will automatically apply the migration when it starts. diff --git a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor index 861dfe9b8..893a547f6 100644 --- a/src/Blogifier.Admin/Pages/Blogs/EditorView.razor +++ b/src/Blogifier.Admin/Pages/Blogs/EditorView.razor @@ -31,7 +31,7 @@ @_localizer["delete"] - + diff --git a/src/Blogifier/Data/AppDbContext.cs b/src/Blogifier/Data/AppDbContext.cs index 5dbd45791..e571ab06b 100644 --- a/src/Blogifier/Data/AppDbContext.cs +++ b/src/Blogifier/Data/AppDbContext.cs @@ -11,21 +11,18 @@ namespace Blogifier.Data; public class AppDbContext : IdentityUserContext { - protected readonly DbContextOptions _options; - - public AppDbContext(DbContextOptions options) : base(options) + public AppDbContext(DbContextOptions options) : base(options) { - _options = options; - } + } public DbSet Options { get; set; } = default!; public DbSet Posts { get; set; } = default!; - public DbSet Storages { get; set; } = default!; - public DbSet StorageReferences { get; set; } = default!; public DbSet Categories { get; set; } = default!; public DbSet PostCategories { get; set; } = default!; - public DbSet Subscribers { get; set; } = default!; public DbSet Newsletters { get; set; } = default!; + public DbSet Subscribers { get; set; } = default!; + public DbSet Storages { get; set; } = default!; + //public DbSet StorageReferences { get; set; } = default!; protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -36,6 +33,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) e.ToTable("User"); e.Property(p => p.Id).HasMaxLength(128); e.Property(p => p.CreatedAt).HasColumnOrder(0); + e.Property(p => p.UpdatedAt).HasColumnOrder(1); e.Property(p => p.PasswordHash).HasMaxLength(256); e.Property(p => p.SecurityStamp).HasMaxLength(32); e.Property(p => p.ConcurrencyStamp).HasMaxLength(64); @@ -65,27 +63,22 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) e.HasIndex(b => b.Key).IsUnique(); }); - modelBuilder.Entity(e => + modelBuilder.Entity(e => { - e.ToTable("StorageReferences"); - e.HasKey(t => new { t.StorageId, t.EntityId, t.Type }); + e.ToTable("Post"); + e.HasIndex(b => b.Slug).IsUnique(); }); + //modelBuilder.Entity(e => + //{ + // e.ToTable("StorageReferences"); + // e.HasKey(t => new { t.StorageId, t.EntityId }); + //}); + modelBuilder.Entity(e => { e.ToTable("PostCategories"); e.HasKey(t => new { t.PostId, t.CategoryId }); }); - - modelBuilder.Entity(e => - { - e.ToTable("Post"); - e.HasIndex(b => b.Slug).IsUnique(); - - e.HasMany(e => e.StorageReferences) - .WithOne(e => e.Post) - .HasForeignKey(e => e.EntityId) - .IsRequired(); - }); } } diff --git a/src/Blogifier/Data/Migrations/20230606095435_Storage.cs b/src/Blogifier/Data/Migrations/20230606095435_Storage.cs deleted file mode 100644 index 8b561c8cc..000000000 --- a/src/Blogifier/Data/Migrations/20230606095435_Storage.cs +++ /dev/null @@ -1,241 +0,0 @@ -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using System; - -#nullable disable - -namespace Blogifier.Data.Migrations -{ - /// - public partial class Storage : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Newsletters_Posts_PostId", - table: "Newsletters"); - - migrationBuilder.DropForeignKey( - name: "FK_PostCategories_Posts_PostId", - table: "PostCategories"); - - migrationBuilder.DropForeignKey( - name: "FK_Posts_User_UserId", - table: "Posts"); - - migrationBuilder.DropPrimaryKey( - name: "PK_Posts", - table: "Posts"); - - migrationBuilder.DropColumn( - name: "AuthorId", - table: "Storages"); - - migrationBuilder.RenameTable( - name: "Posts", - newName: "Post"); - - migrationBuilder.RenameColumn( - name: "StorageType", - table: "Storages", - newName: "Type"); - - migrationBuilder.RenameIndex( - name: "IX_Posts_UserId", - table: "Post", - newName: "IX_Post_UserId"); - - migrationBuilder.AddColumn( - name: "Slug", - table: "Storages", - type: "varchar(2048)", - maxLength: 2048, - nullable: false, - defaultValue: "") - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.AddColumn( - name: "UserId", - table: "Storages", - type: "varchar(128)", - nullable: false, - defaultValue: "") - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.AddPrimaryKey( - name: "PK_Post", - table: "Post", - column: "Id"); - - migrationBuilder.CreateTable( - name: "StorageReferences", - columns: table => new - { - StorageId = table.Column(type: "int", nullable: false), - EntityId = table.Column(type: "int", nullable: false), - Type = table.Column(type: "int", nullable: false), - CreatedAt = table.Column(type: "datetime(6)", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn) - }, - constraints: table => - { - table.PrimaryKey("PK_StorageReferences", x => new { x.StorageId, x.EntityId, x.Type }); - table.ForeignKey( - name: "FK_StorageReferences_Post_EntityId", - column: x => x.EntityId, - principalTable: "Post", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_StorageReferences_Storages_StorageId", - column: x => x.StorageId, - principalTable: "Storages", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.CreateIndex( - name: "IX_Storages_UserId", - table: "Storages", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Post_Slug", - table: "Post", - column: "Slug", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_StorageReferences_EntityId", - table: "StorageReferences", - column: "EntityId"); - - migrationBuilder.AddForeignKey( - name: "FK_Newsletters_Post_PostId", - table: "Newsletters", - column: "PostId", - principalTable: "Post", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_Post_User_UserId", - table: "Post", - column: "UserId", - principalTable: "User", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_PostCategories_Post_PostId", - table: "PostCategories", - column: "PostId", - principalTable: "Post", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_Storages_User_UserId", - table: "Storages", - column: "UserId", - principalTable: "User", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Newsletters_Post_PostId", - table: "Newsletters"); - - migrationBuilder.DropForeignKey( - name: "FK_Post_User_UserId", - table: "Post"); - - migrationBuilder.DropForeignKey( - name: "FK_PostCategories_Post_PostId", - table: "PostCategories"); - - migrationBuilder.DropForeignKey( - name: "FK_Storages_User_UserId", - table: "Storages"); - - migrationBuilder.DropTable( - name: "StorageReferences"); - - migrationBuilder.DropIndex( - name: "IX_Storages_UserId", - table: "Storages"); - - migrationBuilder.DropPrimaryKey( - name: "PK_Post", - table: "Post"); - - migrationBuilder.DropIndex( - name: "IX_Post_Slug", - table: "Post"); - - migrationBuilder.DropColumn( - name: "Slug", - table: "Storages"); - - migrationBuilder.DropColumn( - name: "UserId", - table: "Storages"); - - migrationBuilder.RenameTable( - name: "Post", - newName: "Posts"); - - migrationBuilder.RenameColumn( - name: "Type", - table: "Storages", - newName: "StorageType"); - - migrationBuilder.RenameIndex( - name: "IX_Post_UserId", - table: "Posts", - newName: "IX_Posts_UserId"); - - migrationBuilder.AddColumn( - name: "AuthorId", - table: "Storages", - type: "int", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddPrimaryKey( - name: "PK_Posts", - table: "Posts", - column: "Id"); - - migrationBuilder.AddForeignKey( - name: "FK_Newsletters_Posts_PostId", - table: "Newsletters", - column: "PostId", - principalTable: "Posts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_PostCategories_Posts_PostId", - table: "PostCategories", - column: "PostId", - principalTable: "Posts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_Posts_User_UserId", - table: "Posts", - column: "UserId", - principalTable: "User", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - } -} diff --git a/src/Blogifier/Data/Migrations/20230606095435_Storage.Designer.cs b/src/Blogifier/Data/Migrations/MySql/20230608093107_Init.Designer.cs similarity index 91% rename from src/Blogifier/Data/Migrations/20230606095435_Storage.Designer.cs rename to src/Blogifier/Data/Migrations/MySql/20230608093107_Init.Designer.cs index 26459d812..2bd7fc94b 100644 --- a/src/Blogifier/Data/Migrations/20230606095435_Storage.Designer.cs +++ b/src/Blogifier/Data/Migrations/MySql/20230608093107_Init.Designer.cs @@ -8,11 +8,11 @@ #nullable disable -namespace Blogifier.Data.Migrations +namespace Blogifier.Data.Migrations.MySql { - [DbContext(typeof(AppDbContext))] - [Migration("20230606095435_Storage")] - partial class Storage + [DbContext(typeof(MySqlDbContext))] + [Migration("20230608093107_Init")] + partial class Init { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -103,6 +103,11 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Type") .HasColumnType("int"); + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime(6)") + .HasColumnOrder(1); + b.Property("UserName") .HasMaxLength(256) .HasColumnType("varchar(256)"); @@ -369,28 +374,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("Storages"); }); - modelBuilder.Entity("Blogifier.Storages.StorageReference", b => - { - b.Property("StorageId") - .HasColumnType("int"); - - b.Property("EntityId") - .HasColumnType("int"); - - b.Property("Type") - .HasColumnType("int"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); - - b.HasKey("StorageId", "EntityId", "Type"); - - b.HasIndex("EntityId"); - - b.ToTable("StorageReferences", (string)null); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") @@ -511,25 +494,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("User"); }); - modelBuilder.Entity("Blogifier.Storages.StorageReference", b => - { - b.HasOne("Blogifier.Shared.Post", "Post") - .WithMany("StorageReferences") - .HasForeignKey("EntityId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Blogifier.Storages.Storage", "Storage") - .WithMany("StorageReferences") - .HasForeignKey("StorageId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Post"); - - b.Navigation("Storage"); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("Blogifier.Identity.UserInfo", null) @@ -565,13 +529,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("Blogifier.Shared.Post", b => { b.Navigation("PostCategories"); - - b.Navigation("StorageReferences"); - }); - - modelBuilder.Entity("Blogifier.Storages.Storage", b => - { - b.Navigation("StorageReferences"); }); #pragma warning restore 612, 618 } diff --git a/src/Blogifier/Data/Migrations/20230602104208_Init.cs b/src/Blogifier/Data/Migrations/MySql/20230608093107_Init.cs similarity index 91% rename from src/Blogifier/Data/Migrations/20230602104208_Init.cs rename to src/Blogifier/Data/Migrations/MySql/20230608093107_Init.cs index e280ed4da..445fc0467 100644 --- a/src/Blogifier/Data/Migrations/20230602104208_Init.cs +++ b/src/Blogifier/Data/Migrations/MySql/20230608093107_Init.cs @@ -1,10 +1,10 @@ -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable -namespace Blogifier.Data.Migrations +namespace Blogifier.Data.Migrations.MySql { /// public partial class Init : Migration @@ -55,32 +55,6 @@ protected override void Up(MigrationBuilder migrationBuilder) }) .Annotation("MySql:CharSet", "utf8mb4"); - migrationBuilder.CreateTable( - name: "Storages", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - AuthorId = table.Column(type: "int", nullable: false), - CreatedAt = table.Column(type: "datetime(6)", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - IsDeleted = table.Column(type: "tinyint(1)", nullable: false), - DeletedAt = table.Column(type: "datetime(6)", nullable: true), - Name = table.Column(type: "varchar(256)", maxLength: 256, nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - Path = table.Column(type: "varchar(2048)", maxLength: 2048, nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - Length = table.Column(type: "bigint", nullable: false), - ContentType = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) - .Annotation("MySql:CharSet", "utf8mb4"), - StorageType = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Storages", x => x.Id); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - migrationBuilder.CreateTable( name: "Subscribers", columns: table => new @@ -112,6 +86,8 @@ protected override void Up(MigrationBuilder migrationBuilder) { CreatedAt = table.Column(type: "datetime(6)", nullable: false) .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UpdatedAt = table.Column(type: "datetime(6)", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn), Id = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) .Annotation("MySql:CharSet", "utf8mb4"), NickName = table.Column(type: "varchar(256)", maxLength: 256, nullable: false) @@ -154,7 +130,7 @@ protected override void Up(MigrationBuilder migrationBuilder) .Annotation("MySql:CharSet", "utf8mb4"); migrationBuilder.CreateTable( - name: "Posts", + name: "Post", columns: table => new { Id = table.Column(type: "int", nullable: false) @@ -182,9 +158,44 @@ protected override void Up(MigrationBuilder migrationBuilder) }, constraints: table => { - table.PrimaryKey("PK_Posts", x => x.Id); + table.PrimaryKey("PK_Post", x => x.Id); + table.ForeignKey( + name: "FK_Post_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Storages", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "varchar(128)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CreatedAt = table.Column(type: "datetime(6)", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + IsDeleted = table.Column(type: "tinyint(1)", nullable: false), + DeletedAt = table.Column(type: "datetime(6)", nullable: true), + Slug = table.Column(type: "varchar(2048)", maxLength: 2048, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Name = table.Column(type: "varchar(256)", maxLength: 256, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Path = table.Column(type: "varchar(2048)", maxLength: 2048, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Length = table.Column(type: "bigint", nullable: false), + ContentType = table.Column(type: "varchar(128)", maxLength: 128, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Type = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Storages", x => x.Id); table.ForeignKey( - name: "FK_Posts_User_UserId", + name: "FK_Storages_User_UserId", column: x => x.UserId, principalTable: "User", principalColumn: "Id", @@ -284,9 +295,9 @@ protected override void Up(MigrationBuilder migrationBuilder) { table.PrimaryKey("PK_Newsletters", x => x.Id); table.ForeignKey( - name: "FK_Newsletters_Posts_PostId", + name: "FK_Newsletters_Post_PostId", column: x => x.PostId, - principalTable: "Posts", + principalTable: "Post", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }) @@ -309,9 +320,9 @@ protected override void Up(MigrationBuilder migrationBuilder) principalColumn: "Id", onDelete: ReferentialAction.Cascade); table.ForeignKey( - name: "FK_PostCategories_Posts_PostId", + name: "FK_PostCategories_Post_PostId", column: x => x.PostId, - principalTable: "Posts", + principalTable: "Post", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }) @@ -328,14 +339,25 @@ protected override void Up(MigrationBuilder migrationBuilder) column: "Key", unique: true); + migrationBuilder.CreateIndex( + name: "IX_Post_Slug", + table: "Post", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_UserId", + table: "Post", + column: "UserId"); + migrationBuilder.CreateIndex( name: "IX_PostCategories_CategoryId", table: "PostCategories", column: "CategoryId"); migrationBuilder.CreateIndex( - name: "IX_Posts_UserId", - table: "Posts", + name: "IX_Storages_UserId", + table: "Storages", column: "UserId"); migrationBuilder.CreateIndex( @@ -391,7 +413,7 @@ protected override void Down(MigrationBuilder migrationBuilder) name: "Categories"); migrationBuilder.DropTable( - name: "Posts"); + name: "Post"); migrationBuilder.DropTable( name: "User"); diff --git a/src/Blogifier/Data/Migrations/AppDbContextModelSnapshot.cs b/src/Blogifier/Data/Migrations/MySql/MySqlDbContextModelSnapshot.cs similarity index 91% rename from src/Blogifier/Data/Migrations/AppDbContextModelSnapshot.cs rename to src/Blogifier/Data/Migrations/MySql/MySqlDbContextModelSnapshot.cs index d8aeb9266..68b4308e9 100644 --- a/src/Blogifier/Data/Migrations/AppDbContextModelSnapshot.cs +++ b/src/Blogifier/Data/Migrations/MySql/MySqlDbContextModelSnapshot.cs @@ -7,10 +7,10 @@ #nullable disable -namespace Blogifier.Data.Migrations +namespace Blogifier.Data.Migrations.MySql { - [DbContext(typeof(AppDbContext))] - partial class AppDbContextModelSnapshot : ModelSnapshot + [DbContext(typeof(MySqlDbContext))] + partial class MySqlDbContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { @@ -100,6 +100,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Type") .HasColumnType("int"); + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime(6)") + .HasColumnOrder(1); + b.Property("UserName") .HasMaxLength(256) .HasColumnType("varchar(256)"); @@ -366,28 +371,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Storages"); }); - modelBuilder.Entity("Blogifier.Storages.StorageReference", b => - { - b.Property("StorageId") - .HasColumnType("int"); - - b.Property("EntityId") - .HasColumnType("int"); - - b.Property("Type") - .HasColumnType("int"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); - - b.HasKey("StorageId", "EntityId", "Type"); - - b.HasIndex("EntityId"); - - b.ToTable("StorageReferences", (string)null); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") @@ -508,25 +491,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("User"); }); - modelBuilder.Entity("Blogifier.Storages.StorageReference", b => - { - b.HasOne("Blogifier.Shared.Post", "Post") - .WithMany("StorageReferences") - .HasForeignKey("EntityId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Blogifier.Storages.Storage", "Storage") - .WithMany("StorageReferences") - .HasForeignKey("StorageId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Post"); - - b.Navigation("Storage"); - }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("Blogifier.Identity.UserInfo", null) @@ -562,13 +526,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Blogifier.Shared.Post", b => { b.Navigation("PostCategories"); - - b.Navigation("StorageReferences"); - }); - - modelBuilder.Entity("Blogifier.Storages.Storage", b => - { - b.Navigation("StorageReferences"); }); #pragma warning restore 612, 618 } diff --git a/src/Blogifier/Data/Migrations/Postgres/20230608094908_Init.Designer.cs b/src/Blogifier/Data/Migrations/Postgres/20230608094908_Init.Designer.cs new file mode 100644 index 000000000..f3a45afcd --- /dev/null +++ b/src/Blogifier/Data/Migrations/Postgres/20230608094908_Init.Designer.cs @@ -0,0 +1,555 @@ +// +using System; +using Blogifier.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Blogifier.Data.Migrations.Postgres +{ + [DbContext(typeof(PostgresDbContext))] + [Migration("20230608094908_Init")] + partial class Init + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Blogifier.Identity.UserInfo", b => + { + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("Avatar") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Bio") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasColumnOrder(0) + .HasDefaultValueSql("now()"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("Gender") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NickName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PhoneNumber") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnOrder(1); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("User", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PostId") + .HasColumnType("integer"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("Newsletters"); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Subscriber", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Country") + .HasMaxLength(120) + .HasColumnType("character varying(120)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("Ip") + .HasMaxLength(80) + .HasColumnType("character varying(80)"); + + b.Property("Region") + .HasMaxLength(120) + .HasColumnType("character varying(120)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Subscribers"); + }); + + modelBuilder.Entity("Blogifier.Options.OptionInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("Options", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("character varying(120)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cover") + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("character varying(450)"); + + b.Property("PostType") + .HasColumnType("integer"); + + b.Property("PublishedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Views") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("Post", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.Property("PostId") + .HasColumnType("integer"); + + b.Property("CategoryId") + .HasColumnType("integer"); + + b.HasKey("PostId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.ToTable("PostCategories", (string)null); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Length") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Storages"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasMaxLength(16) + .HasColumnType("character varying(16)"); + + b.Property("ClaimValue") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaim", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("character varying(128)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogin", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("character varying(128)"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserToken", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.HasOne("Blogifier.Shared.Category", "Category") + .WithMany("PostCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany("PostCategories") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Navigation("PostCategories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Navigation("PostCategories"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Blogifier/Data/Migrations/Postgres/20230608094908_Init.cs b/src/Blogifier/Data/Migrations/Postgres/20230608094908_Init.cs new file mode 100644 index 000000000..42ac2abb5 --- /dev/null +++ b/src/Blogifier/Data/Migrations/Postgres/20230608094908_Init.cs @@ -0,0 +1,353 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Blogifier.Data.Migrations.Postgres +{ + /// + public partial class Init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Categories", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + Content = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), + Description = table.Column(type: "character varying(255)", maxLength: 255, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Categories", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Options", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + Key = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + Value = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Options", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Subscribers", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + Email = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), + Ip = table.Column(type: "character varying(80)", maxLength: 80, nullable: true), + Country = table.Column(type: "character varying(120)", maxLength: 120, nullable: true), + Region = table.Column(type: "character varying(120)", maxLength: 120, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Subscribers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "User", + columns: table => new + { + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + Id = table.Column(type: "character varying(128)", maxLength: 128, nullable: false), + NickName = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + Avatar = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), + Bio = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + Gender = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + Type = table.Column(type: "integer", nullable: false), + State = table.Column(type: "integer", nullable: false), + UserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + Email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "boolean", nullable: false), + PasswordHash = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + SecurityStamp = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + ConcurrencyStamp = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + PhoneNumber = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + PhoneNumberConfirmed = table.Column(type: "boolean", nullable: false), + TwoFactorEnabled = table.Column(type: "boolean", nullable: false), + LockoutEnd = table.Column(type: "timestamp with time zone", nullable: true), + LockoutEnabled = table.Column(type: "boolean", nullable: false), + AccessFailedCount = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_User", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Post", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + UserId = table.Column(type: "character varying(128)", maxLength: 128, nullable: false), + Title = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), + Slug = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), + Description = table.Column(type: "character varying(450)", maxLength: 450, nullable: false), + Content = table.Column(type: "text", nullable: false), + Cover = table.Column(type: "character varying(160)", maxLength: 160, nullable: true), + Views = table.Column(type: "integer", nullable: false), + PublishedAt = table.Column(type: "timestamp with time zone", nullable: true), + PostType = table.Column(type: "integer", nullable: false), + State = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Post", x => x.Id); + table.ForeignKey( + name: "FK_Post_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Storages", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserId = table.Column(type: "character varying(128)", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + IsDeleted = table.Column(type: "boolean", nullable: false), + DeletedAt = table.Column(type: "timestamp with time zone", nullable: true), + Slug = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: false), + Name = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + Path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: false), + Length = table.Column(type: "bigint", nullable: false), + ContentType = table.Column(type: "character varying(128)", maxLength: 128, nullable: false), + Type = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Storages", x => x.Id); + table.ForeignKey( + name: "FK_Storages_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaim", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserId = table.Column(type: "character varying(128)", nullable: false), + ClaimType = table.Column(type: "character varying(16)", maxLength: 16, nullable: true), + ClaimValue = table.Column(type: "character varying(256)", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaim", x => x.Id); + table.ForeignKey( + name: "FK_UserClaim_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogin", + columns: table => new + { + LoginProvider = table.Column(type: "text", nullable: false), + ProviderKey = table.Column(type: "text", nullable: false), + ProviderDisplayName = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + UserId = table.Column(type: "character varying(128)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogin_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserToken", + columns: table => new + { + UserId = table.Column(type: "character varying(128)", nullable: false), + LoginProvider = table.Column(type: "text", nullable: false), + Name = table.Column(type: "text", nullable: false), + Value = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserToken_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Newsletters", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + PostId = table.Column(type: "integer", nullable: false), + Success = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Newsletters", x => x.Id); + table.ForeignKey( + name: "FK_Newsletters_Post_PostId", + column: x => x.PostId, + principalTable: "Post", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PostCategories", + columns: table => new + { + PostId = table.Column(type: "integer", nullable: false), + CategoryId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PostCategories", x => new { x.PostId, x.CategoryId }); + table.ForeignKey( + name: "FK_PostCategories_Categories_CategoryId", + column: x => x.CategoryId, + principalTable: "Categories", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PostCategories_Post_PostId", + column: x => x.PostId, + principalTable: "Post", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Newsletters_PostId", + table: "Newsletters", + column: "PostId"); + + migrationBuilder.CreateIndex( + name: "IX_Options_Key", + table: "Options", + column: "Key", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_Slug", + table: "Post", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_UserId", + table: "Post", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_PostCategories_CategoryId", + table: "PostCategories", + column: "CategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_Storages_UserId", + table: "Storages", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "User", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "User", + column: "NormalizedUserName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserClaim_UserId", + table: "UserClaim", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogin_UserId", + table: "UserLogin", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Newsletters"); + + migrationBuilder.DropTable( + name: "Options"); + + migrationBuilder.DropTable( + name: "PostCategories"); + + migrationBuilder.DropTable( + name: "Storages"); + + migrationBuilder.DropTable( + name: "Subscribers"); + + migrationBuilder.DropTable( + name: "UserClaim"); + + migrationBuilder.DropTable( + name: "UserLogin"); + + migrationBuilder.DropTable( + name: "UserToken"); + + migrationBuilder.DropTable( + name: "Categories"); + + migrationBuilder.DropTable( + name: "Post"); + + migrationBuilder.DropTable( + name: "User"); + } + } +} diff --git a/src/Blogifier/Data/Migrations/Postgres/PostgresDbContextModelSnapshot.cs b/src/Blogifier/Data/Migrations/Postgres/PostgresDbContextModelSnapshot.cs new file mode 100644 index 000000000..324b7c149 --- /dev/null +++ b/src/Blogifier/Data/Migrations/Postgres/PostgresDbContextModelSnapshot.cs @@ -0,0 +1,552 @@ +// +using System; +using Blogifier.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Blogifier.Data.Migrations.Postgres +{ + [DbContext(typeof(PostgresDbContext))] + partial class PostgresDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Blogifier.Identity.UserInfo", b => + { + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("Avatar") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Bio") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasColumnOrder(0) + .HasDefaultValueSql("now()"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("Gender") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NickName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PhoneNumber") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnOrder(1); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("User", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PostId") + .HasColumnType("integer"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("Newsletters"); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Subscriber", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Country") + .HasMaxLength(120) + .HasColumnType("character varying(120)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("Ip") + .HasMaxLength(80) + .HasColumnType("character varying(80)"); + + b.Property("Region") + .HasMaxLength(120) + .HasColumnType("character varying(120)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Subscribers"); + }); + + modelBuilder.Entity("Blogifier.Options.OptionInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("Options", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("character varying(120)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cover") + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("character varying(450)"); + + b.Property("PostType") + .HasColumnType("integer"); + + b.Property("PublishedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("character varying(160)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Views") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("Post", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.Property("PostId") + .HasColumnType("integer"); + + b.Property("CategoryId") + .HasColumnType("integer"); + + b.HasKey("PostId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.ToTable("PostCategories", (string)null); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Length") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Storages"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasMaxLength(16) + .HasColumnType("character varying(16)"); + + b.Property("ClaimValue") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaim", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("character varying(128)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogin", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("character varying(128)"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserToken", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.HasOne("Blogifier.Shared.Category", "Category") + .WithMany("PostCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany("PostCategories") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Navigation("PostCategories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Navigation("PostCategories"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Blogifier/Data/Migrations/20230602104208_Init.Designer.cs b/src/Blogifier/Data/Migrations/SqlServer/20230608091513_Init.Designer.cs similarity index 69% rename from src/Blogifier/Data/Migrations/20230602104208_Init.Designer.cs rename to src/Blogifier/Data/Migrations/SqlServer/20230608091513_Init.Designer.cs index 46e58dc6f..9fcd3e73c 100644 --- a/src/Blogifier/Data/Migrations/20230602104208_Init.Designer.cs +++ b/src/Blogifier/Data/Migrations/SqlServer/20230608091513_Init.Designer.cs @@ -3,15 +3,16 @@ using Blogifier.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; #nullable disable -namespace Blogifier.Data.Migrations +namespace Blogifier.Data.Migrations.SqlServer { - [DbContext(typeof(AppDbContext))] - [Migration("20230602104208_Init")] + [DbContext(typeof(SqlServerDbContext))] + [Migration("20230608091513_Init")] partial class Init { /// @@ -20,92 +21,100 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "7.0.5") - .HasAnnotation("Relational:MaxIdentifierLength", 64); + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); modelBuilder.Entity("Blogifier.Identity.UserInfo", b => { b.Property("Id") .HasMaxLength(128) - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.Property("AccessFailedCount") .HasColumnType("int"); b.Property("Avatar") .HasMaxLength(1024) - .HasColumnType("varchar(1024)"); + .HasColumnType("nvarchar(1024)"); b.Property("Bio") .HasMaxLength(2048) - .HasColumnType("varchar(2048)"); + .HasColumnType("nvarchar(2048)"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasMaxLength(64) - .HasColumnType("varchar(64)"); + .HasColumnType("nvarchar(64)"); b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)") - .HasColumnOrder(0); + .HasColumnType("datetime2") + .HasColumnOrder(0) + .HasDefaultValueSql("getdate()"); b.Property("Email") .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("EmailConfirmed") - .HasColumnType("tinyint(1)"); + .HasColumnType("bit"); b.Property("Gender") .HasMaxLength(32) - .HasColumnType("varchar(32)"); + .HasColumnType("nvarchar(32)"); b.Property("LockoutEnabled") - .HasColumnType("tinyint(1)"); + .HasColumnType("bit"); b.Property("LockoutEnd") - .HasColumnType("datetime(6)"); + .HasColumnType("datetimeoffset"); b.Property("NickName") .IsRequired() .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("NormalizedEmail") .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("NormalizedUserName") .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("PasswordHash") .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("PhoneNumber") .HasMaxLength(32) - .HasColumnType("varchar(32)"); + .HasColumnType("nvarchar(32)"); b.Property("PhoneNumberConfirmed") - .HasColumnType("tinyint(1)"); + .HasColumnType("bit"); b.Property("SecurityStamp") .HasMaxLength(32) - .HasColumnType("varchar(32)"); + .HasColumnType("nvarchar(32)"); b.Property("State") .HasColumnType("int"); b.Property("TwoFactorEnabled") - .HasColumnType("tinyint(1)"); + .HasColumnType("bit"); b.Property("Type") .HasColumnType("int"); + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime2") + .HasColumnOrder(1); + b.Property("UserName") .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.HasKey("Id"); @@ -114,7 +123,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasIndex("NormalizedUserName") .IsUnique() - .HasDatabaseName("UserNameIndex"); + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); b.ToTable("User", (string)null); }); @@ -125,19 +135,22 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); b.Property("PostId") .HasColumnType("int"); b.Property("Success") - .HasColumnType("tinyint(1)"); + .HasColumnType("bit"); b.Property("UpdatedAt") .ValueGeneratedOnAddOrUpdate() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2"); b.HasKey("Id"); @@ -152,30 +165,33 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("Country") .HasMaxLength(120) - .HasColumnType("varchar(120)"); + .HasColumnType("nvarchar(120)"); b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); b.Property("Email") .IsRequired() .HasMaxLength(160) - .HasColumnType("varchar(160)"); + .HasColumnType("nvarchar(160)"); b.Property("Ip") .HasMaxLength(80) - .HasColumnType("varchar(80)"); + .HasColumnType("nvarchar(80)"); b.Property("Region") .HasMaxLength(120) - .HasColumnType("varchar(120)"); + .HasColumnType("nvarchar(120)"); b.Property("UpdatedAt") .ValueGeneratedOnAddOrUpdate() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2"); b.HasKey("Id"); @@ -188,22 +204,25 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); b.Property("Key") .IsRequired() .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("UpdatedAt") .ValueGeneratedOnAddOrUpdate() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2"); b.Property("Value") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("nvarchar(max)"); b.HasKey("Id"); @@ -219,18 +238,21 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("Content") .IsRequired() .HasMaxLength(120) - .HasColumnType("varchar(120)"); + .HasColumnType("nvarchar(120)"); b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); b.Property("Description") .HasMaxLength(255) - .HasColumnType("varchar(255)"); + .HasColumnType("nvarchar(255)"); b.HasKey("Id"); @@ -243,33 +265,36 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("Content") .IsRequired() - .HasColumnType("longtext"); + .HasColumnType("nvarchar(max)"); b.Property("Cover") .HasMaxLength(160) - .HasColumnType("varchar(160)"); + .HasColumnType("nvarchar(160)"); b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); b.Property("Description") .IsRequired() .HasMaxLength(450) - .HasColumnType("varchar(450)"); + .HasColumnType("nvarchar(450)"); b.Property("PostType") .HasColumnType("int"); b.Property("PublishedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2"); b.Property("Slug") .IsRequired() .HasMaxLength(160) - .HasColumnType("varchar(160)"); + .HasColumnType("nvarchar(160)"); b.Property("State") .HasColumnType("int"); @@ -277,25 +302,28 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Title") .IsRequired() .HasMaxLength(160) - .HasColumnType("varchar(160)"); + .HasColumnType("nvarchar(160)"); b.Property("UpdatedAt") .ValueGeneratedOnAddOrUpdate() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2"); b.Property("UserId") .IsRequired() .HasMaxLength(128) - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.Property("Views") .HasColumnType("int"); b.HasKey("Id"); + b.HasIndex("Slug") + .IsUnique(); + b.HasIndex("UserId"); - b.ToTable("Posts"); + b.ToTable("Post", (string)null); }); modelBuilder.Entity("Blogifier.Shared.PostCategory", b => @@ -313,29 +341,29 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("PostCategories", (string)null); }); - modelBuilder.Entity("Blogifier.Shared.Storage", b => + modelBuilder.Entity("Blogifier.Storages.Storage", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("AuthorId") - .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ContentType") .IsRequired() .HasMaxLength(128) - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.Property("CreatedAt") .ValueGeneratedOnAdd() - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); b.Property("DeletedAt") - .HasColumnType("datetime(6)"); + .HasColumnType("datetime2"); b.Property("IsDeleted") - .HasColumnType("tinyint(1)"); + .HasColumnType("bit"); b.Property("Length") .HasColumnType("bigint"); @@ -343,18 +371,29 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Name") .IsRequired() .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("Path") .IsRequired() .HasMaxLength(2048) - .HasColumnType("varchar(2048)"); + .HasColumnType("nvarchar(2048)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); - b.Property("StorageType") + b.Property("Type") .HasColumnType("int"); + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(128)"); + b.HasKey("Id"); + b.HasIndex("UserId"); + b.ToTable("Storages"); }); @@ -364,17 +403,19 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("ClaimType") .HasMaxLength(16) - .HasColumnType("varchar(16)"); + .HasColumnType("nvarchar(16)"); b.Property("ClaimValue") .HasMaxLength(256) - .HasColumnType("varchar(256)"); + .HasColumnType("nvarchar(256)"); b.Property("UserId") .IsRequired() - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.HasKey("Id"); @@ -386,18 +427,18 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") - .HasColumnType("varchar(255)"); + .HasColumnType("nvarchar(450)"); b.Property("ProviderKey") - .HasColumnType("varchar(255)"); + .HasColumnType("nvarchar(450)"); b.Property("ProviderDisplayName") .HasMaxLength(128) - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.Property("UserId") .IsRequired() - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.HasKey("LoginProvider", "ProviderKey"); @@ -409,17 +450,17 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId") - .HasColumnType("varchar(128)"); + .HasColumnType("nvarchar(128)"); b.Property("LoginProvider") - .HasColumnType("varchar(255)"); + .HasColumnType("nvarchar(450)"); b.Property("Name") - .HasColumnType("varchar(255)"); + .HasColumnType("nvarchar(450)"); b.Property("Value") .HasMaxLength(1024) - .HasColumnType("varchar(1024)"); + .HasColumnType("nvarchar(1024)"); b.HasKey("UserId", "LoginProvider", "Name"); @@ -467,6 +508,17 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("Post"); }); + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("Blogifier.Identity.UserInfo", null) diff --git a/src/Blogifier/Data/Migrations/SqlServer/20230608091513_Init.cs b/src/Blogifier/Data/Migrations/SqlServer/20230608091513_Init.cs new file mode 100644 index 000000000..4d51c4771 --- /dev/null +++ b/src/Blogifier/Data/Migrations/SqlServer/20230608091513_Init.cs @@ -0,0 +1,353 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Blogifier.Data.Migrations.SqlServer +{ + /// + public partial class Init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Categories", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + Content = table.Column(type: "nvarchar(120)", maxLength: 120, nullable: false), + Description = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Categories", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Options", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + Key = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Options", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Subscribers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + Email = table.Column(type: "nvarchar(160)", maxLength: 160, nullable: false), + Ip = table.Column(type: "nvarchar(80)", maxLength: 80, nullable: true), + Country = table.Column(type: "nvarchar(120)", maxLength: 120, nullable: true), + Region = table.Column(type: "nvarchar(120)", maxLength: 120, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Subscribers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "User", + columns: table => new + { + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + Id = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + NickName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Avatar = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + Bio = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: true), + Gender = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + Type = table.Column(type: "int", nullable: false), + State = table.Column(type: "int", nullable: false), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false), + PasswordHash = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SecurityStamp = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + PhoneNumber = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), + TwoFactorEnabled = table.Column(type: "bit", nullable: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + LockoutEnabled = table.Column(type: "bit", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_User", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Post", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + UserId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Title = table.Column(type: "nvarchar(160)", maxLength: 160, nullable: false), + Slug = table.Column(type: "nvarchar(160)", maxLength: 160, nullable: false), + Description = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), + Content = table.Column(type: "nvarchar(max)", nullable: false), + Cover = table.Column(type: "nvarchar(160)", maxLength: 160, nullable: true), + Views = table.Column(type: "int", nullable: false), + PublishedAt = table.Column(type: "datetime2", nullable: true), + PostType = table.Column(type: "int", nullable: false), + State = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Post", x => x.Id); + table.ForeignKey( + name: "FK_Post_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Storages", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "nvarchar(128)", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + IsDeleted = table.Column(type: "bit", nullable: false), + DeletedAt = table.Column(type: "datetime2", nullable: true), + Slug = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Path = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: false), + Length = table.Column(type: "bigint", nullable: false), + ContentType = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Type = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Storages", x => x.Id); + table.ForeignKey( + name: "FK_Storages_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaim", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "nvarchar(128)", nullable: false), + ClaimType = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true), + ClaimValue = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaim", x => x.Id); + table.ForeignKey( + name: "FK_UserClaim_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogin", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + UserId = table.Column(type: "nvarchar(128)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogin_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserToken", + columns: table => new + { + UserId = table.Column(type: "nvarchar(128)", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserToken_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Newsletters", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedAt = table.Column(type: "datetime2", nullable: false, defaultValueSql: "getdate()"), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + PostId = table.Column(type: "int", nullable: false), + Success = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Newsletters", x => x.Id); + table.ForeignKey( + name: "FK_Newsletters_Post_PostId", + column: x => x.PostId, + principalTable: "Post", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PostCategories", + columns: table => new + { + PostId = table.Column(type: "int", nullable: false), + CategoryId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PostCategories", x => new { x.PostId, x.CategoryId }); + table.ForeignKey( + name: "FK_PostCategories_Categories_CategoryId", + column: x => x.CategoryId, + principalTable: "Categories", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PostCategories_Post_PostId", + column: x => x.PostId, + principalTable: "Post", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Newsletters_PostId", + table: "Newsletters", + column: "PostId"); + + migrationBuilder.CreateIndex( + name: "IX_Options_Key", + table: "Options", + column: "Key", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_Slug", + table: "Post", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_UserId", + table: "Post", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_PostCategories_CategoryId", + table: "PostCategories", + column: "CategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_Storages_UserId", + table: "Storages", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "User", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "User", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_UserClaim_UserId", + table: "UserClaim", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogin_UserId", + table: "UserLogin", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Newsletters"); + + migrationBuilder.DropTable( + name: "Options"); + + migrationBuilder.DropTable( + name: "PostCategories"); + + migrationBuilder.DropTable( + name: "Storages"); + + migrationBuilder.DropTable( + name: "Subscribers"); + + migrationBuilder.DropTable( + name: "UserClaim"); + + migrationBuilder.DropTable( + name: "UserLogin"); + + migrationBuilder.DropTable( + name: "UserToken"); + + migrationBuilder.DropTable( + name: "Categories"); + + migrationBuilder.DropTable( + name: "Post"); + + migrationBuilder.DropTable( + name: "User"); + } + } +} diff --git a/src/Blogifier/Data/Migrations/SqlServer/SqlServerDbContextModelSnapshot.cs b/src/Blogifier/Data/Migrations/SqlServer/SqlServerDbContextModelSnapshot.cs new file mode 100644 index 000000000..3232e3c51 --- /dev/null +++ b/src/Blogifier/Data/Migrations/SqlServer/SqlServerDbContextModelSnapshot.cs @@ -0,0 +1,558 @@ +// +using System; +using Blogifier.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Blogifier.Data.Migrations.SqlServer +{ + [DbContext(typeof(SqlServerDbContext))] + partial class SqlServerDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Blogifier.Identity.UserInfo", b => + { + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Avatar") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Bio") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasColumnOrder(0) + .HasDefaultValueSql("getdate()"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("Gender") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NickName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PhoneNumber") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("State") + .HasColumnType("int"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime2") + .HasColumnOrder(1); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("User", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); + + b.Property("PostId") + .HasColumnType("int"); + + b.Property("Success") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("Newsletters"); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Subscriber", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Country") + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("nvarchar(160)"); + + b.Property("Ip") + .HasMaxLength(80) + .HasColumnType("nvarchar(80)"); + + b.Property("Region") + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Subscribers"); + }); + + modelBuilder.Entity("Blogifier.Options.OptionInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime2"); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("Options", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Cover") + .HasMaxLength(160) + .HasColumnType("nvarchar(160)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("nvarchar(450)"); + + b.Property("PostType") + .HasColumnType("int"); + + b.Property("PublishedAt") + .HasColumnType("datetime2"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("nvarchar(160)"); + + b.Property("State") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("nvarchar(160)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("datetime2"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Views") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("Post", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.Property("PostId") + .HasColumnType("int"); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.HasKey("PostId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.ToTable("PostCategories", (string)null); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2") + .HasDefaultValueSql("getdate()"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Length") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Storages"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)"); + + b.Property("ClaimValue") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaim", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(128)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogin", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(128)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserToken", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.HasOne("Blogifier.Shared.Category", "Category") + .WithMany("PostCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany("PostCategories") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Navigation("PostCategories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Navigation("PostCategories"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Blogifier/Data/Migrations/Sqlite/20230608090804_Init.Designer.cs b/src/Blogifier/Data/Migrations/Sqlite/20230608090804_Init.Designer.cs new file mode 100644 index 000000000..97ac98e4c --- /dev/null +++ b/src/Blogifier/Data/Migrations/Sqlite/20230608090804_Init.Designer.cs @@ -0,0 +1,536 @@ +// +using System; +using Blogifier.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Blogifier.Data.Migrations.Sqlite +{ + [DbContext(typeof(SqliteDbContext))] + [Migration("20230608090804_Init")] + partial class Init + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.5"); + + modelBuilder.Entity("Blogifier.Identity.UserInfo", b => + { + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasMaxLength(1024) + .HasColumnType("TEXT"); + + b.Property("Bio") + .HasMaxLength(2048) + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(64) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnOrder(0) + .HasDefaultValueSql("datetime()"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NickName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT") + .HasColumnOrder(1); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("User", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("Success") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("Newsletters"); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Subscriber", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Country") + .HasMaxLength(120) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("Ip") + .HasMaxLength(80) + .HasColumnType("TEXT"); + + b.Property("Region") + .HasMaxLength(120) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Subscribers"); + }); + + modelBuilder.Entity("Blogifier.Options.OptionInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("Options", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Cover") + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("TEXT"); + + b.Property("PostType") + .HasColumnType("INTEGER"); + + b.Property("PublishedAt") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Views") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("Post", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.HasKey("PostId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.ToTable("PostCategories", (string)null); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("Length") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Storages"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasMaxLength(16) + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaim", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogin", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasMaxLength(1024) + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserToken", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.HasOne("Blogifier.Shared.Category", "Category") + .WithMany("PostCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany("PostCategories") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Navigation("PostCategories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Navigation("PostCategories"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Blogifier/Data/Migrations/Sqlite/20230608090804_Init.cs b/src/Blogifier/Data/Migrations/Sqlite/20230608090804_Init.cs new file mode 100644 index 000000000..57d66c929 --- /dev/null +++ b/src/Blogifier/Data/Migrations/Sqlite/20230608090804_Init.cs @@ -0,0 +1,352 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Blogifier.Data.Migrations.Sqlite +{ + /// + public partial class Init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Categories", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + Content = table.Column(type: "TEXT", maxLength: 120, nullable: false), + Description = table.Column(type: "TEXT", maxLength: 255, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Categories", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Options", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + UpdatedAt = table.Column(type: "TEXT", nullable: false), + Key = table.Column(type: "TEXT", maxLength: 256, nullable: false), + Value = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Options", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Subscribers", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + UpdatedAt = table.Column(type: "TEXT", nullable: false), + Email = table.Column(type: "TEXT", maxLength: 160, nullable: false), + Ip = table.Column(type: "TEXT", maxLength: 80, nullable: true), + Country = table.Column(type: "TEXT", maxLength: 120, nullable: true), + Region = table.Column(type: "TEXT", maxLength: 120, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Subscribers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "User", + columns: table => new + { + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + UpdatedAt = table.Column(type: "TEXT", nullable: false), + Id = table.Column(type: "TEXT", maxLength: 128, nullable: false), + NickName = table.Column(type: "TEXT", maxLength: 256, nullable: false), + Avatar = table.Column(type: "TEXT", maxLength: 1024, nullable: true), + Bio = table.Column(type: "TEXT", maxLength: 2048, nullable: true), + Gender = table.Column(type: "TEXT", maxLength: 32, nullable: true), + Type = table.Column(type: "INTEGER", nullable: false), + State = table.Column(type: "INTEGER", nullable: false), + UserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + Email = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "TEXT", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "INTEGER", nullable: false), + PasswordHash = table.Column(type: "TEXT", maxLength: 256, nullable: true), + SecurityStamp = table.Column(type: "TEXT", maxLength: 32, nullable: true), + ConcurrencyStamp = table.Column(type: "TEXT", maxLength: 64, nullable: true), + PhoneNumber = table.Column(type: "TEXT", maxLength: 32, nullable: true), + PhoneNumberConfirmed = table.Column(type: "INTEGER", nullable: false), + TwoFactorEnabled = table.Column(type: "INTEGER", nullable: false), + LockoutEnd = table.Column(type: "TEXT", nullable: true), + LockoutEnabled = table.Column(type: "INTEGER", nullable: false), + AccessFailedCount = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_User", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Post", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + UpdatedAt = table.Column(type: "TEXT", nullable: false), + UserId = table.Column(type: "TEXT", maxLength: 128, nullable: false), + Title = table.Column(type: "TEXT", maxLength: 160, nullable: false), + Slug = table.Column(type: "TEXT", maxLength: 160, nullable: false), + Description = table.Column(type: "TEXT", maxLength: 450, nullable: false), + Content = table.Column(type: "TEXT", nullable: false), + Cover = table.Column(type: "TEXT", maxLength: 160, nullable: true), + Views = table.Column(type: "INTEGER", nullable: false), + PublishedAt = table.Column(type: "TEXT", nullable: true), + PostType = table.Column(type: "INTEGER", nullable: false), + State = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Post", x => x.Id); + table.ForeignKey( + name: "FK_Post_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Storages", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "TEXT", nullable: false), + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + IsDeleted = table.Column(type: "INTEGER", nullable: false), + DeletedAt = table.Column(type: "TEXT", nullable: true), + Slug = table.Column(type: "TEXT", maxLength: 2048, nullable: false), + Name = table.Column(type: "TEXT", maxLength: 256, nullable: false), + Path = table.Column(type: "TEXT", maxLength: 2048, nullable: false), + Length = table.Column(type: "INTEGER", nullable: false), + ContentType = table.Column(type: "TEXT", maxLength: 128, nullable: false), + Type = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Storages", x => x.Id); + table.ForeignKey( + name: "FK_Storages_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaim", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "TEXT", nullable: false), + ClaimType = table.Column(type: "TEXT", maxLength: 16, nullable: true), + ClaimValue = table.Column(type: "TEXT", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaim", x => x.Id); + table.ForeignKey( + name: "FK_UserClaim_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogin", + columns: table => new + { + LoginProvider = table.Column(type: "TEXT", nullable: false), + ProviderKey = table.Column(type: "TEXT", nullable: false), + ProviderDisplayName = table.Column(type: "TEXT", maxLength: 128, nullable: true), + UserId = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogin_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserToken", + columns: table => new + { + UserId = table.Column(type: "TEXT", nullable: false), + LoginProvider = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", nullable: false), + Value = table.Column(type: "TEXT", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserToken_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Newsletters", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedAt = table.Column(type: "TEXT", nullable: false, defaultValueSql: "datetime()"), + UpdatedAt = table.Column(type: "TEXT", nullable: false), + PostId = table.Column(type: "INTEGER", nullable: false), + Success = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Newsletters", x => x.Id); + table.ForeignKey( + name: "FK_Newsletters_Post_PostId", + column: x => x.PostId, + principalTable: "Post", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PostCategories", + columns: table => new + { + PostId = table.Column(type: "INTEGER", nullable: false), + CategoryId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PostCategories", x => new { x.PostId, x.CategoryId }); + table.ForeignKey( + name: "FK_PostCategories_Categories_CategoryId", + column: x => x.CategoryId, + principalTable: "Categories", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PostCategories_Post_PostId", + column: x => x.PostId, + principalTable: "Post", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Newsletters_PostId", + table: "Newsletters", + column: "PostId"); + + migrationBuilder.CreateIndex( + name: "IX_Options_Key", + table: "Options", + column: "Key", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_Slug", + table: "Post", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Post_UserId", + table: "Post", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_PostCategories_CategoryId", + table: "PostCategories", + column: "CategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_Storages_UserId", + table: "Storages", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "User", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "User", + column: "NormalizedUserName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_UserClaim_UserId", + table: "UserClaim", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogin_UserId", + table: "UserLogin", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Newsletters"); + + migrationBuilder.DropTable( + name: "Options"); + + migrationBuilder.DropTable( + name: "PostCategories"); + + migrationBuilder.DropTable( + name: "Storages"); + + migrationBuilder.DropTable( + name: "Subscribers"); + + migrationBuilder.DropTable( + name: "UserClaim"); + + migrationBuilder.DropTable( + name: "UserLogin"); + + migrationBuilder.DropTable( + name: "UserToken"); + + migrationBuilder.DropTable( + name: "Categories"); + + migrationBuilder.DropTable( + name: "Post"); + + migrationBuilder.DropTable( + name: "User"); + } + } +} diff --git a/src/Blogifier/Data/Migrations/Sqlite/SqliteDbContextModelSnapshot.cs b/src/Blogifier/Data/Migrations/Sqlite/SqliteDbContextModelSnapshot.cs new file mode 100644 index 000000000..7e1f4c644 --- /dev/null +++ b/src/Blogifier/Data/Migrations/Sqlite/SqliteDbContextModelSnapshot.cs @@ -0,0 +1,533 @@ +// +using System; +using Blogifier.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Blogifier.Data.Migrations.Sqlite +{ + [DbContext(typeof(SqliteDbContext))] + partial class SqliteDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.5"); + + modelBuilder.Entity("Blogifier.Identity.UserInfo", b => + { + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasMaxLength(1024) + .HasColumnType("TEXT"); + + b.Property("Bio") + .HasMaxLength(2048) + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(64) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasColumnOrder(0) + .HasDefaultValueSql("datetime()"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("Gender") + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NickName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasMaxLength(32) + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT") + .HasColumnOrder(1); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("User", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("Success") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.ToTable("Newsletters"); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Subscriber", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Country") + .HasMaxLength(120) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("Ip") + .HasMaxLength(80) + .HasColumnType("TEXT"); + + b.Property("Region") + .HasMaxLength(120) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Subscribers"); + }); + + modelBuilder.Entity("Blogifier.Options.OptionInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("Options", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Cover") + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("TEXT"); + + b.Property("PostType") + .HasColumnType("INTEGER"); + + b.Property("PublishedAt") + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(160) + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Views") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("Post", (string)null); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.HasKey("PostId", "CategoryId"); + + b.HasIndex("CategoryId"); + + b.ToTable("PostCategories", (string)null); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValueSql("datetime()"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("Length") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Storages"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasMaxLength(16) + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaim", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogin", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasMaxLength(1024) + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserToken", (string)null); + }); + + modelBuilder.Entity("Blogifier.Newsletters.Newsletter", b => + { + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany() + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blogifier.Shared.PostCategory", b => + { + b.HasOne("Blogifier.Shared.Category", "Category") + .WithMany("PostCategories") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blogifier.Shared.Post", "Post") + .WithMany("PostCategories") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Post"); + }); + + modelBuilder.Entity("Blogifier.Storages.Storage", b => + { + b.HasOne("Blogifier.Identity.UserInfo", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Blogifier.Identity.UserInfo", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Blogifier.Shared.Category", b => + { + b.Navigation("PostCategories"); + }); + + modelBuilder.Entity("Blogifier.Shared.Post", b => + { + b.Navigation("PostCategories"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Blogifier/Data/MySqlDbContext.cs b/src/Blogifier/Data/MySqlDbContext.cs new file mode 100644 index 000000000..380ea230f --- /dev/null +++ b/src/Blogifier/Data/MySqlDbContext.cs @@ -0,0 +1,65 @@ +using Blogifier.Identity; +using Blogifier.Newsletters; +using Blogifier.Options; +using Blogifier.Shared; +using Blogifier.Storages; +using Microsoft.EntityFrameworkCore; + +namespace Blogifier.Data; + +public class MySqlDbContext : AppDbContext +{ + public MySqlDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + e.Property(b => b.UpdatedAt).ValueGeneratedOnAddOrUpdate(); + }); + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + e.Property(b => b.UpdatedAt).ValueGeneratedOnAddOrUpdate(); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + e.Property(b => b.UpdatedAt).ValueGeneratedOnAddOrUpdate(); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + e.Property(b => b.UpdatedAt).ValueGeneratedOnAddOrUpdate(); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + e.Property(b => b.UpdatedAt).ValueGeneratedOnAddOrUpdate(); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + }); + + //modelBuilder.Entity(e => + //{ + // e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + //}); + } +} diff --git a/src/Blogifier/Data/PostgresDbContext.cs b/src/Blogifier/Data/PostgresDbContext.cs new file mode 100644 index 000000000..5cc287860 --- /dev/null +++ b/src/Blogifier/Data/PostgresDbContext.cs @@ -0,0 +1,76 @@ +using Blogifier.Data.ValueGeneration; +using Blogifier.Identity; +using Blogifier.Newsletters; +using Blogifier.Options; +using Blogifier.Shared; +using Blogifier.Storages; +using Microsoft.EntityFrameworkCore; + +namespace Blogifier.Data; + +public class PostgresDbContext : AppDbContext +{ + public PostgresDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + + // https://github.com/dotnet/EntityFramework.Docs/issues/3057 + // https://github.com/dotnet/efcore/issues/19765 + // TOTO No solution has been found + // This configuration is not updated when the entity is updated + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + }); + + //modelBuilder.Entity(e => + //{ + // e.Property(b => b.CreatedAt).HasDefaultValueSql("now()"); + //}); + } +} diff --git a/src/Blogifier/Data/SqlServerDbContext.cs b/src/Blogifier/Data/SqlServerDbContext.cs new file mode 100644 index 000000000..0f983483c --- /dev/null +++ b/src/Blogifier/Data/SqlServerDbContext.cs @@ -0,0 +1,75 @@ +using Blogifier.Data.ValueGeneration; +using Blogifier.Identity; +using Blogifier.Newsletters; +using Blogifier.Options; +using Blogifier.Shared; +using Blogifier.Storages; +using Microsoft.EntityFrameworkCore; + +namespace Blogifier.Data; + +public class SqlServerDbContext : AppDbContext +{ + public SqlServerDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + + // https://github.com/dotnet/EntityFramework.Docs/issues/3057 + // https://github.com/dotnet/efcore/issues/19765 + // TOTO No solution has been found + // This configuration is not updated when the entity is updated + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("getdate()"); + }); + + //modelBuilder.Entity(e => + //{ + // e.Property(b => b.CreatedAt).ValueGeneratedOnAdd(); + //}); + } +} diff --git a/src/Blogifier/Data/SqliteDbContext.cs b/src/Blogifier/Data/SqliteDbContext.cs new file mode 100644 index 000000000..5c2c2365f --- /dev/null +++ b/src/Blogifier/Data/SqliteDbContext.cs @@ -0,0 +1,77 @@ +using Blogifier.Data.ValueGeneration; +using Blogifier.Identity; +using Blogifier.Newsletters; +using Blogifier.Options; +using Blogifier.Shared; +using Blogifier.Storages; +using Microsoft.EntityFrameworkCore; + +namespace Blogifier.Data; + +public class SqliteDbContext : AppDbContext +{ + public SqliteDbContext(DbContextOptions options) : base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + + // https://github.com/dotnet/EntityFramework.Docs/issues/3057 + // https://github.com/dotnet/efcore/issues/19765 + // TOTO No solution has been found + // This configuration is not updated when the entity is updated + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + e.Property(b => b.UpdatedAt) + .HasValueGenerator(typeof(DateTimetValueGenerator)); + }); + + modelBuilder.Entity(e => + { + e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + }); + + //modelBuilder.Entity(e => + //{ + // e.Property(b => b.CreatedAt).HasDefaultValueSql("datetime()"); + //}); + + } +} diff --git a/src/Blogifier/Data/ValueGeneration/UtcDateTimeValueGenerator .cs b/src/Blogifier/Data/ValueGeneration/UtcDateTimeValueGenerator .cs new file mode 100644 index 000000000..8ac0ce84f --- /dev/null +++ b/src/Blogifier/Data/ValueGeneration/UtcDateTimeValueGenerator .cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.ValueGeneration; +using System; +using System.Threading.Tasks; +using System.Threading; + +namespace Blogifier.Data.ValueGeneration; + +public class DateTimetValueGenerator : ValueGenerator +{ + public override bool GeneratesTemporaryValues => false; + + public override DateTime Next(EntityEntry entry) + { + return DateTime.UtcNow; + } + + public override ValueTask NextAsync(EntityEntry entry, CancellationToken cancellationToken = default) + { + return ValueTask.FromResult(DateTime.UtcNow); + } +} diff --git a/src/Blogifier/Identity/UserInfo.cs b/src/Blogifier/Identity/UserInfo.cs index 083533263..de00c0d9e 100644 --- a/src/Blogifier/Identity/UserInfo.cs +++ b/src/Blogifier/Identity/UserInfo.cs @@ -19,8 +19,8 @@ public UserInfo(string userName) : base() UserName = userName; } - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } [StringLength(256)] public string NickName { get; set; } = default!; [StringLength(1024)] diff --git a/src/Blogifier/Newsletters/Newsletter.cs b/src/Blogifier/Newsletters/Newsletter.cs index 6bf25cfa1..c04b4fd27 100644 --- a/src/Blogifier/Newsletters/Newsletter.cs +++ b/src/Blogifier/Newsletters/Newsletter.cs @@ -7,9 +7,7 @@ namespace Blogifier.Newsletters; public class Newsletter : AppEntity { - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } - [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime UpdatedAt { get; set; } public int PostId { get; set; } public bool Success { get; set; } diff --git a/src/Blogifier/Newsletters/Subscriber.cs b/src/Blogifier/Newsletters/Subscriber.cs index 849e10a05..6b8ae5906 100644 --- a/src/Blogifier/Newsletters/Subscriber.cs +++ b/src/Blogifier/Newsletters/Subscriber.cs @@ -7,9 +7,7 @@ namespace Blogifier.Newsletters; public class Subscriber : AppEntity { - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } - [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime UpdatedAt { get; set; } [EmailAddress] [StringLength(160)] diff --git a/src/Blogifier/Options/OptionInfo.cs b/src/Blogifier/Options/OptionInfo.cs index 9b01294f8..03fce7439 100644 --- a/src/Blogifier/Options/OptionInfo.cs +++ b/src/Blogifier/Options/OptionInfo.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; namespace Blogifier.Options; @@ -8,9 +7,7 @@ public class OptionInfo { [Key] public int Id { get; set; } - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } - [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime UpdatedAt { get; set; } [StringLength(256)] public string Key { get; set; } = default!; diff --git a/src/Blogifier/Posts/Category.cs b/src/Blogifier/Posts/Category.cs index 22561545e..8d8cca2c5 100644 --- a/src/Blogifier/Posts/Category.cs +++ b/src/Blogifier/Posts/Category.cs @@ -8,7 +8,6 @@ namespace Blogifier.Shared; public class Category : AppEntity { - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } [StringLength(120)] public string Content { get; set; } = default!; diff --git a/src/Blogifier/Posts/ImportManager.cs b/src/Blogifier/Posts/ImportManager.cs index 19c6c5c26..18a13a82d 100644 --- a/src/Blogifier/Posts/ImportManager.cs +++ b/src/Blogifier/Posts/ImportManager.cs @@ -49,7 +49,7 @@ public async Task> WriteAsync(ImportDto request, stri continue; } - var publishedAt = post.PublishedAt!.Value; + var publishedAt = post.PublishedAt!.Value.ToUniversalTime(); if (post.Cover != null && !post.Cover.Equals(BlogifierConstant.DefaultCover, StringComparison.Ordinal)) { @@ -66,6 +66,7 @@ public async Task> WriteAsync(ImportDto request, stri post.Description = markdownDescription; post.State = PostState.Release; + post.PublishedAt = publishedAt; posts.Add(post); } diff --git a/src/Blogifier/Posts/Post.cs b/src/Blogifier/Posts/Post.cs index ac6560142..2a5c2f658 100644 --- a/src/Blogifier/Posts/Post.cs +++ b/src/Blogifier/Posts/Post.cs @@ -4,15 +4,12 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; namespace Blogifier.Shared; public class Post : AppEntity { - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } - [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime UpdatedAt { get; set; } [StringLength(128)] public string UserId { get; set; } = default!; @@ -34,5 +31,5 @@ public class Post : AppEntity public PostType PostType { get; set; } public PostState State { get; set; } public List? PostCategories { get; set; } - public List? StorageReferences { get; set; } + //public List? StorageReferences { get; set; } } diff --git a/src/Blogifier/Posts/PostProvider.cs b/src/Blogifier/Posts/PostProvider.cs index 9713c24d0..e99f6abce 100644 --- a/src/Blogifier/Posts/PostProvider.cs +++ b/src/Blogifier/Posts/PostProvider.cs @@ -102,7 +102,7 @@ public async Task GetEditorAsync(string slug) .AsNoTracking() .Include(m => m.PostCategories)! .ThenInclude(m => m.Category) - .Include(m => m.StorageReferences!.Where(s => s.Type == StorageReferenceType.Post)) + //.Include(m => m.StorageReferences!.Where(s => s.Type == StorageReferenceType.Post)) .AsSingleQuery() .Where(p => p.Slug == slug); return await _mapper.ProjectTo(query).FirstAsync(); diff --git a/src/Blogifier/Profiles/PostProfile.cs b/src/Blogifier/Profiles/PostProfile.cs index 58bac84da..85dd8b818 100644 --- a/src/Blogifier/Profiles/PostProfile.cs +++ b/src/Blogifier/Profiles/PostProfile.cs @@ -13,9 +13,10 @@ public PostProfile() CreateMap(); CreateMap() .ForMember(d => d.Categories, opt => opt.MapFrom(src => src.PostCategories)) - .ForMember(d => d.Storages, opt => opt.MapFrom(src => src.StorageReferences)) + //.ForMember(d => d.Storages, opt => opt.MapFrom(src => src.StorageReferences)) .ReverseMap() .ForMember(d => d.PostCategories, opt => opt.MapFrom(src => src.Categories)) - .ForMember(d => d.StorageReferences, opt => opt.MapFrom(src => src.Storages)); + //.ForMember(d => d.StorageReferences, opt => opt.MapFrom(src => src.Storages)) + ; } } diff --git a/src/Blogifier/Profiles/StorageProfile.cs b/src/Blogifier/Profiles/StorageProfile.cs index aded18903..51650d06e 100644 --- a/src/Blogifier/Profiles/StorageProfile.cs +++ b/src/Blogifier/Profiles/StorageProfile.cs @@ -9,8 +9,8 @@ public class StorageProfile : Profile public StorageProfile() { CreateMap().ReverseMap(); - CreateMap() - .IncludeMembers(m => m.Storage) - .ReverseMap(); + //CreateMap() + // .IncludeMembers(m => m.Storage) + // .ReverseMap(); } } diff --git a/src/Blogifier/Program.cs b/src/Blogifier/Program.cs index 07a22d1e5..35216ac2a 100644 --- a/src/Blogifier/Program.cs +++ b/src/Blogifier/Program.cs @@ -57,15 +57,30 @@ builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader())); var section = builder.Configuration.GetSection("Blogifier"); -var conn = section.GetValue("ConnString"); -if (section.GetValue("DbProvider") == "SQLite") - builder.Services.AddDbContext(o => o.UseSqlite(conn)); -else if (section.GetValue("DbProvider") == "SqlServer") - builder.Services.AddDbContext(o => o.UseSqlServer(conn)); -else if (section.GetValue("DbProvider") == "Postgres") - builder.Services.AddDbContext(o => o.UseNpgsql(conn)); -else if (section.GetValue("DbProvider") == "MySql") - builder.Services.AddDbContext(o => o.UseMySql(conn, ServerVersion.AutoDetect(conn))); +var provider = section.GetValue("DbProvider"); +var connectionString = section.GetValue("ConnString"); + +if ("Sqlite".Equals(provider, StringComparison.OrdinalIgnoreCase)) +{ + builder.Services.AddDbContext(o => o.UseSqlite(connectionString)); +} +else if ("SqlServer".Equals(provider, StringComparison.OrdinalIgnoreCase)) +{ + builder.Services.AddDbContext(o => o.UseSqlServer(connectionString)); +} +else if ("MySql".Equals(provider, StringComparison.OrdinalIgnoreCase)) +{ + var version = ServerVersion.AutoDetect(connectionString); + builder.Services.AddDbContext(o => o.UseMySql(connectionString, version)); +} +else if ("Postgres".Equals(provider, StringComparison.OrdinalIgnoreCase)) +{ + builder.Services.AddDbContext(o => o.UseNpgsql(connectionString)); +} +else +{ + throw new Exception($"Unsupported provider: {provider}"); +} if (builder.Environment.IsDevelopment()) builder.Services.AddDatabaseDeveloperPageExceptionFilter(); diff --git a/src/Blogifier/Storages/Storage.cs b/src/Blogifier/Storages/Storage.cs index e36f8a76d..2a2412d30 100644 --- a/src/Blogifier/Storages/Storage.cs +++ b/src/Blogifier/Storages/Storage.cs @@ -13,7 +13,6 @@ public class Storage public int Id { get; set; } public string UserId { get; set; } = default!; public UserInfo User { get; set; } = default!; - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedAt { get; set; } public bool IsDeleted { get; set; } public DateTime? DeletedAt { get; set; } @@ -27,5 +26,5 @@ public class Storage [StringLength(128)] public string ContentType { get; set; } = default!; public StorageType Type { get; set; } - public List? StorageReferences { get; set; } + //public List? StorageReferences { get; set; } } diff --git a/src/Blogifier/Storages/StorageReference.cs b/src/Blogifier/Storages/StorageReference.cs index b488fa2e1..8a02d0dcd 100644 --- a/src/Blogifier/Storages/StorageReference.cs +++ b/src/Blogifier/Storages/StorageReference.cs @@ -1,16 +1,20 @@ using Blogifier.Shared; +using Microsoft.Identity.Client.Extensions.Msal; using System; -using System.ComponentModel.DataAnnotations.Schema; - namespace Blogifier.Storages; -public class StorageReference -{ - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public DateTime CreatedAt { get; set; } - public int StorageId { get; set; } - public Storage Storage { get; set; } = default!; - public int EntityId { get; set; } - public StorageReferenceType Type { get; set; } - public Post? Post { get; set; } -} + +// TOTO In the sql server implementation, +// it is found that there may be problems in the design of StorageReference table, +// and the storage reference function is not implemented for the time being, so it is commented out + + +//public class StorageReference +//{ +// public DateTime CreatedAt { get; set; } +// public int StorageId { get; set; } +// public Storage Storage { get; set; } = default!; +// public int EntityId { get; set; } +// public StorageReferenceType Type { get; set; } +// public Post? Post { get; set; } +//} diff --git a/src/Blogifier/appsettings.json b/src/Blogifier/appsettings.json index 6428eb5c2..39348e465 100644 --- a/src/Blogifier/appsettings.json +++ b/src/Blogifier/appsettings.json @@ -1,8 +1,8 @@ { "Blogifier": { - "DbProvider": "MySql", - "ConnString": "server=mysql;user=root;password=root;database=blogifier;", + "DbProvider": "Sqlite", + "ConnString": "Data Source=App_Data/blogifier.db", //"Redis": "redis:6379,password=root,defaultDatabase=0", "Salt": "SECRET-CHANGE-ME!", "DemoMode": false, diff --git a/testEnvironments.json b/testEnvironments.json deleted file mode 100644 index 2c5e92936..000000000 --- a/testEnvironments.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "1", - "environments": [ - // 请参阅 https://aka.ms/remotetesting 获取更多信息 - // 了解如何配置远程环境。 - //{ - // "name": "WSL Ubuntu", - // "type": "wsl", - // "wslDistribution": "Ubuntu" - //}, - //{ - // "name": "Docker dotnet/sdk", - // "type": "docker", - // "dockerImage": "mcr.microsoft.com/dotnet/sdk" - //} - ] -} \ No newline at end of file