diff --git a/PluralKit.Core/Database/Database.cs b/PluralKit.Core/Database/Database.cs index 3c4250c7..9693a654 100644 --- a/PluralKit.Core/Database/Database.cs +++ b/PluralKit.Core/Database/Database.cs @@ -23,18 +23,16 @@ internal partial class Database: IDatabase private readonly ILogger _logger; private readonly IMetrics _metrics; private readonly DbConnectionCountHolder _countHolder; - private readonly DatabaseMigrator _migrator; private readonly NpgsqlDataSource _dataSource; private readonly NpgsqlDataSource _dataSourceMessages; public Database(CoreConfig config, DbConnectionCountHolder countHolder, ILogger logger, - IMetrics metrics, DatabaseMigrator migrator) + IMetrics metrics) { _config = config; _countHolder = countHolder; _metrics = metrics; - _migrator = migrator; _logger = logger.ForContext(); string connectionString(string src) @@ -121,12 +119,6 @@ internal partial class Database: IDatabase return conn; } - public async Task ApplyMigrations() - { - using var conn = await Obtain(); - await _migrator.ApplyMigrations(conn); - } - private class PassthroughTypeHandler: SqlMapper.TypeHandler { public override void SetValue(IDbDataParameter parameter, T value) => parameter.Value = value; diff --git a/PluralKit.Core/Database/IDatabase.cs b/PluralKit.Core/Database/IDatabase.cs index 6662ede9..2664f7fc 100644 --- a/PluralKit.Core/Database/IDatabase.cs +++ b/PluralKit.Core/Database/IDatabase.cs @@ -6,7 +6,6 @@ namespace PluralKit.Core; public interface IDatabase { - Task ApplyMigrations(); Task Obtain(bool messages = false); Task Execute(Func func); Task Execute(Func> func); diff --git a/PluralKit.Core/Database/Utils/DatabaseMigrator.cs b/PluralKit.Core/Database/Utils/DatabaseMigrator.cs deleted file mode 100644 index d4d58093..00000000 --- a/PluralKit.Core/Database/Utils/DatabaseMigrator.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Data; - -using Dapper; - -using Serilog; - -namespace PluralKit.Core; - -internal class DatabaseMigrator -{ - private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files - private const int TargetSchemaVersion = 52; - private readonly ILogger _logger; - - public DatabaseMigrator(ILogger logger) - { - _logger = logger; - } - - public async Task ApplyMigrations(IPKConnection conn) - { - // Run everything in a transaction - await using var tx = await conn.BeginTransactionAsync(); - - // Before applying migrations, clean out views/functions to prevent type errors - await ExecuteSqlFile($"{RootPath}.clean.sql", conn, tx); - - // Apply all migrations between the current database version and the target version - await ApplyMigrations(conn, tx); - - // Now, reapply views/functions (we deleted them above, no need to worry about conflicts) - await ExecuteSqlFile($"{RootPath}.Views.views.sql", conn, tx); - await ExecuteSqlFile($"{RootPath}.Functions.functions.sql", conn, tx); - - // Finally, commit tx - await tx.CommitAsync(); - } - - private async Task ApplyMigrations(IPKConnection conn, IDbTransaction tx) - { - var currentVersion = await GetCurrentDatabaseVersion(conn); - _logger.Information("Current schema version: {CurrentVersion}", currentVersion); - for (var migration = currentVersion + 1; migration <= TargetSchemaVersion; migration++) - { - _logger.Information("Applying schema migration {MigrationId}", migration); - await ExecuteSqlFile($"{RootPath}.Migrations.{migration}.sql", conn, tx); - } - } - - private async Task ExecuteSqlFile(string resourceName, IPKConnection conn, IDbTransaction tx = null) - { - await using var stream = typeof(Database).Assembly.GetManifestResourceStream(resourceName); - if (stream == null) throw new ArgumentException($"Invalid resource name '{resourceName}'"); - - using var reader = new StreamReader(stream); - var query = await reader.ReadToEndAsync(); - - await conn.ExecuteAsync(query, transaction: tx); - - // If the above creates new enum/composite types, we must tell Npgsql to reload the internal type caches - // This will propagate to every other connection as well, since it marks the global type mapper collection dirty. - ((PKConnection)conn).ReloadTypes(); - } - - private async Task GetCurrentDatabaseVersion(IPKConnection conn) - { - // First, check if the "info" table exists (it may not, if this is a *really* old database) - var hasInfoTable = - await conn.QuerySingleOrDefaultAsync( - "select count(*) from information_schema.tables where table_name = 'info'") == 1; - - // If we have the table, read the schema version - if (hasInfoTable) - return await conn.QuerySingleOrDefaultAsync("select schema_version from info"); - - // If not, we return version "-1" - // This means migration 0 will get executed, getting us into a consistent state - // Then, migration 1 gets executed, which creates the info table and sets version to 1 - return -1; - } -} \ No newline at end of file diff --git a/PluralKit.Core/Modules/DataStoreModule.cs b/PluralKit.Core/Modules/DataStoreModule.cs index e6ecdcd5..9f1a6d19 100644 --- a/PluralKit.Core/Modules/DataStoreModule.cs +++ b/PluralKit.Core/Modules/DataStoreModule.cs @@ -10,7 +10,6 @@ public class DataStoreModule: Module protected override void Load(ContainerBuilder builder) { builder.RegisterType().SingleInstance(); - builder.RegisterType().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().AsSelf().SingleInstance(); diff --git a/crates/premium/templates/cancel.html b/crates/premium/templates/cancel.html index 3c4540a8..4146e12c 100644 --- a/crates/premium/templates/cancel.html +++ b/crates/premium/templates/cancel.html @@ -27,6 +27,6 @@

for assistance please email us at billing@pluralkit.me
-
pricing/refunds | terms of service | privacy policy +
PluralKit Premium is offered by PluralKit, LLC. | info/pricing/refund policy | terms of service | privacy policy
home diff --git a/crates/premium/templates/index.html b/crates/premium/templates/index.html index 3f94353d..87cc437e 100644 --- a/crates/premium/templates/index.html +++ b/crates/premium/templates/index.html @@ -133,6 +133,21 @@ error initializing paddle client {% endif %} {% if show_login_form %} + +

+ PluralKit Premium is a paid subscription for the PluralKit Discord bot that offers cosmetic perks as well as power user features. +
Currently offered is +

    +
  • the ability to set custom system/member/group IDs,
  • +
  • lossless, higher resolution image hosting on PluralKit's CDN,
  • +
  • the ability to upload avatars/banners directly from the PluralKit Dashboard,
  • +
  • and a badge on your PluralKit system card to show off your support.
  • +
+ More features will be added in the future! +

+ +Premium is not yet released, please check back soon! +

Enter your email address to log in.

@@ -148,6 +163,6 @@ error initializing paddle client

for assistance please email us at billing@pluralkit.me
-
pricing/refunds | terms of service | privacy policy +
PluralKit Premium is offered by PluralKit, LLC. | info/pricing/refund policy | terms of service | privacy policy
home diff --git a/crates/premium/templates/info.html b/crates/premium/templates/info.html index 969321a7..473e7b9c 100644 --- a/crates/premium/templates/info.html +++ b/crates/premium/templates/info.html @@ -5,6 +5,21 @@

PluralKit Premium

+ +

+ PluralKit Premium is a paid subscription for the PluralKit Discord bot that offers cosmetic perks as well as power user features. +
Currently offered is +

    +
  • the ability to set custom system/member/group IDs,
  • +
  • lossless, higher resolution image hosting on PluralKit's CDN,
  • +
  • the ability to upload avatars/banners directly from the PluralKit Dashboard,
  • +
  • and a badge on your PluralKit system card to show off your support.
  • +
+ More features will be added in the future! +

+ +Premium is not yet released, please check back soon! +

Pricing

PluralKit Premium costs $5/mo plus tax applied as per your region.
For any plans longer than 1 month, the equivalent price is applied - for instance, a 3-month plan is $15/3mo plus tax, or a yearly plan is $60/year plus tax.
There is no discount for pre-paying multiple months.

@@ -14,6 +29,6 @@

for assistance please email us at billing@pluralkit.me
-
pricing/refunds | terms of service | privacy policy +
PluralKit Premium is offered by PluralKit, LLC. | info/pricing/refund policy | terms of service | privacy policy
home