[server] Add disk usage endpoint

This commit is contained in:
Abhishek Shroff
2024-10-08 20:02:28 +05:30
parent 9b35166b19
commit 1bf193d543
4 changed files with 105 additions and 0 deletions

View File

@@ -38,6 +38,12 @@ type resourceResponse struct {
Permissions string `json:"permissions,omitempty"`
}
type diskUsageResponse struct {
TotalSize int64 `json:"size"`
Files int64 `json:"files"`
Dirs int64 `json:"dirs"`
}
type resourceDetailResponse struct {
Metadata resourceResponse `json:"metadata"`
Children []resourceResponse `json:"children,omitempty"`
@@ -57,6 +63,7 @@ type resourceMoveParams struct {
func SetupResourceRoutes(r *gin.RouterGroup) {
group := r.Group("/resources")
group.GET("/ls/:id", handleResourceLsRoute)
group.GET("/du/:id", handleResourceDiskUsageRoute)
group.GET("/metadata/:id", handleResourceMetadataRoute)
group.GET("/details/:id", handleResourceDetailsRoute)
group.GET("/contents/:id", handleResourceContentsRoute)
@@ -113,6 +120,32 @@ func handleResourceLsRoute(c *gin.Context) {
c.JSON(200, results)
}
func handleResourceDiskUsageRoute(c *gin.Context) {
resourceId, err := uuid.Parse(c.Param("id"))
if err != nil {
panic(errResourceIDInvalid)
}
fs := auth.GetFileSystem(c)
resource, err := fs.ResourceByID(resourceId)
if err != nil {
if errors.Is(err, iofs.ErrNotExist) {
err = errResourceNotFound
}
panic(err)
}
info, err := fs.DiskUsage(resource)
if err != nil {
panic(err)
}
c.JSON(200, diskUsageResponse{
TotalSize: info.TotalSize,
Files: info.Files,
Dirs: info.Dirs,
})
}
func handleResourceDetailsRoute(c *gin.Context) {
resourceID, err := uuid.Parse(c.Param("id"))
if err != nil {

View File

@@ -28,6 +28,13 @@ var (
ErrMoveTargetSubdirectory = errors.New("move target subdirectory")
)
type DiskUsageInfo struct {
TotalSize int64
Entities int64
Files int64
Dirs int64
}
type FileSystem interface {
WithDb(*db.DbHandler) FileSystem
RunInTx(fn func(FileSystem) error) error
@@ -41,6 +48,7 @@ type FileSystem interface {
DeleteRecursive(r Resource, hardDelete bool) (uuid.UUIDs, error)
Move(r Resource, name string, parent *uuid.UUID) (Resource, error)
UpdatePermissions(r Resource, username string, permission Permission) error
DiskUsage(r Resource) (DiskUsageInfo, error)
}
type filesystem struct {
@@ -340,6 +348,19 @@ func (f filesystem) Move(r Resource, name string, parent *uuid.UUID) (Resource,
}
}
func (f filesystem) DiskUsage(r Resource) (DiskUsageInfo, error) {
if info, err := f.db.DiskUsage(f.ctx, r.ID()); err != nil {
return DiskUsageInfo{}, err
} else {
return DiskUsageInfo{
TotalSize: info.Size,
Entities: info.Entities,
Files: info.Files,
Dirs: info.Dirs,
}, nil
}
}
func (f filesystem) UpdatePermissions(r Resource, username string, permission Permission) error {
if r.UserPermission() < PermissionReadWriteShare {
return ErrInsufficientPermissions

View File

@@ -85,6 +85,42 @@ func (q *Queries) DeleteRecursive(ctx context.Context, id uuid.UUID) ([]uuid.UUI
return items, nil
}
const diskUsage = `-- name: DiskUsage :one
WITH RECURSIVE nodes(id, parent, size, dir) AS (
SELECT r.id, r.parent, r.size, r.dir
FROM resources r WHERE r.id = $1::uuid
UNION ALL
SELECT r.id, r.parent, r.size, r.dir
FROM resources r JOIN nodes n on r.parent = n.id
WHERE deleted IS NULL
)
SELECT
SUM(size) AS size,
COUNT(*) AS entities,
COUNT(CASE dir WHEN true THEN 1 ELSE NULL END) AS dirs,
COUNT(CASE dir WHEN false THEN 1 ELSE NULL END) AS files
FROM nodes
`
type DiskUsageRow struct {
Size int64
Entities int64
Dirs int64
Files int64
}
func (q *Queries) DiskUsage(ctx context.Context, id uuid.UUID) (DiskUsageRow, error) {
row := q.db.QueryRow(ctx, diskUsage, id)
var i DiskUsageRow
err := row.Scan(
&i.Size,
&i.Entities,
&i.Dirs,
&i.Files,
)
return i, err
}
const hardDeleteRecursive = `-- name: HardDeleteRecursive :many
WITH RECURSIVE nodes(id, parent) AS (
SELECT r.id, r.parent

View File

@@ -44,6 +44,21 @@ SET
WHERE id = @id::uuid
RETURNING *;
-- name: DiskUsage :one
WITH RECURSIVE nodes(id, parent, size, dir) AS (
SELECT r.id, r.parent, r.size, r.dir
FROM resources r WHERE r.id = @id::uuid
UNION ALL
SELECT r.id, r.parent, r.size, r.dir
FROM resources r JOIN nodes n on r.parent = n.id
WHERE deleted IS NULL
)
SELECT
SUM(size) AS size,
COUNT(*) AS entities,
COUNT(CASE dir WHEN true THEN 1 ELSE NULL END) AS dirs,
COUNT(CASE dir WHEN false THEN 1 ELSE NULL END) AS files
FROM nodes;
-- name: DeleteRecursive :many