From 57b29adef10dcefcacf255df05cf6bc11512caf2 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 5 Mar 2020 23:02:22 +0800 Subject: Implement data manager. --- Timeline/Entities/DatabaseContext.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'Timeline/Entities/DatabaseContext.cs') diff --git a/Timeline/Entities/DatabaseContext.cs b/Timeline/Entities/DatabaseContext.cs index 039cbd51..3ed61b71 100644 --- a/Timeline/Entities/DatabaseContext.cs +++ b/Timeline/Entities/DatabaseContext.cs @@ -21,5 +21,6 @@ namespace Timeline.Entities public DbSet TimelinePosts { get; set; } = default!; public DbSet TimelineMembers { get; set; } = default!; public DbSet JwtToken { get; set; } = default!; + public DbSet Data { get; set; } = default!; } } -- cgit v1.2.3 From cc57bddf48fee422850c8b458ac9a22ba0bfaa64 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 6 Mar 2020 19:16:58 +0800 Subject: Migrate database. --- Timeline/Entities/DatabaseContext.cs | 1 + .../20200306110049_AddDataTable.Designer.cs | 290 +++++++++++++++++++++ Timeline/Migrations/20200306110049_AddDataTable.cs | 87 +++++++ .../20200306111553_DropUserDetails.Designer.cs | 290 +++++++++++++++++++++ .../Migrations/20200306111553_DropUserDetails.cs | 17 ++ .../Migrations/DatabaseContextModelSnapshot.cs | 37 ++- Timeline/Timeline.csproj | 4 + 7 files changed, 720 insertions(+), 6 deletions(-) create mode 100644 Timeline/Migrations/20200306110049_AddDataTable.Designer.cs create mode 100644 Timeline/Migrations/20200306110049_AddDataTable.cs create mode 100644 Timeline/Migrations/20200306111553_DropUserDetails.Designer.cs create mode 100644 Timeline/Migrations/20200306111553_DropUserDetails.cs (limited to 'Timeline/Entities/DatabaseContext.cs') diff --git a/Timeline/Entities/DatabaseContext.cs b/Timeline/Entities/DatabaseContext.cs index 3ed61b71..8899308c 100644 --- a/Timeline/Entities/DatabaseContext.cs +++ b/Timeline/Entities/DatabaseContext.cs @@ -13,6 +13,7 @@ namespace Timeline.Entities { modelBuilder.Entity().Property(e => e.Version).HasDefaultValue(0); modelBuilder.Entity().HasIndex(e => e.Username).IsUnique(); + modelBuilder.Entity().HasIndex(e => e.Tag).IsUnique(); } public DbSet Users { get; set; } = default!; diff --git a/Timeline/Migrations/20200306110049_AddDataTable.Designer.cs b/Timeline/Migrations/20200306110049_AddDataTable.Designer.cs new file mode 100644 index 00000000..336ffc18 --- /dev/null +++ b/Timeline/Migrations/20200306110049_AddDataTable.Designer.cs @@ -0,0 +1,290 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Timeline.Entities; + +namespace Timeline.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20200306110049_AddDataTable")] + partial class AddDataTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Timeline.Entities.DataEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Data") + .IsRequired() + .HasColumnName("data") + .HasColumnType("BLOB"); + + b.Property("Ref") + .HasColumnName("ref") + .HasColumnType("INTEGER"); + + b.Property("Tag") + .IsRequired() + .HasColumnName("tag") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Tag") + .IsUnique(); + + b.ToTable("data"); + }); + + modelBuilder.Entity("Timeline.Entities.JwtTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnName("key") + .HasColumnType("BLOB"); + + b.HasKey("Id"); + + b.ToTable("jwt_token"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("CreateTime") + .HasColumnName("create_time") + .HasColumnType("TEXT"); + + b.Property("CurrentPostLocalId") + .HasColumnName("current_post_local_id") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnName("description") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnName("name") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnName("owner") + .HasColumnType("INTEGER"); + + b.Property("Visibility") + .HasColumnName("visibility") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("timelines"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("TimelineId") + .HasColumnName("timeline") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnName("user") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("TimelineId"); + + b.HasIndex("UserId"); + + b.ToTable("timeline_members"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnName("author") + .HasColumnType("INTEGER"); + + b.Property("Content") + .HasColumnName("content") + .HasColumnType("TEXT"); + + b.Property("LastUpdated") + .HasColumnName("last_updated") + .HasColumnType("TEXT"); + + b.Property("LocalId") + .HasColumnName("local_id") + .HasColumnType("INTEGER"); + + b.Property("Time") + .HasColumnName("time") + .HasColumnType("TEXT"); + + b.Property("TimelineId") + .HasColumnName("timeline") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("TimelineId"); + + b.ToTable("timeline_posts"); + }); + + modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("DataTag") + .HasColumnName("data_tag") + .HasColumnType("TEXT"); + + b.Property("LastModified") + .HasColumnName("last_modified") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnName("type") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnName("user") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("user_avatars"); + }); + + modelBuilder.Entity("Timeline.Entities.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Nickname") + .HasColumnName("nickname") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnName("password") + .HasColumnType("TEXT"); + + b.Property("Roles") + .IsRequired() + .HasColumnName("roles") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnName("username") + .HasColumnType("TEXT"); + + b.Property("Version") + .ValueGeneratedOnAdd() + .HasColumnName("version") + .HasColumnType("INTEGER") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Owner") + .WithMany("Timelines") + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany("Members") + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany("TimelinesJoined") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Author") + .WithMany("TimelinePosts") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany("Posts") + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithOne("Avatar") + .HasForeignKey("Timeline.Entities.UserAvatarEntity", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Timeline/Migrations/20200306110049_AddDataTable.cs b/Timeline/Migrations/20200306110049_AddDataTable.cs new file mode 100644 index 00000000..e33bf4c9 --- /dev/null +++ b/Timeline/Migrations/20200306110049_AddDataTable.cs @@ -0,0 +1,87 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Timeline.Migrations +{ + public partial class AddDataTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "data", + columns: table => new + { + id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + tag = table.Column(nullable: false), + data = table.Column(nullable: false), + @ref = table.Column(name: "ref", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_data", x => x.id); + }); + + migrationBuilder.CreateIndex( + name: "IX_data_tag", + table: "data", + column: "tag", + unique: true); + + migrationBuilder.Sql(@" +ALTER TABLE user_avatars + RENAME TO user_avatars_backup; + +CREATE TABLE user_avatars ( + id INTEGER NOT NULL + CONSTRAINT PK_user_avatars PRIMARY KEY AUTOINCREMENT, + data_tag TEXT, + type TEXT, + last_modified TEXT NOT NULL, + user INTEGER NOT NULL, + CONSTRAINT FK_user_avatars_users_user FOREIGN KEY ( + user + ) + REFERENCES users (id) ON DELETE CASCADE +); + +INSERT INTO user_avatars (id, data_tag, type, last_modified, user) + SELECT id, etag, type, last_modified, user FROM user_avatars_backup; + +INSERT OR IGNORE INTO data (tag, data, ref) + SELECT etag, data, 0 FROM user_avatars_backup; + +UPDATE data +SET ref = (SELECT COUNT (*) + FROM user_avatars_backup AS a + WHERE a.etag == data.tag); + +DROP TABLE user_avatars_backup; + +CREATE UNIQUE INDEX IX_user_avatars_user ON user_avatars (user); + "); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "data"); + + migrationBuilder.DropColumn( + name: "data_tag", + table: "user_avatars"); + + migrationBuilder.AddColumn( + name: "data", + table: "user_avatars", + type: "BLOB", + nullable: true); + + migrationBuilder.AddColumn( + name: "etag", + table: "user_avatars", + type: "TEXT", + nullable: true); + } + } +} diff --git a/Timeline/Migrations/20200306111553_DropUserDetails.Designer.cs b/Timeline/Migrations/20200306111553_DropUserDetails.Designer.cs new file mode 100644 index 00000000..f0c4dc08 --- /dev/null +++ b/Timeline/Migrations/20200306111553_DropUserDetails.Designer.cs @@ -0,0 +1,290 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Timeline.Entities; + +namespace Timeline.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20200306111553_DropUserDetails")] + partial class DropUserDetails + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Timeline.Entities.DataEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Data") + .IsRequired() + .HasColumnName("data") + .HasColumnType("BLOB"); + + b.Property("Ref") + .HasColumnName("ref") + .HasColumnType("INTEGER"); + + b.Property("Tag") + .IsRequired() + .HasColumnName("tag") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Tag") + .IsUnique(); + + b.ToTable("data"); + }); + + modelBuilder.Entity("Timeline.Entities.JwtTokenEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnName("key") + .HasColumnType("BLOB"); + + b.HasKey("Id"); + + b.ToTable("jwt_token"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("CreateTime") + .HasColumnName("create_time") + .HasColumnType("TEXT"); + + b.Property("CurrentPostLocalId") + .HasColumnName("current_post_local_id") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnName("description") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnName("name") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnName("owner") + .HasColumnType("INTEGER"); + + b.Property("Visibility") + .HasColumnName("visibility") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("timelines"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("TimelineId") + .HasColumnName("timeline") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnName("user") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("TimelineId"); + + b.HasIndex("UserId"); + + b.ToTable("timeline_members"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnName("author") + .HasColumnType("INTEGER"); + + b.Property("Content") + .HasColumnName("content") + .HasColumnType("TEXT"); + + b.Property("LastUpdated") + .HasColumnName("last_updated") + .HasColumnType("TEXT"); + + b.Property("LocalId") + .HasColumnName("local_id") + .HasColumnType("INTEGER"); + + b.Property("Time") + .HasColumnName("time") + .HasColumnType("TEXT"); + + b.Property("TimelineId") + .HasColumnName("timeline") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("TimelineId"); + + b.ToTable("timeline_posts"); + }); + + modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("DataTag") + .HasColumnName("data_tag") + .HasColumnType("TEXT"); + + b.Property("LastModified") + .HasColumnName("last_modified") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnName("type") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnName("user") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("user_avatars"); + }); + + modelBuilder.Entity("Timeline.Entities.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Nickname") + .HasColumnName("nickname") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnName("password") + .HasColumnType("TEXT"); + + b.Property("Roles") + .IsRequired() + .HasColumnName("roles") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnName("username") + .HasColumnType("TEXT"); + + b.Property("Version") + .ValueGeneratedOnAdd() + .HasColumnName("version") + .HasColumnType("INTEGER") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Owner") + .WithMany("Timelines") + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Timeline.Entities.TimelineMemberEntity", b => + { + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany("Members") + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithMany("TimelinesJoined") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Timeline.Entities.TimelinePostEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "Author") + .WithMany("TimelinePosts") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Timeline.Entities.TimelineEntity", "Timeline") + .WithMany("Posts") + .HasForeignKey("TimelineId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Timeline.Entities.UserAvatarEntity", b => + { + b.HasOne("Timeline.Entities.UserEntity", "User") + .WithOne("Avatar") + .HasForeignKey("Timeline.Entities.UserAvatarEntity", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Timeline/Migrations/20200306111553_DropUserDetails.cs b/Timeline/Migrations/20200306111553_DropUserDetails.cs new file mode 100644 index 00000000..0a176461 --- /dev/null +++ b/Timeline/Migrations/20200306111553_DropUserDetails.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Timeline.Migrations +{ + public partial class DropUserDetails : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable(name: "user_details"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Timeline/Migrations/DatabaseContextModelSnapshot.cs b/Timeline/Migrations/DatabaseContextModelSnapshot.cs index c4b00f47..8170b2f0 100644 --- a/Timeline/Migrations/DatabaseContextModelSnapshot.cs +++ b/Timeline/Migrations/DatabaseContextModelSnapshot.cs @@ -16,6 +16,35 @@ namespace Timeline.Migrations modelBuilder .HasAnnotation("ProductVersion", "3.1.2"); + modelBuilder.Entity("Timeline.Entities.DataEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnName("id") + .HasColumnType("INTEGER"); + + b.Property("Data") + .IsRequired() + .HasColumnName("data") + .HasColumnType("BLOB"); + + b.Property("Ref") + .HasColumnName("ref") + .HasColumnType("INTEGER"); + + b.Property("Tag") + .IsRequired() + .HasColumnName("tag") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Tag") + .IsUnique(); + + b.ToTable("data"); + }); + modelBuilder.Entity("Timeline.Entities.JwtTokenEntity", b => { b.Property("Id") @@ -142,12 +171,8 @@ namespace Timeline.Migrations .HasColumnName("id") .HasColumnType("INTEGER"); - b.Property("Data") - .HasColumnName("data") - .HasColumnType("BLOB"); - - b.Property("ETag") - .HasColumnName("etag") + b.Property("DataTag") + .HasColumnName("data_tag") .HasColumnType("TEXT"); b.Property("LastModified") diff --git a/Timeline/Timeline.csproj b/Timeline/Timeline.csproj index 72bc1572..e993c0b3 100644 --- a/Timeline/Timeline.csproj +++ b/Timeline/Timeline.csproj @@ -7,6 +7,10 @@ 8.0 enable + + + + -- cgit v1.2.3