identity_subcache.go

  1package cache
  2
  3import (
  4	"fmt"
  5
  6	"github.com/MichaelMure/git-bug/entities/identity"
  7	"github.com/MichaelMure/git-bug/entity"
  8	"github.com/MichaelMure/git-bug/repository"
  9)
 10
 11type RepoCacheIdentity struct {
 12	*SubCache[*identity.Identity, *IdentityExcerpt, *IdentityCache]
 13}
 14
 15func NewRepoCacheIdentity(repo repository.ClockedRepo,
 16	resolvers func() entity.Resolvers,
 17	getUserIdentity getUserIdentityFunc) *RepoCacheIdentity {
 18
 19	makeCached := func(i *identity.Identity, entityUpdated func(id entity.Id) error) *IdentityCache {
 20		return NewIdentityCache(i, repo, entityUpdated)
 21	}
 22
 23	makeExcerpt := func(i *identity.Identity) *IdentityExcerpt {
 24		return NewIdentityExcerpt(i)
 25	}
 26
 27	makeIndex := func(i *IdentityCache) []string {
 28		// no indexing
 29		return nil
 30	}
 31
 32	sc := NewSubCache[*identity.Identity, *IdentityExcerpt, *IdentityCache](
 33		repo, resolvers, getUserIdentity,
 34		makeCached, makeExcerpt, makeIndex,
 35		"identity", "identities",
 36		formatVersion, defaultMaxLoadedBugs,
 37	)
 38
 39	return &RepoCacheIdentity{SubCache: sc}
 40}
 41
 42// ResolveIdentityImmutableMetadata retrieve an Identity that has the exact given metadata on
 43// one of its version. If multiple version have the same key, the first defined take precedence.
 44func (c *RepoCacheIdentity) ResolveIdentityImmutableMetadata(key string, value string) (*IdentityCache, error) {
 45	return c.ResolveMatcher(func(excerpt *IdentityExcerpt) bool {
 46		return excerpt.ImmutableMetadata[key] == value
 47	})
 48}
 49
 50func (c *RepoCacheIdentity) NewIdentityFromGitUser() (*IdentityCache, error) {
 51	return c.NewIdentityFromGitUserRaw(nil)
 52}
 53
 54func (c *RepoCacheIdentity) NewIdentityFromGitUserRaw(metadata map[string]string) (*IdentityCache, error) {
 55	i, err := identity.NewFromGitUser(c.repo)
 56	if err != nil {
 57		return nil, err
 58	}
 59	return c.finishIdentity(i, metadata)
 60}
 61
 62// NewIdentity create a new identity
 63// The new identity is written in the repository (commit)
 64func (c *RepoCacheIdentity) NewIdentity(name string, email string) (*IdentityCache, error) {
 65	return c.NewIdentityRaw(name, email, "", "", nil, nil)
 66}
 67
 68// NewIdentityFull create a new identity
 69// The new identity is written in the repository (commit)
 70func (c *RepoCacheIdentity) NewIdentityFull(name string, email string, login string, avatarUrl string, keys []*identity.Key) (*IdentityCache, error) {
 71	return c.NewIdentityRaw(name, email, login, avatarUrl, keys, nil)
 72}
 73
 74func (c *RepoCacheIdentity) NewIdentityRaw(name string, email string, login string, avatarUrl string, keys []*identity.Key, metadata map[string]string) (*IdentityCache, error) {
 75	i, err := identity.NewIdentityFull(c.repo, name, email, login, avatarUrl, keys)
 76	if err != nil {
 77		return nil, err
 78	}
 79	return c.finishIdentity(i, metadata)
 80}
 81
 82func (c *RepoCacheIdentity) finishIdentity(i *identity.Identity, metadata map[string]string) (*IdentityCache, error) {
 83	for key, value := range metadata {
 84		i.SetMetadata(key, value)
 85	}
 86
 87	err := i.Commit(c.repo)
 88	if err != nil {
 89		return nil, err
 90	}
 91
 92	c.mu.Lock()
 93	if _, has := c.cached[i.Id()]; has {
 94		return nil, fmt.Errorf("identity %s already exist in the cache", i.Id())
 95	}
 96
 97	cached := NewIdentityCache(i, c.repo, c.entityUpdated)
 98	c.cached[i.Id()] = cached
 99	c.mu.Unlock()
100
101	// force the write of the excerpt
102	err = c.entityUpdated(i.Id())
103	if err != nil {
104		return nil, err
105	}
106
107	return cached, nil
108}