Server names and admin log full-text search (#6327)

Co-authored-by: Julian Giebel <j.giebel@netrocks.info>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
This commit is contained in:
Julian Giebel
2022-03-13 18:36:48 +01:00
committed by GitHub
parent bd3fc84488
commit 414d226ec5
13 changed files with 2424 additions and 8 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Content.Server.Database.Migrations.Postgres
{
public partial class ServerNameFts : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "server_id",
table: "round",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateTable(
name: "server",
columns: table => new
{
server_id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_server", x => x.server_id);
});
migrationBuilder.InsertData(
"server",
new[] {"server_id", "name"},
new object[] { 0, "unknown" }
);
migrationBuilder.CreateIndex(
name: "IX_round_server_id",
table: "round",
column: "server_id");
migrationBuilder.CreateIndex(
name: "IX_admin_log_message",
table: "admin_log",
column: "message")
.Annotation("Npgsql:TsVectorConfig", "english");
migrationBuilder.AddForeignKey(
name: "FK_round_server_server_id",
table: "round",
column: "server_id",
principalTable: "server",
principalColumn: "server_id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_round_server_server_id",
table: "round");
migrationBuilder.DropTable(
name: "server");
migrationBuilder.DropIndex(
name: "IX_round_server_id",
table: "round");
migrationBuilder.DropIndex(
name: "IX_admin_log_message",
table: "admin_log");
migrationBuilder.DropColumn(
name: "server_id",
table: "round");
}
}
}

View File

@@ -120,6 +120,9 @@ namespace Content.Server.Database.Migrations.Postgres
b.HasKey("Id", "RoundId")
.HasName("PK_admin_log");
b.HasIndex("Message")
.HasAnnotation("Npgsql:TsVectorConfig", "english");
b.HasIndex("RoundId")
.HasDatabaseName("IX_admin_log_round_id");
@@ -559,12 +562,39 @@ namespace Content.Server.Database.Migrations.Postgres
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("ServerId")
.HasColumnType("integer")
.HasColumnName("server_id");
b.HasKey("Id")
.HasName("PK_round");
b.HasIndex("ServerId")
.HasDatabaseName("IX_round_server_id");
b.ToTable("round", (string)null);
});
modelBuilder.Entity("Content.Server.Database.Server", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("server_id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("Id")
.HasName("PK_server");
b.ToTable("server", (string)null);
});
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
{
b.Property<int>("Id")
@@ -908,6 +938,18 @@ namespace Content.Server.Database.Migrations.Postgres
b.Navigation("Preference");
});
modelBuilder.Entity("Content.Server.Database.Round", b =>
{
b.HasOne("Content.Server.Database.Server", "Server")
.WithMany("Rounds")
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("FK_round_server_server_id");
b.Navigation("Server");
});
modelBuilder.Entity("Content.Server.Database.ServerBanHit", b =>
{
b.HasOne("Content.Server.Database.ServerBan", "Ban")
@@ -1016,6 +1058,11 @@ namespace Content.Server.Database.Migrations.Postgres
b.Navigation("AdminLogs");
});
modelBuilder.Entity("Content.Server.Database.Server", b =>
{
b.Navigation("Rounds");
});
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
{
b.Navigation("BanHits");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Content.Server.Database.Migrations.Sqlite
{
public partial class ServerNameFts : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "server_id",
table: "round",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateTable(
name: "server",
columns: table => new
{
server_id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
name = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_server", x => x.server_id);
});
migrationBuilder.InsertData(
"server",
new[] {"server_id", "name"},
new object[] { 0, "unknown" }
);
migrationBuilder.CreateIndex(
name: "IX_round_server_id",
table: "round",
column: "server_id");
migrationBuilder.AddForeignKey(
name: "FK_round_server_server_id",
table: "round",
column: "server_id",
principalTable: "server",
principalColumn: "server_id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_round_server_server_id",
table: "round");
migrationBuilder.DropTable(
name: "server");
migrationBuilder.DropIndex(
name: "IX_round_server_id",
table: "round");
migrationBuilder.DropColumn(
name: "server_id",
table: "round");
}
}
}

View File

@@ -522,12 +522,37 @@ namespace Content.Server.Database.Migrations.Sqlite
.HasColumnType("INTEGER")
.HasColumnName("round_id");
b.Property<int>("ServerId")
.HasColumnType("INTEGER")
.HasColumnName("server_id");
b.HasKey("Id")
.HasName("PK_round");
b.HasIndex("ServerId")
.HasDatabaseName("IX_round_server_id");
b.ToTable("round", (string)null);
});
modelBuilder.Entity("Content.Server.Database.Server", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasColumnName("server_id");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasColumnName("name");
b.HasKey("Id")
.HasName("PK_server");
b.ToTable("server", (string)null);
});
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
{
b.Property<int>("Id")
@@ -857,6 +882,18 @@ namespace Content.Server.Database.Migrations.Sqlite
b.Navigation("Preference");
});
modelBuilder.Entity("Content.Server.Database.Round", b =>
{
b.HasOne("Content.Server.Database.Server", "Server")
.WithMany("Rounds")
.HasForeignKey("ServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("FK_round_server_server_id");
b.Navigation("Server");
});
modelBuilder.Entity("Content.Server.Database.ServerBanHit", b =>
{
b.HasOne("Content.Server.Database.ServerBan", "Ban")
@@ -965,6 +1002,11 @@ namespace Content.Server.Database.Migrations.Sqlite
b.Navigation("AdminLogs");
});
modelBuilder.Entity("Content.Server.Database.Server", b =>
{
b.Navigation("Rounds");
});
modelBuilder.Entity("Content.Server.Database.ServerBan", b =>
{
b.Navigation("BanHits");

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Net;
using System.Text.Json;
using Content.Shared.Database;
@@ -22,6 +23,7 @@ namespace Content.Server.Database
public DbSet<Admin> Admin { get; set; } = null!;
public DbSet<AdminRank> AdminRank { get; set; } = null!;
public DbSet<Round> Round { get; set; } = null!;
public DbSet<Server> Server { get; set; } = null!;
public DbSet<AdminLog> AdminLog { get; set; } = null!;
public DbSet<AdminLogPlayer> AdminLogPlayer { get; set; } = null!;
public DbSet<Whitelist> Whitelist { get; set; } = null!;
@@ -138,6 +140,11 @@ namespace Content.Server.Database
modelBuilder.Entity<ConnectionLog>()
.HasIndex(p => p.UserId);
}
public virtual IQueryable<AdminLog> SearchLogs(IQueryable<AdminLog> query, string searchText)
{
return query.Where(log => EF.Functions.Like(log.Message, "%" + searchText + "%"));
}
}
public class Preference
@@ -295,6 +302,20 @@ namespace Content.Server.Database
public List<Player> Players { get; set; } = default!;
public List<AdminLog> AdminLogs { get; set; } = default!;
[ForeignKey("Server")] public int ServerId { get; set; }
public Server Server { get; set; } = default!;
}
public class Server
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; } = default!;
[InverseProperty(nameof(Round.Server))]
public List<Round> Rounds { get; set; } = default!;
}
[Index(nameof(Type))]

View File

@@ -1,8 +1,10 @@
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using NpgsqlTypes;
namespace Content.Server.Database
{
@@ -59,6 +61,10 @@ namespace Content.Server.Database
"NOT inet '::ffff:0.0.0.0/96' >>= address");
// ReSharper restore StringLiteralTypo
modelBuilder.Entity<AdminLog>()
.HasIndex(l => l.Message)
.IsTsVectorExpressionIndex("english");
foreach(var entity in modelBuilder.Model.GetEntityTypes())
{
foreach(var property in entity.GetProperties())
@@ -68,5 +74,10 @@ namespace Content.Server.Database
}
}
}
public override IQueryable<AdminLog> SearchLogs(IQueryable<AdminLog> query, string searchText)
{
return query.Where(log => EF.Functions.ToTsVector("english", log.Message).Matches(searchText));
}
}
}