2023-07-13 11:23:05 +00:00
|
|
|
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;
|
2023-07-13 11:23:05 +00:00
|
|
|
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;
|
2023-07-13 11:23:05 +00:00
|
|
|
using Microsoft.Identity.Client;
|
2023-02-16 12:57:06 +00:00
|
|
|
using SQLite;
|
2023-07-13 11:23:05 +00:00
|
|
|
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
|
|
|
{
|
2023-07-20 11:57:12 +00:00
|
|
|
// internal const String DbPath = "./db.sqlite";
|
2023-03-09 15:32:11 +00:00
|
|
|
|
2023-07-13 11:23:05 +00:00
|
|
|
private static SQLiteConnection Connection { get; } = ((Func<SQLiteConnection>)(() =>
|
|
|
|
{
|
|
|
|
var latestDb = new DirectoryInfo(@"DbBackups").GetFiles()
|
|
|
|
.OrderBy(f => f.LastWriteTime)
|
|
|
|
.First().Name;
|
2023-03-13 10:48:04 +00:00
|
|
|
|
2023-07-13 11:23:05 +00:00
|
|
|
var fileConnection = new SQLiteConnection("DbBackups/"+latestDb);
|
|
|
|
|
|
|
|
var memoryConnection = new SQLiteConnection(":memory:");
|
|
|
|
|
|
|
|
// fileConnection.Backup(memoryConnection.DatabasePath);
|
|
|
|
|
|
|
|
memoryConnection.CreateTable<User>();
|
|
|
|
memoryConnection.CreateTable<DeletedUser>();
|
|
|
|
memoryConnection.CreateTable<Installation>();
|
|
|
|
memoryConnection.CreateTable<DeletedInstallation>();
|
|
|
|
memoryConnection.CreateTable<DeletedFolder>();
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
foreach (var obj in fileConnection.Table<DeletedInstallation>())
|
|
|
|
{
|
|
|
|
memoryConnection.Insert(obj);
|
|
|
|
}
|
|
|
|
foreach (var obj in fileConnection.Table<DeletedUser>())
|
|
|
|
{
|
|
|
|
memoryConnection.Insert(obj);
|
|
|
|
}
|
|
|
|
foreach (var obj in fileConnection.Table<DeletedFolder>())
|
|
|
|
{
|
|
|
|
memoryConnection.Insert(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
return memoryConnection;
|
|
|
|
}))();
|
|
|
|
|
|
|
|
public static void BackupDatabase()
|
|
|
|
{
|
|
|
|
var filename = "db-" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + ".sqlite";
|
|
|
|
Connection.Backup("DbBackups/"+filename);
|
|
|
|
}
|
|
|
|
|
2023-04-04 08:39:42 +00:00
|
|
|
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>();
|
2023-03-23 12:28:55 +00:00
|
|
|
|
|
|
|
public static void Init()
|
|
|
|
{
|
2023-04-04 08:39:42 +00:00
|
|
|
// 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>();
|
2023-03-23 12:28:55 +00:00
|
|
|
Connection.CreateTable<DeletedUser>();
|
2023-03-15 13:38:06 +00:00
|
|
|
Connection.CreateTable<Installation>();
|
2023-03-23 12:28:55 +00:00
|
|
|
Connection.CreateTable<DeletedInstallation>();
|
|
|
|
Connection.CreateTable<DeletedFolder>();
|
2023-03-15 13:38:06 +00:00
|
|
|
Connection.CreateTable<Folder>();
|
2023-03-16 08:25:36 +00:00
|
|
|
Connection.CreateTable<FolderAccess>();
|
|
|
|
Connection.CreateTable<InstallationAccess>();
|
2023-03-15 13:38:06 +00:00
|
|
|
Connection.CreateTable<Session>();
|
2023-03-23 13:23:03 +00:00
|
|
|
Connection.CreateTable<OrderNumber2Installation>();
|
2023-02-16 12:57:06 +00:00
|
|
|
});
|
2023-03-09 15:32:11 +00:00
|
|
|
|
2023-03-16 09:31:24 +00:00
|
|
|
Observable.Interval(TimeSpan.FromDays(0.5))
|
2023-03-21 10:40:23 +00:00
|
|
|
.StartWith(0) // Do it right away (on startup)
|
|
|
|
.ObserveOn(TaskPoolScheduler.Default)
|
2023-04-04 08:39:42 +00:00
|
|
|
.SubscribeOn(TaskPoolScheduler.Default)
|
2023-03-16 09:31:24 +00:00
|
|
|
.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 _)
|
2023-02-21 08:58:21 +00:00
|
|
|
{
|
2023-03-16 09:31:24 +00:00
|
|
|
await UpdateS3Urls();
|
2023-03-15 13:38:06 +00:00
|
|
|
DeleteStaleSessions();
|
2023-03-16 09:31:24 +00:00
|
|
|
return true;
|
2023-02-21 08:58:21 +00:00
|
|
|
}
|
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
|
|
|
{
|
2023-07-20 11:57:12 +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-03-09 12:20:37 +00:00
|
|
|
|
2023-07-06 08:57:57 +00:00
|
|
|
private static async Task UpdateS3Urls()
|
2023-03-09 12:20:37 +00:00
|
|
|
{
|
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)
|
|
|
|
.Where(i => bucketList.StandardOutput.Contains("\"" + i.BucketName())).ToList()
|
|
|
|
;
|
|
|
|
|
|
|
|
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 12:20:37 +00:00
|
|
|
}
|
2023-03-23 13:58:59 +00:00
|
|
|
|
2023-03-09 15:32:11 +00:00
|
|
|
}
|