From ccaebbf9fc83a985743a62932ed62244e5b54ab2 Mon Sep 17 00:00:00 2001 From: jvyden Date: Mon, 18 Oct 2021 22:35:23 -0400 Subject: [PATCH] Add EntityFramework code first database migrations --- .config/dotnet-tools.json | 12 + DatabaseMigrations/0.sql | 30 -- DatabaseMigrations/1.sql | 22 -- DatabaseMigrations/2.sql | 37 -- DatabaseMigrations/3.sql | 20 -- DatabaseMigrations/4.sql | 16 - DatabaseMigrations/5.sql | 1 - DatabaseMigrations/6.sql | 1 - DatabaseMigrations/7.sql | 17 - .../20211019021627_InitialCreate.Designer.cs | 324 ++++++++++++++++++ .../20211019021627_InitialCreate.cs | 257 ++++++++++++++ .../Migrations/DatabaseModelSnapshot.cs | 322 +++++++++++++++++ ProjectLighthouse/Program.cs | 12 +- ProjectLighthouse/ProjectLighthouse.csproj | 4 + README.md | 22 +- 15 files changed, 946 insertions(+), 151 deletions(-) create mode 100644 .config/dotnet-tools.json delete mode 100644 DatabaseMigrations/0.sql delete mode 100644 DatabaseMigrations/1.sql delete mode 100644 DatabaseMigrations/2.sql delete mode 100644 DatabaseMigrations/3.sql delete mode 100644 DatabaseMigrations/4.sql delete mode 100644 DatabaseMigrations/5.sql delete mode 100644 DatabaseMigrations/6.sql delete mode 100644 DatabaseMigrations/7.sql create mode 100644 ProjectLighthouse/Migrations/20211019021627_InitialCreate.Designer.cs create mode 100644 ProjectLighthouse/Migrations/20211019021627_InitialCreate.cs create mode 100644 ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 00000000..05959425 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "5.0.11", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/DatabaseMigrations/0.sql b/DatabaseMigrations/0.sql deleted file mode 100644 index 12084b43..00000000 --- a/DatabaseMigrations/0.sql +++ /dev/null @@ -1,30 +0,0 @@ -create table Users -( - UserId int auto_increment, - Username tinytext not null, - IconHash text null, - Game int default 0 not null, - Lists int default 0 not null, - HeartCount int default 0 not null, - YayHash text null, - BooHash text null, - Biography text null, - ReviewCount int default 0 not null, - CommentCount int default 0 not null, - PhotosByMeCount int default 0 not null, - PhotosWithMeCount int default 0 not null, - CommentsEnabled tinyint(1) default 1 not null, - FavouriteSlotCount int default 0 not null, - FavouriteUserCount int default 0 not null, - lolcatftwCount int default 0 not null, - Pins text not null, - StaffChallengeGoldCount int default 0 not null, - StaffChallengeSilverCount int default 0 not null, - StaffChallengeBronzeCount int default 0 not null, - UsedSlots int default 0 not null, - constraint users_user_id_uindex - unique (UserId) -); - -alter table Users - add primary key (UserId); diff --git a/DatabaseMigrations/1.sql b/DatabaseMigrations/1.sql deleted file mode 100644 index 87506f00..00000000 --- a/DatabaseMigrations/1.sql +++ /dev/null @@ -1,22 +0,0 @@ -create table Locations -( - Id int not null, - X int not null, - Y int not null -); - -create unique index Locations_UserId_uindex - on Locations (Id); - -alter table Locations - add constraint Locations_pk - primary key (Id); - -alter table Users - add LocationId int null; - -alter table Locations - modify Id int auto_increment; - - - diff --git a/DatabaseMigrations/2.sql b/DatabaseMigrations/2.sql deleted file mode 100644 index f51f6636..00000000 --- a/DatabaseMigrations/2.sql +++ /dev/null @@ -1,37 +0,0 @@ -create table Slots -( - SlotId int, - CreatorId int not null, - Name text not null, - Description text not null, - IconHash text not null, - RootLevel text not null, - Resource text not null, - LocationId int not null, - InitiallyLocked bool default false not null, - SubLevel bool default false null, - Lbp1Only bool default false not null, - Shareable int default 0 not null, - AuthorLabels text not null, - BackgroundHash text not null, - MinimumPlayers int default 1 not null, - MaximumPlayers int default 4 not null, - MoveRequired bool default false null -); - -create unique index Slots_SlotId_uindex - on Slots (SlotId); - -alter table Slots - add constraint Slots_pk - primary key (SlotId); - -alter table Slots - modify SlotId int auto_increment; - -alter table Slots - alter column CreatorId set default -1; - -alter table Slots - modify CreatorId int not null after LocationId; - diff --git a/DatabaseMigrations/3.sql b/DatabaseMigrations/3.sql deleted file mode 100644 index 6bc4c2eb..00000000 --- a/DatabaseMigrations/3.sql +++ /dev/null @@ -1,20 +0,0 @@ -create table Comments -( - CommentId int, - PosterUserId int not null, - TargetUserId int not null, - Timestamp bigint not null, - ThumbsUp int default 0 not null, - ThumbsDown int default 0 not null, - Message longtext not null -); - -create unique index Comments_CommentId_uindex - on Comments (CommentId); - -alter table Comments - add constraint Comments_pk - primary key (CommentId); - -alter table Comments - modify CommentId int auto_increment; diff --git a/DatabaseMigrations/4.sql b/DatabaseMigrations/4.sql deleted file mode 100644 index 10281a40..00000000 --- a/DatabaseMigrations/4.sql +++ /dev/null @@ -1,16 +0,0 @@ -create table Tokens -( - TokenId int, - UserId int not null, - UserToken text not null -); - -create unique index Tokens_TokenId_uindex - on Tokens (TokenId); - -alter table Tokens - add constraint Tokens_pk - primary key (TokenId); - -alter table Tokens - modify TokenId int auto_increment; diff --git a/DatabaseMigrations/5.sql b/DatabaseMigrations/5.sql deleted file mode 100644 index 6bfe2e7a..00000000 --- a/DatabaseMigrations/5.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE Slots MODIFY AuthorLabels TEXT NULL; diff --git a/DatabaseMigrations/6.sql b/DatabaseMigrations/6.sql deleted file mode 100644 index 7e931ca9..00000000 --- a/DatabaseMigrations/6.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE Users ADD COLUMN PlanetHash text not null; diff --git a/DatabaseMigrations/7.sql b/DatabaseMigrations/7.sql deleted file mode 100644 index ac8e1bc9..00000000 --- a/DatabaseMigrations/7.sql +++ /dev/null @@ -1,17 +0,0 @@ -create table QueuedLevels -( - QueuedLevelId int, - UserId int not null, - SlotId int not null -); - -create unique index QueuedLevels_QueuedLevelId_uindex - on QueuedLevels (QueuedLevelId); - -alter table QueuedLevels - add constraint QueuedLevels_pk - primary key (QueuedLevelId); - -alter table QueuedLevels - modify QueuedLevelId int auto_increment; - diff --git a/ProjectLighthouse/Migrations/20211019021627_InitialCreate.Designer.cs b/ProjectLighthouse/Migrations/20211019021627_InitialCreate.Designer.cs new file mode 100644 index 00000000..1ac8af54 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211019021627_InitialCreate.Designer.cs @@ -0,0 +1,324 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ProjectLighthouse; + +namespace ProjectLighthouse.Migrations +{ + [DbContext(typeof(Database))] + [Migration("20211019021627_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("ProjectLighthouse.Types.Comment", b => + { + b.Property("CommentId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("PosterUserId") + .HasColumnType("int"); + + b.Property("TargetUserId") + .HasColumnType("int"); + + b.Property("ThumbsDown") + .HasColumnType("int"); + + b.Property("ThumbsUp") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("bigint"); + + b.HasKey("CommentId"); + + b.HasIndex("PosterUserId"); + + b.HasIndex("TargetUserId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("int"); + + b.Property("Y") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Locations"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b => + { + b.Property("QueuedLevelId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("QueuedLevelId"); + + b.HasIndex("SlotId"); + + b.HasIndex("UserId"); + + b.ToTable("QueuedLevels"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Slot", b => + { + b.Property("SlotId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuthorLabels") + .HasColumnType("longtext"); + + b.Property("BackgroundHash") + .HasColumnType("longtext"); + + b.Property("CreatorId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IconHash") + .HasColumnType("longtext"); + + b.Property("InitiallyLocked") + .HasColumnType("tinyint(1)"); + + b.Property("Lbp1Only") + .HasColumnType("tinyint(1)"); + + b.Property("LocationId") + .HasColumnType("int"); + + b.Property("MaximumPlayers") + .HasColumnType("int"); + + b.Property("MinimumPlayers") + .HasColumnType("int"); + + b.Property("MoveRequired") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Resource") + .HasColumnType("longtext"); + + b.Property("RootLevel") + .HasColumnType("longtext"); + + b.Property("Shareable") + .HasColumnType("int"); + + b.Property("SubLevel") + .HasColumnType("tinyint(1)"); + + b.HasKey("SlotId"); + + b.HasIndex("CreatorId"); + + b.HasIndex("LocationId"); + + b.ToTable("Slots"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Token", b => + { + b.Property("TokenId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("UserToken") + .HasColumnType("longtext"); + + b.HasKey("TokenId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.User", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Biography") + .HasColumnType("longtext"); + + b.Property("BooHash") + .HasColumnType("longtext"); + + b.Property("CommentCount") + .HasColumnType("int"); + + b.Property("CommentsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("FavouriteSlotCount") + .HasColumnType("int"); + + b.Property("FavouriteUserCount") + .HasColumnType("int"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("HeartCount") + .HasColumnType("int"); + + b.Property("IconHash") + .HasColumnType("longtext"); + + b.Property("Lists") + .HasColumnType("int"); + + b.Property("LocationId") + .HasColumnType("int"); + + b.Property("LolCatFtwCount") + .HasColumnType("int"); + + b.Property("PhotosByMeCount") + .HasColumnType("int"); + + b.Property("PhotosWithMeCount") + .HasColumnType("int"); + + b.Property("Pins") + .HasColumnType("longtext"); + + b.Property("PlanetHash") + .HasColumnType("longtext"); + + b.Property("ReviewCount") + .HasColumnType("int"); + + b.Property("StaffChallengeBronzeCount") + .HasColumnType("int"); + + b.Property("StaffChallengeGoldCount") + .HasColumnType("int"); + + b.Property("StaffChallengeSilverCount") + .HasColumnType("int"); + + b.Property("UsedSlots") + .HasColumnType("int"); + + b.Property("Username") + .HasColumnType("longtext"); + + b.Property("YayHash") + .HasColumnType("longtext"); + + b.HasKey("UserId"); + + b.HasIndex("LocationId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Comment", b => + { + b.HasOne("ProjectLighthouse.Types.User", "Poster") + .WithMany() + .HasForeignKey("PosterUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ProjectLighthouse.Types.User", "Target") + .WithMany() + .HasForeignKey("TargetUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Poster"); + + b.Navigation("Target"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b => + { + b.HasOne("ProjectLighthouse.Types.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ProjectLighthouse.Types.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Slot", b => + { + b.HasOne("ProjectLighthouse.Types.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ProjectLighthouse.Types.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Location"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.User", b => + { + b.HasOne("ProjectLighthouse.Types.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Location"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProjectLighthouse/Migrations/20211019021627_InitialCreate.cs b/ProjectLighthouse/Migrations/20211019021627_InitialCreate.cs new file mode 100644 index 00000000..8b375ed1 --- /dev/null +++ b/ProjectLighthouse/Migrations/20211019021627_InitialCreate.cs @@ -0,0 +1,257 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ProjectLighthouse.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Locations", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + X = table.Column(type: "int", nullable: false), + Y = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Locations", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Tokens", + columns: table => new + { + TokenId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "int", nullable: false), + UserToken = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_Tokens", x => x.TokenId); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Username = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + IconHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Game = table.Column(type: "int", nullable: false), + Lists = table.Column(type: "int", nullable: false), + HeartCount = table.Column(type: "int", nullable: false), + YayHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + BooHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Biography = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ReviewCount = table.Column(type: "int", nullable: false), + CommentCount = table.Column(type: "int", nullable: false), + PhotosByMeCount = table.Column(type: "int", nullable: false), + PhotosWithMeCount = table.Column(type: "int", nullable: false), + CommentsEnabled = table.Column(type: "tinyint(1)", nullable: false), + LocationId = table.Column(type: "int", nullable: false), + FavouriteSlotCount = table.Column(type: "int", nullable: false), + FavouriteUserCount = table.Column(type: "int", nullable: false), + LolCatFtwCount = table.Column(type: "int", nullable: false), + Pins = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + StaffChallengeGoldCount = table.Column(type: "int", nullable: false), + StaffChallengeSilverCount = table.Column(type: "int", nullable: false), + StaffChallengeBronzeCount = table.Column(type: "int", nullable: false), + PlanetHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + UsedSlots = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.UserId); + table.ForeignKey( + name: "FK_Users_Locations_LocationId", + column: x => x.LocationId, + principalTable: "Locations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Comments", + columns: table => new + { + CommentId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + PosterUserId = table.Column(type: "int", nullable: false), + TargetUserId = table.Column(type: "int", nullable: false), + Timestamp = table.Column(type: "bigint", nullable: false), + Message = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ThumbsUp = table.Column(type: "int", nullable: false), + ThumbsDown = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Comments", x => x.CommentId); + table.ForeignKey( + name: "FK_Comments_Users_PosterUserId", + column: x => x.PosterUserId, + principalTable: "Users", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Comments_Users_TargetUserId", + column: x => x.TargetUserId, + principalTable: "Users", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Slots", + columns: table => new + { + SlotId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Description = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + IconHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + RootLevel = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Resource = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + LocationId = table.Column(type: "int", nullable: false), + CreatorId = table.Column(type: "int", nullable: false), + InitiallyLocked = table.Column(type: "tinyint(1)", nullable: false), + SubLevel = table.Column(type: "tinyint(1)", nullable: false), + Lbp1Only = table.Column(type: "tinyint(1)", nullable: false), + Shareable = table.Column(type: "int", nullable: false), + AuthorLabels = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + BackgroundHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + MinimumPlayers = table.Column(type: "int", nullable: false), + MaximumPlayers = table.Column(type: "int", nullable: false), + MoveRequired = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Slots", x => x.SlotId); + table.ForeignKey( + name: "FK_Slots_Locations_LocationId", + column: x => x.LocationId, + principalTable: "Locations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Slots_Users_CreatorId", + column: x => x.CreatorId, + principalTable: "Users", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "QueuedLevels", + columns: table => new + { + QueuedLevelId = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "int", nullable: false), + SlotId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_QueuedLevels", x => x.QueuedLevelId); + table.ForeignKey( + name: "FK_QueuedLevels_Slots_SlotId", + column: x => x.SlotId, + principalTable: "Slots", + principalColumn: "SlotId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_QueuedLevels_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_Comments_PosterUserId", + table: "Comments", + column: "PosterUserId"); + + migrationBuilder.CreateIndex( + name: "IX_Comments_TargetUserId", + table: "Comments", + column: "TargetUserId"); + + migrationBuilder.CreateIndex( + name: "IX_QueuedLevels_SlotId", + table: "QueuedLevels", + column: "SlotId"); + + migrationBuilder.CreateIndex( + name: "IX_QueuedLevels_UserId", + table: "QueuedLevels", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_Slots_CreatorId", + table: "Slots", + column: "CreatorId"); + + migrationBuilder.CreateIndex( + name: "IX_Slots_LocationId", + table: "Slots", + column: "LocationId"); + + migrationBuilder.CreateIndex( + name: "IX_Users_LocationId", + table: "Users", + column: "LocationId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Comments"); + + migrationBuilder.DropTable( + name: "QueuedLevels"); + + migrationBuilder.DropTable( + name: "Tokens"); + + migrationBuilder.DropTable( + name: "Slots"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "Locations"); + } + } +} diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs new file mode 100644 index 00000000..98961477 --- /dev/null +++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs @@ -0,0 +1,322 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ProjectLighthouse; + +namespace ProjectLighthouse.Migrations +{ + [DbContext(typeof(Database))] + partial class DatabaseModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("ProjectLighthouse.Types.Comment", b => + { + b.Property("CommentId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("PosterUserId") + .HasColumnType("int"); + + b.Property("TargetUserId") + .HasColumnType("int"); + + b.Property("ThumbsDown") + .HasColumnType("int"); + + b.Property("ThumbsUp") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("bigint"); + + b.HasKey("CommentId"); + + b.HasIndex("PosterUserId"); + + b.HasIndex("TargetUserId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("int"); + + b.Property("Y") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Locations"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b => + { + b.Property("QueuedLevelId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("QueuedLevelId"); + + b.HasIndex("SlotId"); + + b.HasIndex("UserId"); + + b.ToTable("QueuedLevels"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Slot", b => + { + b.Property("SlotId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuthorLabels") + .HasColumnType("longtext"); + + b.Property("BackgroundHash") + .HasColumnType("longtext"); + + b.Property("CreatorId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IconHash") + .HasColumnType("longtext"); + + b.Property("InitiallyLocked") + .HasColumnType("tinyint(1)"); + + b.Property("Lbp1Only") + .HasColumnType("tinyint(1)"); + + b.Property("LocationId") + .HasColumnType("int"); + + b.Property("MaximumPlayers") + .HasColumnType("int"); + + b.Property("MinimumPlayers") + .HasColumnType("int"); + + b.Property("MoveRequired") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Resource") + .HasColumnType("longtext"); + + b.Property("RootLevel") + .HasColumnType("longtext"); + + b.Property("Shareable") + .HasColumnType("int"); + + b.Property("SubLevel") + .HasColumnType("tinyint(1)"); + + b.HasKey("SlotId"); + + b.HasIndex("CreatorId"); + + b.HasIndex("LocationId"); + + b.ToTable("Slots"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Token", b => + { + b.Property("TokenId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("UserToken") + .HasColumnType("longtext"); + + b.HasKey("TokenId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.User", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Biography") + .HasColumnType("longtext"); + + b.Property("BooHash") + .HasColumnType("longtext"); + + b.Property("CommentCount") + .HasColumnType("int"); + + b.Property("CommentsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("FavouriteSlotCount") + .HasColumnType("int"); + + b.Property("FavouriteUserCount") + .HasColumnType("int"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("HeartCount") + .HasColumnType("int"); + + b.Property("IconHash") + .HasColumnType("longtext"); + + b.Property("Lists") + .HasColumnType("int"); + + b.Property("LocationId") + .HasColumnType("int"); + + b.Property("LolCatFtwCount") + .HasColumnType("int"); + + b.Property("PhotosByMeCount") + .HasColumnType("int"); + + b.Property("PhotosWithMeCount") + .HasColumnType("int"); + + b.Property("Pins") + .HasColumnType("longtext"); + + b.Property("PlanetHash") + .HasColumnType("longtext"); + + b.Property("ReviewCount") + .HasColumnType("int"); + + b.Property("StaffChallengeBronzeCount") + .HasColumnType("int"); + + b.Property("StaffChallengeGoldCount") + .HasColumnType("int"); + + b.Property("StaffChallengeSilverCount") + .HasColumnType("int"); + + b.Property("UsedSlots") + .HasColumnType("int"); + + b.Property("Username") + .HasColumnType("longtext"); + + b.Property("YayHash") + .HasColumnType("longtext"); + + b.HasKey("UserId"); + + b.HasIndex("LocationId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Comment", b => + { + b.HasOne("ProjectLighthouse.Types.User", "Poster") + .WithMany() + .HasForeignKey("PosterUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ProjectLighthouse.Types.User", "Target") + .WithMany() + .HasForeignKey("TargetUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Poster"); + + b.Navigation("Target"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.QueuedLevel", b => + { + b.HasOne("ProjectLighthouse.Types.Slot", "Slot") + .WithMany() + .HasForeignKey("SlotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ProjectLighthouse.Types.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Slot"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.Slot", b => + { + b.HasOne("ProjectLighthouse.Types.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ProjectLighthouse.Types.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Creator"); + + b.Navigation("Location"); + }); + + modelBuilder.Entity("ProjectLighthouse.Types.User", b => + { + b.HasOne("ProjectLighthouse.Types.Location", "Location") + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Location"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ProjectLighthouse/Program.cs b/ProjectLighthouse/Program.cs index 780dd5de..11b81681 100644 --- a/ProjectLighthouse/Program.cs +++ b/ProjectLighthouse/Program.cs @@ -1,7 +1,6 @@ using System; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using ProjectLighthouse.Types; @@ -9,7 +8,16 @@ namespace ProjectLighthouse { public static class Program { public static void Main(string[] args) { Console.WriteLine("Welcome to Project Lighthouse!"); - Console.WriteLine(ServerSettings.DbConnected ? "Connected to the database." : "Database unavailable. Starting in stateless mode."); + bool dbConnected = ServerSettings.DbConnected; + Console.WriteLine(dbConnected ? "Connected to the database." : "Database unavailable. Exiting."); + + if(dbConnected) { + Console.WriteLine("Migrating database..."); + new Database().Database.Migrate(); + } + else { + Environment.Exit(1); + } CreateHostBuilder(args).Build().Run(); } diff --git a/ProjectLighthouse/ProjectLighthouse.csproj b/ProjectLighthouse/ProjectLighthouse.csproj index 96ea7037..fd438945 100644 --- a/ProjectLighthouse/ProjectLighthouse.csproj +++ b/ProjectLighthouse/ProjectLighthouse.csproj @@ -9,6 +9,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/README.md b/README.md index ac93ec3f..8a497d4f 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,12 @@ This will be written when we're out of beta. Consider this your barrier to entry Lighthouse requires a MySQL database at this time. For Linux users running docker, one can be set up using the `docker-compose.yml` file in the root of the project folder. -Once you've gotten MySQL running you can create the schema by running all of the `.sql` files in the `DatabaseMigrations` folder against the database. +Next, make sure the `LIGHTHOUSE_DB_CONNECTION_STRING` environment variable is set correctly. +By default it is `server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse`. If you are running the database via +the above `docker-compose.yml` you shouldn't need to change this. For other development/especially production environments +you will need to change this. -Then, you can finally run Lighthouse. It will connect using a connection string stored in `LIGHTHOUSE_DB_CONNECTION_STRING` by default. -The connection string is `server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse` by default. You can modify it if you'd like to, -but you shouldn't need to if you're using docker since the docker-compose file matches this by default. +Once you've gotten MySQL running you can run Lighthouse. It will take care of the rest. ## Connecting @@ -47,4 +48,15 @@ To launch the game with the patched EBOOT, open up RPCS3, go to File, Boot SELF/ Assuming you are running the patched version of RPCS3, you patched the file correctly, the database is migrated, and Lighthouse is running, the game should now connect. -Take a break. \ No newline at end of file +Take a break. + +## Contributing Tips + +### Database + +Some modifications may require updates to the database schema. You can automatically create a migration file by: + +1. Making sure the tools are installed. You can do this by running `dotnet tool restore`. +2. Making sure `LIGHTHOUSE_DB_CONNECTION_STRING is set correctly`. +3. Making your changes to the database. I wont cover this since if you're making database changes you should know what you're doing. +4. Running `dotnet ef migrations add `. \ No newline at end of file