[server] Fix new queries

This commit is contained in:
Abhishek Shroff
2025-06-11 14:31:26 +05:30
parent e2f75024a3
commit 833a2cf5cc
5 changed files with 75 additions and 47 deletions

View File

@@ -13,11 +13,9 @@ type DiskUsageInfo struct {
func (f filesystem) DiskUsage(r Resource) (DiskUsageInfo, error) {
// TODO: #versions This is broken
_, n, q := selectResourceTree(r.id, false, false, false, "content_length", "dir")
n, q := selectResourceTree(r.id, false, "content_length", "dir")
q = q.
From(n).
ClearWhere().
Select(
goqu.SUM(n.Col("content_length")),
goqu.COUNT("*"),
@@ -28,6 +26,7 @@ func (f filesystem) DiskUsage(r Resource) (DiskUsageInfo, error) {
row := f.db.QueryRow(query, args...)
var size, count, dirs int64
err := row.Scan(&size, &count, &dirs)
return DiskUsageInfo{
TotalSize: size,
Entities: count,

View File

@@ -46,11 +46,13 @@ func (f filesystem) Delete(r Resource) (Resource, error) {
func softDelete(d db.Handler, id uuid.UUID) error {
return d.RunInTx(func(db db.Handler) error {
// Select all descendants, not including deleted ones
_, _, q := selectResourceTree(id, false, false, false)
n, q := selectResourceTree(id, false)
r := goqu.T("resources")
// Set modified and deleted
query, params, _ := q.
From(r).
Where(r.Col("id").Eq(pg.From(n).Select("id"))).
Update().
Set(
goqu.Record{
@@ -66,18 +68,21 @@ func softDelete(d db.Handler, id uuid.UUID) error {
// Add to trash
query, params, _ = pg.Insert(goqu.T("trash")).Cols("id").Vals(goqu.Vals{id}).ToSQL()
_, err := db.Exec(query, params...)
return err
})
}
func (f filesystem) softDeleteChildren(id, parent uuid.UUID) error {
err := f.runInTx(func(f filesystem) error {
// Select non-deleted descendents excluding the tree root (id)
_, _, s := selectResourceTree(id, true, false, false)
n, s := selectResourceTree(id, false)
r := goqu.T("resources")
// Mark deleted
q, params, _ := s.Update().
q, params, _ := s.
From(r).
Where(r.Col("id").Eq(pg.From(n).Select("id"))).
Where(r.Col("id").Neq(id)).
Update().
Set(
goqu.Record{
"modified": goqu.L("NOW()"),
@@ -120,12 +125,12 @@ func (f filesystem) DeleteForever(r Resource) error {
}
return f.runInTx(func(f filesystem) error {
// Select all descendants, including deleted resources
r, _, q := selectResourceTree(r.id, false, true, false)
n, q := selectResourceTree(r.id, true)
if err := f.updateResourceModified(parent.id); err != nil {
return err
// deleteAllVersions needs to be called last, as it will enqueue the delete jobs
} else if err := hardDeleteAllVersions(f.db, q, r); err != nil {
} else if err := hardDeleteAllVersions(f.db, q, n); err != nil {
return err
}
return nil
@@ -198,6 +203,7 @@ func (f filesystem) RestoreDeleted(r Resource, parentPathOrUUID string, name str
return
}
id := r.id
err = f.runInTx(func(f filesystem) error {
q, args, _ := pg.Delete(goqu.T("trash")).Where(goqu.C("id").Eq(r.id)).ToSQL()
if _, err := f.db.Exec(q, args...); err != nil {
@@ -205,7 +211,7 @@ func (f filesystem) RestoreDeleted(r Resource, parentPathOrUUID string, name str
}
if parent.id != r.parentID.Bytes || r.name != name {
if err := f.updateResourceNameParent(r.ID(), name, pgtype.UUID{Bytes: parent.id, Valid: true}); err != nil {
if err := f.updateResourceNameParent(id, name, pgtype.UUID{Bytes: parent.id, Valid: true}); err != nil {
return err
} else {
r.name = name
@@ -213,8 +219,12 @@ func (f filesystem) RestoreDeleted(r Resource, parentPathOrUUID string, name str
r.visibleParent = r.parentID
}
}
_, _, s := selectResourceTree(r.id, false, false, false)
query, params, _ := s.Update().Set(
n, s := selectResourceTree(id, false)
r := goqu.T("resources")
query, params, _ := s.
From(r).
Where(r.Col("id").Eq(pg.From(n).Select("id"))).
Update().Set(
goqu.Record{
"modified": goqu.L("NOW()"),
"deleted": nil,
@@ -224,7 +234,7 @@ func (f filesystem) RestoreDeleted(r Resource, parentPathOrUUID string, name str
return err
}
return f.recomputePermissions(r.id)
return f.recomputePermissions(id)
})
r.deleted = pgtype.Timestamp{}
res = r

View File

@@ -8,6 +8,7 @@ import (
"codeberg.org/shroff/phylum/server/internal/jobs"
"codeberg.org/shroff/phylum/server/internal/storage"
"github.com/doug-martin/goqu/v9"
"github.com/doug-martin/goqu/v9/exp"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
)
@@ -63,7 +64,11 @@ func (f filesystem) ReadDirDeleted(r Resource, recursive, includeDeleted bool) (
if !recursive {
_, q = selectDirectChildren(r.id, r.deleted, includeDeleted)
} else {
_, _, q = selectResourceTree(r.id, true, includeDeleted, true)
n, qq := selectResourceTree(r.id, includeDeleted)
id := r.id
var r exp.AliasedExpression
q, r = selectResources(qq, n)
q = q.Where(r.Col("id").Neq(id))
}
query, args, _ := q.ToSQL()

View File

@@ -35,12 +35,11 @@ COALESCE(p.permissions, '{}'::JSONB) AS inherited_permissions
FROM resources r LEFT JOIN resources p ON p.id = r.parent
`
func selectResourceTree(id uuid.UUID, excludeTreeRoot, includeDeleted, includeSubQueries bool, extraCols ...string) (exp.IdentifierExpression, exp.AliasedExpression, *goqu.SelectDataset) {
t := goqu.T("resources")
r := t.As("r")
func selectResourceTree(id uuid.UUID, includeDeleted bool, extraCols ...string) (exp.AliasedExpression, *goqu.SelectDataset) {
r := goqu.T("resources").As("r")
n := goqu.T("nodes").As("n")
rec := pg.From(r).
Select(r.Col("id"), r.Col("parent"), r.Col("deleted"), goqu.L("? + 1", goqu.I("n.depth")))
Select(r.Col("id"), r.Col("parent"), r.Col("deleted"))
if len(extraCols) != 0 {
s := make([]interface{}, len(extraCols))
for i, c := range extraCols {
@@ -56,7 +55,7 @@ func selectResourceTree(id uuid.UUID, excludeTreeRoot, includeDeleted, includeSu
base := pg.
From(r).
Select(r.Col("id"), r.Col("parent"), r.Col("deleted"), goqu.L("0")).
Select(r.Col("id"), r.Col("parent"), r.Col("deleted")).
Where(r.Col("id").Eq(id))
if len(extraCols) != 0 {
@@ -67,27 +66,27 @@ func selectResourceTree(id uuid.UUID, excludeTreeRoot, includeDeleted, includeSu
base = base.SelectAppend(s...)
}
cols := []string{"id", "parent", "deleted", "depth"}
cols = slices.Insert(cols, 4, extraCols...)
idSelect := pg.From(n).Select(n.Col("id"))
if excludeTreeRoot {
idSelect = idSelect.Where(n.Col("depth").Gt(0))
}
cols := []string{"id", "parent", "deleted"}
cols = slices.Insert(cols, 3, extraCols...)
q := pg.
From(t)
if includeSubQueries {
v := goqu.T("resource_versions").As("v")
l := goqu.T("publinks").As("l")
q = q.Select(
t.All(),
pg.Select(goqu.L(versionsQuery)).From(v).Where(v.Col("resource_id").Eq(t.Col("id"))),
pg.Select(goqu.L(publinksQuery)).From(l).Where(l.Col("root").Eq(t.Col("id"))),
From(n).
WithRecursive("nodes("+strings.Join(cols, ",")+")", base.UnionAll(rec))
return n, q
}
func selectResources(q *goqu.SelectDataset, n exp.AliasedExpression) (*goqu.SelectDataset, exp.AliasedExpression) {
r := goqu.T("resources").As("r")
v := goqu.T("resource_versions").As("v")
l := goqu.T("publinks").As("l")
q = q.From(r).
Join(n, goqu.On(r.Col("id").Eq(n.Col("id")))).
Select(
r.All(),
pg.Select(goqu.L(versionsQuery)).From(v).Where(v.Col("resource_id").Eq(r.Col("id"))),
pg.Select(goqu.L(publinksQuery)).From(l).Where(l.Col("root").Eq(r.Col("id"))),
)
}
q = q.WithRecursive("nodes("+strings.Join(cols, ",")+")", base.UnionAll(rec)).
Where(t.Col("id").Eq(idSelect))
return t, n, q
return q, r
}
func selectDirectChildren(id uuid.UUID, deleted pgtype.Timestamp, includeDeleted bool) (exp.AliasedExpression, *goqu.SelectDataset) {

View File

@@ -93,7 +93,7 @@ func TrashCompact(ctx context.Context, duration time.Duration) {
func (f filesystem) TrashSummary() (int, int, error) {
v := goqu.T("resource_versions").As("v")
n, q := f.selectTrash()
n, q := f.selectTrash(time.Time{})
q = q.LeftJoin(v, goqu.On(v.Col("resource_id").Eq(n.Col("id")))).
Select(
goqu.COALESCE(goqu.SUM(v.Col("size")), 0),
@@ -108,20 +108,32 @@ func (f filesystem) TrashSummary() (int, int, error) {
}
func (f filesystem) TrashEmpty() error {
n, q := f.selectTrash()
n, q := f.selectTrash(time.Time{})
return hardDeleteAllVersions(f.db, q, n)
}
func (f filesystem) selectTrash() (exp.AliasedExpression, *goqu.SelectDataset) {
func (f filesystem) selectTrash(time time.Time) (exp.AliasedExpression, *goqu.SelectDataset) {
r := goqu.T("resources").As("r")
n := goqu.T("nodes").As("n")
t := goqu.T("trash").As("t")
base := goqu.From(r).Select(r.Col("id"), r.Col("parent"), r.Col("deleted")).Join(t, goqu.On(t.Col("id").Eq(r.Col("id"))))
base := pg.
From(r).
Select(r.Col("id"), r.Col("parent"), r.Col("deleted")).
Join(t, goqu.On(t.Col("id").Eq(r.Col("id"))))
if !f.fullAccess {
base = base.Where(goqu.L("r.permissions[?]::INTEGER <> 0", f.userID))
}
rec := goqu.From(r).Select(r.Col("id"), r.Col("parent"), r.Col("deleted")).Join(n, goqu.On(r.Col("parent").Eq(n.Col("id"))))
if !time.IsZero() {
base = base.Where(r.Col("deleted").Lt(goqu.V(time.UTC())))
}
rec := pg.
From(r).
Select(r.Col("id"), r.Col("parent"), r.Col("deleted")).
Join(n, goqu.On(r.Col("parent").Eq(n.Col("id")))).
// Some children may be independently trashed (at different times). Don't select those
Where(goqu.L("? IS NOT DISTINCT FROM ?", r.Col("deleted"), n.Col("deleted")))
q := pg.From(n).WithRecursive("nodes(id, parent, deleted)", base.UnionAll(rec))
@@ -129,8 +141,7 @@ func (f filesystem) selectTrash() (exp.AliasedExpression, *goqu.SelectDataset) {
}
func (f filesystem) hardDeleteOldResources(t time.Time) error {
n, q := f.selectTrash()
q = q.Where(n.Col("deleted").Lt(goqu.V(t.UTC())))
n, q := f.selectTrash(t)
return hardDeleteAllVersions(f.db, q, n)
}
@@ -153,7 +164,11 @@ func hardDeleteAllVersions(db db.Handler, q *goqu.SelectDataset, n interface {
}
r := goqu.T("resources")
query, args, _ := q.From(r).Join(n, goqu.On(n.Col("id").Eq(r.Col("id")))).Delete().ToSQL()
fmt.Println("DELETE QUERY")
query, args, _ := q.
From(r).
Where(r.Col("id").Eq(pg.From(n).Select("id"))).
Delete().ToSQL()
if _, err := db.Exec(query, args...); err != nil {
return err