Cleanup/Rearrange building a subscriber query

This commit is contained in:
kolaente 2021-02-13 21:12:07 +01:00
parent 76c72b31de
commit 4c49142315
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
5 changed files with 88 additions and 86 deletions

View File

@ -240,7 +240,7 @@ func (l *List) ReadOne(s *xorm.Session, a web.Auth) (err error) {
}
}
l.Subscription, err = getSubscription(s, SubscriptionEntityList, l.ID, a)
l.Subscription, err = GetSubscription(s, SubscriptionEntityList, l.ID, a)
return
}

View File

@ -171,7 +171,7 @@ func (n *Namespace) ReadOne(s *xorm.Session, a web.Auth) (err error) {
}
*n = *nn
n.Subscription, err = getSubscription(s, SubscriptionEntityNamespace, n.ID, a)
n.Subscription, err = GetSubscription(s, SubscriptionEntityNamespace, n.ID, a)
return
}

View File

@ -18,10 +18,10 @@ package models
import (
"time"
"xorm.io/builder"
"code.vikunja.io/api/pkg/user"
"code.vikunja.io/web"
"xorm.io/builder"
"xorm.io/xorm"
)
@ -84,81 +84,6 @@ func (et SubscriptionEntityType) validate() error {
return &ErrUnknownSubscriptionEntityType{EntityType: et}
}
// Returns a matching subscription for an entity and user.
// It will return the next parent of a subscription. That means for tasks, it will first look for a subscription for
// that task, if there is none it will look for a subscription on the list the task belongs to and if that also
// doesn't exist it will check for a subscription for the namespace the list is belonging to.
func getSubscription(s *xorm.Session, entityType SubscriptionEntityType, entityID int64, a web.Auth) (subscription *Subscription, err error) {
u, is := a.(*user.User)
if !is {
return
}
if err := entityType.validate(); err != nil {
return nil, err
}
subscription = &Subscription{}
var cond builder.Cond
if entityType == SubscriptionEntityNamespace {
cond = builder.And(
builder.Eq{"entity_id": entityID},
builder.Eq{"entity_type": SubscriptionEntityNamespace},
)
}
if entityType == SubscriptionEntityList {
cond = builder.Or(
builder.And(
builder.Eq{"entity_id": entityID},
builder.Eq{"entity_type": SubscriptionEntityList},
),
builder.And(
builder.Eq{"entity_id": builder.
Select("namespace_id").
From("list").
Where(builder.Eq{"id": entityID}),
},
builder.Eq{"entity_type": SubscriptionEntityNamespace},
),
)
}
if entityType == SubscriptionEntityTask {
cond = builder.Or(
builder.And(
builder.Eq{"entity_id": entityID},
builder.Eq{"entity_type": SubscriptionEntityTask},
),
builder.And(
builder.Eq{"entity_id": builder.
Select("namespace_id").
From("list").
Join("INNER", "tasks", "list.id = tasks.list_id").
Where(builder.Eq{"tasks.id": entityID}),
},
builder.Eq{"entity_type": SubscriptionEntityNamespace},
),
builder.And(
builder.Eq{"entity_id": builder.
Select("list_id").
From("tasks").
Where(builder.Eq{"id": entityID}),
},
builder.Eq{"entity_type": SubscriptionEntityList},
),
)
}
_, err = s.
Where("user_id = ?", u.ID).
And(cond).
Get(subscription)
return
}
// Create subscribes the current user to an entity
// @Summary Subscribes the current user to an entity.
// @Description Subscribes the current user to an entity.
@ -220,3 +145,80 @@ func (sb *Subscription) Delete(s *xorm.Session, auth web.Auth) (err error) {
Delete(&Subscription{})
return
}
func getSubscriberCondForEntity(entityType SubscriptionEntityType, entityID int64) (cond builder.Cond) {
if entityType == SubscriptionEntityNamespace {
cond = builder.And(
builder.Eq{"entity_id": entityID},
builder.Eq{"entity_type": SubscriptionEntityNamespace},
)
}
if entityType == SubscriptionEntityList {
cond = builder.Or(
builder.And(
builder.Eq{"entity_id": entityID},
builder.Eq{"entity_type": SubscriptionEntityList},
),
builder.And(
builder.Eq{"entity_id": builder.
Select("namespace_id").
From("list").
Where(builder.Eq{"id": entityID}),
},
builder.Eq{"entity_type": SubscriptionEntityNamespace},
),
)
}
if entityType == SubscriptionEntityTask {
cond = builder.Or(
builder.And(
builder.Eq{"entity_id": entityID},
builder.Eq{"entity_type": SubscriptionEntityTask},
),
builder.And(
builder.Eq{"entity_id": builder.
Select("namespace_id").
From("list").
Join("INNER", "tasks", "list.id = tasks.list_id").
Where(builder.Eq{"tasks.id": entityID}),
},
builder.Eq{"entity_type": SubscriptionEntityNamespace},
),
builder.And(
builder.Eq{"entity_id": builder.
Select("list_id").
From("tasks").
Where(builder.Eq{"id": entityID}),
},
builder.Eq{"entity_type": SubscriptionEntityList},
),
)
}
return
}
// GetSubscription returns a matching subscription for an entity and user.
// It will return the next parent of a subscription. That means for tasks, it will first look for a subscription for
// that task, if there is none it will look for a subscription on the list the task belongs to and if that also
// doesn't exist it will check for a subscription for the namespace the list is belonging to.
func GetSubscription(s *xorm.Session, entityType SubscriptionEntityType, entityID int64, a web.Auth) (subscription *Subscription, err error) {
u, is := a.(*user.User)
if !is {
return
}
if err := entityType.validate(); err != nil {
return nil, err
}
subscription = &Subscription{}
cond := getSubscriberCondForEntity(entityType, entityID)
_, err = s.
Where("user_id = ?", u.ID).
And(cond).
Get(subscription)
return
}

View File

@ -273,7 +273,7 @@ func TestSubscriptionGet(t *testing.T) {
s := db.NewSession()
defer s.Close()
sub, err := getSubscription(s, SubscriptionEntityNamespace, 6, u)
sub, err := GetSubscription(s, SubscriptionEntityNamespace, 6, u)
assert.NoError(t, err)
assert.NotNil(t, sub)
assert.Equal(t, int64(2), sub.ID)
@ -283,7 +283,7 @@ func TestSubscriptionGet(t *testing.T) {
s := db.NewSession()
defer s.Close()
sub, err := getSubscription(s, SubscriptionEntityList, 12, u)
sub, err := GetSubscription(s, SubscriptionEntityList, 12, u)
assert.NoError(t, err)
assert.NotNil(t, sub)
assert.Equal(t, int64(3), sub.ID)
@ -293,7 +293,7 @@ func TestSubscriptionGet(t *testing.T) {
s := db.NewSession()
defer s.Close()
sub, err := getSubscription(s, SubscriptionEntityTask, 22, u)
sub, err := GetSubscription(s, SubscriptionEntityTask, 22, u)
assert.NoError(t, err)
assert.NotNil(t, sub)
assert.Equal(t, int64(4), sub.ID)
@ -306,7 +306,7 @@ func TestSubscriptionGet(t *testing.T) {
defer s.Close()
// List 6 belongs to namespace 6 where user 6 has subscribed to
sub, err := getSubscription(s, SubscriptionEntityList, 6, u)
sub, err := GetSubscription(s, SubscriptionEntityList, 6, u)
assert.NoError(t, err)
assert.NotNil(t, sub)
assert.Equal(t, int64(2), sub.ID)
@ -317,7 +317,7 @@ func TestSubscriptionGet(t *testing.T) {
defer s.Close()
// Task 20 belongs to list 11 which belongs to namespace 6 where the user has subscribed
sub, err := getSubscription(s, SubscriptionEntityTask, 20, u)
sub, err := GetSubscription(s, SubscriptionEntityTask, 20, u)
assert.NoError(t, err)
assert.NotNil(t, sub)
assert.Equal(t, int64(2), sub.ID)
@ -328,7 +328,7 @@ func TestSubscriptionGet(t *testing.T) {
defer s.Close()
// Task 21 belongs to list 12 which the user has subscribed to
sub, err := getSubscription(s, SubscriptionEntityTask, 21, u)
sub, err := GetSubscription(s, SubscriptionEntityTask, 21, u)
assert.NoError(t, err)
assert.NotNil(t, sub)
assert.Equal(t, int64(3), sub.ID)
@ -339,7 +339,7 @@ func TestSubscriptionGet(t *testing.T) {
s := db.NewSession()
defer s.Close()
_, err := getSubscription(s, 2342, 21, u)
_, err := GetSubscription(s, 2342, 21, u)
assert.Error(t, err)
assert.True(t, IsErrUnknownSubscriptionEntityType(err))
})

View File

@ -1245,6 +1245,6 @@ func (t *Task) ReadOne(s *xorm.Session, a web.Auth) (err error) {
*t = *taskMap[t.ID]
t.Subscription, err = getSubscription(s, SubscriptionEntityTask, t.ID, a)
t.Subscription, err = GetSubscription(s, SubscriptionEntityTask, t.ID, a)
return
}