lazy_board.go

  1package models
  2
  3import (
  4	"sync"
  5	"time"
  6
  7	"github.com/git-bug/git-bug/cache"
  8	"github.com/git-bug/git-bug/entities/board"
  9	"github.com/git-bug/git-bug/entity"
 10	"github.com/git-bug/git-bug/entity/dag"
 11)
 12
 13// BoardWrapper is an interface used by the GraphQL resolvers to handle a board.
 14// Depending on the situation, a Board can already be fully loaded in memory or not.
 15// This interface is used to wrap either a lazyBoard or a loadedBoard depending on the situation.
 16type BoardWrapper interface {
 17	Id() entity.Id
 18	LastEdit() time.Time
 19	CreatedAt() time.Time
 20
 21	Title() string
 22	Description() string
 23	Columns() ([]*board.Column, error)
 24
 25	Actors() ([]IdentityWrapper, error)
 26	Operations() ([]dag.Operation, error)
 27}
 28
 29var _ BoardWrapper = &lazyBoard{}
 30
 31type lazyBoard struct {
 32	cache   *cache.RepoCache
 33	excerpt *cache.BoardExcerpt
 34
 35	mu   sync.Mutex
 36	snap *board.Snapshot
 37}
 38
 39func NewLazyBoard(cache *cache.RepoCache, excerpt *cache.BoardExcerpt) *lazyBoard {
 40	return &lazyBoard{
 41		cache:   cache,
 42		excerpt: excerpt,
 43	}
 44}
 45
 46func (lb *lazyBoard) load() error {
 47	lb.mu.Lock()
 48	defer lb.mu.Unlock()
 49
 50	if lb.snap != nil {
 51		return nil
 52	}
 53
 54	b, err := lb.cache.Boards().Resolve(lb.excerpt.Id())
 55	if err != nil {
 56		return err
 57	}
 58
 59	lb.snap = b.Snapshot()
 60	return nil
 61}
 62
 63func (lb *lazyBoard) identity(id entity.Id) (IdentityWrapper, error) {
 64	i, err := lb.cache.Identities().ResolveExcerpt(id)
 65	if err != nil {
 66		return nil, err
 67	}
 68	return &lazyIdentity{cache: lb.cache, excerpt: i}, nil
 69}
 70
 71func (lb *lazyBoard) Id() entity.Id {
 72	return lb.excerpt.Id()
 73}
 74
 75func (lb *lazyBoard) LastEdit() time.Time {
 76	return lb.excerpt.EditTime()
 77}
 78
 79func (lb *lazyBoard) CreatedAt() time.Time {
 80	return lb.excerpt.CreateTime()
 81}
 82
 83func (lb *lazyBoard) Title() string {
 84	return lb.excerpt.Title
 85}
 86
 87func (lb *lazyBoard) Description() string {
 88	return lb.excerpt.Description
 89}
 90
 91func (lb *lazyBoard) Columns() ([]*board.Column, error) {
 92	err := lb.load()
 93	if err != nil {
 94		return nil, err
 95	}
 96	return lb.snap.Columns, nil
 97}
 98
 99func (lb *lazyBoard) Actors() ([]IdentityWrapper, error) {
100	result := make([]IdentityWrapper, len(lb.excerpt.Actors))
101	for i, actorId := range lb.excerpt.Actors {
102		actor, err := lb.identity(actorId)
103		if err != nil {
104			return nil, err
105		}
106		result[i] = actor
107	}
108	return result, nil
109}
110
111func (lb *lazyBoard) Operations() ([]dag.Operation, error) {
112	err := lb.load()
113	if err != nil {
114		return nil, err
115	}
116	return lb.snap.Operations, nil
117}
118
119var _ BoardWrapper = &loadedBoard{}
120
121type loadedBoard struct {
122	*board.Snapshot
123}
124
125func NewLoadedBoard(snap *board.Snapshot) *loadedBoard {
126	return &loadedBoard{Snapshot: snap}
127}
128
129func (l *loadedBoard) LastEdit() time.Time {
130	return l.Snapshot.EditTime()
131}
132
133func (l *loadedBoard) CreatedAt() time.Time {
134	return l.Snapshot.CreateTime
135}
136
137func (l *loadedBoard) Title() string {
138	return l.Snapshot.Title
139}
140
141func (l *loadedBoard) Description() string {
142	return l.Snapshot.Description
143}
144
145func (l *loadedBoard) Columns() ([]*board.Column, error) {
146	return l.Snapshot.Columns, nil
147}
148
149func (l *loadedBoard) Actors() ([]IdentityWrapper, error) {
150	res := make([]IdentityWrapper, len(l.Snapshot.Actors))
151	for i, actor := range l.Snapshot.Actors {
152		res[i] = NewLoadedIdentity(actor)
153	}
154	return res, nil
155}
156
157func (l *loadedBoard) Operations() ([]dag.Operation, error) {
158	return l.Snapshot.Operations, nil
159}