Innovenergy_trunk/csharp/App/Backend/Database/Db.cs

119 lines
4.0 KiB
C#

using System.Reactive.Concurrency;
using System.Reactive.Linq;
using CliWrap;
using CliWrap.Buffered;
using InnovEnergy.App.Backend.DataTypes;
using InnovEnergy.App.Backend.DataTypes.Methods;
using InnovEnergy.App.Backend.Relations;
using InnovEnergy.Lib.Utils;
using SQLite;
namespace InnovEnergy.App.Backend.Database;
public static partial class Db
{
internal const String DbPath = "./db.sqlite";
private static SQLiteConnection Connection { get; } = new SQLiteConnection(DbPath);
public static TableQuery<Session> Sessions => Connection.Table<Session>();
public static TableQuery<Folder> Folders => Connection.Table<Folder>();
public static TableQuery<Installation> Installations => Connection.Table<Installation>();
public static TableQuery<User> Users => Connection.Table<User>();
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
public static TableQuery<OrderNumber2Installation> OrderNumber2Installation => Connection.Table<OrderNumber2Installation>();
public static TableQuery<DeletedInstallation> DeletedInstallations => Connection.Table<DeletedInstallation>();
public static TableQuery<DeletedUser> DeletedUsers => Connection.Table<DeletedUser>();
public static TableQuery<DeletedFolder> DeletedFolders => Connection.Table<DeletedFolder>();
public static void Init()
{
// used to force static constructor
}
static Db()
{
// on startup create/migrate tables
Connection.RunInTransaction(() =>
{
Connection.CreateTable<User>();
Connection.CreateTable<DeletedUser>();
Connection.CreateTable<Installation>();
Connection.CreateTable<DeletedInstallation>();
Connection.CreateTable<DeletedFolder>();
Connection.CreateTable<Folder>();
Connection.CreateTable<FolderAccess>();
Connection.CreateTable<InstallationAccess>();
Connection.CreateTable<Session>();
Connection.CreateTable<OrderNumber2Installation>();
});
Observable.Interval(TimeSpan.FromDays(0.5))
.StartWith(0) // Do it right away (on startup)
.ObserveOn(TaskPoolScheduler.Default)
.SubscribeOn(TaskPoolScheduler.Default)
.SelectMany(Cleanup)
.Subscribe();
}
private static Boolean RunTransaction(Func<Boolean> func)
{
var savepoint = Connection.SaveTransactionPoint();
var success = false;
try
{
success = func();
}
finally
{
if (success)
Connection.Release(savepoint);
else
Connection.RollbackTo(savepoint);
}
return success;
}
private static async Task<Boolean> Cleanup(Int64 _)
{
await UpdateS3Urls();
DeleteStaleSessions();
return true;
}
private static void DeleteStaleSessions()
{
var deadline = DateTime.Now - Session.MaxAge;
Sessions.Delete(s => s.LastSeen < deadline);
}
private static async Task UpdateS3Urls()
{
var bucketList = await Cli.Wrap("exo")
.WithArguments("storage list -O json")
.ExecuteBufferedAsync();
var installationsToUpdate = Installations
.Select(i => i)
.Where(i => bucketList.StandardOutput.Contains("\"" + i.BucketName())).ToList()
;
foreach (var installation in installationsToUpdate)
{
await installation.RenewS3Credentials();
}
}
}