Commit ae65f1a2 authored by Denis Arh's avatar Denis Arh
Browse files

Optimize role-relation store

parent 87b9a650
package cache
// This file is an auto-generated file
// Custom cache implementation for role membership
//
// Template: pkg/codegen/assets/store_cache.gen.go.tpl
// Definitions: store/role_members.yaml
//
// Changes to this file may cause incorrect behavior
// and will be lost if the code is regenerated.
// Caching role members and user memberships
import (
"context"
"errors"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/types"
"time"
)
var _ = errors.Is
func (c Cache) cacheRoleMember(res *types.RoleMember) {
// cacheRoleMembership handles both - membership and members!
func (c Cache) cacheRoleRelationships(i uint64, mm []uint64) {
var (
ttl time.Duration = 0
cost int64 = 1
)
if c.roleMembers.SetWithTTL(res.ID, res, cost, ttl) {
for _, ikey := range c.roleMemberIndexes(res) {
c.roleMembers.SetWithTTL(ikey, res.ID, cost, ttl)
}
}
c.roleMembers.SetWithTTL(i, mm, cost, ttl)
}
func (c Cache) getCachedRoleMemberByKey(ikey string) (interface{}, bool) {
if val, found := c.roleMembers.Get(ikey); found {
if id, ok := val.(uint64); ok {
return c.roleMembers.Get(id)
func (c Cache) getRoleRelationships(i uint64) ([]uint64, bool) {
if val, found := c.roleMembers.Get(i); found {
if mm, ok := val.([]uint64); ok {
return mm, true
}
c.roleMembers.Del(val)
}
c.roleMembers.Del(i)
return nil, false
}
func (c Cache) roleMemberIndexes(res *types.RoleMember) []string {
return []string{}
}
// CreateRoleMember updates cache and forwards call to next configured store
func (c Cache) CreateRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
for _, res := range rr {
if err = c.Storer.CreateRoleMember(ctx, res); err != nil {
return err
}
c.cacheRoleMember(res)
func (c Cache) SearchRoleMembers(ctx context.Context, roleID uint64) ([]uint64, error) {
if mm, found := c.getRoleRelationships(roleID); found {
return mm, nil
}
return nil
if mm, err := c.Storer.SearchRoleMembers(ctx, roleID); err != nil {
return nil, err
} else {
c.cacheRoleRelationships(roleID, mm)
return mm, nil
}
}
// UpdateRoleMember updates cache and forwards call to next configured store
func (c Cache) UpdateRoleMember(ctx context.Context, rr ...*types.RoleMember) error {
for _, res := range rr {
if err := c.Storer.UpdateRoleMember(ctx, res); err != nil {
return err
}
c.cacheRoleMember(res)
func (c Cache) SearchUserMemberships(ctx context.Context, userID uint64) ([]uint64, error) {
if mm, found := c.getRoleRelationships(userID); found {
return mm, nil
}
return nil
if mm, err := c.Storer.SearchUserMemberships(ctx, userID); err != nil {
return nil, err
} else {
c.cacheRoleRelationships(userID, mm)
return mm, nil
}
}
// UpsertRoleMember updates cache and forwards call to next configured store
func (c Cache) UpsertRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
// CreateRoleMember updates cache and forwards call to next configured store
func (c Cache) CreateRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
for _, res := range rr {
if err = c.Storer.UpsertRoleMember(ctx, res); err != nil {
if err = c.Storer.CreateRoleMember(ctx, res); err != nil {
return err
}
c.cacheRoleMember(res)
// remove all cache entries to this role/user
c.roleMembers.Del(res.RoleID)
c.roleMembers.Del(res.UserID)
}
return nil
......@@ -93,10 +82,9 @@ func (c Cache) DeleteRoleMember(ctx context.Context, rr ...*types.RoleMember) (e
return
}
c.roleMembers.Del(res.ID)
for _, key := range c.roleMemberIndexes(res) {
c.roleMembers.Del(key)
}
// remove all cache entries to this role/user
c.roleMembers.Del(res.RoleID)
c.roleMembers.Del(res.UserID)
}
return nil
......@@ -108,7 +96,9 @@ func (c Cache) DeleteRoleMemberByUserIDRoleID(ctx context.Context, userID uint64
return err
}
c.roleMembers.Del(ID)
// remove all cache entries to this role/user
c.roleMembers.Del(userID)
c.roleMembers.Del(roleID)
return nil
}
......
......@@ -20,25 +20,6 @@ import (
var _ = errors.Is
// SearchRoleMembers returns all matching rows
//
// This function calls convertRoleMemberFilter with the given
// types.RoleMemberFilter and expects to receive a working squirrel.SelectBuilder
func (s Store) SearchRoleMembers(ctx context.Context, f types.RoleMemberFilter) (types.RoleMemberSet, types.RoleMemberFilter, error) {
var (
err error
set []*types.RoleMember
q squirrel.SelectBuilder
)
q = s.roleMembersSelectBuilder()
return set, f, s.config.ErrorHandler(func() error {
set, _, _, err = s.QueryRoleMembers(ctx, q, nil)
return err
}())
}
// QueryRoleMembers queries the database, converts and checks each row and
// returns collected set
//
......@@ -97,50 +78,6 @@ func (s Store) CreateRoleMember(ctx context.Context, rr ...*types.RoleMember) (e
return
}
// UpdateRoleMember updates one or more existing rows in role_members
func (s Store) UpdateRoleMember(ctx context.Context, rr ...*types.RoleMember) error {
return s.config.ErrorHandler(s.partialRoleMemberUpdate(ctx, nil, rr...))
}
// partialRoleMemberUpdate updates one or more existing rows in role_members
func (s Store) partialRoleMemberUpdate(ctx context.Context, onlyColumns []string, rr ...*types.RoleMember) (err error) {
for _, res := range rr {
err = s.checkRoleMemberConstraints(ctx, res)
if err != nil {
return err
}
err = s.execUpdateRoleMembers(
ctx,
squirrel.Eq{
s.preprocessColumn("rm.rel_user", ""): store.PreprocessValue(res.UserID, ""), s.preprocessColumn("rm.rel_role", ""): store.PreprocessValue(res.RoleID, ""),
},
s.internalRoleMemberEncoder(res).Skip("rel_user", "rel_role").Only(onlyColumns...))
if err != nil {
return s.config.ErrorHandler(err)
}
}
return
}
// UpsertRoleMember updates one or more existing rows in role_members
func (s Store) UpsertRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
for _, res := range rr {
err = s.checkRoleMemberConstraints(ctx, res)
if err != nil {
return err
}
err = s.config.ErrorHandler(s.execUpsertRoleMembers(ctx, s.internalRoleMemberEncoder(res)))
if err != nil {
return err
}
}
return nil
}
// DeleteRoleMember Deletes one or more rows from role_members table
func (s Store) DeleteRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
for _, res := range rr {
......@@ -194,28 +131,6 @@ func (s Store) execCreateRoleMembers(ctx context.Context, payload store.Payload)
return s.config.ErrorHandler(s.Exec(ctx, s.InsertBuilder(s.roleMemberTable()).SetMap(payload)))
}
// execUpdateRoleMembers updates all matched (by cnd) rows in role_members with given data
func (s Store) execUpdateRoleMembers(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
return s.config.ErrorHandler(s.Exec(ctx, s.UpdateBuilder(s.roleMemberTable("rm")).Where(cnd).SetMap(set)))
}
// execUpsertRoleMembers inserts new or updates matching (by-primary-key) rows in role_members with given data
func (s Store) execUpsertRoleMembers(ctx context.Context, set store.Payload) error {
upsert, err := s.config.UpsertBuilder(
s.config,
s.roleMemberTable(),
set,
"rel_user",
"rel_role",
)
if err != nil {
return err
}
return s.config.ErrorHandler(s.Exec(ctx, upsert))
}
// execDeleteRoleMembers Deletes all matched (by cnd) rows in role_members with given data
func (s Store) execDeleteRoleMembers(ctx context.Context, cnd squirrel.Sqlizer) error {
return s.config.ErrorHandler(s.Exec(ctx, s.DeleteBuilder(s.roleMemberTable("rm")).Where(cnd)))
......@@ -275,7 +190,7 @@ func (Store) roleMemberColumns(aa ...string) []string {
}
}
// {true true false false false}
// {false true false false false}
// internalRoleMemberEncoder encodes fields from types.RoleMember to store.Payload (map)
//
......
package rdbms
import (
"context"
)
func (s Store) SearchRoleMembers(ctx context.Context, roleID uint64) ([]uint64, error) {
return nil, nil
}
func (s Store) SearchUserMemberships(ctx context.Context, userID uint64) ([]uint64, error) {
return nil, nil
}
......@@ -15,44 +15,31 @@ import (
type (
RoleMembers interface {
SearchRoleMembers(ctx context.Context, f types.RoleMemberFilter) (types.RoleMemberSet, types.RoleMemberFilter, error)
CreateRoleMember(ctx context.Context, rr ...*types.RoleMember) error
UpdateRoleMember(ctx context.Context, rr ...*types.RoleMember) error
UpsertRoleMember(ctx context.Context, rr ...*types.RoleMember) error
DeleteRoleMember(ctx context.Context, rr ...*types.RoleMember) error
DeleteRoleMemberByUserIDRoleID(ctx context.Context, userID uint64, roleID uint64) error
TruncateRoleMembers(ctx context.Context) error
// Additional custom functions
// SearchRoleMembers (custom function)
SearchRoleMembers(ctx context.Context, _roleID uint64) ([]uint64, error)
// SearchUserMemberships (custom function)
SearchUserMemberships(ctx context.Context, _userID uint64) ([]uint64, error)
}
)
var _ *types.RoleMember
var _ context.Context
// SearchRoleMembers returns all matching RoleMembers from store
func SearchRoleMembers(ctx context.Context, s RoleMembers, f types.RoleMemberFilter) (types.RoleMemberSet, types.RoleMemberFilter, error) {
return s.SearchRoleMembers(ctx, f)
}
// CreateRoleMember creates one or more RoleMembers in store
func CreateRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
return s.CreateRoleMember(ctx, rr...)
}
// UpdateRoleMember updates one or more (existing) RoleMembers in store
func UpdateRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
return s.UpdateRoleMember(ctx, rr...)
}
// UpsertRoleMember creates new or updates existing one or more RoleMembers in store
func UpsertRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
return s.UpsertRoleMember(ctx, rr...)
}
// DeleteRoleMember Deletes one or more RoleMembers from store
func DeleteRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
return s.DeleteRoleMember(ctx, rr...)
......@@ -67,3 +54,11 @@ func DeleteRoleMemberByUserIDRoleID(ctx context.Context, s RoleMembers, userID u
func TruncateRoleMembers(ctx context.Context, s RoleMembers) error {
return s.TruncateRoleMembers(ctx)
}
func SearchRoleMembers(ctx context.Context, s RoleMembers, _roleID uint64) ([]uint64, error) {
return s.SearchRoleMembers(ctx, _roleID)
}
func SearchUserMemberships(ctx context.Context, s RoleMembers, _userID uint64) ([]uint64, error) {
return s.SearchUserMemberships(ctx, _userID)
}
......@@ -14,6 +14,25 @@ search:
enablePaging: false
customFilterConverter: true
enableFilterCheckFunction: false
enable: false
update:
enable: false
upsert:
enable: false
cache:
enable: true
codegen: false
functions:
- name: SearchRoleMembers
arguments:
- { name: roleID, type: uint64 }
return: [ "[]uint64", error ]
- name: SearchUserMemberships
arguments:
- { name: userID, type: uint64 }
return: [ "[]uint64", error ]
......@@ -420,8 +420,15 @@ func (svc role) Unarchive(roleID uint64) (err error) {
}
func (svc role) Membership(userID uint64) (types.RoleMemberSet, error) {
mm, _, err := store.SearchRoleMembers(svc.ctx, svc.store, types.RoleMemberFilter{UserID: userID})
return mm, err
var (
rr, err = store.SearchUserMemberships(svc.ctx, svc.store, userID)
set = types.RoleMemberSet{}
)
for _, roleID := range rr {
set = append(set, &types.RoleMember{RoleID: roleID, UserID: userID})
}
return set, err
}
func (svc role) MemberList(roleID uint64) (mm types.RoleMemberSet, err error) {
......@@ -446,7 +453,14 @@ func (svc role) MemberList(roleID uint64) (mm types.RoleMemberSet, err error) {
return RoleErrNotAllowedToRead()
}
mm, _, err = store.SearchRoleMembers(svc.ctx, svc.store, types.RoleMemberFilter{RoleID: roleID})
var (
rr, err = store.SearchRoleMembers(svc.ctx, svc.store, roleID)
)
for _, userID := range rr {
mm = append(mm, &types.RoleMember{RoleID: roleID, UserID: userID})
}
return err
}()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment