aboutsummaryrefslogtreecommitdiffstats
path: root/entity
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2022-12-21 21:54:36 +0100
committerMichael Muré <batolettre@gmail.com>2022-12-21 21:54:36 +0100
commit9b98fc06489353053564b431ac0c0d73a5c55a56 (patch)
tree67cab95c0c6167c0982516a2dda610bd5ece9eab /entity
parent905c9a90f134842b97e2cf729d8b11ff59bfd766 (diff)
downloadgit-bug-9b98fc06489353053564b431ac0c0d73a5c55a56.tar.gz
cache: tie up the refactor up to compiling
Diffstat (limited to 'entity')
-rw-r--r--entity/dag/entity.go34
-rw-r--r--entity/dag/entity_actions_test.go2
-rw-r--r--entity/err.go16
-rw-r--r--entity/interface.go12
-rw-r--r--entity/resolver.go29
-rw-r--r--entity/streamed.go6
6 files changed, 47 insertions, 52 deletions
diff --git a/entity/dag/entity.go b/entity/dag/entity.go
index 03b97aa0..2028e1b4 100644
--- a/entity/dag/entity.go
+++ b/entity/dag/entity.go
@@ -33,19 +33,6 @@ type Definition struct {
FormatVersion uint
}
-type Actions[EntityT entity.Interface] struct {
- Wrap func(e *Entity) EntityT
- New func() EntityT
- Read func(repo repository.ClockedRepo, id entity.Id) (EntityT, error)
- ReadWithResolver func(repo repository.ClockedRepo, resolvers entity.Resolvers, id entity.Id) (EntityT, error)
- ReadAll func(repo repository.ClockedRepo) <-chan StreamedEntity[EntityT]
- ListLocalIds func(repo repository.Repo) ([]entity.Id, error)
- Fetch func(repo repository.Repo, remote string) (string, error)
- Push func(repo repository.Repo, remote string) (string, error)
- Pull func(repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, mergeAuthor identity.Interface) error
- MergeAll func(repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, mergeAuthor identity.Interface) <-chan entity.MergeResult
-}
-
// Entity is a data structure stored in a chain of git objects, supporting actions like Push, Pull and Merge.
type Entity struct {
// A Lamport clock is a logical clock that allow to order event
@@ -96,6 +83,9 @@ func readRemote[EntityT entity.Interface](def Definition, wrapper func(e *Entity
// read fetch from git and decode an Entity at an arbitrary git reference.
func read[EntityT entity.Interface](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers, ref string) (EntityT, error) {
rootHash, err := repo.ResolveRef(ref)
+ if err == repository.ErrNotFound {
+ return *new(EntityT), entity.NewErrNotFound(def.Typename)
+ }
if err != nil {
return *new(EntityT), err
}
@@ -260,6 +250,9 @@ func read[EntityT entity.Interface](def Definition, wrapper func(e *Entity) Enti
// operation blobs can be implemented instead.
func readClockNoCheck(def Definition, repo repository.ClockedRepo, ref string) error {
rootHash, err := repo.ResolveRef(ref)
+ if err == repository.ErrNotFound {
+ return entity.NewErrNotFound(def.Typename)
+ }
if err != nil {
return err
}
@@ -306,14 +299,9 @@ func readClockNoCheck(def Definition, repo repository.ClockedRepo, ref string) e
return nil
}
-type StreamedEntity[EntityT entity.Interface] struct {
- Entity EntityT
- Err error
-}
-
// ReadAll read and parse all local Entity
-func ReadAll[EntityT entity.Interface](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers) <-chan StreamedEntity[EntityT] {
- out := make(chan StreamedEntity[EntityT])
+func ReadAll[EntityT entity.Interface](def Definition, wrapper func(e *Entity) EntityT, repo repository.ClockedRepo, resolvers entity.Resolvers) <-chan entity.StreamedEntity[EntityT] {
+ out := make(chan entity.StreamedEntity[EntityT])
go func() {
defer close(out)
@@ -322,7 +310,7 @@ func ReadAll[EntityT entity.Interface](def Definition, wrapper func(e *Entity) E
refs, err := repo.ListRefs(refPrefix)
if err != nil {
- out <- StreamedEntity[EntityT]{Err: err}
+ out <- entity.StreamedEntity[EntityT]{Err: err}
return
}
@@ -330,11 +318,11 @@ func ReadAll[EntityT entity.Interface](def Definition, wrapper func(e *Entity) E
e, err := read[EntityT](def, wrapper, repo, resolvers, ref)
if err != nil {
- out <- StreamedEntity[EntityT]{Err: err}
+ out <- entity.StreamedEntity[EntityT]{Err: err}
return
}
- out <- StreamedEntity[EntityT]{Entity: e}
+ out <- entity.StreamedEntity[EntityT]{Entity: e}
}
}()
diff --git a/entity/dag/entity_actions_test.go b/entity/dag/entity_actions_test.go
index d93059de..fd219644 100644
--- a/entity/dag/entity_actions_test.go
+++ b/entity/dag/entity_actions_test.go
@@ -11,7 +11,7 @@ import (
"github.com/MichaelMure/git-bug/repository"
)
-func allEntities(t testing.TB, bugs <-chan StreamedEntity[*Foo]) []*Foo {
+func allEntities(t testing.TB, bugs <-chan entity.StreamedEntity[*Foo]) []*Foo {
t.Helper()
var result []*Foo
diff --git a/entity/err.go b/entity/err.go
index 9d7c266e..4453d36e 100644
--- a/entity/err.go
+++ b/entity/err.go
@@ -5,6 +5,8 @@ import (
"strings"
)
+// ErrNotFound is to be returned when an entity, item, element is
+// not found.
type ErrNotFound struct {
typename string
}
@@ -22,13 +24,15 @@ func IsErrNotFound(err error) bool {
return ok
}
+// ErrMultipleMatch is to be returned when more than one entity, item, element
+// is found, where only one was expected.
type ErrMultipleMatch struct {
- entityType string
- Matching []Id
+ typename string
+ Matching []Id
}
-func NewErrMultipleMatch(entityType string, matching []Id) *ErrMultipleMatch {
- return &ErrMultipleMatch{entityType: entityType, Matching: matching}
+func NewErrMultipleMatch(typename string, matching []Id) *ErrMultipleMatch {
+ return &ErrMultipleMatch{typename: typename, Matching: matching}
}
func (e ErrMultipleMatch) Error() string {
@@ -39,7 +43,7 @@ func (e ErrMultipleMatch) Error() string {
}
return fmt.Sprintf("Multiple matching %s found:\n%s",
- e.entityType,
+ e.typename,
strings.Join(matching, "\n"))
}
@@ -48,6 +52,8 @@ func IsErrMultipleMatch(err error) bool {
return ok
}
+// ErrInvalidFormat is to be returned when reading on-disk data with an unexpected
+// format or version.
type ErrInvalidFormat struct {
version uint
expected uint
diff --git a/entity/interface.go b/entity/interface.go
index 572ba602..3035ac88 100644
--- a/entity/interface.go
+++ b/entity/interface.go
@@ -12,15 +12,3 @@ type Interface interface {
// Validate check if the Entity data is valid
Validate() error
}
-
-// type Commitable interface {
-// Interface
-// NeedCommit() bool
-// CommitAsNeeded(repo repository.ClockedRepo) error
-// Commit(repo repository.ClockedRepo) error
-// }
-
-//
-// type Operation interface {
-//
-// }
diff --git a/entity/resolver.go b/entity/resolver.go
index 9cacbf00..bd16b901 100644
--- a/entity/resolver.go
+++ b/entity/resolver.go
@@ -5,16 +5,23 @@ import (
"sync"
)
+// Resolved is a minimal interface on which Resolver operates on.
+// Notably, this operates on Entity and Excerpt in the cache.
+type Resolved interface {
+ // Id returns the object identifier.
+ Id() Id
+}
+
// Resolver is an interface to find an Entity from its Id
type Resolver interface {
- Resolve(id Id) (Interface, error)
+ Resolve(id Id) (Resolved, error)
}
// Resolvers is a collection of Resolver, for different type of Entity
-type Resolvers map[Interface]Resolver
+type Resolvers map[Resolved]Resolver
// Resolve use the appropriate sub-resolver for the given type and find the Entity matching the Id.
-func Resolve[T Interface](rs Resolvers, id Id) (T, error) {
+func Resolve[T Resolved](rs Resolvers, id Id) (T, error) {
var zero T
for t, resolver := range rs {
switch t.(type) {
@@ -35,17 +42,17 @@ var _ Resolver = &CachedResolver{}
type CachedResolver struct {
resolver Resolver
mu sync.RWMutex
- entities map[Id]Interface
+ entities map[Id]Resolved
}
func NewCachedResolver(resolver Resolver) *CachedResolver {
return &CachedResolver{
resolver: resolver,
- entities: make(map[Id]Interface),
+ entities: make(map[Id]Resolved),
}
}
-func (c *CachedResolver) Resolve(id Id) (Interface, error) {
+func (c *CachedResolver) Resolve(id Id) (Resolved, error) {
c.mu.RLock()
if i, ok := c.entities[id]; ok {
c.mu.RUnlock()
@@ -64,18 +71,18 @@ func (c *CachedResolver) Resolve(id Id) (Interface, error) {
return i, nil
}
-var _ Resolver = ResolverFunc[Interface](nil)
+var _ Resolver = ResolverFunc[Resolved](nil)
// ResolverFunc is a helper to morph a function resolver into a Resolver
-type ResolverFunc[T Interface] func(id Id) (T, error)
+type ResolverFunc[EntityT Resolved] func(id Id) (EntityT, error)
-func (fn ResolverFunc[T]) Resolve(id Id) (Interface, error) {
+func (fn ResolverFunc[EntityT]) Resolve(id Id) (Resolved, error) {
return fn(id)
}
// MakeResolver create a resolver able to return the given entities.
-func MakeResolver(entities ...Interface) Resolver {
- return ResolverFunc[Interface](func(id Id) (Interface, error) {
+func MakeResolver(entities ...Resolved) Resolver {
+ return ResolverFunc[Resolved](func(id Id) (Resolved, error) {
for _, entity := range entities {
if entity.Id() == id {
return entity, nil
diff --git a/entity/streamed.go b/entity/streamed.go
new file mode 100644
index 00000000..789224a3
--- /dev/null
+++ b/entity/streamed.go
@@ -0,0 +1,6 @@
+package entity
+
+type StreamedEntity[EntityT Interface] struct {
+ Entity EntityT
+ Err error
+}