Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: redefine annotation document ID as nillable/pointer type #57

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 91 additions & 49 deletions backends/ent/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (backend *Backend) AddAnnotationToDocuments(name, value string, documentIDs

for _, id := range docUUIDs {
data = append(data, &ent.Annotation{
DocumentID: id,
DocumentID: &id,
Name: name,
Value: value,
})
Expand All @@ -64,10 +64,18 @@ func (backend *Backend) AddAnnotationToNodes(name, value string, nodeIDs ...stri
return fmt.Errorf("querying nodes: %w", err)
}

for _, n := range nodes {
for idx := range nodes {
documentID, err := nodes[idx].
QueryNodeLists().
QueryDocument().
OnlyID(backend.ctx)
if err != nil {
return fmt.Errorf("querying node edges for document ID: %w", err)
}

data = append(data, &ent.Annotation{
DocumentID: n.DocumentID,
NodeID: &n.ID,
DocumentID: &documentID,
NodeID: &nodes[idx].ID,
Name: name,
Value: value,
})
Expand All @@ -80,21 +88,23 @@ func (backend *Backend) AddAnnotationToNodes(name, value string, nodeIDs ...stri
func (backend *Backend) AddDocumentAnnotations(documentID, name string, values ...string) error {
data := ent.Annotations{}

documentUUID, err := backend.client.Metadata.Query().
ids, err := backend.client.Metadata.Query().
WithDocument().
Where(metadata.NativeIDEQ(documentID)).
QueryDocument().
OnlyID(backend.ctx)
IDs(backend.ctx)
if err != nil {
return fmt.Errorf("querying documents: %w", err)
}

for _, value := range values {
data = append(data, &ent.Annotation{
DocumentID: documentUUID,
Name: name,
Value: value,
})
for idx := range ids {
for _, value := range values {
data = append(data, &ent.Annotation{
DocumentID: &ids[idx],
Name: name,
Value: value,
})
}
}

return backend.withTx(backend.saveAnnotations(data...))
Expand All @@ -104,20 +114,21 @@ func (backend *Backend) AddDocumentAnnotations(documentID, name string, values .
func (backend *Backend) AddNodeAnnotations(nodeID, name string, values ...string) error {
data := ent.Annotations{}

result, err := backend.client.Node.Query().
nodes, err := backend.client.Node.Query().
Where(node.NativeIDEQ(nodeID)).
Only(backend.ctx)
All(backend.ctx)
if err != nil {
return fmt.Errorf("querying documents: %w", err)
}

for _, value := range values {
data = append(data, &ent.Annotation{
DocumentID: result.DocumentID,
NodeID: &result.ID,
Name: name,
Value: value,
})
for idx := range nodes {
for _, value := range values {
data = append(data, &ent.Annotation{
NodeID: &nodes[idx].ID,
Name: name,
Value: value,
})
}
}

return backend.withTx(backend.saveAnnotations(data...))
Expand Down Expand Up @@ -238,16 +249,15 @@ func (backend *Backend) GetDocumentUniqueAnnotation(documentID, name string) (st
return "", errUninitializedClient
}

result, err := backend.client.Annotation.Query().
Where(
annotation.HasDocumentWith(
document.HasMetadataWith(metadata.NativeIDEQ(documentID)),
),
results, err := backend.client.Annotation.Query().
Where(annotation.And(
annotation.HasDocumentWith(document.HasMetadataWith(metadata.NativeIDEQ(documentID))),
annotation.NameEQ(name),
annotation.IsUniqueEQ(true),
annotation.Not(annotation.HasNode()),
).
Only(backend.ctx)
)).
Unique(true).
All(backend.ctx)
if err != nil {
if ent.IsNotFound(err) {
return "", nil
Expand All @@ -256,7 +266,14 @@ func (backend *Backend) GetDocumentUniqueAnnotation(documentID, name string) (st
return "", fmt.Errorf("retrieving unique annotation for document: %w", err)
}

return result.Value, nil
value := results[0].Value
for _, result := range results {
if result.Value != value {
return "", fmt.Errorf("%w", &ent.NotSingularError{})
}
}

return value, nil
}

// GetNodeAnnotations gets all annotations for the specified
Expand Down Expand Up @@ -319,13 +336,14 @@ func (backend *Backend) GetNodeUniqueAnnotation(nodeID, name string) (string, er
return "", errUninitializedClient
}

result, err := backend.client.Annotation.Query().
Where(
results, err := backend.client.Annotation.Query().
Where(annotation.And(
annotation.HasNodeWith(node.NativeIDEQ(nodeID)),
annotation.NameEQ(name),
annotation.IsUniqueEQ(true),
).
Only(backend.ctx)
)).
Unique(true).
All(backend.ctx)
if err != nil {
if ent.IsNotFound(err) {
return "", nil
Expand All @@ -334,7 +352,14 @@ func (backend *Backend) GetNodeUniqueAnnotation(nodeID, name string) (string, er
return "", fmt.Errorf("retrieving unique annotation for node: %w", err)
}

return result.Value, nil
value := results[0].Value
for _, result := range results {
if result.Value != value {
return "", fmt.Errorf("%w", &ent.NotSingularError{})
}
}

return value, nil
}

// RemoveDocumentAnnotations removes all annotations with the specified name from
Expand Down Expand Up @@ -392,22 +417,27 @@ func (backend *Backend) SetDocumentAnnotations(documentID, name string, values .

// SetDocumentUniqueAnnotation sets a named annotation value that is unique to the specified document.
func (backend *Backend) SetDocumentUniqueAnnotation(documentID, name, value string) error {
documentUUID, err := backend.client.Metadata.Query().
ids, err := backend.client.Metadata.Query().
WithDocument().
Where(metadata.NativeIDEQ(documentID)).
QueryDocument().
OnlyID(backend.ctx)
IDs(backend.ctx)
if err != nil {
return fmt.Errorf("%w", err)
}

return backend.withTx(
backend.saveAnnotations(&ent.Annotation{
DocumentID: documentUUID,
annotations := ent.Annotations{}

for idx := range ids {
annotations = append(annotations, &ent.Annotation{
DocumentID: &ids[idx],
Name: name,
Value: value,
IsUnique: true,
}),
)
})
}

return backend.withTx(backend.saveAnnotations(annotations...))
}

// SetNodeAnnotations explicitly sets the named annotations for the specified node.
Expand All @@ -421,20 +451,32 @@ func (backend *Backend) SetNodeAnnotations(nodeID, name string, values ...string

// SetNodeUniqueAnnotation sets a named annotation value that is unique to the specified node.
func (backend *Backend) SetNodeUniqueAnnotation(nodeID, name, value string) error {
result, err := backend.client.Node.Query().
nodes, err := backend.client.Node.Query().
Where(node.NativeIDEQ(nodeID)).
Only(backend.ctx)
All(backend.ctx)
if err != nil {
return fmt.Errorf("querying nodes: %w", err)
}

return backend.withTx(
backend.saveAnnotations(&ent.Annotation{
DocumentID: result.DocumentID,
NodeID: &result.ID,
annotations := ent.Annotations{}

for idx := range nodes {
documentID, err := nodes[idx].
QueryNodeLists().
QueryDocument().
OnlyID(backend.ctx)
if err != nil {
return fmt.Errorf("querying node edges for document ID: %w", err)
}

annotations = append(annotations, &ent.Annotation{
DocumentID: &documentID,
NodeID: &nodes[idx].ID,
Name: name,
Value: value,
IsUnique: true,
}),
)
})
}

return backend.withTx(backend.saveAnnotations(annotations...))
}
4 changes: 2 additions & 2 deletions backends/ent/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ func (as *annotationsSuite) TestBackend_SetDocumentUniqueAnnotation() { //nolint
annotations := as.getTestResult(annotationName)

as.Require().Len(annotations, subtest.expectedLen)
as.Equal(uniqueID, annotations[subtest.documentIdx].DocumentID)
as.Equal(&uniqueID, annotations[subtest.documentIdx].DocumentID)
as.Equal(annotationName, annotations[subtest.documentIdx].Name)
as.Equal(subtest.value, annotations[subtest.documentIdx].Value)
})
Expand Down Expand Up @@ -622,7 +622,7 @@ func (as *annotationsSuite) TestBackend_SetNodeUniqueAnnotation() { //nolint:dup
annotations := as.getTestResult(annotationName)

as.Require().Len(annotations, subtest.expectedLen)
as.Equal(uniqueID, annotations[subtest.nodeIdx].DocumentID)
as.Equal(&uniqueID, annotations[subtest.nodeIdx].DocumentID)
as.Equal(annotationName, annotations[subtest.nodeIdx].Name)
as.Equal(subtest.value, annotations[subtest.nodeIdx].Value)
})
Expand Down
6 changes: 3 additions & 3 deletions backends/ent/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ func (backend *Backend) Store(doc *sbom.Document, opts *storage.StoreOptions) er

// Set each annotation's document ID if not specified.
for _, a := range annotations {
if a.DocumentID == uuid.Nil {
a.DocumentID = id
if a.DocumentID == nil || a.DocumentID == &uuid.Nil {
a.DocumentID = &id
}
}

Expand All @@ -96,7 +96,7 @@ func (backend *Backend) saveAnnotations(annotations ...*ent.Annotation) TxFunc {

for idx := range annotations {
builder := tx.Annotation.Create().
SetDocumentID(annotations[idx].DocumentID).
SetNillableDocumentID(annotations[idx].DocumentID).
SetNillableNodeID(annotations[idx].NodeID).
SetName(annotations[idx].Name).
SetValue(annotations[idx].Value).
Expand Down
19 changes: 10 additions & 9 deletions internal/backends/ent/annotation.go

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

5 changes: 1 addition & 4 deletions internal/backends/ent/annotation/annotation.go

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

2 changes: 1 addition & 1 deletion internal/backends/ent/annotation/where.go

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

Loading
Loading