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

170 lines
5.5 KiB
C#
Raw Normal View History

using System.Data.SQLite;
2023-03-21 10:40:23 +00:00
using System.Reactive.Concurrency;
2023-03-15 13:38:06 +00:00
using System.Reactive.Linq;
using System.Runtime.InteropServices;
2023-07-06 08:57:57 +00:00
using CliWrap;
using CliWrap.Buffered;
2023-03-15 13:38:06 +00:00
using InnovEnergy.App.Backend.DataTypes;
2023-03-16 09:34:47 +00:00
using InnovEnergy.App.Backend.DataTypes.Methods;
2023-03-15 13:38:06 +00:00
using InnovEnergy.App.Backend.Relations;
2023-02-16 12:57:06 +00:00
using InnovEnergy.Lib.Utils;
using Microsoft.Identity.Client;
2023-02-16 12:57:06 +00:00
using SQLite;
using SQLiteConnection = SQLite.SQLiteConnection;
2023-02-16 12:57:06 +00:00
2023-03-15 13:38:06 +00:00
2023-03-08 12:20:33 +00:00
namespace InnovEnergy.App.Backend.Database;
2023-02-16 12:57:06 +00:00
2023-03-15 13:38:06 +00:00
2023-03-13 10:36:50 +00:00
public static partial class Db
2023-02-16 12:57:06 +00:00
{
// internal const String DbPath = "./db.sqlite";
2023-03-09 15:32:11 +00:00
private static SQLiteConnection Connection { get; } = ((Func<SQLiteConnection>)(() =>
{
var latestDb = new DirectoryInfo(@"DbBackups").GetFiles()
.OrderBy(f => f.LastWriteTime)
2023-08-23 09:31:30 +00:00
.Last().Name;
var fileConnection = new SQLiteConnection("DbBackups/"+latestDb);
var memoryConnection = new SQLiteConnection(":memory:");
// fileConnection.Backup(memoryConnection.DatabasePath);
memoryConnection.CreateTable<User>();
memoryConnection.CreateTable<Installation>();
memoryConnection.CreateTable<Folder>();
memoryConnection.CreateTable<FolderAccess>();
memoryConnection.CreateTable<InstallationAccess>();
memoryConnection.CreateTable<Session>();
memoryConnection.CreateTable<OrderNumber2Installation>();
foreach (var obj in fileConnection.Table<Session>())
{
memoryConnection.Insert(obj);
}
foreach (var obj in fileConnection.Table<Folder>())
{
memoryConnection.Insert(obj);
}
foreach (var obj in fileConnection.Table<Installation>())
{
memoryConnection.Insert(obj);
}
foreach (var obj in fileConnection.Table<User>())
{
memoryConnection.Insert(obj);
}
foreach (var obj in fileConnection.Table<FolderAccess>())
{
memoryConnection.Insert(obj);
}
foreach (var obj in fileConnection.Table<InstallationAccess>())
{
memoryConnection.Insert(obj);
}
foreach (var obj in fileConnection.Table<OrderNumber2Installation>())
{
memoryConnection.Insert(obj);
}
return memoryConnection;
}))();
public static void BackupDatabase()
{
var filename = "db-" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + ".sqlite";
Connection.Backup("DbBackups/"+filename);
}
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>();
2023-03-23 12:28:55 +00:00
public static void Init()
{
// used to force static constructor
2023-03-23 12:28:55 +00:00
}
2023-03-09 15:32:11 +00:00
2023-02-16 12:57:06 +00:00
static Db()
{
// on startup create/migrate tables
2023-03-09 15:32:11 +00:00
2023-03-15 13:38:06 +00:00
Connection.RunInTransaction(() =>
2023-02-16 12:57:06 +00:00
{
2023-03-15 13:38:06 +00:00
Connection.CreateTable<User>();
Connection.CreateTable<Installation>();
Connection.CreateTable<Folder>();
Connection.CreateTable<FolderAccess>();
Connection.CreateTable<InstallationAccess>();
2023-03-15 13:38:06 +00:00
Connection.CreateTable<Session>();
Connection.CreateTable<OrderNumber2Installation>();
2023-02-16 12:57:06 +00:00
});
2023-03-09 15:32:11 +00:00
2023-08-23 09:31:30 +00:00
Observable.Interval(TimeSpan.FromHours(0.5))
2023-03-21 10:40:23 +00:00
.StartWith(0) // Do it right away (on startup)
.ObserveOn(TaskPoolScheduler.Default)
.SubscribeOn(TaskPoolScheduler.Default)
.SelectMany(Cleanup)
2023-03-21 10:40:23 +00:00
.Subscribe();
2023-02-16 12:57:06 +00:00
}
2023-03-09 15:32:11 +00:00
2023-03-15 13:38:06 +00:00
private static Boolean RunTransaction(Func<Boolean> func)
2023-02-16 12:57:06 +00:00
{
2023-03-15 13:38:06 +00:00
var savepoint = Connection.SaveTransactionPoint();
var success = false;
2023-02-16 12:57:06 +00:00
try
{
2023-03-15 13:38:06 +00:00
success = func();
2023-02-16 12:57:06 +00:00
}
2023-03-15 13:38:06 +00:00
finally
2023-02-16 12:57:06 +00:00
{
2023-03-15 13:38:06 +00:00
if (success)
Connection.Release(savepoint);
else
Connection.RollbackTo(savepoint);
2023-02-16 12:57:06 +00:00
}
2023-03-09 15:32:11 +00:00
2023-03-15 13:38:06 +00:00
return success;
2023-02-16 12:57:06 +00:00
}
2023-03-09 15:32:11 +00:00
2023-02-16 12:57:06 +00:00
2023-03-16 09:34:47 +00:00
private static async Task<Boolean> Cleanup(Int64 _)
{
await UpdateS3Urls();
2023-03-15 13:38:06 +00:00
DeleteStaleSessions();
return true;
}
2023-03-09 11:50:21 +00:00
2023-03-15 13:38:06 +00:00
private static void DeleteStaleSessions()
2023-03-09 11:50:21 +00:00
{
var deadline = DateTime.Now.AddDays((-1)*Session.MaxAge.Days);
2023-03-15 13:38:06 +00:00
Sessions.Delete(s => s.LastSeen < deadline);
2023-03-09 11:50:21 +00:00
}
2023-07-06 08:57:57 +00:00
private static async Task UpdateS3Urls()
{
2023-07-06 08:57:57 +00:00
var bucketList = await Cli.Wrap("exo")
.WithArguments("storage list -O json")
.ExecuteBufferedAsync();
var installationsToUpdate = Installations
.Select(i => i)
2023-08-23 09:31:30 +00:00
.Where(i => bucketList.StandardOutput.Contains("\"" + i.BucketName() + "\"")).ToList();
2023-07-06 08:57:57 +00:00
foreach (var installation in installationsToUpdate)
{
2023-07-13 07:40:04 +00:00
await installation.RenewS3Credentials();
2023-07-06 08:57:57 +00:00
}
}
2023-03-09 15:32:11 +00:00
}