Skip to content

Commit

Permalink
Merge pull request protobom#30 from jhoward-lm/set-unique-annotations
Browse files Browse the repository at this point in the history
refactor: enable custom unique annotations instead of static name "alias"
  • Loading branch information
puerco authored Aug 30, 2024
2 parents d68f106 + 5efae06 commit 7ea764c
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 76 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ linters:
enable:
- asciicheck
- bodyclose
- copyloopvar
- cyclop
- dogsled
- dupl
Expand All @@ -43,7 +44,6 @@ linters:
- errorlint
- err113
- exhaustive
- exportloopref
- forbidigo
- forcetypeassert
- funlen
Expand Down
129 changes: 66 additions & 63 deletions backends/ent/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/protobom/storage/internal/backends/ent"
"github.com/protobom/storage/internal/backends/ent/annotation"
"github.com/protobom/storage/internal/backends/ent/document"
"github.com/protobom/storage/internal/backends/ent/predicate"
)

func (backend *Backend) createAnnotations(data ...*ent.Annotation) error {
Expand All @@ -27,7 +28,8 @@ func (backend *Backend) createAnnotations(data ...*ent.Annotation) error {
builder := tx.Annotation.Create().
SetDocumentID(data[idx].DocumentID).
SetName(data[idx].Name).
SetValue(data[idx].Value)
SetValue(data[idx].Value).
SetIsUnique(data[idx].IsUnique)

builders = append(builders, builder)
}
Expand Down Expand Up @@ -77,14 +79,16 @@ func (backend *Backend) AddAnnotationToDocuments(name, value string, documentIDs

// ClearAnnotations removes all annotations from the specified documents.
func (backend *Backend) ClearAnnotations(documentIDs ...string) error {
if len(documentIDs) == 0 {
return nil
}

tx, err := backend.txClient()
if err != nil {
return err
}

_, err = tx.Annotation.Delete().
Where(annotation.DocumentIDIn(documentIDs...)).
Exec(backend.ctx)
_, err = tx.Annotation.Delete().Where(annotation.DocumentIDIn(documentIDs...)).Exec(backend.ctx)
if err != nil {
return rollback(tx, fmt.Errorf("clearing annotations: %w", err))
}
Expand All @@ -96,47 +100,22 @@ func (backend *Backend) ClearAnnotations(documentIDs ...string) error {
return nil
}

// GetDocumentAlias gets the value for the annotation named "alias".
func (backend *Backend) GetDocumentAlias(documentID string) (string, error) {
if backend.client == nil {
return "", errUninitializedClient
}

query := backend.client.Annotation.Query().
Where(
annotation.And(
annotation.HasDocumentWith(document.IDEQ(documentID)),
annotation.NameEQ("alias"),
),
)

result, err := query.Only(backend.ctx)
if err != nil {
if ent.IsNotFound(err) {
return "", nil
}

return "", fmt.Errorf("retrieving document alias: %w", err)
}

return result.Value, nil
}

// GetDocumentAnnotations gets all annotations for the specified
// document, limited to a set of annotation names if specified.
func (backend *Backend) GetDocumentAnnotations(documentID string, names ...string) (ent.Annotations, error) {
if backend.client == nil {
return nil, errUninitializedClient
}

query := backend.client.Annotation.Query().
Where(annotation.HasDocumentWith(document.IDEQ(documentID)))
predicates := []predicate.Annotation{
annotation.HasDocumentWith(document.IDEQ(documentID)),
}

if len(names) > 0 {
query.Where(annotation.NameIn(names...))
predicates = append(predicates, annotation.NameIn(names...))
}

annotations, err := query.All(backend.ctx)
annotations, err := backend.client.Annotation.Query().Where(predicates...).All(backend.ctx)
if err != nil {
return nil, fmt.Errorf("querying annotations: %w", err)
}
Expand All @@ -151,23 +130,46 @@ func (backend *Backend) GetDocumentsByAnnotation(name string, values ...string)
return nil, errUninitializedClient
}

ids, err := backend.client.Document.Query().
Where(
document.HasAnnotationsWith(
annotation.And(
annotation.NameEQ(name),
annotation.ValueIn(values...),
),
),
).
IDs(backend.ctx)
predicates := []predicate.Document{
document.HasAnnotationsWith(annotation.NameEQ(name)),
}

if len(values) > 0 {
predicates = append(predicates, document.HasAnnotationsWith(annotation.ValueIn(values...)))
}

ids, err := backend.client.Document.Query().Where(predicates...).IDs(backend.ctx)
if err != nil {
return nil, fmt.Errorf("querying documents table: %w", err)
}

return backend.GetDocumentsByID(ids...)
}

// GetDocumentUniqueAnnotation gets the value for a unique annotation.
func (backend *Backend) GetDocumentUniqueAnnotation(documentID, name string) (string, error) {
if backend.client == nil {
return "", errUninitializedClient
}

result, err := backend.client.Annotation.Query().
Where(
annotation.HasDocumentWith(document.IDEQ(documentID)),
annotation.NameEQ(name),
annotation.IsUniqueEQ(true),
).
Only(backend.ctx)
if err != nil {
if ent.IsNotFound(err) {
return "", nil
}

return "", fmt.Errorf("retrieving unique annotation for document: %w", err)
}

return result.Value, nil
}

// RemoveAnnotations removes all annotations with the specified name from
// the document, limited to a set of annotation values if specified.
func (backend *Backend) RemoveAnnotations(documentID, name string, values ...string) error {
Expand All @@ -176,16 +178,16 @@ func (backend *Backend) RemoveAnnotations(documentID, name string, values ...str
return err
}

_, err = tx.Annotation.Delete().
Where(
annotation.And(
annotation.DocumentIDEQ(documentID),
annotation.NameEQ(name),
annotation.ValueIn(values...),
),
).
Exec(backend.ctx)
if err != nil {
predicates := []predicate.Annotation{
annotation.DocumentIDEQ(documentID),
annotation.NameEQ(name),
}

if len(values) > 0 {
predicates = append(predicates, annotation.ValueIn(values...))
}

if _, err := tx.Annotation.Delete().Where(predicates...).Exec(backend.ctx); err != nil {
return rollback(tx, fmt.Errorf("removing annotations: %w", err))
}

Expand All @@ -196,15 +198,6 @@ func (backend *Backend) RemoveAnnotations(documentID, name string, values ...str
return nil
}

// SetDocumentAlias set the value for the annotation named "alias".
func (backend *Backend) SetDocumentAlias(documentID, value string) error {
if err := backend.RemoveAnnotations(documentID, "alias"); err != nil {
return err
}

return backend.AddAnnotations(documentID, "alias", value)
}

// SetAnnotations explicitly sets the named annotations for the specified document.
func (backend *Backend) SetAnnotations(documentID, name string, values ...string) error {
if err := backend.ClearAnnotations(documentID); err != nil {
Expand All @@ -213,3 +206,13 @@ func (backend *Backend) SetAnnotations(documentID, name string, values ...string

return backend.AddAnnotations(documentID, name, values...)
}

// SetUniqueAnnotation sets a named annotation value that is unique to the specified document.
func (backend *Backend) SetUniqueAnnotation(documentID, name, value string) error {
return backend.createAnnotations(&ent.Annotation{
DocumentID: documentID,
Name: name,
Value: value,
IsUnique: true,
})
}
13 changes: 13 additions & 0 deletions internal/backends/ent/annotation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions internal/backends/ent/annotation/annotation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions internal/backends/ent/annotation/where.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7ea764c

Please sign in to comment.