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 Login() (string, error)
22 AvatarUrl() (string, error)
23 Keys() ([]*identity.Key, error)
24 ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error)
25 DisplayName() string
26 IsProtected() (bool, error)
27 LastModificationLamport() (lamport.Time, error)
28 LastModification() (timestamp.Timestamp, error)
29}
30
31var _ IdentityWrapper = &lazyIdentity{}
32
33type lazyIdentity struct {
34 cache *cache.RepoCache
35 excerpt *cache.IdentityExcerpt
36
37 mu sync.Mutex
38 id *cache.IdentityCache
39}
40
41func NewLazyIdentity(cache *cache.RepoCache, excerpt *cache.IdentityExcerpt) *lazyIdentity {
42 return &lazyIdentity{
43 cache: cache,
44 excerpt: excerpt,
45 }
46}
47
48func (li *lazyIdentity) load() (*cache.IdentityCache, error) {
49 if li.id != nil {
50 return li.id, nil
51 }
52
53 li.mu.Lock()
54 defer li.mu.Unlock()
55
56 id, err := li.cache.ResolveIdentity(li.excerpt.Id)
57 if err != nil {
58 return nil, fmt.Errorf("cache: missing identity %v", li.excerpt.Id)
59 }
60 li.id = id
61 return id, nil
62}
63
64func (li *lazyIdentity) Id() entity.Id {
65 return li.excerpt.Id
66}
67
68func (li *lazyIdentity) Name() string {
69 return li.excerpt.Name
70}
71
72func (li *lazyIdentity) Email() (string, error) {
73 id, err := li.load()
74 if err != nil {
75 return "", err
76 }
77 return id.Email(), nil
78}
79
80func (li *lazyIdentity) Login() (string, error) {
81 id, err := li.load()
82 if err != nil {
83 return "", err
84 }
85 return id.Login(), nil
86}
87
88func (li *lazyIdentity) AvatarUrl() (string, error) {
89 id, err := li.load()
90 if err != nil {
91 return "", err
92 }
93 return id.AvatarUrl(), nil
94}
95
96func (li *lazyIdentity) Keys() ([]*identity.Key, error) {
97 id, err := li.load()
98 if err != nil {
99 return nil, err
100 }
101 return id.Keys(), nil
102}
103
104func (li *lazyIdentity) ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error) {
105 id, err := li.load()
106 if err != nil {
107 return nil, err
108 }
109 return id.ValidKeysAtTime(time), nil
110}
111
112func (li *lazyIdentity) DisplayName() string {
113 return li.excerpt.DisplayName()
114}
115
116func (li *lazyIdentity) IsProtected() (bool, error) {
117 id, err := li.load()
118 if err != nil {
119 return false, err
120 }
121 return id.IsProtected(), nil
122}
123
124func (li *lazyIdentity) LastModificationLamport() (lamport.Time, error) {
125 id, err := li.load()
126 if err != nil {
127 return 0, err
128 }
129 return id.LastModificationLamport(), nil
130}
131
132func (li *lazyIdentity) LastModification() (timestamp.Timestamp, error) {
133 id, err := li.load()
134 if err != nil {
135 return 0, err
136 }
137 return id.LastModification(), nil
138}
139
140var _ IdentityWrapper = &loadedIdentity{}
141
142type loadedIdentity struct {
143 identity.Interface
144}
145
146func NewLoadedIdentity(id identity.Interface) *loadedIdentity {
147 return &loadedIdentity{Interface: id}
148}
149
150func (l loadedIdentity) Email() (string, error) {
151 return l.Interface.Email(), nil
152}
153
154func (l loadedIdentity) Login() (string, error) {
155 return l.Interface.Login(), nil
156}
157
158func (l loadedIdentity) AvatarUrl() (string, error) {
159 return l.Interface.AvatarUrl(), nil
160}
161
162func (l loadedIdentity) Keys() ([]*identity.Key, error) {
163 return l.Interface.Keys(), nil
164}
165
166func (l loadedIdentity) ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error) {
167 return l.Interface.ValidKeysAtTime(time), nil
168}
169
170func (l loadedIdentity) IsProtected() (bool, error) {
171 return l.Interface.IsProtected(), nil
172}
173
174func (l loadedIdentity) LastModificationLamport() (lamport.Time, error) {
175 return l.Interface.LastModificationLamport(), nil
176}
177
178func (l loadedIdentity) LastModification() (timestamp.Timestamp, error) {
179 return l.Interface.LastModification(), nil
180}