Make DB class static

This commit is contained in:
ig 2023-03-13 11:36:50 +01:00
parent 6db610d308
commit 5a082c22e8
8 changed files with 177 additions and 142 deletions

View File

@ -1,19 +1,18 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using InnovEnergy.App.Backend.Model; using InnovEnergy.App.Backend.Model;
using InnovEnergy.App.Backend.Model.Relations; using InnovEnergy.App.Backend.Model.Relations;
using InnovEnergy.App.Backend.Utils;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using SQLite; using SQLite;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db : IDisposable public static partial class Db
{ {
internal const String DbPath = "./db.sqlite"; internal const String DbPath = "./db.sqlite";
private readonly SQLiteConnection _Db; // internal handle to the connection, disposable private static readonly SQLiteConnection _Db = new SQLiteConnection(DbPath);
private TableQuery<Session> Sessions => _Db.Table<Session>(); private static TableQuery<Session> Sessions => _Db.Table<Session>();
[SuppressMessage("ReSharper", "AccessToDisposedClosure")] [SuppressMessage("ReSharper", "AccessToDisposedClosure")]
static Db() static Db()
@ -33,16 +32,9 @@ public partial class Db : IDisposable
}); });
} }
// private, force access through Connect()
private Db() => _Db = new SQLiteConnection(DbPath);
public static Db Connect() => new Db();
public void Dispose() => _Db.Dispose();
// the C in CRUD // the C in CRUD
private Int64 Create(TreeNode treeNode) private static Int64 Create(TreeNode treeNode)
{ {
try try
{ {
@ -56,7 +48,7 @@ public partial class Db : IDisposable
} }
private Boolean Create(Session session) private static Boolean Create(Session session)
{ {
try try
{ {
@ -70,7 +62,7 @@ public partial class Db : IDisposable
} }
// the U in CRUD // the U in CRUD
private Boolean Update(TreeNode treeNode) private static Boolean Update(TreeNode treeNode)
{ {
try try
{ {
@ -84,7 +76,7 @@ public partial class Db : IDisposable
} }
// the D in CRUD // the D in CRUD
private Boolean Delete(TreeNode treeNode) private static Boolean Delete(TreeNode treeNode)
{ {
try try
{ {
@ -97,49 +89,49 @@ public partial class Db : IDisposable
} }
} }
public IEnumerable<Installation> GetAllAccessibleInstallations(User user) public static IEnumerable<Installation> GetAllAccessibleInstallations(User user)
{ {
var direct = GetDirectlyAccessibleInstallations(user); var direct = GetDirectlyAccessibleInstallations(user);
var fromFolders = GetAllAccessibleFolders(user) var fromFolders = GetAllAccessibleFolders(user)
.SelectMany(GetChildInstallations); .SelectMany(GetChildInstallations);
return direct return direct
.Concat(fromFolders) .Concat(fromFolders)
.Distinct(); .Distinct();
} }
public IEnumerable<Folder> GetAllAccessibleFolders(User user) public static IEnumerable<Folder> GetAllAccessibleFolders(User user)
{ {
return GetDirectlyAccessibleFolders(user) return GetDirectlyAccessibleFolders(user)
.SelectMany(GetDescendantFolders) .SelectMany(GetDescendantFolders)
.Distinct(); .Distinct();
// Distinct because the user might have direct access // Distinct because the user might have direct access
// to a child folder of a folder he has already access to // to a child folder of a folder he has already access to
} }
public IEnumerable<Installation> GetDirectlyAccessibleInstallations(User user) public static IEnumerable<Installation> GetDirectlyAccessibleInstallations(User user)
{ {
return User2Installation return User2Installation
.Where(r => r.UserId == user.Id) .Where(r => r.UserId == user.Id)
.Select(r => r.InstallationId) .Select(r => r.InstallationId)
.Select(GetInstallationById) .Select(GetInstallationById)
.NotNull() .NotNull()
.Do(i => i.ParentId = 0); // hide inaccessible parents from calling user .Do(i => i.ParentId = 0); // hide inaccessible parents from calling user
} }
public IEnumerable<Folder> GetDirectlyAccessibleFolders(User user) public static IEnumerable<Folder> GetDirectlyAccessibleFolders(User user)
{ {
return User2Folder return User2Folder
.Where(r => r.UserId == user.Id) .Where(r => r.UserId == user.Id)
.Select(r => r.FolderId) .Select(r => r.FolderId)
.Select(GetFolderById) .Select(GetFolderById)
.NotNull() .NotNull()
.Do(i => i.ParentId = 0); // hide inaccessible parents from calling user; .Do(i => i.ParentId = 0); // hide inaccessible parents from calling user;
} }
public Boolean AddToAccessibleInstallations(Int64 userId, Int64 updatedInstallationId) public static Boolean AddToAccessibleInstallations(Int64 userId, Int64 updatedInstallationId)
{ {
var con = new User2Installation var con = new User2Installation
{ {
@ -158,7 +150,7 @@ public partial class Db : IDisposable
} }
} }
public Boolean AddToAccessibleFolders(Int64 userId, Int64 updatedFolderId) public static Boolean AddToAccessibleFolders(Int64 userId, Int64 updatedFolderId)
{ {
var con = new User2Folder var con = new User2Folder
{ {
@ -178,7 +170,7 @@ public partial class Db : IDisposable
} }
public User? GetUserByToken(String token) public static User? GetUserByToken(String token)
{ {
return Sessions return Sessions
.Where(s => s.Token == token).ToList() .Where(s => s.Token == token).ToList()
@ -189,9 +181,9 @@ public partial class Db : IDisposable
} }
public Boolean NewSession(Session ses) => Create(ses); public static Boolean NewSession(Session ses) => Create(ses);
public Boolean DeleteSession(Int64 id) public static Boolean DeleteSession(Int64 id)
{ {
try try
{ {
@ -204,13 +196,14 @@ public partial class Db : IDisposable
} }
} }
public Object? GetInstallationS3Key(Int64 installationId) public static String? GetInstallationS3Key(Int64 installationId)
{ {
return Installations return Installations
.FirstOrDefault(installation => installation.Id == installationId).S3Key; .FirstOrDefault(i => i.Id == installationId)?
.S3Key;
} }
public void DeleteS3KeysDaily() public static void DeleteAllS3Keys()
{ {
foreach (var installation in Installations.ToList()) foreach (var installation in Installations.ToList())
{ {

View File

@ -1,18 +0,0 @@
using InnovEnergy.App.Backend.Model;
using SQLite;
namespace InnovEnergy.App.Backend.Database;
// TODO ?
public struct DbConnection
{
public DbConnection(SQLiteConnection connection, User caller)
{
Connection = connection;
Caller = caller;
}
public SQLiteConnection Connection { get;}
public User Caller { get;}
}

View File

@ -2,9 +2,9 @@ using InnovEnergy.App.Backend.Model.Relations;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db public static partial class Db
{ {
public void CreateFakeRelations() public static void CreateFakeRelations()
{ {
_Db.RunInTransaction(() => _Db.RunInTransaction(() =>
{ {
@ -16,7 +16,7 @@ public partial class Db
}); });
} }
private void CreateFakeUserTree() private static void CreateFakeUserTree()
{ {
foreach (var userId in Enumerable.Range(1, NbUsers)) foreach (var userId in Enumerable.Range(1, NbUsers))
{ {
@ -32,7 +32,7 @@ public partial class Db
} }
} }
private void CreateFakeFolderTree() private static void CreateFakeFolderTree()
{ {
foreach (var folderId in Enumerable.Range(1, NbFolders)) foreach (var folderId in Enumerable.Range(1, NbFolders))
{ {
@ -48,7 +48,7 @@ public partial class Db
} }
} }
private void LinkFakeInstallationsToFolders() private static void LinkFakeInstallationsToFolders()
{ {
var nFolders = NbFolders; var nFolders = NbFolders;
@ -59,7 +59,7 @@ public partial class Db
} }
} }
private void GiveFakeUsersAccessToFolders() private static void GiveFakeUsersAccessToFolders()
{ {
foreach (var uf in User2Folder) // remove existing relations foreach (var uf in User2Folder) // remove existing relations
_Db.Delete(uf); _Db.Delete(uf);
@ -79,7 +79,7 @@ public partial class Db
} }
} }
private void GiveFakeUsersAccessToInstallations() private static void GiveFakeUsersAccessToInstallations()
{ {
foreach (var ui in User2Installation) // remove existing relations foreach (var ui in User2Installation) // remove existing relations
_Db.Delete(ui); _Db.Delete(ui);

View File

@ -1,17 +1,16 @@
using InnovEnergy.App.Backend.Model; using InnovEnergy.App.Backend.Model;
using InnovEnergy.App.Backend.Utils;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using SQLite; using SQLite;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db public static partial class Db
{ {
private TableQuery<Folder> Folders => _Db.Table<Folder>(); private static TableQuery<Folder> Folders => _Db.Table<Folder>();
public Int32 NbFolders => Folders.Count(); public static Int32 NbFolders => Folders.Count();
public Folder? GetFolderById(Int64 id) public static Folder? GetFolderById(Int64 id)
{ {
return Folders.FirstOrDefault(u => u.Id == id); return Folders.FirstOrDefault(u => u.Id == id);
@ -21,56 +20,76 @@ public partial class Db
//return PopulateDescendants(folder); //return PopulateDescendants(folder);
} }
public IEnumerable<Folder> GetChildFolders(Folder parent) public static IEnumerable<Folder> GetChildFolders(Folder parent)
{ {
return Folders.Where(f => f.ParentId == parent.Id); return Folders.Where(f => f.ParentId == parent.Id);
} }
public IEnumerable<Folder> GetDescendantFolders(Folder parent) public static IEnumerable<Installation> GetChildInstallations(Folder parent)
{
return parent.Traverse(GetChildFolders);
}
public IEnumerable<Installation> GetChildInstallations(Folder parent)
{ {
return Installations.Where(f => f.ParentId == parent.Id); return Installations.Where(f => f.ParentId == parent.Id);
} }
public IEnumerable<User> GetChildUsers(User parent) public static IEnumerable<Folder> GetDescendantFolders(Folder parent)
{ {
return Users.Where(f => f.ParentId == parent.Id); return parent.Traverse(GetChildFolders);
} }
public IEnumerable<User> GetDescendantUsers(User parent) public static Boolean IsDescendantOf(Folder folder, Int64 ancestorFolderId)
{ {
return parent.Traverse(GetChildUsers); return Ancestors(folder)
.Any(u => u.Id == ancestorFolderId);
} }
public Int64 CreateFolder(Folder folder) public static Boolean IsDescendantOf(Folder folder, Folder ancestor)
{
return IsDescendantOf(folder, ancestor.Id);
}
private static IEnumerable<Folder> Ancestors(Folder child)
{
return child.Unfold(GetParent);
}
public static Folder? GetParent(Folder f)
{
return IsRoot(f)
? null
: GetFolderById(f.ParentId);
}
public static Boolean IsRoot(Folder f)
{
return f.ParentId == 0; // root has ParentId 0 by definition
}
public static Int64 CreateFolder(Folder folder)
{ {
return Create(folder); return Create(folder);
} }
public Boolean UpdateFolder(Folder folder) public static Boolean UpdateFolder(Folder folder)
{ {
// TODO: no circles in path // TODO: no circles in path
return Update(folder); return Update(folder);
} }
public Boolean ChangeParent(Installation child, Int64 parentId) // These should not be necessary, just Update folder/installation with new parentId
{
child.ParentId = parentId;
return UpdateInstallation(child);
}
public Boolean ChangeParent(Folder child, Int64 parentId)
{
child.ParentId = parentId;
return UpdateFolder(child);
}
public Boolean DeleteFolder(Folder folder) // public Boolean ChangeParent(Installation child, Int64 parentId)
// {
// child.ParentId = parentId;
// return UpdateInstallation(child);
// }
//
// public Boolean ChangeParent(Folder child, Int64 parentId)
// {
// child.ParentId = parentId;
// return UpdateFolder(child);
// }
public static Boolean DeleteFolder(Folder folder)
{ {
// Delete direct children // Delete direct children
User2Folder .Delete(f => f.FolderId == folder.Id); User2Folder .Delete(f => f.FolderId == folder.Id);

View File

@ -1,37 +1,55 @@
using InnovEnergy.App.Backend.Model; using InnovEnergy.App.Backend.Model;
using InnovEnergy.App.Backend.Utils;
using SQLite; using SQLite;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db public static partial class Db
{ {
private TableQuery<Installation> Installations => _Db.Table<Installation>(); private static TableQuery<Installation> Installations => _Db.Table<Installation>();
public Int32 NbInstallations => Installations.Count(); public static Int32 NbInstallations => Installations.Count();
public Installation? GetInstallationById(Int64 id) => Installations public static Installation? GetInstallationById(Int64 id) => Installations
.FirstOrDefault(u => u.Id == id); .FirstOrDefault(u => u.Id == id);
public Int64 CreateInstallation(Installation installation) private static IEnumerable<Folder> Ancestors(Installation installation)
{
var parentFolder = GetParent(installation);
return parentFolder is null
? Enumerable.Empty<Folder>()
: Ancestors(parentFolder);
}
public static Folder? GetParent(Installation installation)
{
return IsRoot(installation)
? null
: GetFolderById(installation.ParentId);
}
public static Boolean IsRoot(Installation i)
{
return i.ParentId == 0; // root has ParentId 0 by definition
}
public static Int64 CreateInstallation(Installation installation)
{ {
return Create(installation); return Create(installation);
} }
public Boolean UpdateInstallation(Installation installation) public static Boolean UpdateInstallation(Installation installation)
{ {
return Update(installation); return Update(installation);
} }
public static Boolean DeleteInstallation(Installation installation)
public Boolean DeleteInstallation(Installation installation)
{ {
User2Installation.Delete(i => i.InstallationId == installation.Id); User2Installation.Delete(i => i.InstallationId == installation.Id);
return Delete(installation); return Delete(installation);
} }
} }

View File

@ -9,34 +9,43 @@ using InnovEnergy.App.Backend.Utils;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using SQLite; using SQLite;
#pragma warning disable CS0472
#pragma warning disable CS8602
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db
public static partial class Db
{ {
private TableQuery<User> Users => _Db.Table<User>(); private static TableQuery<User> Users => _Db.Table<User>();
public Int32 NbUsers => Users.Count(); public static Int32 NbUsers => Users.Count();
public User? GetUserById(Int64 id) public static IEnumerable<User> GetChildUsers(User parent)
{
return Users.Where(f => f.ParentId == parent.Id);
}
public static IEnumerable<User> GetDescendantUsers(User parent)
{
return parent.Traverse(GetChildUsers);
}
public static User? GetUserById(Int64 id)
{ {
return Users.FirstOrDefault(u => u.Id == id); return Users.FirstOrDefault(u => u.Id == id);
} }
public Boolean IsParentOfChild(Int64 parentId, User child) public static Boolean IsDescendantOf(User user, User ancestor)
{ {
return Ancestors(child) return Ancestors(user)
.Any(u => u.Id == parentId); .Any(u => u.Id == ancestor.Id);
} }
private IEnumerable<User> Ancestors(User child) private static IEnumerable<User> Ancestors(User child)
{ {
return child.Unfold(GetParent); return child.Unfold(GetParent);
} }
public User? GetParent(User u) public static User? GetParent(User u)
{ {
return IsRoot(u) return IsRoot(u)
? null ? null
@ -48,9 +57,28 @@ public partial class Db
return u.ParentId == 0; // root has ParentId 0 by definition return u.ParentId == 0; // root has ParentId 0 by definition
} }
public User? GetUserByEmail(String email) => Users.FirstOrDefault(u => u.Email == email); public static Boolean HasDirectAccessToFolder(User user, Folder folder)
{
return HasDirectAccessToFolder(user, folder.Id);
}
public static Boolean HasDirectAccessToFolder(User user, Int64 folderId)
{
return User2Folder.Any(r => r.FolderId == folderId && r.UserId == user.Id);
}
public static Boolean HasAccessToFolder(User user, Int64 folderId)
{
var folder = GetFolderById(folderId);
if (folder is null)
return false;
public Int64 CreateUser(User user) return Ancestors(folder).Any(f => HasDirectAccessToFolder(user, f));
}
public static User? GetUserByEmail(String email) => Users.FirstOrDefault(u => u.Email == email);
public static Int64 CreateUser(User user)
{ {
if (GetUserByEmail(user.Email) is not null) if (GetUserByEmail(user.Email) is not null)
return -1; // TODO: User with that email already exists return -1; // TODO: User with that email already exists
@ -69,13 +97,12 @@ public partial class Db
private static Byte[] HmacSha256Digest(String message, String secret) private static Byte[] HmacSha256Digest(String message, String secret)
{ {
var encoding = new UTF8Encoding(); var encoding = new UTF8Encoding();
var keyBytes = encoding.GetBytes(secret); var keyBytes = encoding.GetBytes(secret);
var messageBytes = encoding.GetBytes(message); var messageBytes = encoding.GetBytes(message);
var cryptographer = new HMACSHA256(keyBytes); var cryptographer = new HMACSHA256(keyBytes);
var bytes = cryptographer.ComputeHash(messageBytes); return cryptographer.ComputeHash(messageBytes);
return bytes;
} }
private static String BuildSignature(String method, String path, String data, Int64 time, String secret) private static String BuildSignature(String method, String path, String data, Int64 time, String secret)
@ -93,7 +120,6 @@ public partial class Db
Console.WriteLine("Message to sign:\n" + messageToSign); Console.WriteLine("Message to sign:\n" + messageToSign);
var hmac = HmacSha256Digest(messageToSign, secret); var hmac = HmacSha256Digest(messageToSign, secret);
return Convert.ToBase64String(hmac); return Convert.ToBase64String(hmac);
} }
@ -149,7 +175,7 @@ public partial class Db
// //
// } // }
public Object? CreateAndSaveInstallationS3ApiKey(Installation installation) public static Object CreateAndSaveInstallationS3ApiKey(Installation installation)
{ {
//EXOSCALE API URL //EXOSCALE API URL
const String url = "https://api-ch-dk-2.exoscale.com/v2/"; const String url = "https://api-ch-dk-2.exoscale.com/v2/";
@ -192,7 +218,7 @@ public partial class Db
return newKey; return newKey;
} }
public Boolean UpdateUser(User user) public static Boolean UpdateUser(User user)
{ {
var oldUser = GetUserById(user.Id); var oldUser = GetUserById(user.Id);
if (oldUser == null) if (oldUser == null)
@ -208,7 +234,7 @@ public partial class Db
return Update(user); return Update(user);
} }
public Boolean DeleteUser(User user) public static Boolean DeleteUser(User user)
{ {
User2Folder.Delete(u => u.UserId == user.Id); User2Folder.Delete(u => u.UserId == user.Id);
User2Installation.Delete(u => u.UserId == user.Id); User2Installation.Delete(u => u.UserId == user.Id);

View File

@ -1,12 +1,12 @@
using InnovEnergy.App.Backend.Model.Relations; using InnovEnergy.App.Backend.Model.Relations;
using SQLite; using SQLite;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db public static partial class Db
{ {
private TableQuery<User2Folder> User2Folder => _Db.Table<User2Folder>(); private static TableQuery<User2Folder> User2Folder => _Db.Table<User2Folder>();
public Int32 NbUser2Folder => User2Folder.Count(); public static Int32 NbUser2Folder => User2Folder.Count();
} }

View File

@ -3,12 +3,9 @@ using SQLite;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public partial class Db public static partial class Db
{ {
private TableQuery<User2Installation> User2Installation => _Db.Table<User2Installation>(); private static TableQuery<User2Installation> User2Installation => _Db.Table<User2Installation>();
public Int32 NbUser2Installation => User2Installation.Count(); public static Int32 NbUser2Installation => User2Installation.Count();
} }