lazy_identity.go

  1package models
  2
  3import (
  4	"fmt"
  5	"sync"
  6
  7	"github.com/MichaelMure/git-bug/cache"
  8	"github.com/MichaelMure/git-bug/entity"
  9	"github.com/MichaelMure/git-bug/identity"
 10	"github.com/MichaelMure/git-bug/util/lamport"
 11	"github.com/MichaelMure/git-bug/util/timestamp"
 12)
 13
 14// IdentityWrapper is an interface used by the GraphQL resolvers to handle an identity.
 15// Depending on the situation, an Identity can already be fully loaded in memory or not.
 16// This interface is used to wrap either a lazyIdentity or a loadedIdentity depending on the situation.
 17type IdentityWrapper interface {
 18	Id() entity.Id
 19	Name() string
 20	Email() (string, error)
 21	AvatarUrl() (string, error)
 22	Keys() ([]*identity.Key, error)
 23	ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error)
 24	DisplayName() string
 25	IsProtected() (bool, error)
 26	LastModificationLamport() (lamport.Time, error)
 27	LastModification() (timestamp.Timestamp, error)
 28}
 29
 30var _ IdentityWrapper = &lazyIdentity{}
 31
 32type lazyIdentity struct {
 33	cache   *cache.RepoCache
 34	excerpt *cache.IdentityExcerpt
 35
 36	mu sync.Mutex
 37	id *cache.IdentityCache
 38}
 39
 40func NewLazyIdentity(cache *cache.RepoCache, excerpt *cache.IdentityExcerpt) *lazyIdentity {
 41	return &lazyIdentity{
 42		cache:   cache,
 43		excerpt: excerpt,
 44	}
 45}
 46
 47func (li *lazyIdentity) load() (*cache.IdentityCache, error) {
 48	if li.id != nil {
 49		return li.id, nil
 50	}
 51
 52	li.mu.Lock()
 53	defer li.mu.Unlock()
 54
 55	id, err := li.cache.ResolveIdentity(li.excerpt.Id)
 56	if err != nil {
 57		return nil, fmt.Errorf("cache: missing identity %v", li.excerpt.Id)
 58	}
 59	li.id = id
 60	return id, nil
 61}
 62
 63func (li *lazyIdentity) Id() entity.Id {
 64	return li.excerpt.Id
 65}
 66
 67func (li *lazyIdentity) Name() string {
 68	return li.excerpt.Name
 69}
 70
 71func (li *lazyIdentity) Email() (string, error) {
 72	id, err := li.load()
 73	if err != nil {
 74		return "", err
 75	}
 76	return id.Email(), nil
 77}
 78
 79func (li *lazyIdentity) AvatarUrl() (string, error) {
 80	id, err := li.load()
 81	if err != nil {
 82		return "", err
 83	}
 84	return id.AvatarUrl(), nil
 85}
 86
 87func (li *lazyIdentity) Keys() ([]*identity.Key, error) {
 88	id, err := li.load()
 89	if err != nil {
 90		return nil, err
 91	}
 92	return id.Keys(), nil
 93}
 94
 95func (li *lazyIdentity) ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error) {
 96	id, err := li.load()
 97	if err != nil {
 98		return nil, err
 99	}
100	return id.ValidKeysAtTime(time), nil
101}
102
103func (li *lazyIdentity) DisplayName() string {
104	return li.excerpt.DisplayName()
105}
106
107func (li *lazyIdentity) IsProtected() (bool, error) {
108	id, err := li.load()
109	if err != nil {
110		return false, err
111	}
112	return id.IsProtected(), nil
113}
114
115func (li *lazyIdentity) LastModificationLamport() (lamport.Time, error) {
116	id, err := li.load()
117	if err != nil {
118		return 0, err
119	}
120	return id.LastModificationLamport(), nil
121}
122
123func (li *lazyIdentity) LastModification() (timestamp.Timestamp, error) {
124	id, err := li.load()
125	if err != nil {
126		return 0, err
127	}
128	return id.LastModification(), nil
129}
130
131var _ IdentityWrapper = &loadedIdentity{}
132
133type loadedIdentity struct {
134	identity.Interface
135}
136
137func NewLoadedIdentity(id identity.Interface) *loadedIdentity {
138	return &loadedIdentity{Interface: id}
139}
140
141func (l loadedIdentity) Email() (string, error) {
142	return l.Interface.Email(), nil
143}
144
145func (l loadedIdentity) AvatarUrl() (string, error) {
146	return l.Interface.AvatarUrl(), nil
147}
148
149func (l loadedIdentity) Keys() ([]*identity.Key, error) {
150	return l.Interface.Keys(), nil
151}
152
153func (l loadedIdentity) ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error) {
154	return l.Interface.ValidKeysAtTime(time), nil
155}
156
157func (l loadedIdentity) IsProtected() (bool, error) {
158	return l.Interface.IsProtected(), nil
159}
160
161func (l loadedIdentity) LastModificationLamport() (lamport.Time, error) {
162	return l.Interface.LastModificationLamport(), nil
163}
164
165func (l loadedIdentity) LastModification() (timestamp.Timestamp, error) {
166	return l.Interface.LastModification(), nil
167}