using System.Diagnostics.CodeAnalysis; using InnovEnergy.App.Backend.Model; using InnovEnergy.App.Backend.Model.Relations; using InnovEnergy.Lib.Utils; using SQLite; namespace InnovEnergy.App.Backend.Database; public static partial class Db { internal const String DbPath = "./db.sqlite"; public static SQLiteConnection Connection { get; } = new SQLiteConnection(DbPath); public static TableQuery Sessions => Connection.Table(); public static TableQuery Folders => Connection.Table(); public static TableQuery Installations => Connection.Table(); public static TableQuery Users => Connection.Table(); public static TableQuery User2Folder => Connection.Table(); public static TableQuery User2Installation => Connection.Table(); public static Int32 NbUser2Installation => User2Installation.Count(); public static Int32 NbUser2Folder => User2Folder.Count(); public static Int32 NbFolders => Folders.Count(); public static Int32 NbInstallations => Installations.Count(); public static Int32 NbUsers => Users.Count(); public static Folder? GetFolderById(Int64 id) { return Folders .FirstOrDefault(f => f.Id == id); } public static Installation? GetInstallationById(Int64 id) { return Installations .FirstOrDefault(i => i.Id == id); } public static User? GetUserById(Int64 id) { return Users .FirstOrDefault(u => u.Id == id); } [SuppressMessage("ReSharper", "AccessToDisposedClosure")] static Db() { // on startup create/migrate tables using var db = new SQLiteConnection(DbPath); db.RunInTransaction(() => { db.CreateTable(); db.CreateTable(); db.CreateTable(); db.CreateTable(); db.CreateTable(); db.CreateTable(); }); } // the C in CRUD private static Int64 Create(TreeNode treeNode) { try { Connection.Insert(treeNode); return SQLite3.LastInsertRowid(Connection.Handle); } catch (Exception e) { return -1; } } private static Boolean Create(Session session) { try { Connection.Insert(session); return true; } catch (Exception e) { return false; } } // the U in CRUD private static Boolean Update(TreeNode treeNode) { try { Connection.InsertOrReplace(treeNode); return true; } catch (Exception e) { return false; } } // the D in CRUD private static Boolean Delete(TreeNode treeNode) { try { Connection.Delete(treeNode); return true; } catch (Exception e) { return false; } } public static IEnumerable GetAllAccessibleInstallations(User user) { var direct = GetDirectlyAccessibleInstallations(user); var fromFolders = GetAllAccessibleFolders(user) .SelectMany(GetChildInstallations); return direct .Concat(fromFolders) .Distinct(); } public static IEnumerable GetAllAccessibleFolders(User user) { return GetDirectlyAccessibleFolders(user) .SelectMany(GetDescendantFolders) .Distinct(); // Distinct because the user might have direct access // to a child folder of a folder he has already access to } public static IEnumerable GetDirectlyAccessibleInstallations(User user) { return User2Installation .Where(r => r.UserId == user.Id) .Select(r => r.InstallationId) .Select(GetInstallationById) .NotNull() .Do(i => i.ParentId = 0); // hide inaccessible parents from calling user } public static IEnumerable GetDirectlyAccessibleFolders(User user) { return User2Folder .Where(r => r.UserId == user.Id) .Select(r => r.FolderId) .Select(GetFolderById) .NotNull() .Do(i => i.ParentId = 0); // hide inaccessible parents from calling user; } public static Boolean AddToAccessibleInstallations(Int64 userId, Int64 updatedInstallationId) { var con = new User2Installation { UserId = userId, InstallationId = updatedInstallationId }; try { Connection.Insert(con); return true; } catch (Exception e) { return false; } } public static Boolean AddToAccessibleFolders(Int64 userId, Int64 updatedFolderId) { var con = new User2Folder { UserId = userId, FolderId = updatedFolderId }; try { Connection.Insert(con); return true; } catch (Exception e) { return false; } } public static User? GetUserByToken(String token) { return Sessions .Where(s => s.Token == token).ToList() .Where(s => s.Valid) .Select(s => s.UserId) .Select(GetUserById) .FirstOrDefault(); } public static Boolean NewSession(Session ses) => Create(ses); public static Boolean DeleteSession(Int64 id) { try { Sessions.Delete(u => u.UserId == id); return true; } catch (Exception e) { return false; } } public static String? GetInstallationS3Key(Int64 installationId) { return Installations .FirstOrDefault(i => i.Id == installationId)? .S3Key; } public static void DeleteAllS3Keys() { foreach (var installation in Installations.ToList()) { installation.S3Key = null; Update(installation); } } }