Merge branch 'dev' into 978-DiscordEmbeds

This commit is contained in:
Jordan Brown
2020-05-24 23:26:50 -04:00
committed by GitHub
23 changed files with 2616 additions and 146 deletions
+77 -31
View File
@@ -11,42 +11,19 @@ branches:
jobs:
include:
- env:
- DoxGeneration=true
name: "Dox Generation"
addons:
apt:
packages:
- doxygen
- graphviz
- env:
- DoxGeneration=false
- DockerBuild=false
- DMAPI=true
- BYOND_MAJOR="513"
- BYOND_MINOR="1517"
- DMEName="tests/DMAPI/travistester.dme"
name: "DMAPI Unit Tests"
cache:
directories:
- $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
addons:
apt:
packages:
- libc6-i386
- libstdc++6:i386
- env:
- DoxGeneration=false
- DockerBuild=false
- DMAPI=false
- CONFIG=Debug
name: "Test Server Debug"
- CONFIG=Release
- TGS4_TEST_DATABASE_TYPE=MySql
- TGS4_TEST_CONNECTION_STRING="server=127.0.0.1;uid=root;pwd=;database=tgs_test"
name: "MySql Integration Test"
language: csharp
mono: none
dotnet: 3.1
services:
- mysql
dotnet: 3.1
cache:
directories:
- $HOME/.nuget/packages:
@@ -60,12 +37,12 @@ jobs:
- DockerBuild=false
- DMAPI=false
- CONFIG=Release
name: "Test Server Release"
- TGS4_TEST_DATABASE_TYPE=Sqlite
- TGS4_TEST_CONNECTION_STRING="Data Source=TravisTestDB.sqlite3;Mode=ReadWriteCreate"
name: "Sqlite Integration Test"
language: csharp
mono: none
dotnet: 3.1
services:
- mysql
cache:
directories:
- $HOME/.nuget/packages:
@@ -74,12 +51,81 @@ jobs:
packages:
- libc6-i386
- libstdc++6:i386
# - env:
# - DoxGeneration=false
# - DockerBuild=false
# - DMAPI=false
# - CONFIG=Release
# - TGS4_TEST_DATABASE_TYPE=PostgresSql
# - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test"
# name: "PostgresSql Integration Test"
# language: csharp
# mono: none
# dotnet: 3.1
# services:
# - postgresql
# cache:
# directories:
# - $HOME/.nuget/packages:
# addons:
# apt:
# packages:
# - libc6-i386
# - libstdc++6:i386
- env:
- DoxGeneration=false
- DockerBuild=false
- DMAPI=false
- CONFIG=Debug
name: "Debug Unit Tests"
language: csharp
mono: none
dotnet: 3.1
cache:
directories:
- $HOME/.nuget/packages:
- env:
- DoxGeneration=false
- DockerBuild=false
- DMAPI=false
- CONFIG=Release
name: "Release Unit Tests"
language: csharp
mono: none
dotnet: 3.1
cache:
directories:
- $HOME/.nuget/packages:
- env:
- DoxGeneration=false
- DockerBuild=true
name: "Docker Build"
services:
- docker
- env:
- DoxGeneration=false
- DockerBuild=false
- DMAPI=true
- BYOND_MAJOR="513"
- BYOND_MINOR="1517"
- DMEName="tests/DMAPI/travistester.dme"
name: "DMAPI Unit Tests"
cache:
directories:
- $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
addons:
apt:
packages:
- libc6-i386
- libstdc++6:i386
- env:
- DoxGeneration=true
name: "Dox Generation"
addons:
apt:
packages:
- doxygen
- graphviz
install:
- if [ $DoxGeneration = false ] && [ $DockerBuild = false ] && [ $DMAPI = true ]; then build/install_byond.sh; fi
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup>
<!-- This is the authorative version list -->
<!-- Integration tests will ensure they match across the board -->
<TgsCoreVersion>4.2.5</TgsCoreVersion>
<TgsCoreVersion>4.2.6</TgsCoreVersion>
<TgsApiVersion>6.4.1</TgsApiVersion>
<TgsClientVersion>7.0.0</TgsClientVersion>
<TgsDmapiVersion>5.2.1</TgsDmapiVersion>
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
set -e
export TGS4_TEST_DISCORD_CHANNEL=493119635319947269
export TGS4_TEST_IRC_CHANNEL=\#botbus
export TGS4_TEST_TEMP_DIRECTORY=~/tgs4_test
#token set in CI settings
cd tests/Tgstation.Server.Tests
dotnet build -c $CONFIG
$HOME/.dotnet/tools/coverlet bin/$CONFIG/netcoreapp3.1/Tgstation.Server.Tests.dll --target "dotnet" --targetargs "test -c $CONFIG --no-build" --format opencover --output "../../TestResults/integration_test.xml" --include "[Tgstation.Server*]*" --exclude "[Tgstation.Server.Tests*]*" --exclude "[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations.*"
cd ../../TestResults
bash <(curl -s https://codecov.io/bash) -f integration_test.xml -F integration
+5 -18
View File
@@ -7,6 +7,11 @@ mkdir TestResults
source ~/.nvm/nvm.sh && nvm install 10
if [[ ! -z "${TGS4_TEST_CONNECTION_STRING}" ]]; then
build/integration_test.sh
exit
fi
cd tests/Tgstation.Server.Api.Tests
dotnet build -c $CONFIG /p:CopyLocalLockFileAssemblies=true
@@ -32,22 +37,6 @@ cd ../Tgstation.Server.Host.Console.Tests
dotnet build -c $CONFIG /p:CopyLocalLockFileAssemblies=true
$HOME/.dotnet/tools/coverlet bin/$CONFIG/netcoreapp3.1/Tgstation.Server.Host.Console.Tests.dll --target "dotnet" --targetargs "test -c $CONFIG --no-build" --format opencover --output "../../TestResults/console.xml" --include "[Tgstation.Server*]*" --exclude "[Tgstation.Server.Host.Console.Tests*]*"
cd ../Tgstation.Server.Tests
export TGS4_TEST_DATABASE_TYPE=MySql
export TGS4_TEST_DISCORD_CHANNEL=493119635319947269
export TGS4_TEST_CONNECTION_STRING="server=127.0.0.1;uid=root;pwd=;database=tgs_test"
export TGS4_TEST_IRC_CHANNEL=\#botbus
export TGS4_TEST_TEMP_DIRECTORY=~/tgs4_test
#token set in CI settings
dotnet build -c $CONFIG /p:CopyLocalLockFileAssemblies=true
$HOME/.dotnet/tools/coverlet bin/$CONFIG/netcoreapp3.1/Tgstation.Server.Tests.dll --target "dotnet" --targetargs "test -c $CONFIG --no-build" --format opencover --output "../../TestResults/servermy.xml" --include "[Tgstation.Server*]*" --exclude "[Tgstation.Server.Tests*]*" --exclude "[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations.*"
#Run again for Sqlite
export TGS4_TEST_DATABASE_TYPE=Sqlite
export TGS4_TEST_CONNECTION_STRING="Data Source=TravisTestDB.sqlite3;Mode=ReadWriteCreate"
$HOME/.dotnet/tools/coverlet bin/$CONFIG/netcoreapp3.1/Tgstation.Server.Tests.dll --target "dotnet" --targetargs "test -c $CONFIG --no-build" --format opencover --output "../../TestResults/serversl.xml" --include "[Tgstation.Server*]*" --exclude "[Tgstation.Server.Tests*]*" --exclude "[Tgstation.Server.Host]Tgstation.Server.Host.Database.Migrations.*"
cd ../../TestResults
bash <(curl -s https://codecov.io/bash) -f api.xml -F unittests
@@ -55,5 +44,3 @@ bash <(curl -s https://codecov.io/bash) -f client.xml -F unittests
bash <(curl -s https://codecov.io/bash) -f host.xml -F unittests
bash <(curl -s https://codecov.io/bash) -f watchdog.xml -F unittests
bash <(curl -s https://codecov.io/bash) -f console.xml -F unittests
bash <(curl -s https://codecov.io/bash) -f servermy.xml -F integration
bash <(curl -s https://codecov.io/bash) -f serversl.xml -F integration
+1 -1
View File
@@ -216,7 +216,7 @@ namespace Tgstation.Server.Client
try
{
var token = await RunRequest<Token>(Routes.Root, null, HttpMethod.Post, null, true, cancellationToken);
var token = await RunRequest<Token>(Routes.Root, new object(), HttpMethod.Post, null, true, cancellationToken);
headers = new ApiHeaders(headers.UserAgent!, token.Bearer!);
}
catch (ClientException)
@@ -62,13 +62,16 @@ namespace Tgstation.Server.Client
token = await api.Update<Token>(Routes.Root, cancellationToken).ConfigureAwait(false);
}
var client = CreateFromToken(host, token);
var apiHeaders = new ApiHeaders(productHeaderValue, token.Bearer!);
var client = new ServerClient(ApiClientFactory.CreateApiClient(host, apiHeaders, loginHeaders), token);
if (timeout.HasValue)
client.Timeout = timeout.Value;
var apiHeaders = new ApiHeaders(productHeaderValue, token.Bearer!);
foreach (var requestLogger in requestLoggers)
client.AddRequestLogger(requestLogger);
return new ServerClient(ApiClientFactory.CreateApiClient(host, apiHeaders, loginHeaders), token);
return client;
}
/// <inheritdoc />
@@ -16,7 +16,7 @@
<RepositoryUrl>https://github.com/tgstation/tgstation-server</RepositoryUrl>
<Copyright>2018</Copyright>
<PackageTags>json web api tgstation-server tgstation ss13 byond client</PackageTags>
<PackageReleaseNotes>.Net Standard 2.1, allow login requests to be logged.</PackageReleaseNotes>
<PackageReleaseNotes>Fixed automatic refresh erroring internally. Fixed request loggers given to ServerClientFactory not being passed to the IServerClient.</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "3.1.3",
"version": "3.1.4",
"commands": [
"dotnet-ef"
]
@@ -723,7 +723,7 @@ namespace Tgstation.Server.Host.Components.Deployment
logger.LogTrace("Begin Compile");
using var progressCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var progressTask = estimatedDuration.HasValue ? ProgressTask(progressReporter, estimatedDuration.Value, cancellationToken) : Task.CompletedTask;
var progressTask = estimatedDuration.HasValue ? ProgressTask(progressReporter, estimatedDuration.Value, progressCts.Token) : Task.CompletedTask;
try
{
using var byondLock = await byond.UseExecutables(null, cancellationToken).ConfigureAwait(false);
@@ -24,5 +24,10 @@
/// Use Sqlite
/// </summary>
Sqlite,
/// <summary>
/// Use PostgresSql
/// </summary>
PostgresSql,
}
}
@@ -117,7 +117,12 @@ namespace Tgstation.Server.Host.Controllers
[ProducesResponseType(404)]
public async Task<IActionResult> GetId(long id, CancellationToken cancellationToken)
{
var job = await DatabaseContext.Jobs.Where(x => x.Id == id && x.Instance.Id == Instance.Id).Include(x => x.StartedBy).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
var job = await DatabaseContext
.Jobs
.Where(x => x.Id == id && x.Instance.Id == Instance.Id)
.Include(x => x.StartedBy)
.FirstOrDefaultAsync(cancellationToken)
.ConfigureAwait(false);
if (job == default)
return NotFound();
var api = job.ToApi();
@@ -224,6 +224,9 @@ namespace Tgstation.Server.Host.Core
case DatabaseType.Sqlite:
AddTypedContext<SqliteDatabaseContext>();
break;
case DatabaseType.PostgresSql:
AddTypedContext<PostgresSqlDatabaseContext>();
break;
default:
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid {0}: {1}!", nameof(DatabaseType), dbType));
}
@@ -3,6 +3,7 @@ using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.Data.Sqlite;
using MySql.Data.MySqlClient;
using Npgsql;
using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database
@@ -34,6 +35,11 @@ namespace Tgstation.Server.Host.Database
{
ConnectionString = connectionString
};
case DatabaseType.PostgresSql:
return new NpgsqlConnection
{
ConnectionString = connectionString
};
default:
throw new ArgumentOutOfRangeException(nameof(databaseType), databaseType, "Invalid DatabaseType!");
}
@@ -354,9 +354,14 @@ namespace Tgstation.Server.Host.Database
// Update this with new migrations as they are made
string targetMigration = null;
if (DatabaseType == DatabaseType.PostgresSql && version < new Version(4, 3, 0))
throw new NotSupportedException("Cannot migrate below version 4.3.0 with PostgresSql!");
if (version < new Version(4, 1, 0))
throw new NotSupportedException("Cannot migrate below version 4.1.0!");
else if (version < new Version(4, 2, 0))
if (version < new Version(4, 2, 0))
targetMigration = DatabaseType == DatabaseType.Sqlite ? nameof(SLRebuild) : nameof(MSFixCascadingDelete);
if (targetMigration == null)
@@ -379,6 +384,9 @@ namespace Tgstation.Server.Host.Database
case DatabaseType.Sqlite:
migrationSubstitution = "SL{0}";
break;
case DatabaseType.PostgresSql:
migrationSubstitution = "PG{0}";
break;
default:
throw new InvalidOperationException($"Invalid DatabaseType: {DatabaseType}");
}
@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Logging;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
using Tgstation.Server.Host.System;
namespace Tgstation.Server.Host.Database.Design
{
/// <inheritdoc />
sealed class PostgresSqlDesignTimeDbContextFactory : IDesignTimeDbContextFactory<PostgresSqlDatabaseContext>
{
/// <inheritdoc />
public PostgresSqlDatabaseContext CreateDbContext(string[] args)
{
using var loggerFactory = new LoggerFactory();
return new PostgresSqlDatabaseContext(
new DbContextOptions<PostgresSqlDatabaseContext>(),
DesignTimeDbContextFactoryHelpers.GetDbContextOptions(
DatabaseType.PostgresSql,
"Application Name=tgstation-server;Host=127.0.0.1;Password=qCkWimNgLfWwpr7TnUHs;Username=postgres;Database=TGS_Design"),
new DatabaseSeeder(
new CryptographySuite(
new PasswordHasher<User>()),
new PlatformIdentifier()),
loggerFactory.CreateLogger<PostgresSqlDatabaseContext>());
}
}
}
@@ -0,0 +1,816 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Tgstation.Server.Host.Database.Migrations
{
[DbContext(typeof(PostgresSqlDatabaseContext))]
[Migration("20200516111712_PGCreate")]
partial class PGCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<int>("ChannelLimit")
.HasColumnType("integer");
b.Property<string>("ConnectionString")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("Enabled")
.HasColumnType("boolean");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("integer");
b.Property<long>("ReconnectionInterval")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId", "Name")
.IsUnique();
b.ToTable("ChatBots");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("ChatSettingsId")
.HasColumnType("bigint");
b.Property<decimal?>("DiscordChannelId")
.HasColumnType("numeric(20,0)");
b.Property<string>("IrcChannel")
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<bool?>("IsAdminChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("IsUpdatesChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("IsWatchdogChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("Tag")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("ChatSettingsId", "DiscordChannelId")
.IsUnique();
b.HasIndex("ChatSettingsId", "IrcChannel")
.IsUnique();
b.ToTable("ChatChannels");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("ByondVersion")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("DMApiMajorVersion")
.HasColumnType("integer");
b.Property<int?>("DMApiMinorVersion")
.HasColumnType("integer");
b.Property<int?>("DMApiPatchVersion")
.HasColumnType("integer");
b.Property<Guid?>("DirectoryName")
.IsRequired()
.HasColumnType("uuid");
b.Property<string>("DmeName")
.IsRequired()
.HasColumnType("text");
b.Property<long>("JobId")
.HasColumnType("bigint");
b.Property<int>("MinimumSecurityLevel")
.HasColumnType("integer");
b.Property<string>("Output")
.IsRequired()
.HasColumnType("text");
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("DirectoryName");
b.HasIndex("JobId")
.IsUnique();
b.HasIndex("RevisionInformationId");
b.ToTable("CompileJobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool?>("AllowWebClient")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("AutoStart")
.IsRequired()
.HasColumnType("boolean");
b.Property<long>("HeartbeatSeconds")
.HasColumnType("bigint");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<int>("PrimaryPort")
.HasColumnType("integer");
b.Property<int>("SecondaryPort")
.HasColumnType("integer");
b.Property<int>("SecurityLevel")
.HasColumnType("integer");
b.Property<long>("StartupTimeout")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamDaemonSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<int>("ApiValidationPort")
.HasColumnType("integer");
b.Property<int>("ApiValidationSecurityLevel")
.HasColumnType("integer");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("ProjectName")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamMakerSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long?>("AlphaId")
.HasColumnType("bigint");
b.Property<bool>("AlphaIsActive")
.HasColumnType("boolean");
b.Property<long?>("BravoId")
.HasColumnType("bigint");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("AlphaId");
b.HasIndex("BravoId");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("WatchdogReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("AutoUpdateInterval")
.HasColumnType("bigint");
b.Property<int>("ChatBotLimit")
.HasColumnType("integer");
b.Property<int>("ConfigurationType")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("Online")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Path")
.IsUnique();
b.ToTable("Instances");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal>("ByondRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("ChatBotRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("ConfigurationRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("DreamDaemonRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("DreamMakerRights")
.HasColumnType("numeric(20,0)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<decimal>("InstanceUserRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("RepositoryRights")
.HasColumnType("numeric(20,0)");
b.Property<long?>("UserId")
.IsRequired()
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId");
b.HasIndex("UserId", "InstanceId")
.IsUnique();
b.ToTable("InstanceUsers");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal?>("CancelRight")
.HasColumnType("numeric(20,0)");
b.Property<decimal?>("CancelRightsType")
.HasColumnType("numeric(20,0)");
b.Property<bool?>("Cancelled")
.IsRequired()
.HasColumnType("boolean");
b.Property<long?>("CancelledById")
.HasColumnType("bigint");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<long?>("ErrorCode")
.HasColumnType("bigint");
b.Property<string>("ExceptionDetails")
.HasColumnType("text");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StartedAt")
.IsRequired()
.HasColumnType("timestamp with time zone");
b.Property<long>("StartedById")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StoppedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CancelledById");
b.HasIndex("InstanceId");
b.HasIndex("StartedById");
b.ToTable("Jobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AccessIdentifier")
.IsRequired()
.HasColumnType("text");
b.Property<long>("CompileJobId")
.HasColumnType("bigint");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("integer");
b.Property<int>("Port")
.HasColumnType("integer");
b.Property<int>("ProcessId")
.HasColumnType("integer");
b.Property<int>("RebootState")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CompileJobId");
b.ToTable("ReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AccessToken")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("AccessUser")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("AutoUpdatesKeepTestMerges")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("AutoUpdatesSynchronize")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("CommitterEmail")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("CommitterName")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<bool?>("PostTestMergeComment")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("PushTestMergeCommits")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("ShowTestMergeCommitters")
.IsRequired()
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("RepositorySettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.Property<long>("TestMergeId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RevisionInformationId");
b.HasIndex("TestMergeId");
b.ToTable("RevInfoTestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("CommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("OriginCommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.HasKey("Id");
b.HasIndex("InstanceId", "CommitSha")
.IsUnique();
b.ToTable("RevisionInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Author")
.IsRequired()
.HasColumnType("text");
b.Property<string>("BodyAtMerge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<DateTimeOffset>("MergedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("MergedById")
.HasColumnType("bigint");
b.Property<int>("Number")
.HasColumnType("integer");
b.Property<long?>("PrimaryRevisionInformationId")
.IsRequired()
.HasColumnType("bigint");
b.Property<string>("PullRequestRevision")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<string>("TitleAtMerge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("MergedById");
b.HasIndex("PrimaryRevisionInformationId")
.IsUnique();
b.ToTable("TestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal>("AdministrationRights")
.HasColumnType("numeric(20,0)");
b.Property<string>("CanonicalName")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset?>("CreatedAt")
.IsRequired()
.HasColumnType("timestamp with time zone");
b.Property<long?>("CreatedById")
.HasColumnType("bigint");
b.Property<bool?>("Enabled")
.IsRequired()
.HasColumnType("boolean");
b.Property<decimal>("InstanceManagerRights")
.HasColumnType("numeric(20,0)");
b.Property<DateTimeOffset?>("LastPasswordUpdate")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("SystemIdentifier")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CanonicalName")
.IsUnique();
b.HasIndex("CreatedById");
b.HasIndex("SystemIdentifier")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("ChatSettings")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
.WithMany("Channels")
.HasForeignKey("ChatSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
.WithOne()
.HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("CompileJobs")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamDaemonSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamMakerSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha")
.WithMany()
.HasForeignKey("AlphaId");
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo")
.WithMany()
.HasForeignKey("BravoId");
b.HasOne("Tgstation.Server.Host.Models.Instance", null)
.WithOne("WatchdogReattachInformation")
.HasForeignKey("Tgstation.Server.Host.Models.DualReattachInformation", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("InstanceUsers")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", null)
.WithMany("InstanceUsers")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
.WithMany()
.HasForeignKey("CancelledById");
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("Jobs")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
.WithMany()
.HasForeignKey("StartedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
.WithMany()
.HasForeignKey("CompileJobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("RepositorySettings")
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("ActiveTestMerges")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
.WithMany("RevisonInformations")
.HasForeignKey("TestMergeId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("RevisionInformations")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
.WithMany("TestMerges")
.HasForeignKey("MergedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
.WithOne("PrimaryTestMerge")
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
.WithMany("CreatedUsers")
.HasForeignKey("CreatedById");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,638 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Tgstation.Server.Host.Database.Migrations
{
/// <summary>
/// Create initial schema for PostgreSQL.
/// </summary>
public partial class PGCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.CreateTable(
name: "Instances",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(maxLength: 10000, nullable: false),
Path = table.Column<string>(nullable: false),
Online = table.Column<bool>(nullable: false),
ConfigurationType = table.Column<int>(nullable: false),
AutoUpdateInterval = table.Column<long>(nullable: false),
ChatBotLimit = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Instances", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Enabled = table.Column<bool>(nullable: false),
CreatedAt = table.Column<DateTimeOffset>(nullable: false),
SystemIdentifier = table.Column<string>(nullable: true),
Name = table.Column<string>(maxLength: 10000, nullable: false),
AdministrationRights = table.Column<decimal>(nullable: false),
InstanceManagerRights = table.Column<decimal>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
CreatedById = table.Column<long>(nullable: true),
CanonicalName = table.Column<string>(nullable: false),
LastPasswordUpdate = table.Column<DateTimeOffset>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
table.ForeignKey(
name: "FK_Users_Users_CreatedById",
column: x => x.CreatedById,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "ChatBots",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(maxLength: 100, nullable: false),
Enabled = table.Column<bool>(nullable: true),
ReconnectionInterval = table.Column<long>(nullable: false),
ChannelLimit = table.Column<int>(nullable: false),
Provider = table.Column<int>(nullable: false),
ConnectionString = table.Column<string>(maxLength: 10000, nullable: false),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChatBots", x => x.Id);
table.ForeignKey(
name: "FK_ChatBots_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "DreamDaemonSettings",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AllowWebClient = table.Column<bool>(nullable: false),
SecurityLevel = table.Column<int>(nullable: false),
PrimaryPort = table.Column<int>(nullable: false),
SecondaryPort = table.Column<int>(nullable: false),
StartupTimeout = table.Column<long>(nullable: false),
HeartbeatSeconds = table.Column<long>(nullable: false),
AutoStart = table.Column<bool>(nullable: false),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DreamDaemonSettings", x => x.Id);
table.ForeignKey(
name: "FK_DreamDaemonSettings_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "DreamMakerSettings",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ProjectName = table.Column<string>(maxLength: 10000, nullable: true),
ApiValidationPort = table.Column<int>(nullable: false),
ApiValidationSecurityLevel = table.Column<int>(nullable: false),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DreamMakerSettings", x => x.Id);
table.ForeignKey(
name: "FK_DreamMakerSettings_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "RepositorySettings",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CommitterName = table.Column<string>(maxLength: 10000, nullable: false),
CommitterEmail = table.Column<string>(maxLength: 10000, nullable: false),
AccessUser = table.Column<string>(maxLength: 10000, nullable: true),
AccessToken = table.Column<string>(maxLength: 10000, nullable: true),
PushTestMergeCommits = table.Column<bool>(nullable: false),
ShowTestMergeCommitters = table.Column<bool>(nullable: false),
AutoUpdatesKeepTestMerges = table.Column<bool>(nullable: false),
AutoUpdatesSynchronize = table.Column<bool>(nullable: false),
PostTestMergeComment = table.Column<bool>(nullable: false),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RepositorySettings", x => x.Id);
table.ForeignKey(
name: "FK_RepositorySettings_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "RevisionInformations",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CommitSha = table.Column<string>(maxLength: 40, nullable: false),
OriginCommitSha = table.Column<string>(maxLength: 40, nullable: false),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RevisionInformations", x => x.Id);
table.ForeignKey(
name: "FK_RevisionInformations_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "InstanceUsers",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserId = table.Column<long>(nullable: false),
InstanceUserRights = table.Column<decimal>(nullable: false),
ByondRights = table.Column<decimal>(nullable: false),
DreamDaemonRights = table.Column<decimal>(nullable: false),
DreamMakerRights = table.Column<decimal>(nullable: false),
RepositoryRights = table.Column<decimal>(nullable: false),
ChatBotRights = table.Column<decimal>(nullable: false),
ConfigurationRights = table.Column<decimal>(nullable: false),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_InstanceUsers", x => x.Id);
table.ForeignKey(
name: "FK_InstanceUsers_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InstanceUsers_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Jobs",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Description = table.Column<string>(nullable: false),
ErrorCode = table.Column<long>(nullable: true),
ExceptionDetails = table.Column<string>(nullable: true),
StartedAt = table.Column<DateTimeOffset>(nullable: false),
StoppedAt = table.Column<DateTimeOffset>(nullable: true),
Cancelled = table.Column<bool>(nullable: false),
CancelRightsType = table.Column<decimal>(nullable: true),
CancelRight = table.Column<decimal>(nullable: true),
StartedById = table.Column<long>(nullable: false),
CancelledById = table.Column<long>(nullable: true),
InstanceId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Jobs", x => x.Id);
table.ForeignKey(
name: "FK_Jobs_Users_CancelledById",
column: x => x.CancelledById,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Jobs_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Jobs_Users_StartedById",
column: x => x.StartedById,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ChatChannels",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
IrcChannel = table.Column<string>(maxLength: 100, nullable: true),
DiscordChannelId = table.Column<decimal>(nullable: true),
IsAdminChannel = table.Column<bool>(nullable: false),
IsWatchdogChannel = table.Column<bool>(nullable: false),
IsUpdatesChannel = table.Column<bool>(nullable: false),
Tag = table.Column<string>(maxLength: 10000, nullable: true),
ChatSettingsId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChatChannels", x => x.Id);
table.ForeignKey(
name: "FK_ChatChannels_ChatBots_ChatSettingsId",
column: x => x.ChatSettingsId,
principalTable: "ChatBots",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TestMerges",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Number = table.Column<int>(nullable: false),
PullRequestRevision = table.Column<string>(maxLength: 40, nullable: false),
Comment = table.Column<string>(maxLength: 10000, nullable: true),
TitleAtMerge = table.Column<string>(nullable: false),
BodyAtMerge = table.Column<string>(nullable: false),
Url = table.Column<string>(nullable: false),
Author = table.Column<string>(nullable: false),
MergedAt = table.Column<DateTimeOffset>(nullable: false),
MergedById = table.Column<long>(nullable: false),
PrimaryRevisionInformationId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TestMerges", x => x.Id);
table.ForeignKey(
name: "FK_TestMerges_Users_MergedById",
column: x => x.MergedById,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_TestMerges_RevisionInformations_PrimaryRevisionInformationId",
column: x => x.PrimaryRevisionInformationId,
principalTable: "RevisionInformations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "CompileJobs",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
DmeName = table.Column<string>(nullable: false),
Output = table.Column<string>(nullable: false),
DirectoryName = table.Column<Guid>(nullable: false),
MinimumSecurityLevel = table.Column<int>(nullable: false),
JobId = table.Column<long>(nullable: false),
RevisionInformationId = table.Column<long>(nullable: false),
ByondVersion = table.Column<string>(nullable: false),
DMApiMajorVersion = table.Column<int>(nullable: true),
DMApiMinorVersion = table.Column<int>(nullable: true),
DMApiPatchVersion = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_CompileJobs", x => x.Id);
table.ForeignKey(
name: "FK_CompileJobs_Jobs_JobId",
column: x => x.JobId,
principalTable: "Jobs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_CompileJobs_RevisionInformations_RevisionInformationId",
column: x => x.RevisionInformationId,
principalTable: "RevisionInformations",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "RevInfoTestMerges",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
TestMergeId = table.Column<long>(nullable: false),
RevisionInformationId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RevInfoTestMerges", x => x.Id);
table.ForeignKey(
name: "FK_RevInfoTestMerges_RevisionInformations_RevisionInformationId",
column: x => x.RevisionInformationId,
principalTable: "RevisionInformations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_RevInfoTestMerges_TestMerges_TestMergeId",
column: x => x.TestMergeId,
principalTable: "TestMerges",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "ReattachInformations",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AccessIdentifier = table.Column<string>(nullable: false),
ProcessId = table.Column<int>(nullable: false),
IsPrimary = table.Column<bool>(nullable: false),
Port = table.Column<int>(nullable: false),
RebootState = table.Column<int>(nullable: false),
LaunchSecurityLevel = table.Column<int>(nullable: false),
CompileJobId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ReattachInformations", x => x.Id);
table.ForeignKey(
name: "FK_ReattachInformations_CompileJobs_CompileJobId",
column: x => x.CompileJobId,
principalTable: "CompileJobs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "WatchdogReattachInformations",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AlphaIsActive = table.Column<bool>(nullable: false),
InstanceId = table.Column<long>(nullable: false),
AlphaId = table.Column<long>(nullable: true),
BravoId = table.Column<long>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_WatchdogReattachInformations", x => x.Id);
table.ForeignKey(
name: "FK_WatchdogReattachInformations_ReattachInformations_AlphaId",
column: x => x.AlphaId,
principalTable: "ReattachInformations",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_WatchdogReattachInformations_ReattachInformations_BravoId",
column: x => x.BravoId,
principalTable: "ReattachInformations",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_WatchdogReattachInformations_Instances_InstanceId",
column: x => x.InstanceId,
principalTable: "Instances",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ChatBots_InstanceId_Name",
table: "ChatBots",
columns: new[] { "InstanceId", "Name" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ChatChannels_ChatSettingsId_DiscordChannelId",
table: "ChatChannels",
columns: new[] { "ChatSettingsId", "DiscordChannelId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ChatChannels_ChatSettingsId_IrcChannel",
table: "ChatChannels",
columns: new[] { "ChatSettingsId", "IrcChannel" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_CompileJobs_DirectoryName",
table: "CompileJobs",
column: "DirectoryName");
migrationBuilder.CreateIndex(
name: "IX_CompileJobs_JobId",
table: "CompileJobs",
column: "JobId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_CompileJobs_RevisionInformationId",
table: "CompileJobs",
column: "RevisionInformationId");
migrationBuilder.CreateIndex(
name: "IX_DreamDaemonSettings_InstanceId",
table: "DreamDaemonSettings",
column: "InstanceId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_DreamMakerSettings_InstanceId",
table: "DreamMakerSettings",
column: "InstanceId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Instances_Path",
table: "Instances",
column: "Path",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_InstanceUsers_InstanceId",
table: "InstanceUsers",
column: "InstanceId");
migrationBuilder.CreateIndex(
name: "IX_InstanceUsers_UserId_InstanceId",
table: "InstanceUsers",
columns: new[] { "UserId", "InstanceId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Jobs_CancelledById",
table: "Jobs",
column: "CancelledById");
migrationBuilder.CreateIndex(
name: "IX_Jobs_InstanceId",
table: "Jobs",
column: "InstanceId");
migrationBuilder.CreateIndex(
name: "IX_Jobs_StartedById",
table: "Jobs",
column: "StartedById");
migrationBuilder.CreateIndex(
name: "IX_ReattachInformations_CompileJobId",
table: "ReattachInformations",
column: "CompileJobId");
migrationBuilder.CreateIndex(
name: "IX_RepositorySettings_InstanceId",
table: "RepositorySettings",
column: "InstanceId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_RevInfoTestMerges_RevisionInformationId",
table: "RevInfoTestMerges",
column: "RevisionInformationId");
migrationBuilder.CreateIndex(
name: "IX_RevInfoTestMerges_TestMergeId",
table: "RevInfoTestMerges",
column: "TestMergeId");
migrationBuilder.CreateIndex(
name: "IX_RevisionInformations_InstanceId_CommitSha",
table: "RevisionInformations",
columns: new[] { "InstanceId", "CommitSha" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_TestMerges_MergedById",
table: "TestMerges",
column: "MergedById");
migrationBuilder.CreateIndex(
name: "IX_TestMerges_PrimaryRevisionInformationId",
table: "TestMerges",
column: "PrimaryRevisionInformationId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Users_CanonicalName",
table: "Users",
column: "CanonicalName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Users_CreatedById",
table: "Users",
column: "CreatedById");
migrationBuilder.CreateIndex(
name: "IX_Users_SystemIdentifier",
table: "Users",
column: "SystemIdentifier",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_WatchdogReattachInformations_AlphaId",
table: "WatchdogReattachInformations",
column: "AlphaId");
migrationBuilder.CreateIndex(
name: "IX_WatchdogReattachInformations_BravoId",
table: "WatchdogReattachInformations",
column: "BravoId");
migrationBuilder.CreateIndex(
name: "IX_WatchdogReattachInformations_InstanceId",
table: "WatchdogReattachInformations",
column: "InstanceId",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
if (migrationBuilder == null)
throw new ArgumentNullException(nameof(migrationBuilder));
migrationBuilder.DropTable(
name: "ChatChannels");
migrationBuilder.DropTable(
name: "DreamDaemonSettings");
migrationBuilder.DropTable(
name: "DreamMakerSettings");
migrationBuilder.DropTable(
name: "InstanceUsers");
migrationBuilder.DropTable(
name: "RepositorySettings");
migrationBuilder.DropTable(
name: "RevInfoTestMerges");
migrationBuilder.DropTable(
name: "WatchdogReattachInformations");
migrationBuilder.DropTable(
name: "ChatBots");
migrationBuilder.DropTable(
name: "TestMerges");
migrationBuilder.DropTable(
name: "ReattachInformations");
migrationBuilder.DropTable(
name: "CompileJobs");
migrationBuilder.DropTable(
name: "Jobs");
migrationBuilder.DropTable(
name: "RevisionInformations");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Instances");
}
}
}
@@ -0,0 +1,814 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Tgstation.Server.Host.Database;
namespace Tgstation.Server.Host.Migrations
{
[DbContext(typeof(PostgresSqlDatabaseContext))]
partial class PostgresSqlDatabaseContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<int>("ChannelLimit")
.HasColumnType("integer");
b.Property<string>("ConnectionString")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("Enabled")
.HasColumnType("boolean");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<int>("Provider")
.HasColumnType("integer");
b.Property<long>("ReconnectionInterval")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId", "Name")
.IsUnique();
b.ToTable("ChatBots");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("ChatSettingsId")
.HasColumnType("bigint");
b.Property<decimal?>("DiscordChannelId")
.HasColumnType("numeric(20,0)");
b.Property<string>("IrcChannel")
.HasColumnType("character varying(100)")
.HasMaxLength(100);
b.Property<bool?>("IsAdminChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("IsUpdatesChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("IsWatchdogChannel")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("Tag")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("ChatSettingsId", "DiscordChannelId")
.IsUnique();
b.HasIndex("ChatSettingsId", "IrcChannel")
.IsUnique();
b.ToTable("ChatChannels");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("ByondVersion")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("DMApiMajorVersion")
.HasColumnType("integer");
b.Property<int?>("DMApiMinorVersion")
.HasColumnType("integer");
b.Property<int?>("DMApiPatchVersion")
.HasColumnType("integer");
b.Property<Guid?>("DirectoryName")
.IsRequired()
.HasColumnType("uuid");
b.Property<string>("DmeName")
.IsRequired()
.HasColumnType("text");
b.Property<long>("JobId")
.HasColumnType("bigint");
b.Property<int>("MinimumSecurityLevel")
.HasColumnType("integer");
b.Property<string>("Output")
.IsRequired()
.HasColumnType("text");
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("DirectoryName");
b.HasIndex("JobId")
.IsUnique();
b.HasIndex("RevisionInformationId");
b.ToTable("CompileJobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool?>("AllowWebClient")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("AutoStart")
.IsRequired()
.HasColumnType("boolean");
b.Property<long>("HeartbeatSeconds")
.HasColumnType("bigint");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<int>("PrimaryPort")
.HasColumnType("integer");
b.Property<int>("SecondaryPort")
.HasColumnType("integer");
b.Property<int>("SecurityLevel")
.HasColumnType("integer");
b.Property<long>("StartupTimeout")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamDaemonSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<int>("ApiValidationPort")
.HasColumnType("integer");
b.Property<int>("ApiValidationSecurityLevel")
.HasColumnType("integer");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("ProjectName")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("DreamMakerSettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long?>("AlphaId")
.HasColumnType("bigint");
b.Property<bool>("AlphaIsActive")
.HasColumnType("boolean");
b.Property<long?>("BravoId")
.HasColumnType("bigint");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("AlphaId");
b.HasIndex("BravoId");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("WatchdogReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("AutoUpdateInterval")
.HasColumnType("bigint");
b.Property<int>("ChatBotLimit")
.HasColumnType("integer");
b.Property<int>("ConfigurationType")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("Online")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("Path")
.IsUnique();
b.ToTable("Instances");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal>("ByondRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("ChatBotRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("ConfigurationRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("DreamDaemonRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("DreamMakerRights")
.HasColumnType("numeric(20,0)");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<decimal>("InstanceUserRights")
.HasColumnType("numeric(20,0)");
b.Property<decimal>("RepositoryRights")
.HasColumnType("numeric(20,0)");
b.Property<long?>("UserId")
.IsRequired()
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("InstanceId");
b.HasIndex("UserId", "InstanceId")
.IsUnique();
b.ToTable("InstanceUsers");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal?>("CancelRight")
.HasColumnType("numeric(20,0)");
b.Property<decimal?>("CancelRightsType")
.HasColumnType("numeric(20,0)");
b.Property<bool?>("Cancelled")
.IsRequired()
.HasColumnType("boolean");
b.Property<long?>("CancelledById")
.HasColumnType("bigint");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<long?>("ErrorCode")
.HasColumnType("bigint");
b.Property<string>("ExceptionDetails")
.HasColumnType("text");
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StartedAt")
.IsRequired()
.HasColumnType("timestamp with time zone");
b.Property<long>("StartedById")
.HasColumnType("bigint");
b.Property<DateTimeOffset?>("StoppedAt")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CancelledById");
b.HasIndex("InstanceId");
b.HasIndex("StartedById");
b.ToTable("Jobs");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AccessIdentifier")
.IsRequired()
.HasColumnType("text");
b.Property<long>("CompileJobId")
.HasColumnType("bigint");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<int>("LaunchSecurityLevel")
.HasColumnType("integer");
b.Property<int>("Port")
.HasColumnType("integer");
b.Property<int>("ProcessId")
.HasColumnType("integer");
b.Property<int>("RebootState")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CompileJobId");
b.ToTable("ReattachInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("AccessToken")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("AccessUser")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<bool?>("AutoUpdatesKeepTestMerges")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("AutoUpdatesSynchronize")
.IsRequired()
.HasColumnType("boolean");
b.Property<string>("CommitterEmail")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("CommitterName")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<bool?>("PostTestMergeComment")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("PushTestMergeCommits")
.IsRequired()
.HasColumnType("boolean");
b.Property<bool?>("ShowTestMergeCommitters")
.IsRequired()
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("InstanceId")
.IsUnique();
b.ToTable("RepositorySettings");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<long>("RevisionInformationId")
.HasColumnType("bigint");
b.Property<long>("TestMergeId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RevisionInformationId");
b.HasIndex("TestMergeId");
b.ToTable("RevInfoTestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("CommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<long>("InstanceId")
.HasColumnType("bigint");
b.Property<string>("OriginCommitSha")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.HasKey("Id");
b.HasIndex("InstanceId", "CommitSha")
.IsUnique();
b.ToTable("RevisionInformations");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Author")
.IsRequired()
.HasColumnType("text");
b.Property<string>("BodyAtMerge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Comment")
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<DateTimeOffset>("MergedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("MergedById")
.HasColumnType("bigint");
b.Property<int>("Number")
.HasColumnType("integer");
b.Property<long?>("PrimaryRevisionInformationId")
.IsRequired()
.HasColumnType("bigint");
b.Property<string>("PullRequestRevision")
.IsRequired()
.HasColumnType("character varying(40)")
.HasMaxLength(40);
b.Property<string>("TitleAtMerge")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("MergedById");
b.HasIndex("PrimaryRevisionInformationId")
.IsUnique();
b.ToTable("TestMerges");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.Property<long?>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<decimal>("AdministrationRights")
.HasColumnType("numeric(20,0)");
b.Property<string>("CanonicalName")
.IsRequired()
.HasColumnType("text");
b.Property<DateTimeOffset?>("CreatedAt")
.IsRequired()
.HasColumnType("timestamp with time zone");
b.Property<long?>("CreatedById")
.HasColumnType("bigint");
b.Property<bool?>("Enabled")
.IsRequired()
.HasColumnType("boolean");
b.Property<decimal>("InstanceManagerRights")
.HasColumnType("numeric(20,0)");
b.Property<DateTimeOffset?>("LastPasswordUpdate")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(10000)")
.HasMaxLength(10000);
b.Property<string>("PasswordHash")
.HasColumnType("text");
b.Property<string>("SystemIdentifier")
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CanonicalName")
.IsUnique();
b.HasIndex("CreatedById");
b.HasIndex("SystemIdentifier")
.IsUnique();
b.ToTable("Users");
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("ChatSettings")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
.WithMany("Channels")
.HasForeignKey("ChatSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
.WithOne()
.HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("CompileJobs")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamDaemonSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("DreamMakerSettings")
.HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha")
.WithMany()
.HasForeignKey("AlphaId");
b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo")
.WithMany()
.HasForeignKey("BravoId");
b.HasOne("Tgstation.Server.Host.Models.Instance", null)
.WithOne("WatchdogReattachInformation")
.HasForeignKey("Tgstation.Server.Host.Models.DualReattachInformation", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("InstanceUsers")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", null)
.WithMany("InstanceUsers")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
.WithMany()
.HasForeignKey("CancelledById");
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("Jobs")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
.WithMany()
.HasForeignKey("StartedById")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
.WithMany()
.HasForeignKey("CompileJobId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithOne("RepositorySettings")
.HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
.WithMany("ActiveTestMerges")
.HasForeignKey("RevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
.WithMany("RevisonInformations")
.HasForeignKey("TestMergeId")
.OnDelete(DeleteBehavior.ClientNoAction)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
{
b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
.WithMany("RevisionInformations")
.HasForeignKey("InstanceId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
.WithMany("TestMerges")
.HasForeignKey("MergedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
.WithOne("PrimaryTestMerge")
.HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
{
b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
.WithMany("CreatedUsers")
.HasForeignKey("CreatedById");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,47 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Diagnostics;
using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Database
{
/// <summary>
/// <see cref="DatabaseContext{TParentContext}"/> for PostgresSQL.
/// </summary>
sealed class PostgresSqlDatabaseContext : DatabaseContext<PostgresSqlDatabaseContext>
{
/// <summary>
/// Construct a <see cref="SqlServerDatabaseContext"/>
/// </summary>
/// <param name="dbContextOptions">The <see cref="DbContextOptions{TContext}"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseConfiguration">The <see cref="IOptions{TOptions}"/> of <see cref="DatabaseConfiguration"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="databaseSeeder">The <see cref="IDatabaseSeeder"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="DatabaseContext{TParentContext}"/></param>
public PostgresSqlDatabaseContext(
DbContextOptions<PostgresSqlDatabaseContext> dbContextOptions,
IOptions<DatabaseConfiguration> databaseConfiguration,
IDatabaseSeeder databaseSeeder,
ILogger<PostgresSqlDatabaseContext> logger)
: base(dbContextOptions, databaseConfiguration, databaseSeeder, logger)
{ }
/// <inheritdoc />
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
base.OnConfiguring(options);
options.UseNpgsql(DatabaseConfiguration.ConnectionString, x => x.EnableRetryOnFailure());
}
/// <inheritdoc />
protected override void ValidateDatabaseType()
{
if (!Debugger.IsAttached)
throw new NotImplementedException("PostgresSQL implementation is not complete yet!");
if (DatabaseType != DatabaseType.PostgresSql)
throw new InvalidOperationException("Invalid DatabaseType for SqliteDatabaseContext!");
}
}
}
@@ -25,7 +25,7 @@ namespace Tgstation.Server.Host.Database
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
base.OnConfiguring(options);
options.UseSqlServer(DatabaseConfiguration.ConnectionString);
options.UseSqlServer(DatabaseConfiguration.ConnectionString, x => x.EnableRetryOnFailure());
}
/// <inheritdoc />
+116 -71
View File
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data.Common;
@@ -275,34 +276,38 @@ namespace Tgstation.Server.Host.Setup
/// <summary>
/// Prompt the user for the <see cref="DatabaseType"/>.
/// </summary>
/// <param name="firstTime">If this is the user's first time here.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the input <see cref="DatabaseType"/>.</returns>
async Task<DatabaseType> PromptDatabaseType(CancellationToken cancellationToken)
async Task<DatabaseType> PromptDatabaseType(bool firstTime, CancellationToken cancellationToken)
{
await console.WriteAsync(String.Empty, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync(
"NOTE: It is HIGHLY reccommended that TGS runs on a complete relational database, specfically *NOT* Sqlite.",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(
"Sqlite, by nature cannot perform several DDL operations. Because of this future compatiblility cannot be guaranteed.",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(
"This means that you may not be able to update to the next minor version of TGS4 without a clean re-installation!",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(
"Please consider taking the time to set up a relational database if this is meant to be a long-standing server.",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(String.Empty, true, cancellationToken).ConfigureAwait(false);
if (firstTime)
{
await console.WriteAsync(String.Empty, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync(
"NOTE: It is HIGHLY reccommended that TGS runs on a complete relational database, specfically *NOT* Sqlite.",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(
"Sqlite, by nature cannot perform several DDL operations. Because of this future compatiblility cannot be guaranteed.",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(
"This means that you may not be able to update to the next minor version of TGS4 without a clean re-installation!",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(
"Please consider taking the time to set up a relational database if this is meant to be a long-standing server.",
true,
cancellationToken)
.ConfigureAwait(false);
await console.WriteAsync(String.Empty, true, cancellationToken).ConfigureAwait(false);
await asyncDelayer.Delay(TimeSpan.FromSeconds(3), cancellationToken).ConfigureAwait(false);
await asyncDelayer.Delay(TimeSpan.FromSeconds(3), cancellationToken).ConfigureAwait(false);
}
await console.WriteAsync("What SQL database type will you be using?", true, cancellationToken).ConfigureAwait(false);
do
@@ -310,10 +315,13 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync(
String.Format(
CultureInfo.InvariantCulture,
"Please enter one of {0}, {1}, {2} or {3}: ",
"Please enter one of {0}, {1}, {2}, or {3}: ",
DatabaseType.MariaDB,
DatabaseType.MySql,
#pragma warning disable SA1515 // Single-line comment should be preceded by blank line
// DatabaseType.PostgresSql,
DatabaseType.SqlServer,
#pragma warning restore SA1515 // Single-line comment should be preceded by blank line
DatabaseType.Sqlite),
false,
cancellationToken)
@@ -332,19 +340,22 @@ namespace Tgstation.Server.Host.Setup
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the new <see cref="DatabaseConfiguration"/></returns>
#pragma warning disable CA1502 // TODO: Decomplexify
async Task<DatabaseConfiguration> ConfigureDatabase(CancellationToken cancellationToken)
{
bool firstTime = true;
do
{
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
var databaseConfiguration = new DatabaseConfiguration
{
DatabaseType = await PromptDatabaseType(cancellationToken).ConfigureAwait(false)
DatabaseType = await PromptDatabaseType(firstTime, cancellationToken).ConfigureAwait(false)
};
firstTime = false;
string serverAddress = null;
uint? mySQLServerPort = null;
ushort? serverPort = null;
bool isSqliteDB = databaseConfiguration.DatabaseType == DatabaseType.Sqlite;
if (!isSqliteDB)
@@ -353,15 +364,17 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync(null, true, cancellationToken).ConfigureAwait(false);
await console.WriteAsync("Enter the server's address and port [<server>:<port> or <server>] (blank for local): ", false, cancellationToken).ConfigureAwait(false);
serverAddress = await console.ReadLineAsync(false, cancellationToken).ConfigureAwait(false);
if (!String.IsNullOrWhiteSpace(serverAddress) && databaseConfiguration.DatabaseType == DatabaseType.SqlServer)
if (String.IsNullOrWhiteSpace(serverAddress))
serverAddress = null;
else if (databaseConfiguration.DatabaseType == DatabaseType.SqlServer)
{
var match = Regex.Match(serverAddress, @"^(?<server>.+):(?<port>.+)$");
if (match.Success)
{
serverAddress = match.Groups["server"].Value;
var portString = match.Groups["port"].Value;
if (uint.TryParse(portString, out uint port))
mySQLServerPort = port;
if (UInt16.TryParse(portString, out var port))
serverPort = port;
else
{
await console.WriteAsync($"Failed to parse port \"{portString}\", please try again.", true, cancellationToken).ConfigureAwait(false);
@@ -434,53 +447,84 @@ namespace Tgstation.Server.Host.Setup
connectionString,
databaseConfiguration.DatabaseType);
if (databaseConfiguration.DatabaseType == DatabaseType.SqlServer)
switch (databaseConfiguration.DatabaseType)
{
var csb = new SqlConnectionStringBuilder
{
ApplicationName = assemblyInformationProvider.VersionPrefix,
DataSource = serverAddress ?? "(local)"
};
case DatabaseType.SqlServer:
{
var csb = new SqlConnectionStringBuilder
{
ApplicationName = assemblyInformationProvider.VersionPrefix,
DataSource = serverAddress ?? "(local)"
};
if (useWinAuth)
csb.IntegratedSecurity = true;
else
{
csb.UserID = username;
csb.Password = password;
}
if (useWinAuth)
csb.IntegratedSecurity = true;
else
{
csb.UserID = username;
csb.Password = password;
}
CreateTestConnection(csb.ConnectionString);
csb.InitialCatalog = databaseName;
databaseConfiguration.ConnectionString = csb.ConnectionString;
}
else if(databaseConfiguration.DatabaseType == DatabaseType.Sqlite)
{
var csb = new SqliteConnectionStringBuilder
{
DataSource = databaseName,
Mode = dbExists ? SqliteOpenMode.ReadOnly : SqliteOpenMode.ReadWriteCreate
};
CreateTestConnection(csb.ConnectionString);
csb.InitialCatalog = databaseName;
databaseConfiguration.ConnectionString = csb.ConnectionString;
}
CreateTestConnection(csb.ConnectionString);
databaseConfiguration.ConnectionString = csb.ConnectionString;
}
else
{
// MySQL/MariaDB
var csb = new MySqlConnectionStringBuilder
{
Server = serverAddress ?? "127.0.0.1",
UserID = username,
Password = password
};
break;
case DatabaseType.MariaDB:
case DatabaseType.MySql:
{
// MySQL/MariaDB
var csb = new MySqlConnectionStringBuilder
{
Server = serverAddress ?? "127.0.0.1",
UserID = username,
Password = password
};
if (mySQLServerPort.HasValue)
csb.Port = mySQLServerPort.Value;
if (serverPort.HasValue)
csb.Port = serverPort.Value;
CreateTestConnection(csb.ConnectionString);
csb.Database = databaseName;
databaseConfiguration.ConnectionString = csb.ConnectionString;
CreateTestConnection(csb.ConnectionString);
csb.Database = databaseName;
databaseConfiguration.ConnectionString = csb.ConnectionString;
}
break;
case DatabaseType.Sqlite:
{
var csb = new SqliteConnectionStringBuilder
{
DataSource = databaseName,
Mode = dbExists ? SqliteOpenMode.ReadOnly : SqliteOpenMode.ReadWriteCreate
};
CreateTestConnection(csb.ConnectionString);
databaseConfiguration.ConnectionString = csb.ConnectionString;
}
break;
case DatabaseType.PostgresSql:
{
var csb = new NpgsqlConnectionStringBuilder
{
ApplicationName = assemblyInformationProvider.VersionPrefix,
Host = serverAddress ?? "127.0.0.1",
Password = password,
Username = username
};
if (serverPort.HasValue)
csb.Port = serverPort.Value;
CreateTestConnection(csb.ConnectionString);
csb.Database = databaseName;
databaseConfiguration.ConnectionString = csb.ConnectionString;
}
break;
default:
throw new InvalidOperationException("Invalid DatabaseType!");
}
try
@@ -502,6 +546,7 @@ namespace Tgstation.Server.Host.Setup
}
while (true);
}
#pragma warning restore CA1502
/// <summary>
/// Prompts the user to create a <see cref="GeneralConfiguration"/>
@@ -48,25 +48,26 @@
<PackageReference Include="Cyberboss.SmartIrc4net.Standard" Version="0.4.6" />
<PackageReference Include="Discord.Net.WebSocket" Version="2.2.0" />
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0034" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.3" />
<PackageReference Include="Octokit" Version="0.47.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.1" />
<!-- If this is updated, be sure to update the reference in the README.md -->
@@ -85,7 +86,7 @@
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.1" />
<PackageReference Include="System.Management" Version="4.7.0" />
<PackageReference Include="Wangkanai.Detection.Browser" Version="2.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.0.49" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.0.50" />
</ItemGroup>
<ItemGroup>
@@ -48,14 +48,12 @@ namespace Tgstation.Server.Host.Components.Repository.Tests
tempDir,
default);
using (var repo = await TestRepoLoading(tempDir))
{
var gitObject = repo.Lookup("f636418bf47d238d33b0e4a34f0072b23a8aad0e");
Assert.IsNotNull(gitObject);
var commit = gitObject.Peel<Commit>();
using var repo = await TestRepoLoading(tempDir);
var gitObject = repo.Lookup("f636418bf47d238d33b0e4a34f0072b23a8aad0e");
Assert.IsNotNull(gitObject);
var commit = gitObject.Peel<Commit>();
Assert.AreEqual("Update Test.md", commit.Message);
}
Assert.AreEqual("Update Test.md", commit.Message);
}
finally
{