add GetTree endpoint

This commit is contained in:
ig 2023-02-24 13:59:56 +01:00
parent 313e5f4a81
commit 599b23da2c
4 changed files with 78 additions and 27 deletions

View File

@ -160,8 +160,47 @@ public class Controller
.GetAllAccessibleFolders(caller)
.ToList(); // important!
}
[Returns<TreeNode[]>] // assuming swagger knows about arrays but not lists (JSON)
[Returns(HttpStatusCode.Unauthorized)]
[HttpGet($"{nameof(GetTree)}/")]
public Object GetTree()
{
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
using var db = Db.Connect();
var folders = db
.GetDirectlyAccessibleFolders(caller) // ReSharper disable once AccessToDisposedClosure
.Select(f => PopulateChildren(db, f));
var installations = db.GetDirectlyAccessibleInstallations(caller);
return folders
.Concat<TreeNode>(installations)
.ToList(); // important!
}
private static Folder PopulateChildren(Db db, Folder folder, HashSet<Int64>? hs = null)
{
// TODO: remove cycle detector
hs ??= new HashSet<Int64>();
if (!hs.Add(folder.Id))
throw new Exception("Cycle detected: folder " + folder.Id);
var installations = db.GetChildInstallations(folder);
var folders = db
.GetChildFolders(folder)
.Select(c => PopulateChildren(db, c, hs));
folder.Children = folders.Concat<TreeNode>(installations).ToList();
return folder;
}
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
[HttpPut($"{nameof(UpdateUser)}/")]
@ -184,7 +223,7 @@ public class Controller
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
[HttpPut($"{nameof(UpdateInstallation)}/")]
public Object UpdateInstallation(Installation updatedInstallation)
public Object UpdateInstallation(Installation installation)
{
var caller = GetCaller();
@ -195,7 +234,7 @@ public class Controller
var hasAccessToInstallation = db
.GetAllAccessibleInstallations(caller)
.Any(i => i.Id == updatedInstallation.Id);
.Any(i => i.Id == installation.Id);
if (!hasAccessToInstallation)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
@ -203,7 +242,7 @@ public class Controller
// TODO: accessibility by other users etc
// TODO: sanity check changes
return db.UpdateInstallation(updatedInstallation);
return db.UpdateInstallation(installation);
}

View File

@ -0,0 +1,24 @@
using System.Diagnostics.CodeAnalysis;
namespace Innovenergy.Backend.Model;
public abstract partial class TreeNode
{
protected Boolean Equals(TreeNode other)
{
return Id == other.Id && ParentId == other.ParentId;
}
public override Boolean Equals(Object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((TreeNode)obj);
}
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")]
public override Int32 GetHashCode()
{
return HashCode.Combine(Id, ParentId);
}
}

View File

@ -2,33 +2,20 @@ using SQLite;
namespace Innovenergy.Backend.Model;
public abstract class TreeNode
public abstract partial class TreeNode
{
[PrimaryKey, AutoIncrement]
public Int64 Id { get; set; }
public String Name { get; set; } = "";
public String Information { get; set; } = ""; // unstructured random info
protected Boolean Equals(TreeNode other)
{
return Id == other.Id && ParentId == other.ParentId;
}
public override Boolean Equals(Object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == this.GetType() && Equals((TreeNode)obj);
}
public override Int32 GetHashCode()
{
return HashCode.Combine(Id, ParentId);
}
[Indexed] // parent/child relation
public Int64 ParentId { get; set; }
[Ignore] // not in DB, can be used in typescript as type discriminator
public String Type => GetType().Name;
[Ignore]
public IReadOnlyList<TreeNode>? Children { get; set; }
}

View File

@ -3,9 +3,9 @@ using Microsoft.OpenApi.Models;
namespace Innovenergy.Backend;
public class Program
public static class Program
{
public static void Main(string[] args)
public static void Main(String[] args)
{
using (var db = Db.Connect())
db.CreateFakeRelations();
@ -18,10 +18,11 @@ public class Program
builder.Services.AddHttpContextAccessor();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.WithOrigins("*").AllowAnyHeader().AllowAnyMethod()));
builder.Services.AddSwaggerGen(config =>
builder.Services.AddSwaggerGen(c =>
{
config.SwaggerDoc("v1", new OpenApiInfo{ Title = "My API", Version = "V1" });
config.OperationFilter<HeaderFilter>(); //Todo testing throw me out
c.SwaggerDoc("v1", new OpenApiInfo { Title = "InnovEnergy Backend API", Version = "v1" });
c.UseAllOfToExtendReferenceSchemas();
c.OperationFilter<HeaderFilter>(); //Todo testing throw me out
});