upd(sam) explicit db inject from service

This commit is contained in:
Tit Petric
2018-09-25 13:38:43 +00:00
parent c781664fa6
commit 1689228e31
15 changed files with 123 additions and 137 deletions
+6 -6
View File
@@ -11,8 +11,8 @@ import (
)
type (
Attachment interface {
With(ctx context.Context) Attachment
AttachmentRepository interface {
With(ctx context.Context, db *factory.DB) AttachmentRepository
FindAttachmentByID(id uint64) (*types.Attachment, error)
FindAttachmentByMessageID(IDs ...uint64) (types.MessageAttachmentSet, error)
@@ -32,13 +32,13 @@ const (
ErrAttachmentNotFound = repositoryError("AttachmentNotFound")
)
func NewAttachment(ctx context.Context) Attachment {
return (&attachment{}).With(ctx)
func Attachment(ctx context.Context, db *factory.DB) AttachmentRepository {
return (&attachment{}).With(ctx, db)
}
func (r *attachment) With(ctx context.Context) Attachment {
func (r *attachment) With(ctx context.Context, db *factory.DB) AttachmentRepository {
return &attachment{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
+6 -6
View File
@@ -10,8 +10,8 @@ import (
)
type (
Channel interface {
With(ctx context.Context) Channel
ChannelRepository interface {
With(ctx context.Context, db *factory.DB) ChannelRepository
FindChannelByID(id uint64) (*types.Channel, error)
FindDirectChannelByUserID(fromUserID, toUserID uint64) (*types.Channel, error)
@@ -58,13 +58,13 @@ const (
ErrChannelNotFound = repositoryError("ChannelNotFound")
)
func NewChannel(ctx context.Context) Channel {
return (&channel{}).With(ctx)
func Channel(ctx context.Context, db *factory.DB) ChannelRepository {
return (&channel{}).With(ctx, db)
}
func (r *channel) With(ctx context.Context) Channel {
func (r *channel) With(ctx context.Context, db *factory.DB) ChannelRepository {
return &channel{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
+5 -5
View File
@@ -33,7 +33,7 @@ The reading of the event queue table is triggered by pubsub.
type (
Events interface {
With(ctx context.Context) Events
With(ctx context.Context, db *factory.DB) Events
Pull(origin uint64) ([]*types.EventQueueItem, error)
Push(eqi *types.EventQueueItem) error
@@ -45,13 +45,13 @@ type (
}
)
func NewEvents(ctx context.Context) Events {
return (&events{}).With(ctx)
func NewEvents(ctx context.Context, db *factory.DB) Events {
return (&events{}).With(ctx, db)
}
func (r *events) With(ctx context.Context) Events {
func (r *events) With(ctx context.Context, db *factory.DB) Events {
return &events{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
+6 -6
View File
@@ -10,8 +10,8 @@ import (
)
type (
Message interface {
With(ctx context.Context) Message
MessageRepository interface {
With(ctx context.Context, db *factory.DB) MessageRepository
FindMessageByID(id uint64) (*types.Message, error)
FindMessages(filter *types.MessageFilter) (types.MessageSet, error)
@@ -43,13 +43,13 @@ const (
ErrMessageNotFound = repositoryError("MessageNotFound")
)
func NewMessage(ctx context.Context) Message {
return (&message{}).With(ctx)
func Message(ctx context.Context, db *factory.DB) MessageRepository {
return (&message{}).With(ctx, db)
}
func (r *message) With(ctx context.Context) Message {
func (r *message) With(ctx context.Context, db *factory.DB) MessageRepository {
return &message{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
+6 -6
View File
@@ -10,8 +10,8 @@ import (
)
type (
Organisation interface {
With(ctx context.Context) Organisation
OrganisationRepository interface {
With(ctx context.Context, db *factory.DB) OrganisationRepository
FindOrganisationByID(id uint64) (*types.Organisation, error)
FindOrganisations(filter *types.OrganisationFilter) ([]*types.Organisation, error)
@@ -33,13 +33,13 @@ const (
ErrOrganisationNotFound = repositoryError("OrganisationNotFound")
)
func NewOrganisation(ctx context.Context) Organisation {
return (&organisation{}).With(ctx)
func Organisation(ctx context.Context, db *factory.DB) OrganisationRepository {
return (&organisation{}).With(ctx, db)
}
func (r *organisation) With(ctx context.Context) Organisation {
func (r *organisation) With(ctx context.Context, db *factory.DB) OrganisationRepository {
return &organisation{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
+6 -6
View File
@@ -10,8 +10,8 @@ import (
)
type (
Reaction interface {
With(ctx context.Context) Reaction
ReactionRepository interface {
With(ctx context.Context, db *factory.DB) ReactionRepository
FindReactionByID(id uint64) (*types.Reaction, error)
FindReactionsByRange(channelID, fromReactionID, toReactionID uint64) ([]*types.Reaction, error)
@@ -28,13 +28,13 @@ const (
ErrReactionNotFound = repositoryError("ReactionNotFound")
)
func NewReaction(ctx context.Context) Reaction {
return (&reaction{}).With(ctx)
func Reaction(ctx context.Context, db *factory.DB) ReactionRepository {
return (&reaction{}).With(ctx, db)
}
func (r *reaction) With(ctx context.Context) Reaction {
func (r *reaction) With(ctx context.Context, db *factory.DB) ReactionRepository {
return &reaction{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
+11 -28
View File
@@ -11,44 +11,24 @@ import (
type (
repository struct {
ctx context.Context
// Get database handle
dbh func(ctxs ...context.Context) *factory.DB
dbh *factory.DB
}
)
var (
_db *factory.DB
_ctx context.Context
)
// DB returns a repository-wide singleton DB handle
func DB(ctxs ...context.Context) *factory.DB {
if _db == nil {
_db = factory.Database.MustGet()
}
for _, ctx := range ctxs {
_db = _db.With(ctx)
_ctx = ctx
break
}
return _db
// DB produces a contextual DB handle
func DB(ctx context.Context) *factory.DB {
return factory.Database.MustGet().With(ctx)
}
func Identity(ctx context.Context) uint64 {
return auth.GetIdentityFromContext(ctx).Identity()
}
// With updates repository and database contexts
func (r *repository) With(ctx context.Context) *repository {
res := &repository{
func (r *repository) With(ctx context.Context, db *factory.DB) *repository {
return &repository{
ctx: ctx,
dbh: DB,
dbh: db,
}
if r != nil {
res.dbh = r.dbh
}
return res
}
// Context returns current active repository context
@@ -58,5 +38,8 @@ func (r *repository) Context() context.Context {
// db returns context-aware db handle
func (r *repository) db() *factory.DB {
return r.dbh(r.ctx)
if r.dbh != nil {
return r.dbh
}
return DB(r.ctx)
}
+6 -6
View File
@@ -10,8 +10,8 @@ import (
)
type (
Team interface {
With(ctx context.Context) Team
TeamRepository interface {
With(ctx context.Context, db *factory.DB) TeamRepository
FindTeamByID(id uint64) (*types.Team, error)
FindTeams(filter *types.TeamFilter) ([]*types.Team, error)
@@ -35,13 +35,13 @@ const (
ErrTeamNotFound = repositoryError("TeamNotFound")
)
func NewTeam(ctx context.Context) Team {
return (&team{}).With(ctx)
func Team(ctx context.Context, db *factory.DB) TeamRepository {
return (&team{}).With(ctx, db)
}
func (r *team) With(ctx context.Context) Team {
func (r *team) With(ctx context.Context, db *factory.DB) TeamRepository {
return &team{
repository: r.repository.With(ctx),
repository: r.repository.With(ctx, db),
}
}
-1
View File
@@ -35,7 +35,6 @@ func (Attachment) New() *Attachment {
func (ctrl *Attachment) Original(ctx context.Context, r *request.AttachmentOriginal) (interface{}, error) {
return ctrl.get(r.AttachmentID, false, r.Download)
}
func (ctrl *Attachment) Preview(ctx context.Context, r *request.AttachmentPreview) (interface{}, error) {
+20 -23
View File
@@ -20,16 +20,12 @@ import (
type (
attachment struct {
db *factory.DB
ctx context.Context
attachment repository.Attachment
message repository.Message
attachment repository.AttachmentRepository
message repository.MessageRepository
store store.Store
config struct {
url string
previewUrl string
}
}
AttachmentService interface {
@@ -43,25 +39,26 @@ type (
}
)
const (
attachmentURL = "/attachment/%d/%s"
attachmentPreviewURL = "/attachment/%d/%s/preview"
)
func Attachment(store store.Store) *attachment {
svc := &attachment{
ctx: context.Background(),
attachment: repository.NewAttachment(context.Background()),
message: repository.NewMessage(context.Background()),
store: store,
}
svc.config.url = "/attachment/%d/%s"
svc.config.previewUrl = "/attachment/%d/%s/preview"
svc := (&attachment{
store: store,
}).With(context.Background()).(*attachment)
return svc
}
func (svc *attachment) With(ctx context.Context) AttachmentService {
db := repository.DB(ctx)
return &attachment{
db: db,
ctx: ctx,
attachment: svc.attachment.With(ctx),
message: svc.message.With(ctx),
attachment: repository.Attachment(ctx, db),
message: repository.Message(ctx, db),
store: svc.store,
config: svc.config,
}
}
@@ -70,11 +67,11 @@ func (svc *attachment) FindByID(id uint64) (*types.Attachment, error) {
}
func (svc *attachment) OpenOriginal(att *types.Attachment) (io.ReadSeeker, error) {
return svc.store.Open(att.Url)
return svc.store.Open(attachmentURL)
}
func (svc *attachment) OpenPreview(att *types.Attachment) (io.ReadSeeker, error) {
return svc.store.Open(att.PreviewUrl)
return svc.store.Open(attachmentPreviewURL)
}
@@ -141,7 +138,7 @@ func (svc *attachment) Create(channelId uint64, name string, size int64, fh io.R
log.Printf("File %s stored as %s", att.Name, att.Url)
return att, repository.DB().Transaction(func() (err error) {
return att, svc.db.Transaction(func() (err error) {
if att, err = svc.attachment.CreateAttachment(att); err != nil {
return
@@ -176,12 +173,12 @@ func (svc *attachment) Create(channelId uint64, name string, size int64, fh io.R
// Generates URL to a location
func (svc *attachment) url(att *types.Attachment) string {
return fmt.Sprintf(svc.config.url, att.ID, url.PathEscape(att.Name))
return fmt.Sprintf(attachmentURL, att.ID, url.PathEscape(att.Name))
}
// Generates URL to a location
func (svc *attachment) previewUrl(att *types.Attachment) string {
return fmt.Sprintf(svc.config.previewUrl, att.ID, url.PathEscape(att.Name))
return fmt.Sprintf(attachmentPreviewURL, att.ID, url.PathEscape(att.Name))
}
func (svc *attachment) extractMeta(att *types.Attachment, file io.ReadSeeker) (err error) {
+16 -16
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"github.com/crusttech/crust/sam/repository"
"github.com/crusttech/crust/sam/types"
@@ -12,10 +13,11 @@ import (
type (
channel struct {
db *factory.DB
ctx context.Context
channel repository.Channel
message repository.Message
channel repository.ChannelRepository
message repository.MessageRepository
}
ChannelService interface {
@@ -38,20 +40,18 @@ type (
)
func Channel() *channel {
var svc = &channel{
ctx: context.Background(),
channel: repository.NewChannel(context.Background()),
message: repository.NewMessage(context.Background()),
}
svc := (&channel{}).With(context.Background()).(*channel)
//svc.sec.ch = ChannelSecurity(svc.channel)
return svc
}
func (svc *channel) With(ctx context.Context) ChannelService {
db := repository.DB(ctx)
return &channel{
db: db,
ctx: ctx,
channel: svc.channel.With(ctx),
message: svc.message.With(ctx),
channel: repository.Channel(ctx, db),
message: repository.Message(ctx, db),
}
}
@@ -84,7 +84,7 @@ func (svc *channel) preloadMembers(set types.ChannelSet) error {
// Returns all channels with membership info
func (svc *channel) FindByMembership() (rval []*types.Channel, err error) {
return rval, repository.DB().Transaction(func() error {
return rval, svc.db.Transaction(func() error {
var chMemberId = repository.Identity(svc.ctx)
var mm []*types.ChannelMember
@@ -111,7 +111,7 @@ func (svc *channel) FindByMembership() (rval []*types.Channel, err error) {
func (svc *channel) Create(in *types.Channel) (out *types.Channel, err error) {
// @todo: [SECURITY] permission check if user can add channel
return out, repository.DB().Transaction(func() (err error) {
return out, svc.db.Transaction(func() (err error) {
var msg *types.Message
// @todo get organisation from somewhere
@@ -188,7 +188,7 @@ func (svc *channel) Create(in *types.Channel) (out *types.Channel, err error) {
}
func (svc *channel) Update(in *types.Channel) (out *types.Channel, err error) {
return out, repository.DB().Transaction(func() (err error) {
return out, svc.db.Transaction(func() (err error) {
var msgs types.MessageSet
// @todo [SECURITY] can user access this channel?
@@ -271,7 +271,7 @@ func (svc *channel) Update(in *types.Channel) (out *types.Channel, err error) {
}
func (svc *channel) Delete(id uint64) error {
return repository.DB().Transaction(func() (err error) {
return svc.db.Transaction(func() (err error) {
var userID = repository.Identity(svc.ctx)
var ch *types.Channel
@@ -293,7 +293,7 @@ func (svc *channel) Delete(id uint64) error {
}
func (svc *channel) Recover(id uint64) error {
return repository.DB().Transaction(func() (err error) {
return svc.db.Transaction(func() (err error) {
var userID = repository.Identity(svc.ctx)
var ch *types.Channel
@@ -315,7 +315,7 @@ func (svc *channel) Recover(id uint64) error {
}
func (svc *channel) Archive(id uint64) error {
return repository.DB().Transaction(func() (err error) {
return svc.db.Transaction(func() (err error) {
var userID = repository.Identity(svc.ctx)
var ch *types.Channel
@@ -337,7 +337,7 @@ func (svc *channel) Archive(id uint64) error {
}
func (svc *channel) Unarchive(id uint64) error {
return repository.DB().Transaction(func() (err error) {
return svc.db.Transaction(func() (err error) {
var userID = repository.Identity(svc.ctx)
var ch *types.Channel
+14 -14
View File
@@ -4,6 +4,7 @@ import (
"context"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"github.com/crusttech/crust/sam/repository"
"github.com/crusttech/crust/sam/types"
@@ -11,11 +12,12 @@ import (
type (
message struct {
db *factory.DB
ctx context.Context
channel repository.Channel
message repository.Message
reaction repository.Reaction
channel repository.ChannelRepository
message repository.MessageRepository
reaction repository.ReactionRepository
att AttachmentService
}
@@ -44,23 +46,21 @@ type (
)
func Message(attSvc AttachmentService) *message {
m := &message{
ctx: context.Background(),
att: attSvc,
channel: repository.NewChannel(context.Background()),
message: repository.NewMessage(context.Background()),
reaction: repository.NewReaction(context.Background()),
}
m := (&message{
att: attSvc,
}).With(context.Background()).(*message)
return m
}
func (svc *message) With(ctx context.Context) MessageService {
db := repository.DB(ctx)
return &message{
db: db,
ctx: ctx,
att: svc.att,
channel: svc.channel.With(ctx),
message: svc.message.With(ctx),
reaction: svc.reaction.With(ctx),
channel: repository.Channel(ctx, db),
message: repository.Message(ctx, db),
reaction: repository.Reaction(ctx, db),
}
}
@@ -81,7 +81,7 @@ func (svc *message) Find(filter *types.MessageFilter) (mm types.MessageSet, err
}
func (svc *message) Direct(recipientID uint64, in *types.Message) (out *types.Message, err error) {
return out, repository.DB().Transaction(func() (err error) {
return out, svc.db.Transaction(func() (err error) {
var currentUserID = repository.Identity(svc.ctx)
// @todo [SECURITY] verify if current user can send direct messages to anyone?
+9 -6
View File
@@ -3,14 +3,18 @@ package service
import (
"context"
"github.com/titpetric/factory"
"github.com/crusttech/crust/sam/repository"
"github.com/crusttech/crust/sam/types"
)
type (
organisation struct {
db *factory.DB
ctx context.Context
rpo repository.Organisation
rpo repository.OrganisationRepository
}
OrganisationService interface {
@@ -28,16 +32,15 @@ type (
)
func Organisation() *organisation {
return &organisation{
ctx: context.Background(),
rpo: repository.NewOrganisation(context.Background()),
}
return (&organisation{}).With(context.Background()).(*organisation)
}
func (svc *organisation) With(ctx context.Context) OrganisationService {
db := repository.DB(ctx)
return &organisation{
db: db,
ctx: ctx,
rpo: svc.rpo.With(ctx),
rpo: repository.Organisation(ctx, db),
}
}
+11 -7
View File
@@ -2,14 +2,19 @@ package service
import (
"context"
"github.com/titpetric/factory"
"github.com/crusttech/crust/sam/repository"
"github.com/crusttech/crust/sam/types"
)
type (
team struct {
ctx context.Context
team repository.Team
db *factory.DB
ctx context.Context
team repository.TeamRepository
}
TeamService interface {
@@ -29,16 +34,15 @@ type (
)
func Team() *team {
return &team{
ctx: context.Background(),
team: repository.NewTeam(context.Background()),
}
return (&team{}).With(context.Background()).(*team)
}
func (svc *team) With(ctx context.Context) TeamService {
db := repository.DB(ctx)
return &team{
db: db,
ctx: ctx,
team: svc.team.With(ctx),
team: repository.Team(ctx, db),
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ import (
func MountRoutes(ctx context.Context, config *repository.Flags) func(chi.Router) {
return func(r chi.Router) {
events := repository.NewEvents(ctx)
events := repository.NewEvents(ctx, nil)
go func() {
for {