mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2024-11-25 14:42:44 +01:00
Compare commits
3 Commits
1024a58a47
...
4f5e27f651
Author | SHA1 | Date | |
---|---|---|---|
4f5e27f651 | |||
cbf81ec95a | |||
8a80cb8c20 |
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
|
using Avalonia.Threading;
|
||||||
using DHT.Desktop.Dialogs.File;
|
using DHT.Desktop.Dialogs.File;
|
||||||
using DHT.Desktop.Dialogs.Message;
|
using DHT.Desktop.Dialogs.Message;
|
||||||
using DHT.Server.Database;
|
using DHT.Server.Database;
|
||||||
@ -42,10 +44,15 @@ static class DatabaseGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IDatabaseFile?> TryOpenOrCreateDatabaseFromPath(string path, Window window, ISchemaUpgradeCallbacks schemaUpgradeCallbacks) {
|
public static async Task<IDatabaseFile?> TryOpenOrCreateDatabaseFromPath(string path, Window window, ISchemaUpgradeCallbacks schemaUpgradeCallbacks) {
|
||||||
|
var prevSynchronizationContext = SynchronizationContext.Current;
|
||||||
|
SynchronizationContext.SetSynchronizationContext(new AvaloniaSynchronizationContext());
|
||||||
|
var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
||||||
|
SynchronizationContext.SetSynchronizationContext(prevSynchronizationContext);
|
||||||
|
|
||||||
IDatabaseFile? file = null;
|
IDatabaseFile? file = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
file = await SqliteDatabaseFile.OpenOrCreate(path, schemaUpgradeCallbacks);
|
file = await SqliteDatabaseFile.OpenOrCreate(path, schemaUpgradeCallbacks, taskScheduler);
|
||||||
} catch (InvalidDatabaseVersionException ex) {
|
} catch (InvalidDatabaseVersionException ex) {
|
||||||
await Dialog.ShowOk(window, "Database Error", "Database '" + Path.GetFileName(path) + "' appears to be corrupted (invalid version: " + ex.Version + ").");
|
await Dialog.ShowOk(window, "Database Error", "Database '" + Path.GetFileName(path) + "' appears to be corrupted (invalid version: " + ex.Version + ").");
|
||||||
} catch (DatabaseTooNewException ex) {
|
} catch (DatabaseTooNewException ex) {
|
||||||
|
@ -86,13 +86,10 @@ sealed class DatabasePageModel : BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async Task MergeWithDatabaseFromPaths(IDatabaseFile target, string[] paths, ProgressDialog dialog, IProgressCallback callback) {
|
private static async Task MergeWithDatabaseFromPaths(IDatabaseFile target, string[] paths, ProgressDialog dialog, IProgressCallback callback) {
|
||||||
int total = paths.Length;
|
var schemaUpgradeCallbacks = new SchemaUpgradeCallbacks(dialog, paths.Length);
|
||||||
|
|
||||||
await PerformImport(target, paths, dialog, callback, "Database Merge", "Database Error", "database file", async path => {
|
await PerformImport(target, paths, dialog, callback, "Database Merge", "Database Error", "database file", async path => {
|
||||||
SynchronizationContext? prevSyncContext = SynchronizationContext.Current;
|
IDatabaseFile? db = await DatabaseGui.TryOpenOrCreateDatabaseFromPath(path, dialog, schemaUpgradeCallbacks);
|
||||||
SynchronizationContext.SetSynchronizationContext(new AvaloniaSynchronizationContext());
|
|
||||||
IDatabaseFile? db = await DatabaseGui.TryOpenOrCreateDatabaseFromPath(path, dialog, new SchemaUpgradeCallbacks(dialog, total));
|
|
||||||
SynchronizationContext.SetSynchronizationContext(prevSyncContext);
|
|
||||||
|
|
||||||
if (db == null) {
|
if (db == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -21,7 +21,7 @@ public static class LegacyArchiveImport {
|
|||||||
|
|
||||||
public static async Task<bool> Read(Stream stream, IDatabaseFile db, FakeSnowflake fakeSnowflake, Func<Data.Server[], Task<Dictionary<Data.Server, ulong>?>> askForServerIds) {
|
public static async Task<bool> Read(Stream stream, IDatabaseFile db, FakeSnowflake fakeSnowflake, Func<Data.Server[], Task<Dictionary<Data.Server, ulong>?>> askForServerIds) {
|
||||||
var perf = Log.Start();
|
var perf = Log.Start();
|
||||||
var root = await JsonSerializer.DeserializeAsync(stream, LegacyArchiveJsonContext.Default.JsonElement);
|
var root = await JsonSerializer.DeserializeAsync(stream, JsonElementContext.Default.JsonElement);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var meta = root.RequireObject("meta");
|
var meta = root.RequireObject("meta");
|
||||||
|
@ -18,7 +18,7 @@ namespace DHT.Server.Database.Sqlite;
|
|||||||
public sealed class SqliteDatabaseFile : IDatabaseFile {
|
public sealed class SqliteDatabaseFile : IDatabaseFile {
|
||||||
private const int DefaultPoolSize = 5;
|
private const int DefaultPoolSize = 5;
|
||||||
|
|
||||||
public static async Task<SqliteDatabaseFile?> OpenOrCreate(string path, ISchemaUpgradeCallbacks schemaUpgradeCallbacks) {
|
public static async Task<SqliteDatabaseFile?> OpenOrCreate(string path, ISchemaUpgradeCallbacks schemaUpgradeCallbacks, TaskScheduler computeTaskResultScheduler) {
|
||||||
var connectionString = new SqliteConnectionStringBuilder {
|
var connectionString = new SqliteConnectionStringBuilder {
|
||||||
DataSource = path,
|
DataSource = path,
|
||||||
Mode = SqliteOpenMode.ReadWriteCreate,
|
Mode = SqliteOpenMode.ReadWriteCreate,
|
||||||
@ -36,7 +36,7 @@ public sealed class SqliteDatabaseFile : IDatabaseFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wasOpened) {
|
if (wasOpened) {
|
||||||
return new SqliteDatabaseFile(path, pool);
|
return new SqliteDatabaseFile(path, pool, computeTaskResultScheduler);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pool.Dispose();
|
pool.Dispose();
|
||||||
@ -53,13 +53,13 @@ public sealed class SqliteDatabaseFile : IDatabaseFile {
|
|||||||
private readonly AsyncValueComputer<long>.Single totalAttachmentsComputer;
|
private readonly AsyncValueComputer<long>.Single totalAttachmentsComputer;
|
||||||
private readonly AsyncValueComputer<long>.Single totalDownloadsComputer;
|
private readonly AsyncValueComputer<long>.Single totalDownloadsComputer;
|
||||||
|
|
||||||
private SqliteDatabaseFile(string path, SqliteConnectionPool pool) {
|
private SqliteDatabaseFile(string path, SqliteConnectionPool pool, TaskScheduler computeTaskResultScheduler) {
|
||||||
this.log = Log.ForType(typeof(SqliteDatabaseFile), System.IO.Path.GetFileName(path));
|
this.log = Log.ForType(typeof(SqliteDatabaseFile), System.IO.Path.GetFileName(path));
|
||||||
this.pool = pool;
|
this.pool = pool;
|
||||||
|
|
||||||
this.totalMessagesComputer = AsyncValueComputer<long>.WithResultProcessor(UpdateMessageStatistics).WithOutdatedResults().BuildWithComputer(ComputeMessageStatistics);
|
this.totalMessagesComputer = AsyncValueComputer<long>.WithResultProcessor(UpdateMessageStatistics, computeTaskResultScheduler).WithOutdatedResults().BuildWithComputer(ComputeMessageStatistics);
|
||||||
this.totalAttachmentsComputer = AsyncValueComputer<long>.WithResultProcessor(UpdateAttachmentStatistics).WithOutdatedResults().BuildWithComputer(ComputeAttachmentStatistics);
|
this.totalAttachmentsComputer = AsyncValueComputer<long>.WithResultProcessor(UpdateAttachmentStatistics, computeTaskResultScheduler).WithOutdatedResults().BuildWithComputer(ComputeAttachmentStatistics);
|
||||||
this.totalDownloadsComputer = AsyncValueComputer<long>.WithResultProcessor(UpdateDownloadStatistics).WithOutdatedResults().BuildWithComputer(ComputeDownloadStatistics);
|
this.totalDownloadsComputer = AsyncValueComputer<long>.WithResultProcessor(UpdateDownloadStatistics, computeTaskResultScheduler).WithOutdatedResults().BuildWithComputer(ComputeDownloadStatistics);
|
||||||
|
|
||||||
this.Path = path;
|
this.Path = path;
|
||||||
this.Statistics = new DatabaseStatistics();
|
this.Statistics = new DatabaseStatistics();
|
||||||
|
@ -60,6 +60,10 @@ abstract class BaseEndpoint {
|
|||||||
protected abstract Task<IHttpOutput> Respond(HttpContext ctx);
|
protected abstract Task<IHttpOutput> Respond(HttpContext ctx);
|
||||||
|
|
||||||
protected static async Task<JsonElement> ReadJson(HttpContext ctx) {
|
protected static async Task<JsonElement> ReadJson(HttpContext ctx) {
|
||||||
return await ctx.Request.ReadFromJsonAsync<JsonElement?>() ?? throw new HttpException(HttpStatusCode.UnsupportedMediaType, "This endpoint only accepts JSON.");
|
try {
|
||||||
|
return await ctx.Request.ReadFromJsonAsync(JsonElementContext.Default.JsonElement);
|
||||||
|
} catch (JsonException) {
|
||||||
|
throw new HttpException(HttpStatusCode.UnsupportedMediaType, "This endpoint only accepts JSON.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace DHT.Server.Database.Import;
|
namespace DHT.Utils.Http;
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, GenerationMode = JsonSourceGenerationMode.Default)]
|
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, GenerationMode = JsonSourceGenerationMode.Default)]
|
||||||
[JsonSerializable(typeof(JsonElement))]
|
[JsonSerializable(typeof(JsonElement))]
|
||||||
sealed partial class LegacyArchiveJsonContext : JsonSerializerContext {}
|
public sealed partial class JsonElementContext : JsonSerializerContext {}
|
Loading…
Reference in New Issue
Block a user