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}