From 73c04b1f700f5b27580074b8e065a2cfa4106d04 Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Thu, 16 Jan 2025 11:20:19 -0600 Subject: [PATCH] refactor: redefine annotation document ID as nillable/pointer type Signed-off-by: Jonathan Howard --- backends/ent/annotations.go | 140 ++-- backends/ent/annotations_test.go | 4 +- backends/ent/store.go | 6 +- internal/backends/ent/annotation.go | 19 +- .../backends/ent/annotation/annotation.go | 5 +- internal/backends/ent/annotation/where.go | 2 +- internal/backends/ent/annotation_create.go | 80 ++- internal/backends/ent/annotation_query.go | 7 +- internal/backends/ent/annotation_update.go | 121 ++++ internal/backends/ent/client.go | 84 ++- internal/backends/ent/document.go | 49 +- internal/backends/ent/document/document.go | 58 +- internal/backends/ent/document/where.go | 97 ++- internal/backends/ent/document_create.go | 105 ++- internal/backends/ent/document_query.go | 179 ++++- internal/backends/ent/document_update.go | 163 +++++ internal/backends/ent/metadata.go | 57 +- internal/backends/ent/metadata/metadata.go | 52 +- internal/backends/ent/metadata/where.go | 71 +- internal/backends/ent/metadata_create.go | 64 +- internal/backends/ent/metadata_query.go | 143 ++-- ...71940_annotations_nillable_document_id.sql | 59 ++ .../backends/ent/migrate/migrations/atlas.sum | 3 +- internal/backends/ent/migrate/schema.go | 51 +- internal/backends/ent/mutation.go | 612 +++++++++++------- internal/backends/ent/nodelist.go | 53 +- internal/backends/ent/nodelist/nodelist.go | 48 +- internal/backends/ent/nodelist/where.go | 61 +- internal/backends/ent/nodelist_create.go | 62 +- internal/backends/ent/nodelist_query.go | 129 ++-- internal/backends/ent/runtime.go | 11 +- internal/backends/ent/schema/annotation.go | 21 +- internal/backends/ent/schema/document.go | 34 +- internal/backends/ent/schema/metadata.go | 13 +- internal/backends/ent/schema/node_list.go | 13 +- 35 files changed, 1752 insertions(+), 924 deletions(-) create mode 100644 internal/backends/ent/migrate/migrations/20250116171940_annotations_nillable_document_id.sql diff --git a/backends/ent/annotations.go b/backends/ent/annotations.go index 617a531..37b357a 100644 --- a/backends/ent/annotations.go +++ b/backends/ent/annotations.go @@ -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, }) @@ -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, }) @@ -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...)) @@ -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...)) @@ -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 @@ -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 @@ -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 @@ -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 @@ -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. @@ -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...)) } diff --git a/backends/ent/annotations_test.go b/backends/ent/annotations_test.go index 5a248f0..f128554 100644 --- a/backends/ent/annotations_test.go +++ b/backends/ent/annotations_test.go @@ -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) }) @@ -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) }) diff --git a/backends/ent/store.go b/backends/ent/store.go index 05101dc..ed361de 100644 --- a/backends/ent/store.go +++ b/backends/ent/store.go @@ -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 } } @@ -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). diff --git a/internal/backends/ent/annotation.go b/internal/backends/ent/annotation.go index 96cd695..d349dde 100644 --- a/internal/backends/ent/annotation.go +++ b/internal/backends/ent/annotation.go @@ -25,7 +25,7 @@ type Annotation struct { // ID of the ent. ID int `json:"id,omitempty"` // DocumentID holds the value of the "document_id" field. - DocumentID uuid.UUID `json:"document_id,omitempty"` + DocumentID *uuid.UUID `json:"document_id,omitempty"` // NodeID holds the value of the "node_id" field. NodeID *uuid.UUID `json:"node_id,omitempty"` // Name holds the value of the "name" field. @@ -78,7 +78,7 @@ func (*Annotation) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case annotation.FieldNodeID: + case annotation.FieldDocumentID, annotation.FieldNodeID: values[i] = &sql.NullScanner{S: new(uuid.UUID)} case annotation.FieldIsUnique: values[i] = new(sql.NullBool) @@ -86,8 +86,6 @@ func (*Annotation) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullInt64) case annotation.FieldName, annotation.FieldValue: values[i] = new(sql.NullString) - case annotation.FieldDocumentID: - values[i] = new(uuid.UUID) default: values[i] = new(sql.UnknownType) } @@ -110,10 +108,11 @@ func (a *Annotation) assignValues(columns []string, values []any) error { } a.ID = int(value.Int64) case annotation.FieldDocumentID: - if value, ok := values[i].(*uuid.UUID); !ok { + if value, ok := values[i].(*sql.NullScanner); !ok { return fmt.Errorf("unexpected type %T for field document_id", values[i]) - } else if value != nil { - a.DocumentID = *value + } else if value.Valid { + a.DocumentID = new(uuid.UUID) + *a.DocumentID = *value.S.(*uuid.UUID) } case annotation.FieldNodeID: if value, ok := values[i].(*sql.NullScanner); !ok { @@ -186,8 +185,10 @@ func (a *Annotation) String() string { var builder strings.Builder builder.WriteString("Annotation(") builder.WriteString(fmt.Sprintf("id=%v, ", a.ID)) - builder.WriteString("document_id=") - builder.WriteString(fmt.Sprintf("%v", a.DocumentID)) + if v := a.DocumentID; v != nil { + builder.WriteString("document_id=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } builder.WriteString(", ") if v := a.NodeID; v != nil { builder.WriteString("node_id=") diff --git a/internal/backends/ent/annotation/annotation.go b/internal/backends/ent/annotation/annotation.go index 82e78f8..7df7abf 100644 --- a/internal/backends/ent/annotation/annotation.go +++ b/internal/backends/ent/annotation/annotation.go @@ -10,7 +10,6 @@ package annotation import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" - "github.com/google/uuid" ) const ( @@ -71,8 +70,6 @@ func ValidColumn(column string) bool { } var ( - // DefaultDocumentID holds the default value on creation for the "document_id" field. - DefaultDocumentID func() uuid.UUID // DefaultIsUnique holds the default value on creation for the "is_unique" field. DefaultIsUnique bool ) @@ -127,7 +124,7 @@ func newDocumentStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.To(DocumentInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, DocumentTable, DocumentColumn), + sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn), ) } func newNodeStep() *sqlgraph.Step { diff --git a/internal/backends/ent/annotation/where.go b/internal/backends/ent/annotation/where.go index f6db0e5..8663b84 100644 --- a/internal/backends/ent/annotation/where.go +++ b/internal/backends/ent/annotation/where.go @@ -289,7 +289,7 @@ func HasDocument() predicate.Annotation { return predicate.Annotation(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, DocumentTable, DocumentColumn), + sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn), ) sqlgraph.HasNeighbors(s, step) }) diff --git a/internal/backends/ent/annotation_create.go b/internal/backends/ent/annotation_create.go index 130ec2f..17f2d1d 100644 --- a/internal/backends/ent/annotation_create.go +++ b/internal/backends/ent/annotation_create.go @@ -128,10 +128,6 @@ func (ac *AnnotationCreate) ExecX(ctx context.Context) { // defaults sets the default values of the builder before save. func (ac *AnnotationCreate) defaults() { - if _, ok := ac.mutation.DocumentID(); !ok { - v := annotation.DefaultDocumentID() - ac.mutation.SetDocumentID(v) - } if _, ok := ac.mutation.IsUnique(); !ok { v := annotation.DefaultIsUnique ac.mutation.SetIsUnique(v) @@ -191,7 +187,7 @@ func (ac *AnnotationCreate) createSpec() (*Annotation, *sqlgraph.CreateSpec) { if nodes := ac.mutation.DocumentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, - Inverse: false, + Inverse: true, Table: annotation.DocumentTable, Columns: []string{annotation.DocumentColumn}, Bidi: false, @@ -202,7 +198,7 @@ func (ac *AnnotationCreate) createSpec() (*Annotation, *sqlgraph.CreateSpec) { for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } - _node.DocumentID = nodes[0] + _node.DocumentID = &nodes[0] _spec.Edges = append(_spec.Edges, edge) } if nodes := ac.mutation.NodeIDs(); len(nodes) > 0 { @@ -274,6 +270,24 @@ type ( } ) +// SetDocumentID sets the "document_id" field. +func (u *AnnotationUpsert) SetDocumentID(v uuid.UUID) *AnnotationUpsert { + u.Set(annotation.FieldDocumentID, v) + return u +} + +// UpdateDocumentID sets the "document_id" field to the value that was provided on create. +func (u *AnnotationUpsert) UpdateDocumentID() *AnnotationUpsert { + u.SetExcluded(annotation.FieldDocumentID) + return u +} + +// ClearDocumentID clears the value of the "document_id" field. +func (u *AnnotationUpsert) ClearDocumentID() *AnnotationUpsert { + u.SetNull(annotation.FieldDocumentID) + return u +} + // SetNodeID sets the "node_id" field. func (u *AnnotationUpsert) SetNodeID(v uuid.UUID) *AnnotationUpsert { u.Set(annotation.FieldNodeID, v) @@ -338,11 +352,6 @@ func (u *AnnotationUpsert) UpdateIsUnique() *AnnotationUpsert { // Exec(ctx) func (u *AnnotationUpsertOne) UpdateNewValues() *AnnotationUpsertOne { u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) - u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { - if _, exists := u.create.mutation.DocumentID(); exists { - s.SetIgnore(annotation.FieldDocumentID) - } - })) return u } @@ -373,6 +382,27 @@ func (u *AnnotationUpsertOne) Update(set func(*AnnotationUpsert)) *AnnotationUps return u } +// SetDocumentID sets the "document_id" field. +func (u *AnnotationUpsertOne) SetDocumentID(v uuid.UUID) *AnnotationUpsertOne { + return u.Update(func(s *AnnotationUpsert) { + s.SetDocumentID(v) + }) +} + +// UpdateDocumentID sets the "document_id" field to the value that was provided on create. +func (u *AnnotationUpsertOne) UpdateDocumentID() *AnnotationUpsertOne { + return u.Update(func(s *AnnotationUpsert) { + s.UpdateDocumentID() + }) +} + +// ClearDocumentID clears the value of the "document_id" field. +func (u *AnnotationUpsertOne) ClearDocumentID() *AnnotationUpsertOne { + return u.Update(func(s *AnnotationUpsert) { + s.ClearDocumentID() + }) +} + // SetNodeID sets the "node_id" field. func (u *AnnotationUpsertOne) SetNodeID(v uuid.UUID) *AnnotationUpsertOne { return u.Update(func(s *AnnotationUpsert) { @@ -610,13 +640,6 @@ type AnnotationUpsertBulk struct { // Exec(ctx) func (u *AnnotationUpsertBulk) UpdateNewValues() *AnnotationUpsertBulk { u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues()) - u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) { - for _, b := range u.create.builders { - if _, exists := b.mutation.DocumentID(); exists { - s.SetIgnore(annotation.FieldDocumentID) - } - } - })) return u } @@ -647,6 +670,27 @@ func (u *AnnotationUpsertBulk) Update(set func(*AnnotationUpsert)) *AnnotationUp return u } +// SetDocumentID sets the "document_id" field. +func (u *AnnotationUpsertBulk) SetDocumentID(v uuid.UUID) *AnnotationUpsertBulk { + return u.Update(func(s *AnnotationUpsert) { + s.SetDocumentID(v) + }) +} + +// UpdateDocumentID sets the "document_id" field to the value that was provided on create. +func (u *AnnotationUpsertBulk) UpdateDocumentID() *AnnotationUpsertBulk { + return u.Update(func(s *AnnotationUpsert) { + s.UpdateDocumentID() + }) +} + +// ClearDocumentID clears the value of the "document_id" field. +func (u *AnnotationUpsertBulk) ClearDocumentID() *AnnotationUpsertBulk { + return u.Update(func(s *AnnotationUpsert) { + s.ClearDocumentID() + }) +} + // SetNodeID sets the "node_id" field. func (u *AnnotationUpsertBulk) SetNodeID(v uuid.UUID) *AnnotationUpsertBulk { return u.Update(func(s *AnnotationUpsert) { diff --git a/internal/backends/ent/annotation_query.go b/internal/backends/ent/annotation_query.go index 0d8b5e5..4f073c8 100644 --- a/internal/backends/ent/annotation_query.go +++ b/internal/backends/ent/annotation_query.go @@ -82,7 +82,7 @@ func (aq *AnnotationQuery) QueryDocument() *DocumentQuery { step := sqlgraph.NewStep( sqlgraph.From(annotation.Table, annotation.FieldID, selector), sqlgraph.To(document.Table, document.FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, annotation.DocumentTable, annotation.DocumentColumn), + sqlgraph.Edge(sqlgraph.M2O, true, annotation.DocumentTable, annotation.DocumentColumn), ) fromU = sqlgraph.SetNeighbors(aq.driver.Dialect(), step) return fromU, nil @@ -454,7 +454,10 @@ func (aq *AnnotationQuery) loadDocument(ctx context.Context, query *DocumentQuer ids := make([]uuid.UUID, 0, len(nodes)) nodeids := make(map[uuid.UUID][]*Annotation) for i := range nodes { - fk := nodes[i].DocumentID + if nodes[i].DocumentID == nil { + continue + } + fk := *nodes[i].DocumentID if _, ok := nodeids[fk]; !ok { ids = append(ids, fk) } diff --git a/internal/backends/ent/annotation_update.go b/internal/backends/ent/annotation_update.go index e0bdce6..fd8ac94 100644 --- a/internal/backends/ent/annotation_update.go +++ b/internal/backends/ent/annotation_update.go @@ -17,6 +17,7 @@ import ( "entgo.io/ent/schema/field" "github.com/google/uuid" "github.com/protobom/storage/internal/backends/ent/annotation" + "github.com/protobom/storage/internal/backends/ent/document" "github.com/protobom/storage/internal/backends/ent/node" "github.com/protobom/storage/internal/backends/ent/predicate" ) @@ -34,6 +35,26 @@ func (au *AnnotationUpdate) Where(ps ...predicate.Annotation) *AnnotationUpdate return au } +// SetDocumentID sets the "document_id" field. +func (au *AnnotationUpdate) SetDocumentID(u uuid.UUID) *AnnotationUpdate { + au.mutation.SetDocumentID(u) + return au +} + +// SetNillableDocumentID sets the "document_id" field if the given value is not nil. +func (au *AnnotationUpdate) SetNillableDocumentID(u *uuid.UUID) *AnnotationUpdate { + if u != nil { + au.SetDocumentID(*u) + } + return au +} + +// ClearDocumentID clears the value of the "document_id" field. +func (au *AnnotationUpdate) ClearDocumentID() *AnnotationUpdate { + au.mutation.ClearDocumentID() + return au +} + // SetNodeID sets the "node_id" field. func (au *AnnotationUpdate) SetNodeID(u uuid.UUID) *AnnotationUpdate { au.mutation.SetNodeID(u) @@ -96,6 +117,11 @@ func (au *AnnotationUpdate) SetNillableIsUnique(b *bool) *AnnotationUpdate { return au } +// SetDocument sets the "document" edge to the Document entity. +func (au *AnnotationUpdate) SetDocument(d *Document) *AnnotationUpdate { + return au.SetDocumentID(d.ID) +} + // SetNode sets the "node" edge to the Node entity. func (au *AnnotationUpdate) SetNode(n *Node) *AnnotationUpdate { return au.SetNodeID(n.ID) @@ -106,6 +132,12 @@ func (au *AnnotationUpdate) Mutation() *AnnotationMutation { return au.mutation } +// ClearDocument clears the "document" edge to the Document entity. +func (au *AnnotationUpdate) ClearDocument() *AnnotationUpdate { + au.mutation.ClearDocument() + return au +} + // ClearNode clears the "node" edge to the Node entity. func (au *AnnotationUpdate) ClearNode() *AnnotationUpdate { au.mutation.ClearNode() @@ -157,6 +189,35 @@ func (au *AnnotationUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := au.mutation.IsUnique(); ok { _spec.SetField(annotation.FieldIsUnique, field.TypeBool, value) } + if au.mutation.DocumentCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: annotation.DocumentTable, + Columns: []string{annotation.DocumentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := au.mutation.DocumentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: annotation.DocumentTable, + Columns: []string{annotation.DocumentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if au.mutation.NodeCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, @@ -206,6 +267,26 @@ type AnnotationUpdateOne struct { mutation *AnnotationMutation } +// SetDocumentID sets the "document_id" field. +func (auo *AnnotationUpdateOne) SetDocumentID(u uuid.UUID) *AnnotationUpdateOne { + auo.mutation.SetDocumentID(u) + return auo +} + +// SetNillableDocumentID sets the "document_id" field if the given value is not nil. +func (auo *AnnotationUpdateOne) SetNillableDocumentID(u *uuid.UUID) *AnnotationUpdateOne { + if u != nil { + auo.SetDocumentID(*u) + } + return auo +} + +// ClearDocumentID clears the value of the "document_id" field. +func (auo *AnnotationUpdateOne) ClearDocumentID() *AnnotationUpdateOne { + auo.mutation.ClearDocumentID() + return auo +} + // SetNodeID sets the "node_id" field. func (auo *AnnotationUpdateOne) SetNodeID(u uuid.UUID) *AnnotationUpdateOne { auo.mutation.SetNodeID(u) @@ -268,6 +349,11 @@ func (auo *AnnotationUpdateOne) SetNillableIsUnique(b *bool) *AnnotationUpdateOn return auo } +// SetDocument sets the "document" edge to the Document entity. +func (auo *AnnotationUpdateOne) SetDocument(d *Document) *AnnotationUpdateOne { + return auo.SetDocumentID(d.ID) +} + // SetNode sets the "node" edge to the Node entity. func (auo *AnnotationUpdateOne) SetNode(n *Node) *AnnotationUpdateOne { return auo.SetNodeID(n.ID) @@ -278,6 +364,12 @@ func (auo *AnnotationUpdateOne) Mutation() *AnnotationMutation { return auo.mutation } +// ClearDocument clears the "document" edge to the Document entity. +func (auo *AnnotationUpdateOne) ClearDocument() *AnnotationUpdateOne { + auo.mutation.ClearDocument() + return auo +} + // ClearNode clears the "node" edge to the Node entity. func (auo *AnnotationUpdateOne) ClearNode() *AnnotationUpdateOne { auo.mutation.ClearNode() @@ -359,6 +451,35 @@ func (auo *AnnotationUpdateOne) sqlSave(ctx context.Context) (_node *Annotation, if value, ok := auo.mutation.IsUnique(); ok { _spec.SetField(annotation.FieldIsUnique, field.TypeBool, value) } + if auo.mutation.DocumentCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: annotation.DocumentTable, + Columns: []string{annotation.DocumentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := auo.mutation.DocumentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: annotation.DocumentTable, + Columns: []string{annotation.DocumentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if auo.mutation.NodeCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/internal/backends/ent/client.go b/internal/backends/ent/client.go index fbd922f..9f71707 100644 --- a/internal/backends/ent/client.go +++ b/internal/backends/ent/client.go @@ -445,7 +445,7 @@ func (c *AnnotationClient) QueryDocument(a *Annotation) *DocumentQuery { step := sqlgraph.NewStep( sqlgraph.From(annotation.Table, annotation.FieldID, id), sqlgraph.To(document.Table, document.FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, annotation.DocumentTable, annotation.DocumentColumn), + sqlgraph.Edge(sqlgraph.M2O, true, annotation.DocumentTable, annotation.DocumentColumn), ) fromV = sqlgraph.Neighbors(a.driver.Dialect(), step) return fromV, nil @@ -602,6 +602,22 @@ func (c *DocumentClient) GetX(ctx context.Context, id uuid.UUID) *Document { return obj } +// QueryAnnotations queries the annotations edge of a Document. +func (c *DocumentClient) QueryAnnotations(d *Document) *AnnotationQuery { + query := (&AnnotationClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := d.ID + step := sqlgraph.NewStep( + sqlgraph.From(document.Table, document.FieldID, id), + sqlgraph.To(annotation.Table, annotation.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, document.AnnotationsTable, document.AnnotationsColumn), + ) + fromV = sqlgraph.Neighbors(d.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryMetadata queries the metadata edge of a Document. func (c *DocumentClient) QueryMetadata(d *Document) *MetadataQuery { query := (&MetadataClient{config: c.config}).Query() @@ -610,7 +626,7 @@ func (c *DocumentClient) QueryMetadata(d *Document) *MetadataQuery { step := sqlgraph.NewStep( sqlgraph.From(document.Table, document.FieldID, id), sqlgraph.To(metadata.Table, metadata.FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, document.MetadataTable, document.MetadataColumn), + sqlgraph.Edge(sqlgraph.O2O, true, document.MetadataTable, document.MetadataColumn), ) fromV = sqlgraph.Neighbors(d.driver.Dialect(), step) return fromV, nil @@ -626,7 +642,7 @@ func (c *DocumentClient) QueryNodeList(d *Document) *NodeListQuery { step := sqlgraph.NewStep( sqlgraph.From(document.Table, document.FieldID, id), sqlgraph.To(nodelist.Table, nodelist.FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, document.NodeListTable, document.NodeListColumn), + sqlgraph.Edge(sqlgraph.O2O, true, document.NodeListTable, document.NodeListColumn), ) fromV = sqlgraph.Neighbors(d.driver.Dialect(), step) return fromV, nil @@ -1656,6 +1672,22 @@ func (c *MetadataClient) GetX(ctx context.Context, id uuid.UUID) *Metadata { return obj } +// QueryDocument queries the document edge of a Metadata. +func (c *MetadataClient) QueryDocument(m *Metadata) *DocumentQuery { + query := (&DocumentClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := m.ID + step := sqlgraph.NewStep( + sqlgraph.From(metadata.Table, metadata.FieldID, id), + sqlgraph.To(document.Table, document.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, metadata.DocumentTable, metadata.DocumentColumn), + ) + fromV = sqlgraph.Neighbors(m.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryTools queries the tools edge of a Metadata. func (c *MetadataClient) QueryTools(m *Metadata) *ToolQuery { query := (&ToolClient{config: c.config}).Query() @@ -1720,22 +1752,6 @@ func (c *MetadataClient) QuerySourceData(m *Metadata) *SourceDataQuery { return query } -// QueryDocument queries the document edge of a Metadata. -func (c *MetadataClient) QueryDocument(m *Metadata) *DocumentQuery { - query := (&DocumentClient{config: c.config}).Query() - query.path = func(context.Context) (fromV *sql.Selector, _ error) { - id := m.ID - step := sqlgraph.NewStep( - sqlgraph.From(metadata.Table, metadata.FieldID, id), - sqlgraph.To(document.Table, document.FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, metadata.DocumentTable, metadata.DocumentColumn), - ) - fromV = sqlgraph.Neighbors(m.driver.Dialect(), step) - return fromV, nil - } - return query -} - // Hooks returns the client hooks. func (c *MetadataClient) Hooks() []Hook { return c.hooks.Metadata @@ -2210,15 +2226,15 @@ func (c *NodeListClient) GetX(ctx context.Context, id uuid.UUID) *NodeList { return obj } -// QueryEdgeTypes queries the edge_types edge of a NodeList. -func (c *NodeListClient) QueryEdgeTypes(nl *NodeList) *EdgeTypeQuery { - query := (&EdgeTypeClient{config: c.config}).Query() +// QueryDocument queries the document edge of a NodeList. +func (c *NodeListClient) QueryDocument(nl *NodeList) *DocumentQuery { + query := (&DocumentClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := nl.ID step := sqlgraph.NewStep( sqlgraph.From(nodelist.Table, nodelist.FieldID, id), - sqlgraph.To(edgetype.Table, edgetype.FieldID), - sqlgraph.Edge(sqlgraph.M2M, false, nodelist.EdgeTypesTable, nodelist.EdgeTypesPrimaryKey...), + sqlgraph.To(document.Table, document.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, nodelist.DocumentTable, nodelist.DocumentColumn), ) fromV = sqlgraph.Neighbors(nl.driver.Dialect(), step) return fromV, nil @@ -2226,15 +2242,15 @@ func (c *NodeListClient) QueryEdgeTypes(nl *NodeList) *EdgeTypeQuery { return query } -// QueryNodes queries the nodes edge of a NodeList. -func (c *NodeListClient) QueryNodes(nl *NodeList) *NodeQuery { - query := (&NodeClient{config: c.config}).Query() +// QueryEdgeTypes queries the edge_types edge of a NodeList. +func (c *NodeListClient) QueryEdgeTypes(nl *NodeList) *EdgeTypeQuery { + query := (&EdgeTypeClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := nl.ID step := sqlgraph.NewStep( sqlgraph.From(nodelist.Table, nodelist.FieldID, id), - sqlgraph.To(node.Table, node.FieldID), - sqlgraph.Edge(sqlgraph.M2M, false, nodelist.NodesTable, nodelist.NodesPrimaryKey...), + sqlgraph.To(edgetype.Table, edgetype.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, nodelist.EdgeTypesTable, nodelist.EdgeTypesPrimaryKey...), ) fromV = sqlgraph.Neighbors(nl.driver.Dialect(), step) return fromV, nil @@ -2242,15 +2258,15 @@ func (c *NodeListClient) QueryNodes(nl *NodeList) *NodeQuery { return query } -// QueryDocument queries the document edge of a NodeList. -func (c *NodeListClient) QueryDocument(nl *NodeList) *DocumentQuery { - query := (&DocumentClient{config: c.config}).Query() +// QueryNodes queries the nodes edge of a NodeList. +func (c *NodeListClient) QueryNodes(nl *NodeList) *NodeQuery { + query := (&NodeClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := nl.ID step := sqlgraph.NewStep( sqlgraph.From(nodelist.Table, nodelist.FieldID, id), - sqlgraph.To(document.Table, document.FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, nodelist.DocumentTable, nodelist.DocumentColumn), + sqlgraph.To(node.Table, node.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, nodelist.NodesTable, nodelist.NodesPrimaryKey...), ) fromV = sqlgraph.Neighbors(nl.driver.Dialect(), step) return fromV, nil diff --git a/internal/backends/ent/document.go b/internal/backends/ent/document.go index 5168f47..ccf8f64 100644 --- a/internal/backends/ent/document.go +++ b/internal/backends/ent/document.go @@ -21,9 +21,13 @@ import ( // Document is the model entity for the Document schema. type Document struct { - config + config `json:"-"` // ID of the ent. ID uuid.UUID `json:"id,omitempty"` + // MetadataID holds the value of the "metadata_id" field. + MetadataID uuid.UUID `json:"metadata_id,omitempty"` + // NodeListID holds the value of the "node_list_id" field. + NodeListID uuid.UUID `json:"node_list_id,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the DocumentQuery when eager-loading is set. Edges DocumentEdges `json:"edges"` @@ -32,13 +36,24 @@ type Document struct { // DocumentEdges holds the relations/edges for other nodes in the graph. type DocumentEdges struct { + // Annotations holds the value of the annotations edge. + Annotations []*Annotation `json:"annotations,omitempty"` // Metadata holds the value of the metadata edge. Metadata *Metadata `json:"metadata,omitempty"` // NodeList holds the value of the node_list edge. NodeList *NodeList `json:"node_list,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [2]bool + loadedTypes [3]bool +} + +// AnnotationsOrErr returns the Annotations value or an error if the edge +// was not loaded in eager-loading. +func (e DocumentEdges) AnnotationsOrErr() ([]*Annotation, error) { + if e.loadedTypes[0] { + return e.Annotations, nil + } + return nil, &NotLoadedError{edge: "annotations"} } // MetadataOrErr returns the Metadata value or an error if the edge @@ -46,7 +61,7 @@ type DocumentEdges struct { func (e DocumentEdges) MetadataOrErr() (*Metadata, error) { if e.Metadata != nil { return e.Metadata, nil - } else if e.loadedTypes[0] { + } else if e.loadedTypes[1] { return nil, &NotFoundError{label: metadata.Label} } return nil, &NotLoadedError{edge: "metadata"} @@ -57,7 +72,7 @@ func (e DocumentEdges) MetadataOrErr() (*Metadata, error) { func (e DocumentEdges) NodeListOrErr() (*NodeList, error) { if e.NodeList != nil { return e.NodeList, nil - } else if e.loadedTypes[1] { + } else if e.loadedTypes[2] { return nil, &NotFoundError{label: nodelist.Label} } return nil, &NotLoadedError{edge: "node_list"} @@ -68,7 +83,7 @@ func (*Document) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case document.FieldID: + case document.FieldID, document.FieldMetadataID, document.FieldNodeListID: values[i] = new(uuid.UUID) default: values[i] = new(sql.UnknownType) @@ -91,6 +106,18 @@ func (d *Document) assignValues(columns []string, values []any) error { } else if value != nil { d.ID = *value } + case document.FieldMetadataID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field metadata_id", values[i]) + } else if value != nil { + d.MetadataID = *value + } + case document.FieldNodeListID: + if value, ok := values[i].(*uuid.UUID); !ok { + return fmt.Errorf("unexpected type %T for field node_list_id", values[i]) + } else if value != nil { + d.NodeListID = *value + } default: d.selectValues.Set(columns[i], values[i]) } @@ -104,6 +131,11 @@ func (d *Document) Value(name string) (ent.Value, error) { return d.selectValues.Get(name) } +// QueryAnnotations queries the "annotations" edge of the Document entity. +func (d *Document) QueryAnnotations() *AnnotationQuery { + return NewDocumentClient(d.config).QueryAnnotations(d) +} + // QueryMetadata queries the "metadata" edge of the Document entity. func (d *Document) QueryMetadata() *MetadataQuery { return NewDocumentClient(d.config).QueryMetadata(d) @@ -136,7 +168,12 @@ func (d *Document) Unwrap() *Document { func (d *Document) String() string { var builder strings.Builder builder.WriteString("Document(") - builder.WriteString(fmt.Sprintf("id=%v", d.ID)) + builder.WriteString(fmt.Sprintf("id=%v, ", d.ID)) + builder.WriteString("metadata_id=") + builder.WriteString(fmt.Sprintf("%v", d.MetadataID)) + builder.WriteString(", ") + builder.WriteString("node_list_id=") + builder.WriteString(fmt.Sprintf("%v", d.NodeListID)) builder.WriteByte(')') return builder.String() } diff --git a/internal/backends/ent/document/document.go b/internal/backends/ent/document/document.go index 7d08b64..5d16f6b 100644 --- a/internal/backends/ent/document/document.go +++ b/internal/backends/ent/document/document.go @@ -18,31 +18,46 @@ const ( Label = "document" // FieldID holds the string denoting the id field in the database. FieldID = "id" + // FieldMetadataID holds the string denoting the metadata_id field in the database. + FieldMetadataID = "metadata_id" + // FieldNodeListID holds the string denoting the node_list_id field in the database. + FieldNodeListID = "node_list_id" + // EdgeAnnotations holds the string denoting the annotations edge name in mutations. + EdgeAnnotations = "annotations" // EdgeMetadata holds the string denoting the metadata edge name in mutations. EdgeMetadata = "metadata" // EdgeNodeList holds the string denoting the node_list edge name in mutations. EdgeNodeList = "node_list" // Table holds the table name of the document in the database. Table = "documents" + // AnnotationsTable is the table that holds the annotations relation/edge. + AnnotationsTable = "annotations" + // AnnotationsInverseTable is the table name for the Annotation entity. + // It exists in this package in order to avoid circular dependency with the "annotation" package. + AnnotationsInverseTable = "annotations" + // AnnotationsColumn is the table column denoting the annotations relation/edge. + AnnotationsColumn = "document_id" // MetadataTable is the table that holds the metadata relation/edge. - MetadataTable = "metadata" + MetadataTable = "documents" // MetadataInverseTable is the table name for the Metadata entity. // It exists in this package in order to avoid circular dependency with the "metadata" package. MetadataInverseTable = "metadata" // MetadataColumn is the table column denoting the metadata relation/edge. - MetadataColumn = "document_id" + MetadataColumn = "metadata_id" // NodeListTable is the table that holds the node_list relation/edge. - NodeListTable = "node_lists" + NodeListTable = "documents" // NodeListInverseTable is the table name for the NodeList entity. // It exists in this package in order to avoid circular dependency with the "nodelist" package. NodeListInverseTable = "node_lists" // NodeListColumn is the table column denoting the node_list relation/edge. - NodeListColumn = "document_id" + NodeListColumn = "node_list_id" ) // Columns holds all SQL columns for document fields. var Columns = []string{ FieldID, + FieldMetadataID, + FieldNodeListID, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -68,6 +83,30 @@ func ByID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldID, opts...).ToFunc() } +// ByMetadataID orders the results by the metadata_id field. +func ByMetadataID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldMetadataID, opts...).ToFunc() +} + +// ByNodeListID orders the results by the node_list_id field. +func ByNodeListID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldNodeListID, opts...).ToFunc() +} + +// ByAnnotationsCount orders the results by annotations count. +func ByAnnotationsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newAnnotationsStep(), opts...) + } +} + +// ByAnnotations orders the results by annotations terms. +func ByAnnotations(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newAnnotationsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + // ByMetadataField orders the results by metadata field. func ByMetadataField(field string, opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { @@ -81,17 +120,24 @@ func ByNodeListField(field string, opts ...sql.OrderTermOption) OrderOption { sqlgraph.OrderByNeighborTerms(s, newNodeListStep(), sql.OrderByField(field, opts...)) } } +func newAnnotationsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(AnnotationsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, AnnotationsTable, AnnotationsColumn), + ) +} func newMetadataStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.To(MetadataInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, MetadataTable, MetadataColumn), + sqlgraph.Edge(sqlgraph.O2O, true, MetadataTable, MetadataColumn), ) } func newNodeListStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.To(NodeListInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, NodeListTable, NodeListColumn), + sqlgraph.Edge(sqlgraph.O2O, true, NodeListTable, NodeListColumn), ) } diff --git a/internal/backends/ent/document/where.go b/internal/backends/ent/document/where.go index 6bbe14f..c39e6cd 100644 --- a/internal/backends/ent/document/where.go +++ b/internal/backends/ent/document/where.go @@ -59,12 +59,105 @@ func IDLTE(id uuid.UUID) predicate.Document { return predicate.Document(sql.FieldLTE(FieldID, id)) } +// MetadataID applies equality check predicate on the "metadata_id" field. It's identical to MetadataIDEQ. +func MetadataID(v uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldEQ(FieldMetadataID, v)) +} + +// NodeListID applies equality check predicate on the "node_list_id" field. It's identical to NodeListIDEQ. +func NodeListID(v uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldEQ(FieldNodeListID, v)) +} + +// MetadataIDEQ applies the EQ predicate on the "metadata_id" field. +func MetadataIDEQ(v uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldEQ(FieldMetadataID, v)) +} + +// MetadataIDNEQ applies the NEQ predicate on the "metadata_id" field. +func MetadataIDNEQ(v uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldNEQ(FieldMetadataID, v)) +} + +// MetadataIDIn applies the In predicate on the "metadata_id" field. +func MetadataIDIn(vs ...uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldIn(FieldMetadataID, vs...)) +} + +// MetadataIDNotIn applies the NotIn predicate on the "metadata_id" field. +func MetadataIDNotIn(vs ...uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldNotIn(FieldMetadataID, vs...)) +} + +// MetadataIDIsNil applies the IsNil predicate on the "metadata_id" field. +func MetadataIDIsNil() predicate.Document { + return predicate.Document(sql.FieldIsNull(FieldMetadataID)) +} + +// MetadataIDNotNil applies the NotNil predicate on the "metadata_id" field. +func MetadataIDNotNil() predicate.Document { + return predicate.Document(sql.FieldNotNull(FieldMetadataID)) +} + +// NodeListIDEQ applies the EQ predicate on the "node_list_id" field. +func NodeListIDEQ(v uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldEQ(FieldNodeListID, v)) +} + +// NodeListIDNEQ applies the NEQ predicate on the "node_list_id" field. +func NodeListIDNEQ(v uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldNEQ(FieldNodeListID, v)) +} + +// NodeListIDIn applies the In predicate on the "node_list_id" field. +func NodeListIDIn(vs ...uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldIn(FieldNodeListID, vs...)) +} + +// NodeListIDNotIn applies the NotIn predicate on the "node_list_id" field. +func NodeListIDNotIn(vs ...uuid.UUID) predicate.Document { + return predicate.Document(sql.FieldNotIn(FieldNodeListID, vs...)) +} + +// NodeListIDIsNil applies the IsNil predicate on the "node_list_id" field. +func NodeListIDIsNil() predicate.Document { + return predicate.Document(sql.FieldIsNull(FieldNodeListID)) +} + +// NodeListIDNotNil applies the NotNil predicate on the "node_list_id" field. +func NodeListIDNotNil() predicate.Document { + return predicate.Document(sql.FieldNotNull(FieldNodeListID)) +} + +// HasAnnotations applies the HasEdge predicate on the "annotations" edge. +func HasAnnotations() predicate.Document { + return predicate.Document(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, AnnotationsTable, AnnotationsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasAnnotationsWith applies the HasEdge predicate on the "annotations" edge with a given conditions (other predicates). +func HasAnnotationsWith(preds ...predicate.Annotation) predicate.Document { + return predicate.Document(func(s *sql.Selector) { + step := newAnnotationsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasMetadata applies the HasEdge predicate on the "metadata" edge. func HasMetadata() predicate.Document { return predicate.Document(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, MetadataTable, MetadataColumn), + sqlgraph.Edge(sqlgraph.O2O, true, MetadataTable, MetadataColumn), ) sqlgraph.HasNeighbors(s, step) }) @@ -87,7 +180,7 @@ func HasNodeList() predicate.Document { return predicate.Document(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, NodeListTable, NodeListColumn), + sqlgraph.Edge(sqlgraph.O2O, true, NodeListTable, NodeListColumn), ) sqlgraph.HasNeighbors(s, step) }) diff --git a/internal/backends/ent/document_create.go b/internal/backends/ent/document_create.go index 4da9f14..0ac77fb 100644 --- a/internal/backends/ent/document_create.go +++ b/internal/backends/ent/document_create.go @@ -17,6 +17,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" + "github.com/protobom/storage/internal/backends/ent/annotation" "github.com/protobom/storage/internal/backends/ent/document" "github.com/protobom/storage/internal/backends/ent/metadata" "github.com/protobom/storage/internal/backends/ent/nodelist" @@ -30,6 +31,34 @@ type DocumentCreate struct { conflict []sql.ConflictOption } +// SetMetadataID sets the "metadata_id" field. +func (dc *DocumentCreate) SetMetadataID(u uuid.UUID) *DocumentCreate { + dc.mutation.SetMetadataID(u) + return dc +} + +// SetNillableMetadataID sets the "metadata_id" field if the given value is not nil. +func (dc *DocumentCreate) SetNillableMetadataID(u *uuid.UUID) *DocumentCreate { + if u != nil { + dc.SetMetadataID(*u) + } + return dc +} + +// SetNodeListID sets the "node_list_id" field. +func (dc *DocumentCreate) SetNodeListID(u uuid.UUID) *DocumentCreate { + dc.mutation.SetNodeListID(u) + return dc +} + +// SetNillableNodeListID sets the "node_list_id" field if the given value is not nil. +func (dc *DocumentCreate) SetNillableNodeListID(u *uuid.UUID) *DocumentCreate { + if u != nil { + dc.SetNodeListID(*u) + } + return dc +} + // SetID sets the "id" field. func (dc *DocumentCreate) SetID(u uuid.UUID) *DocumentCreate { dc.mutation.SetID(u) @@ -44,18 +73,19 @@ func (dc *DocumentCreate) SetNillableID(u *uuid.UUID) *DocumentCreate { return dc } -// SetMetadataID sets the "metadata" edge to the Metadata entity by ID. -func (dc *DocumentCreate) SetMetadataID(id uuid.UUID) *DocumentCreate { - dc.mutation.SetMetadataID(id) +// AddAnnotationIDs adds the "annotations" edge to the Annotation entity by IDs. +func (dc *DocumentCreate) AddAnnotationIDs(ids ...int) *DocumentCreate { + dc.mutation.AddAnnotationIDs(ids...) return dc } -// SetNillableMetadataID sets the "metadata" edge to the Metadata entity by ID if the given value is not nil. -func (dc *DocumentCreate) SetNillableMetadataID(id *uuid.UUID) *DocumentCreate { - if id != nil { - dc = dc.SetMetadataID(*id) +// AddAnnotations adds the "annotations" edges to the Annotation entity. +func (dc *DocumentCreate) AddAnnotations(a ...*Annotation) *DocumentCreate { + ids := make([]int, len(a)) + for i := range a { + ids[i] = a[i].ID } - return dc + return dc.AddAnnotationIDs(ids...) } // SetMetadata sets the "metadata" edge to the Metadata entity. @@ -63,20 +93,6 @@ func (dc *DocumentCreate) SetMetadata(m *Metadata) *DocumentCreate { return dc.SetMetadataID(m.ID) } -// SetNodeListID sets the "node_list" edge to the NodeList entity by ID. -func (dc *DocumentCreate) SetNodeListID(id uuid.UUID) *DocumentCreate { - dc.mutation.SetNodeListID(id) - return dc -} - -// SetNillableNodeListID sets the "node_list" edge to the NodeList entity by ID if the given value is not nil. -func (dc *DocumentCreate) SetNillableNodeListID(id *uuid.UUID) *DocumentCreate { - if id != nil { - dc = dc.SetNodeListID(*id) - } - return dc -} - // SetNodeList sets the "node_list" edge to the NodeList entity. func (dc *DocumentCreate) SetNodeList(n *NodeList) *DocumentCreate { return dc.SetNodeListID(n.ID) @@ -161,10 +177,26 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) { _node.ID = id _spec.ID.Value = &id } + if nodes := dc.mutation.AnnotationsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } if nodes := dc.mutation.MetadataIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, - Inverse: false, + Inverse: true, Table: document.MetadataTable, Columns: []string{document.MetadataColumn}, Bidi: false, @@ -175,12 +207,13 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) { for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } + _node.MetadataID = nodes[0] _spec.Edges = append(_spec.Edges, edge) } if nodes := dc.mutation.NodeListIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, - Inverse: false, + Inverse: true, Table: document.NodeListTable, Columns: []string{document.NodeListColumn}, Bidi: false, @@ -191,6 +224,7 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) { for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } + _node.NodeListID = nodes[0] _spec.Edges = append(_spec.Edges, edge) } return _node, _spec @@ -200,11 +234,17 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) { // of the `INSERT` statement. For example: // // client.Document.Create(). +// SetMetadataID(v). // OnConflict( // // Update the row with the new values // // the was proposed for insertion. // sql.ResolveWithNewValues(), // ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.DocumentUpsert) { +// SetMetadataID(v+v). +// }). // Exec(ctx) func (dc *DocumentCreate) OnConflict(opts ...sql.ConflictOption) *DocumentUpsertOne { dc.conflict = opts @@ -256,6 +296,12 @@ func (u *DocumentUpsertOne) UpdateNewValues() *DocumentUpsertOne { if _, exists := u.create.mutation.ID(); exists { s.SetIgnore(document.FieldID) } + if _, exists := u.create.mutation.MetadataID(); exists { + s.SetIgnore(document.FieldMetadataID) + } + if _, exists := u.create.mutation.NodeListID(); exists { + s.SetIgnore(document.FieldNodeListID) + } })) return u } @@ -420,6 +466,11 @@ func (dcb *DocumentCreateBulk) ExecX(ctx context.Context) { // // the was proposed for insertion. // sql.ResolveWithNewValues(), // ). +// // Override some of the fields with custom +// // update values. +// Update(func(u *ent.DocumentUpsert) { +// SetMetadataID(v+v). +// }). // Exec(ctx) func (dcb *DocumentCreateBulk) OnConflict(opts ...sql.ConflictOption) *DocumentUpsertBulk { dcb.conflict = opts @@ -465,6 +516,12 @@ func (u *DocumentUpsertBulk) UpdateNewValues() *DocumentUpsertBulk { if _, exists := b.mutation.ID(); exists { s.SetIgnore(document.FieldID) } + if _, exists := b.mutation.MetadataID(); exists { + s.SetIgnore(document.FieldMetadataID) + } + if _, exists := b.mutation.NodeListID(); exists { + s.SetIgnore(document.FieldNodeListID) + } } })) return u diff --git a/internal/backends/ent/document_query.go b/internal/backends/ent/document_query.go index 8f3801e..4e1dfa6 100644 --- a/internal/backends/ent/document_query.go +++ b/internal/backends/ent/document_query.go @@ -18,6 +18,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/google/uuid" + "github.com/protobom/storage/internal/backends/ent/annotation" "github.com/protobom/storage/internal/backends/ent/document" "github.com/protobom/storage/internal/backends/ent/metadata" "github.com/protobom/storage/internal/backends/ent/nodelist" @@ -27,12 +28,13 @@ import ( // DocumentQuery is the builder for querying Document entities. type DocumentQuery struct { config - ctx *QueryContext - order []document.OrderOption - inters []Interceptor - predicates []predicate.Document - withMetadata *MetadataQuery - withNodeList *NodeListQuery + ctx *QueryContext + order []document.OrderOption + inters []Interceptor + predicates []predicate.Document + withAnnotations *AnnotationQuery + withMetadata *MetadataQuery + withNodeList *NodeListQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -69,6 +71,28 @@ func (dq *DocumentQuery) Order(o ...document.OrderOption) *DocumentQuery { return dq } +// QueryAnnotations chains the current query on the "annotations" edge. +func (dq *DocumentQuery) QueryAnnotations() *AnnotationQuery { + query := (&AnnotationClient{config: dq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := dq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := dq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(document.Table, document.FieldID, selector), + sqlgraph.To(annotation.Table, annotation.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, document.AnnotationsTable, document.AnnotationsColumn), + ) + fromU = sqlgraph.SetNeighbors(dq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryMetadata chains the current query on the "metadata" edge. func (dq *DocumentQuery) QueryMetadata() *MetadataQuery { query := (&MetadataClient{config: dq.config}).Query() @@ -83,7 +107,7 @@ func (dq *DocumentQuery) QueryMetadata() *MetadataQuery { step := sqlgraph.NewStep( sqlgraph.From(document.Table, document.FieldID, selector), sqlgraph.To(metadata.Table, metadata.FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, document.MetadataTable, document.MetadataColumn), + sqlgraph.Edge(sqlgraph.O2O, true, document.MetadataTable, document.MetadataColumn), ) fromU = sqlgraph.SetNeighbors(dq.driver.Dialect(), step) return fromU, nil @@ -105,7 +129,7 @@ func (dq *DocumentQuery) QueryNodeList() *NodeListQuery { step := sqlgraph.NewStep( sqlgraph.From(document.Table, document.FieldID, selector), sqlgraph.To(nodelist.Table, nodelist.FieldID), - sqlgraph.Edge(sqlgraph.O2O, false, document.NodeListTable, document.NodeListColumn), + sqlgraph.Edge(sqlgraph.O2O, true, document.NodeListTable, document.NodeListColumn), ) fromU = sqlgraph.SetNeighbors(dq.driver.Dialect(), step) return fromU, nil @@ -300,19 +324,31 @@ func (dq *DocumentQuery) Clone() *DocumentQuery { return nil } return &DocumentQuery{ - config: dq.config, - ctx: dq.ctx.Clone(), - order: append([]document.OrderOption{}, dq.order...), - inters: append([]Interceptor{}, dq.inters...), - predicates: append([]predicate.Document{}, dq.predicates...), - withMetadata: dq.withMetadata.Clone(), - withNodeList: dq.withNodeList.Clone(), + config: dq.config, + ctx: dq.ctx.Clone(), + order: append([]document.OrderOption{}, dq.order...), + inters: append([]Interceptor{}, dq.inters...), + predicates: append([]predicate.Document{}, dq.predicates...), + withAnnotations: dq.withAnnotations.Clone(), + withMetadata: dq.withMetadata.Clone(), + withNodeList: dq.withNodeList.Clone(), // clone intermediate query. sql: dq.sql.Clone(), path: dq.path, } } +// WithAnnotations tells the query-builder to eager-load the nodes that are connected to +// the "annotations" edge. The optional arguments are used to configure the query builder of the edge. +func (dq *DocumentQuery) WithAnnotations(opts ...func(*AnnotationQuery)) *DocumentQuery { + query := (&AnnotationClient{config: dq.config}).Query() + for _, opt := range opts { + opt(query) + } + dq.withAnnotations = query + return dq +} + // WithMetadata tells the query-builder to eager-load the nodes that are connected to // the "metadata" edge. The optional arguments are used to configure the query builder of the edge. func (dq *DocumentQuery) WithMetadata(opts ...func(*MetadataQuery)) *DocumentQuery { @@ -337,6 +373,18 @@ func (dq *DocumentQuery) WithNodeList(opts ...func(*NodeListQuery)) *DocumentQue // GroupBy is used to group vertices by one or more fields/columns. // It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// MetadataID uuid.UUID `json:"metadata_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Document.Query(). +// GroupBy(document.FieldMetadataID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) func (dq *DocumentQuery) GroupBy(field string, fields ...string) *DocumentGroupBy { dq.ctx.Fields = append([]string{field}, fields...) grbuild := &DocumentGroupBy{build: dq} @@ -348,6 +396,16 @@ func (dq *DocumentQuery) GroupBy(field string, fields ...string) *DocumentGroupB // Select allows the selection one or more fields/columns for the given query, // instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// MetadataID uuid.UUID `json:"metadata_id,omitempty"` +// } +// +// client.Document.Query(). +// Select(document.FieldMetadataID). +// Scan(ctx, &v) func (dq *DocumentQuery) Select(fields ...string) *DocumentSelect { dq.ctx.Fields = append(dq.ctx.Fields, fields...) sbuild := &DocumentSelect{DocumentQuery: dq} @@ -391,7 +449,8 @@ func (dq *DocumentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Doc var ( nodes = []*Document{} _spec = dq.querySpec() - loadedTypes = [2]bool{ + loadedTypes = [3]bool{ + dq.withAnnotations != nil, dq.withMetadata != nil, dq.withNodeList != nil, } @@ -414,6 +473,13 @@ func (dq *DocumentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Doc if len(nodes) == 0 { return nodes, nil } + if query := dq.withAnnotations; query != nil { + if err := dq.loadAnnotations(ctx, query, nodes, + func(n *Document) { n.Edges.Annotations = []*Annotation{} }, + func(n *Document, e *Annotation) { n.Edges.Annotations = append(n.Edges.Annotations, e) }); err != nil { + return nil, err + } + } if query := dq.withMetadata; query != nil { if err := dq.loadMetadata(ctx, query, nodes, nil, func(n *Document, e *Metadata) { n.Edges.Metadata = e }); err != nil { @@ -429,18 +495,21 @@ func (dq *DocumentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Doc return nodes, nil } -func (dq *DocumentQuery) loadMetadata(ctx context.Context, query *MetadataQuery, nodes []*Document, init func(*Document), assign func(*Document, *Metadata)) error { +func (dq *DocumentQuery) loadAnnotations(ctx context.Context, query *AnnotationQuery, nodes []*Document, init func(*Document), assign func(*Document, *Annotation)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[uuid.UUID]*Document) for i := range nodes { fks = append(fks, nodes[i].ID) nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } } if len(query.ctx.Fields) > 0 { - query.ctx.AppendFieldOnce(metadata.FieldDocumentID) + query.ctx.AppendFieldOnce(annotation.FieldDocumentID) } - query.Where(predicate.Metadata(func(s *sql.Selector) { - s.Where(sql.InValues(s.C(document.MetadataColumn), fks...)) + query.Where(predicate.Annotation(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(document.AnnotationsColumn), fks...)) })) neighbors, err := query.All(ctx) if err != nil { @@ -448,38 +517,72 @@ func (dq *DocumentQuery) loadMetadata(ctx context.Context, query *MetadataQuery, } for _, n := range neighbors { fk := n.DocumentID - node, ok := nodeids[fk] + if fk == nil { + return fmt.Errorf(`foreign-key "document_id" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] if !ok { - return fmt.Errorf(`unexpected referenced foreign-key "document_id" returned %v for node %v`, fk, n.ID) + return fmt.Errorf(`unexpected referenced foreign-key "document_id" returned %v for node %v`, *fk, n.ID) } assign(node, n) } return nil } +func (dq *DocumentQuery) loadMetadata(ctx context.Context, query *MetadataQuery, nodes []*Document, init func(*Document), assign func(*Document, *Metadata)) error { + ids := make([]uuid.UUID, 0, len(nodes)) + nodeids := make(map[uuid.UUID][]*Document) + for i := range nodes { + fk := nodes[i].MetadataID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(metadata.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "metadata_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} func (dq *DocumentQuery) loadNodeList(ctx context.Context, query *NodeListQuery, nodes []*Document, init func(*Document), assign func(*Document, *NodeList)) error { - fks := make([]driver.Value, 0, len(nodes)) - nodeids := make(map[uuid.UUID]*Document) + ids := make([]uuid.UUID, 0, len(nodes)) + nodeids := make(map[uuid.UUID][]*Document) for i := range nodes { - fks = append(fks, nodes[i].ID) - nodeids[nodes[i].ID] = nodes[i] + fk := nodes[i].NodeListID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) } - if len(query.ctx.Fields) > 0 { - query.ctx.AppendFieldOnce(nodelist.FieldDocumentID) + if len(ids) == 0 { + return nil } - query.Where(predicate.NodeList(func(s *sql.Selector) { - s.Where(sql.InValues(s.C(document.NodeListColumn), fks...)) - })) + query.Where(nodelist.IDIn(ids...)) neighbors, err := query.All(ctx) if err != nil { return err } for _, n := range neighbors { - fk := n.DocumentID - node, ok := nodeids[fk] + nodes, ok := nodeids[n.ID] if !ok { - return fmt.Errorf(`unexpected referenced foreign-key "document_id" returned %v for node %v`, fk, n.ID) + return fmt.Errorf(`unexpected foreign-key "node_list_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) } - assign(node, n) } return nil } @@ -509,6 +612,12 @@ func (dq *DocumentQuery) querySpec() *sqlgraph.QuerySpec { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } + if dq.withMetadata != nil { + _spec.Node.AddColumnOnce(document.FieldMetadataID) + } + if dq.withNodeList != nil { + _spec.Node.AddColumnOnce(document.FieldNodeListID) + } } if ps := dq.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { diff --git a/internal/backends/ent/document_update.go b/internal/backends/ent/document_update.go index cf7577c..71f4d4e 100644 --- a/internal/backends/ent/document_update.go +++ b/internal/backends/ent/document_update.go @@ -15,6 +15,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" + "github.com/protobom/storage/internal/backends/ent/annotation" "github.com/protobom/storage/internal/backends/ent/document" "github.com/protobom/storage/internal/backends/ent/predicate" ) @@ -32,11 +33,47 @@ func (du *DocumentUpdate) Where(ps ...predicate.Document) *DocumentUpdate { return du } +// AddAnnotationIDs adds the "annotations" edge to the Annotation entity by IDs. +func (du *DocumentUpdate) AddAnnotationIDs(ids ...int) *DocumentUpdate { + du.mutation.AddAnnotationIDs(ids...) + return du +} + +// AddAnnotations adds the "annotations" edges to the Annotation entity. +func (du *DocumentUpdate) AddAnnotations(a ...*Annotation) *DocumentUpdate { + ids := make([]int, len(a)) + for i := range a { + ids[i] = a[i].ID + } + return du.AddAnnotationIDs(ids...) +} + // Mutation returns the DocumentMutation object of the builder. func (du *DocumentUpdate) Mutation() *DocumentMutation { return du.mutation } +// ClearAnnotations clears all "annotations" edges to the Annotation entity. +func (du *DocumentUpdate) ClearAnnotations() *DocumentUpdate { + du.mutation.ClearAnnotations() + return du +} + +// RemoveAnnotationIDs removes the "annotations" edge to Annotation entities by IDs. +func (du *DocumentUpdate) RemoveAnnotationIDs(ids ...int) *DocumentUpdate { + du.mutation.RemoveAnnotationIDs(ids...) + return du +} + +// RemoveAnnotations removes "annotations" edges to Annotation entities. +func (du *DocumentUpdate) RemoveAnnotations(a ...*Annotation) *DocumentUpdate { + ids := make([]int, len(a)) + for i := range a { + ids[i] = a[i].ID + } + return du.RemoveAnnotationIDs(ids...) +} + // Save executes the query and returns the number of nodes affected by the update operation. func (du *DocumentUpdate) Save(ctx context.Context) (int, error) { return withHooks(ctx, du.sqlSave, du.mutation, du.hooks) @@ -73,6 +110,51 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) { } } } + if du.mutation.AnnotationsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := du.mutation.RemovedAnnotationsIDs(); len(nodes) > 0 && !du.mutation.AnnotationsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := du.mutation.AnnotationsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if n, err = sqlgraph.UpdateNodes(ctx, du.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{document.Label} @@ -93,11 +175,47 @@ type DocumentUpdateOne struct { mutation *DocumentMutation } +// AddAnnotationIDs adds the "annotations" edge to the Annotation entity by IDs. +func (duo *DocumentUpdateOne) AddAnnotationIDs(ids ...int) *DocumentUpdateOne { + duo.mutation.AddAnnotationIDs(ids...) + return duo +} + +// AddAnnotations adds the "annotations" edges to the Annotation entity. +func (duo *DocumentUpdateOne) AddAnnotations(a ...*Annotation) *DocumentUpdateOne { + ids := make([]int, len(a)) + for i := range a { + ids[i] = a[i].ID + } + return duo.AddAnnotationIDs(ids...) +} + // Mutation returns the DocumentMutation object of the builder. func (duo *DocumentUpdateOne) Mutation() *DocumentMutation { return duo.mutation } +// ClearAnnotations clears all "annotations" edges to the Annotation entity. +func (duo *DocumentUpdateOne) ClearAnnotations() *DocumentUpdateOne { + duo.mutation.ClearAnnotations() + return duo +} + +// RemoveAnnotationIDs removes the "annotations" edge to Annotation entities by IDs. +func (duo *DocumentUpdateOne) RemoveAnnotationIDs(ids ...int) *DocumentUpdateOne { + duo.mutation.RemoveAnnotationIDs(ids...) + return duo +} + +// RemoveAnnotations removes "annotations" edges to Annotation entities. +func (duo *DocumentUpdateOne) RemoveAnnotations(a ...*Annotation) *DocumentUpdateOne { + ids := make([]int, len(a)) + for i := range a { + ids[i] = a[i].ID + } + return duo.RemoveAnnotationIDs(ids...) +} + // Where appends a list predicates to the DocumentUpdate builder. func (duo *DocumentUpdateOne) Where(ps ...predicate.Document) *DocumentUpdateOne { duo.mutation.Where(ps...) @@ -164,6 +282,51 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err } } } + if duo.mutation.AnnotationsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := duo.mutation.RemovedAnnotationsIDs(); len(nodes) > 0 && !duo.mutation.AnnotationsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := duo.mutation.AnnotationsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: document.AnnotationsTable, + Columns: []string{document.AnnotationsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(annotation.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &Document{config: duo.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/internal/backends/ent/metadata.go b/internal/backends/ent/metadata.go index 16a2bb7..b126e7a 100644 --- a/internal/backends/ent/metadata.go +++ b/internal/backends/ent/metadata.go @@ -27,8 +27,6 @@ type Metadata struct { ID uuid.UUID `json:"id,omitempty"` // ProtoMessage holds the value of the "proto_message" field. ProtoMessage *sbom.Metadata `json:"proto_message,omitempty"` - // DocumentID holds the value of the "document_id" field. - DocumentID uuid.UUID `json:"document_id,omitempty"` // NativeID holds the value of the "native_id" field. NativeID string `json:"native_id,omitempty"` // Version holds the value of the "version" field. @@ -47,6 +45,8 @@ type Metadata struct { // MetadataEdges holds the relations/edges for other nodes in the graph. type MetadataEdges struct { + // Document holds the value of the document edge. + Document *Document `json:"document,omitempty"` // Tools holds the value of the tools edge. Tools []*Tool `json:"tools,omitempty"` // Authors holds the value of the authors edge. @@ -55,17 +55,26 @@ type MetadataEdges struct { DocumentTypes []*DocumentType `json:"document_types,omitempty"` // SourceData holds the value of the source_data edge. SourceData []*SourceData `json:"source_data,omitempty"` - // Document holds the value of the document edge. - Document *Document `json:"document,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. loadedTypes [5]bool } +// DocumentOrErr returns the Document value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e MetadataEdges) DocumentOrErr() (*Document, error) { + if e.Document != nil { + return e.Document, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: document.Label} + } + return nil, &NotLoadedError{edge: "document"} +} + // ToolsOrErr returns the Tools value or an error if the edge // was not loaded in eager-loading. func (e MetadataEdges) ToolsOrErr() ([]*Tool, error) { - if e.loadedTypes[0] { + if e.loadedTypes[1] { return e.Tools, nil } return nil, &NotLoadedError{edge: "tools"} @@ -74,7 +83,7 @@ func (e MetadataEdges) ToolsOrErr() ([]*Tool, error) { // AuthorsOrErr returns the Authors value or an error if the edge // was not loaded in eager-loading. func (e MetadataEdges) AuthorsOrErr() ([]*Person, error) { - if e.loadedTypes[1] { + if e.loadedTypes[2] { return e.Authors, nil } return nil, &NotLoadedError{edge: "authors"} @@ -83,7 +92,7 @@ func (e MetadataEdges) AuthorsOrErr() ([]*Person, error) { // DocumentTypesOrErr returns the DocumentTypes value or an error if the edge // was not loaded in eager-loading. func (e MetadataEdges) DocumentTypesOrErr() ([]*DocumentType, error) { - if e.loadedTypes[2] { + if e.loadedTypes[3] { return e.DocumentTypes, nil } return nil, &NotLoadedError{edge: "document_types"} @@ -92,23 +101,12 @@ func (e MetadataEdges) DocumentTypesOrErr() ([]*DocumentType, error) { // SourceDataOrErr returns the SourceData value or an error if the edge // was not loaded in eager-loading. func (e MetadataEdges) SourceDataOrErr() ([]*SourceData, error) { - if e.loadedTypes[3] { + if e.loadedTypes[4] { return e.SourceData, nil } return nil, &NotLoadedError{edge: "source_data"} } -// DocumentOrErr returns the Document value or an error if the edge -// was not loaded in eager-loading, or loaded but was not found. -func (e MetadataEdges) DocumentOrErr() (*Document, error) { - if e.Document != nil { - return e.Document, nil - } else if e.loadedTypes[4] { - return nil, &NotFoundError{label: document.Label} - } - return nil, &NotLoadedError{edge: "document"} -} - // scanValues returns the types for scanning values from sql.Rows. func (*Metadata) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) @@ -120,7 +118,7 @@ func (*Metadata) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullString) case metadata.FieldDate: values[i] = new(sql.NullTime) - case metadata.FieldID, metadata.FieldDocumentID: + case metadata.FieldID: values[i] = new(uuid.UUID) default: values[i] = new(sql.UnknownType) @@ -149,12 +147,6 @@ func (m *Metadata) assignValues(columns []string, values []any) error { } else if value.Valid { m.ProtoMessage = value.S.(*sbom.Metadata) } - case metadata.FieldDocumentID: - if value, ok := values[i].(*uuid.UUID); !ok { - return fmt.Errorf("unexpected type %T for field document_id", values[i]) - } else if value != nil { - m.DocumentID = *value - } case metadata.FieldNativeID: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field native_id", values[i]) @@ -198,6 +190,11 @@ func (m *Metadata) Value(name string) (ent.Value, error) { return m.selectValues.Get(name) } +// QueryDocument queries the "document" edge of the Metadata entity. +func (m *Metadata) QueryDocument() *DocumentQuery { + return NewMetadataClient(m.config).QueryDocument(m) +} + // QueryTools queries the "tools" edge of the Metadata entity. func (m *Metadata) QueryTools() *ToolQuery { return NewMetadataClient(m.config).QueryTools(m) @@ -218,11 +215,6 @@ func (m *Metadata) QuerySourceData() *SourceDataQuery { return NewMetadataClient(m.config).QuerySourceData(m) } -// QueryDocument queries the "document" edge of the Metadata entity. -func (m *Metadata) QueryDocument() *DocumentQuery { - return NewMetadataClient(m.config).QueryDocument(m) -} - // Update returns a builder for updating this Metadata. // Note that you need to call Metadata.Unwrap() before calling this method if this Metadata // was returned from a transaction, and the transaction was committed or rolled back. @@ -251,9 +243,6 @@ func (m *Metadata) String() string { builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") - builder.WriteString("document_id=") - builder.WriteString(fmt.Sprintf("%v", m.DocumentID)) - builder.WriteString(", ") builder.WriteString("native_id=") builder.WriteString(m.NativeID) builder.WriteString(", ") diff --git a/internal/backends/ent/metadata/metadata.go b/internal/backends/ent/metadata/metadata.go index 9fe5f07..9e3e3a3 100644 --- a/internal/backends/ent/metadata/metadata.go +++ b/internal/backends/ent/metadata/metadata.go @@ -20,8 +20,6 @@ const ( FieldID = "id" // FieldProtoMessage holds the string denoting the proto_message field in the database. FieldProtoMessage = "proto_message" - // FieldDocumentID holds the string denoting the document_id field in the database. - FieldDocumentID = "document_id" // FieldNativeID holds the string denoting the native_id field in the database. FieldNativeID = "native_id" // FieldVersion holds the string denoting the version field in the database. @@ -32,6 +30,8 @@ const ( FieldDate = "date" // FieldComment holds the string denoting the comment field in the database. FieldComment = "comment" + // EdgeDocument holds the string denoting the document edge name in mutations. + EdgeDocument = "document" // EdgeTools holds the string denoting the tools edge name in mutations. EdgeTools = "tools" // EdgeAuthors holds the string denoting the authors edge name in mutations. @@ -40,10 +40,15 @@ const ( EdgeDocumentTypes = "document_types" // EdgeSourceData holds the string denoting the source_data edge name in mutations. EdgeSourceData = "source_data" - // EdgeDocument holds the string denoting the document edge name in mutations. - EdgeDocument = "document" // Table holds the table name of the metadata in the database. Table = "metadata" + // DocumentTable is the table that holds the document relation/edge. + DocumentTable = "documents" + // DocumentInverseTable is the table name for the Document entity. + // It exists in this package in order to avoid circular dependency with the "document" package. + DocumentInverseTable = "documents" + // DocumentColumn is the table column denoting the document relation/edge. + DocumentColumn = "metadata_id" // ToolsTable is the table that holds the tools relation/edge. ToolsTable = "tools" // ToolsInverseTable is the table name for the Tool entity. @@ -72,20 +77,12 @@ const ( SourceDataInverseTable = "source_data" // SourceDataColumn is the table column denoting the source_data relation/edge. SourceDataColumn = "metadata_id" - // DocumentTable is the table that holds the document relation/edge. - DocumentTable = "metadata" - // DocumentInverseTable is the table name for the Document entity. - // It exists in this package in order to avoid circular dependency with the "document" package. - DocumentInverseTable = "documents" - // DocumentColumn is the table column denoting the document relation/edge. - DocumentColumn = "document_id" ) // Columns holds all SQL columns for metadata fields. var Columns = []string{ FieldID, FieldProtoMessage, - FieldDocumentID, FieldNativeID, FieldVersion, FieldName, @@ -118,11 +115,6 @@ func ByID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldID, opts...).ToFunc() } -// ByDocumentID orders the results by the document_id field. -func ByDocumentID(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldDocumentID, opts...).ToFunc() -} - // ByNativeID orders the results by the native_id field. func ByNativeID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldNativeID, opts...).ToFunc() @@ -148,6 +140,13 @@ func ByComment(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldComment, opts...).ToFunc() } +// ByDocumentField orders the results by document field. +func ByDocumentField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newDocumentStep(), sql.OrderByField(field, opts...)) + } +} + // ByToolsCount orders the results by tools count. func ByToolsCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { @@ -203,12 +202,12 @@ func BySourceData(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { sqlgraph.OrderByNeighborTerms(s, newSourceDataStep(), append([]sql.OrderTerm{term}, terms...)...) } } - -// ByDocumentField orders the results by document field. -func ByDocumentField(field string, opts ...sql.OrderTermOption) OrderOption { - return func(s *sql.Selector) { - sqlgraph.OrderByNeighborTerms(s, newDocumentStep(), sql.OrderByField(field, opts...)) - } +func newDocumentStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(DocumentInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, DocumentTable, DocumentColumn), + ) } func newToolsStep() *sqlgraph.Step { return sqlgraph.NewStep( @@ -238,10 +237,3 @@ func newSourceDataStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.O2M, false, SourceDataTable, SourceDataColumn), ) } -func newDocumentStep() *sqlgraph.Step { - return sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(DocumentInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, DocumentTable, DocumentColumn), - ) -} diff --git a/internal/backends/ent/metadata/where.go b/internal/backends/ent/metadata/where.go index 95dcb05..e41562f 100644 --- a/internal/backends/ent/metadata/where.go +++ b/internal/backends/ent/metadata/where.go @@ -67,11 +67,6 @@ func ProtoMessage(v *sbom.Metadata) predicate.Metadata { return predicate.Metadata(sql.FieldEQ(FieldProtoMessage, v)) } -// DocumentID applies equality check predicate on the "document_id" field. It's identical to DocumentIDEQ. -func DocumentID(v uuid.UUID) predicate.Metadata { - return predicate.Metadata(sql.FieldEQ(FieldDocumentID, v)) -} - // NativeID applies equality check predicate on the "native_id" field. It's identical to NativeIDEQ. func NativeID(v string) predicate.Metadata { return predicate.Metadata(sql.FieldEQ(FieldNativeID, v)) @@ -137,26 +132,6 @@ func ProtoMessageLTE(v *sbom.Metadata) predicate.Metadata { return predicate.Metadata(sql.FieldLTE(FieldProtoMessage, v)) } -// DocumentIDEQ applies the EQ predicate on the "document_id" field. -func DocumentIDEQ(v uuid.UUID) predicate.Metadata { - return predicate.Metadata(sql.FieldEQ(FieldDocumentID, v)) -} - -// DocumentIDNEQ applies the NEQ predicate on the "document_id" field. -func DocumentIDNEQ(v uuid.UUID) predicate.Metadata { - return predicate.Metadata(sql.FieldNEQ(FieldDocumentID, v)) -} - -// DocumentIDIn applies the In predicate on the "document_id" field. -func DocumentIDIn(vs ...uuid.UUID) predicate.Metadata { - return predicate.Metadata(sql.FieldIn(FieldDocumentID, vs...)) -} - -// DocumentIDNotIn applies the NotIn predicate on the "document_id" field. -func DocumentIDNotIn(vs ...uuid.UUID) predicate.Metadata { - return predicate.Metadata(sql.FieldNotIn(FieldDocumentID, vs...)) -} - // NativeIDEQ applies the EQ predicate on the "native_id" field. func NativeIDEQ(v string) predicate.Metadata { return predicate.Metadata(sql.FieldEQ(FieldNativeID, v)) @@ -457,6 +432,29 @@ func CommentContainsFold(v string) predicate.Metadata { return predicate.Metadata(sql.FieldContainsFold(FieldComment, v)) } +// HasDocument applies the HasEdge predicate on the "document" edge. +func HasDocument() predicate.Metadata { + return predicate.Metadata(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, DocumentTable, DocumentColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates). +func HasDocumentWith(preds ...predicate.Document) predicate.Metadata { + return predicate.Metadata(func(s *sql.Selector) { + step := newDocumentStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasTools applies the HasEdge predicate on the "tools" edge. func HasTools() predicate.Metadata { return predicate.Metadata(func(s *sql.Selector) { @@ -549,29 +547,6 @@ func HasSourceDataWith(preds ...predicate.SourceData) predicate.Metadata { }) } -// HasDocument applies the HasEdge predicate on the "document" edge. -func HasDocument() predicate.Metadata { - return predicate.Metadata(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, DocumentTable, DocumentColumn), - ) - sqlgraph.HasNeighbors(s, step) - }) -} - -// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates). -func HasDocumentWith(preds ...predicate.Document) predicate.Metadata { - return predicate.Metadata(func(s *sql.Selector) { - step := newDocumentStep() - sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { - for _, p := range preds { - p(s) - } - }) - }) -} - // And groups predicates with the AND operator between them. func And(predicates ...predicate.Metadata) predicate.Metadata { return predicate.Metadata(sql.AndPredicates(predicates...)) diff --git a/internal/backends/ent/metadata_create.go b/internal/backends/ent/metadata_create.go index 85cab3a..ad95a4e 100644 --- a/internal/backends/ent/metadata_create.go +++ b/internal/backends/ent/metadata_create.go @@ -41,12 +41,6 @@ func (mc *MetadataCreate) SetProtoMessage(s *sbom.Metadata) *MetadataCreate { return mc } -// SetDocumentID sets the "document_id" field. -func (mc *MetadataCreate) SetDocumentID(u uuid.UUID) *MetadataCreate { - mc.mutation.SetDocumentID(u) - return mc -} - // SetNativeID sets the "native_id" field. func (mc *MetadataCreate) SetNativeID(s string) *MetadataCreate { mc.mutation.SetNativeID(s) @@ -91,6 +85,17 @@ func (mc *MetadataCreate) SetNillableID(u *uuid.UUID) *MetadataCreate { return mc } +// SetDocumentID sets the "document" edge to the Document entity by ID. +func (mc *MetadataCreate) SetDocumentID(id uuid.UUID) *MetadataCreate { + mc.mutation.SetDocumentID(id) + return mc +} + +// SetDocument sets the "document" edge to the Document entity. +func (mc *MetadataCreate) SetDocument(d *Document) *MetadataCreate { + return mc.SetDocumentID(d.ID) +} + // AddToolIDs adds the "tools" edge to the Tool entity by IDs. func (mc *MetadataCreate) AddToolIDs(ids ...uuid.UUID) *MetadataCreate { mc.mutation.AddToolIDs(ids...) @@ -151,11 +156,6 @@ func (mc *MetadataCreate) AddSourceData(s ...*SourceData) *MetadataCreate { return mc.AddSourceDatumIDs(ids...) } -// SetDocument sets the "document" edge to the Document entity. -func (mc *MetadataCreate) SetDocument(d *Document) *MetadataCreate { - return mc.SetDocumentID(d.ID) -} - // Mutation returns the MetadataMutation object of the builder. func (mc *MetadataCreate) Mutation() *MetadataMutation { return mc.mutation @@ -202,9 +202,6 @@ func (mc *MetadataCreate) check() error { if _, ok := mc.mutation.ProtoMessage(); !ok { return &ValidationError{Name: "proto_message", err: errors.New(`ent: missing required field "Metadata.proto_message"`)} } - if _, ok := mc.mutation.DocumentID(); !ok { - return &ValidationError{Name: "document_id", err: errors.New(`ent: missing required field "Metadata.document_id"`)} - } if _, ok := mc.mutation.NativeID(); !ok { return &ValidationError{Name: "native_id", err: errors.New(`ent: missing required field "Metadata.native_id"`)} } @@ -288,6 +285,22 @@ func (mc *MetadataCreate) createSpec() (*Metadata, *sqlgraph.CreateSpec) { _spec.SetField(metadata.FieldComment, field.TypeString, value) _node.Comment = value } + if nodes := mc.mutation.DocumentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: false, + Table: metadata.DocumentTable, + Columns: []string{metadata.DocumentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } if nodes := mc.mutation.ToolsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -352,23 +365,6 @@ func (mc *MetadataCreate) createSpec() (*Metadata, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := mc.mutation.DocumentIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2O, - Inverse: true, - Table: metadata.DocumentTable, - Columns: []string{metadata.DocumentColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _node.DocumentID = nodes[0] - _spec.Edges = append(_spec.Edges, edge) - } return _node, _spec } @@ -489,9 +485,6 @@ func (u *MetadataUpsertOne) UpdateNewValues() *MetadataUpsertOne { if _, exists := u.create.mutation.ProtoMessage(); exists { s.SetIgnore(metadata.FieldProtoMessage) } - if _, exists := u.create.mutation.DocumentID(); exists { - s.SetIgnore(metadata.FieldDocumentID) - } if _, exists := u.create.mutation.NativeID(); exists { s.SetIgnore(metadata.FieldNativeID) } @@ -768,9 +761,6 @@ func (u *MetadataUpsertBulk) UpdateNewValues() *MetadataUpsertBulk { if _, exists := b.mutation.ProtoMessage(); exists { s.SetIgnore(metadata.FieldProtoMessage) } - if _, exists := b.mutation.DocumentID(); exists { - s.SetIgnore(metadata.FieldDocumentID) - } if _, exists := b.mutation.NativeID(); exists { s.SetIgnore(metadata.FieldNativeID) } diff --git a/internal/backends/ent/metadata_query.go b/internal/backends/ent/metadata_query.go index 58ceb54..e6f3703 100644 --- a/internal/backends/ent/metadata_query.go +++ b/internal/backends/ent/metadata_query.go @@ -34,11 +34,11 @@ type MetadataQuery struct { order []metadata.OrderOption inters []Interceptor predicates []predicate.Metadata + withDocument *DocumentQuery withTools *ToolQuery withAuthors *PersonQuery withDocumentTypes *DocumentTypeQuery withSourceData *SourceDataQuery - withDocument *DocumentQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -75,6 +75,28 @@ func (mq *MetadataQuery) Order(o ...metadata.OrderOption) *MetadataQuery { return mq } +// QueryDocument chains the current query on the "document" edge. +func (mq *MetadataQuery) QueryDocument() *DocumentQuery { + query := (&DocumentClient{config: mq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := mq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := mq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(metadata.Table, metadata.FieldID, selector), + sqlgraph.To(document.Table, document.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, metadata.DocumentTable, metadata.DocumentColumn), + ) + fromU = sqlgraph.SetNeighbors(mq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryTools chains the current query on the "tools" edge. func (mq *MetadataQuery) QueryTools() *ToolQuery { query := (&ToolClient{config: mq.config}).Query() @@ -163,28 +185,6 @@ func (mq *MetadataQuery) QuerySourceData() *SourceDataQuery { return query } -// QueryDocument chains the current query on the "document" edge. -func (mq *MetadataQuery) QueryDocument() *DocumentQuery { - query := (&DocumentClient{config: mq.config}).Query() - query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { - if err := mq.prepareQuery(ctx); err != nil { - return nil, err - } - selector := mq.sqlQuery(ctx) - if err := selector.Err(); err != nil { - return nil, err - } - step := sqlgraph.NewStep( - sqlgraph.From(metadata.Table, metadata.FieldID, selector), - sqlgraph.To(document.Table, document.FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, metadata.DocumentTable, metadata.DocumentColumn), - ) - fromU = sqlgraph.SetNeighbors(mq.driver.Dialect(), step) - return fromU, nil - } - return query -} - // First returns the first Metadata entity from the query. // Returns a *NotFoundError when no Metadata was found. func (mq *MetadataQuery) First(ctx context.Context) (*Metadata, error) { @@ -377,17 +377,28 @@ func (mq *MetadataQuery) Clone() *MetadataQuery { order: append([]metadata.OrderOption{}, mq.order...), inters: append([]Interceptor{}, mq.inters...), predicates: append([]predicate.Metadata{}, mq.predicates...), + withDocument: mq.withDocument.Clone(), withTools: mq.withTools.Clone(), withAuthors: mq.withAuthors.Clone(), withDocumentTypes: mq.withDocumentTypes.Clone(), withSourceData: mq.withSourceData.Clone(), - withDocument: mq.withDocument.Clone(), // clone intermediate query. sql: mq.sql.Clone(), path: mq.path, } } +// WithDocument tells the query-builder to eager-load the nodes that are connected to +// the "document" edge. The optional arguments are used to configure the query builder of the edge. +func (mq *MetadataQuery) WithDocument(opts ...func(*DocumentQuery)) *MetadataQuery { + query := (&DocumentClient{config: mq.config}).Query() + for _, opt := range opts { + opt(query) + } + mq.withDocument = query + return mq +} + // WithTools tells the query-builder to eager-load the nodes that are connected to // the "tools" edge. The optional arguments are used to configure the query builder of the edge. func (mq *MetadataQuery) WithTools(opts ...func(*ToolQuery)) *MetadataQuery { @@ -432,17 +443,6 @@ func (mq *MetadataQuery) WithSourceData(opts ...func(*SourceDataQuery)) *Metadat return mq } -// WithDocument tells the query-builder to eager-load the nodes that are connected to -// the "document" edge. The optional arguments are used to configure the query builder of the edge. -func (mq *MetadataQuery) WithDocument(opts ...func(*DocumentQuery)) *MetadataQuery { - query := (&DocumentClient{config: mq.config}).Query() - for _, opt := range opts { - opt(query) - } - mq.withDocument = query - return mq -} - // GroupBy is used to group vertices by one or more fields/columns. // It is often used with aggregate functions, like: count, max, mean, min, sum. // @@ -522,11 +522,11 @@ func (mq *MetadataQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Met nodes = []*Metadata{} _spec = mq.querySpec() loadedTypes = [5]bool{ + mq.withDocument != nil, mq.withTools != nil, mq.withAuthors != nil, mq.withDocumentTypes != nil, mq.withSourceData != nil, - mq.withDocument != nil, } ) _spec.ScanValues = func(columns []string) ([]any, error) { @@ -547,6 +547,12 @@ func (mq *MetadataQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Met if len(nodes) == 0 { return nodes, nil } + if query := mq.withDocument; query != nil { + if err := mq.loadDocument(ctx, query, nodes, nil, + func(n *Metadata, e *Document) { n.Edges.Document = e }); err != nil { + return nil, err + } + } if query := mq.withTools; query != nil { if err := mq.loadTools(ctx, query, nodes, func(n *Metadata) { n.Edges.Tools = []*Tool{} }, @@ -575,15 +581,36 @@ func (mq *MetadataQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Met return nil, err } } - if query := mq.withDocument; query != nil { - if err := mq.loadDocument(ctx, query, nodes, nil, - func(n *Metadata, e *Document) { n.Edges.Document = e }); err != nil { - return nil, err - } - } return nodes, nil } +func (mq *MetadataQuery) loadDocument(ctx context.Context, query *DocumentQuery, nodes []*Metadata, init func(*Metadata), assign func(*Metadata, *Document)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[uuid.UUID]*Metadata) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(document.FieldMetadataID) + } + query.Where(predicate.Document(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(metadata.DocumentColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.MetadataID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "metadata_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} func (mq *MetadataQuery) loadTools(ctx context.Context, query *ToolQuery, nodes []*Metadata, init func(*Metadata), assign func(*Metadata, *Tool)) error { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[uuid.UUID]*Metadata) @@ -705,35 +732,6 @@ func (mq *MetadataQuery) loadSourceData(ctx context.Context, query *SourceDataQu } return nil } -func (mq *MetadataQuery) loadDocument(ctx context.Context, query *DocumentQuery, nodes []*Metadata, init func(*Metadata), assign func(*Metadata, *Document)) error { - ids := make([]uuid.UUID, 0, len(nodes)) - nodeids := make(map[uuid.UUID][]*Metadata) - for i := range nodes { - fk := nodes[i].DocumentID - if _, ok := nodeids[fk]; !ok { - ids = append(ids, fk) - } - nodeids[fk] = append(nodeids[fk], nodes[i]) - } - if len(ids) == 0 { - return nil - } - query.Where(document.IDIn(ids...)) - neighbors, err := query.All(ctx) - if err != nil { - return err - } - for _, n := range neighbors { - nodes, ok := nodeids[n.ID] - if !ok { - return fmt.Errorf(`unexpected foreign-key "document_id" returned %v`, n.ID) - } - for i := range nodes { - assign(nodes[i], n) - } - } - return nil -} func (mq *MetadataQuery) sqlCount(ctx context.Context) (int, error) { _spec := mq.querySpec() @@ -760,9 +758,6 @@ func (mq *MetadataQuery) querySpec() *sqlgraph.QuerySpec { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } - if mq.withDocument != nil { - _spec.Node.AddColumnOnce(metadata.FieldDocumentID) - } } if ps := mq.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { diff --git a/internal/backends/ent/migrate/migrations/20250116171940_annotations_nillable_document_id.sql b/internal/backends/ent/migrate/migrations/20250116171940_annotations_nillable_document_id.sql new file mode 100644 index 0000000..4e530a1 --- /dev/null +++ b/internal/backends/ent/migrate/migrations/20250116171940_annotations_nillable_document_id.sql @@ -0,0 +1,59 @@ +-- Disable the enforcement of foreign-keys constraints +PRAGMA foreign_keys = off; +-- Create "new_metadata" table +CREATE TABLE `new_metadata` ( + `id` uuid NOT NULL, + `proto_message` blob NOT NULL, + `native_id` text NOT NULL, + `version` text NOT NULL, + `name` text NOT NULL, + `date` datetime NOT NULL, + `comment` text NOT NULL, + PRIMARY KEY (`id`) +); +-- Copy rows from old table "metadata" to new temporary table "new_metadata" +INSERT INTO `new_metadata` (`id`, `proto_message`, `native_id`, `version`, `name`, `date`, `comment`) SELECT `id`, `proto_message`, `native_id`, `version`, `name`, `date`, `comment` FROM `metadata`; +-- Drop "metadata" table after copying rows +DROP TABLE `metadata`; +-- Rename temporary table "new_metadata" to "metadata" +ALTER TABLE `new_metadata` RENAME TO `metadata`; +-- Create index "idx_metadata" to table: "metadata" +CREATE UNIQUE INDEX `idx_metadata` ON `metadata` (`native_id`, `version`, `name`); +-- Create "new_node_lists" table +CREATE TABLE `new_node_lists` ( + `id` uuid NOT NULL, + `proto_message` blob NOT NULL, + `root_elements` json NOT NULL, + PRIMARY KEY (`id`) +); +-- Copy rows from old table "node_lists" to new temporary table "new_node_lists" +INSERT INTO `new_node_lists` (`id`, `proto_message`, `root_elements`) SELECT `id`, `proto_message`, `root_elements` FROM `node_lists`; +-- Drop "node_lists" table after copying rows +DROP TABLE `node_lists`; +-- Rename temporary table "new_node_lists" to "node_lists" +ALTER TABLE `new_node_lists` RENAME TO `node_lists`; +-- Create "new_documents" table +CREATE TABLE `new_documents` ( + `id` uuid NOT NULL, + `metadata_id` uuid NULL, + `node_list_id` uuid NULL, + PRIMARY KEY (`id`), + CONSTRAINT `documents_metadata_document` FOREIGN KEY (`metadata_id`) REFERENCES `metadata` (`id`) ON DELETE SET NULL, + CONSTRAINT `documents_node_lists_document` FOREIGN KEY (`node_list_id`) REFERENCES `node_lists` (`id`) ON DELETE SET NULL +); +-- Copy rows from old table "documents" to new temporary table "new_documents" +INSERT INTO `new_documents` (`id`) SELECT `id` FROM `documents`; +-- Drop "documents" table after copying rows +DROP TABLE `documents`; +-- Rename temporary table "new_documents" to "documents" +ALTER TABLE `new_documents` RENAME TO `documents`; +-- Create index "documents_metadata_id_key" to table: "documents" +CREATE UNIQUE INDEX `documents_metadata_id_key` ON `documents` (`metadata_id`); +-- Create index "documents_node_list_id_key" to table: "documents" +CREATE UNIQUE INDEX `documents_node_list_id_key` ON `documents` (`node_list_id`); +-- Create index "idx_annotations_node_id" to table: "annotations" +CREATE INDEX `idx_annotations_node_id` ON `annotations` (`node_id`); +-- Create index "idx_annotations_document_id" to table: "annotations" +CREATE INDEX `idx_annotations_document_id` ON `annotations` (`document_id`); +-- Enable back the enforcement of foreign-keys constraints +PRAGMA foreign_keys = on; diff --git a/internal/backends/ent/migrate/migrations/atlas.sum b/internal/backends/ent/migrate/migrations/atlas.sum index 577ca8d..9804b9a 100644 --- a/internal/backends/ent/migrate/migrations/atlas.sum +++ b/internal/backends/ent/migrate/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:LsrssYsdcm8jjYaT6GHzhPlZ7soWyhOvqryWvUOkngA= +h1:lIrfcCk+LYFBqsFjGSqZ9QnvvS8jecCevrYZdG6GdDk= 20241016141529_initial.sql h1:cZ5Nr+1kj075buwWNz8SHKlRSFaV3L0dzpT9htnXQY4= 20241101155047_store_protos.sql h1:ALraUjMTZaPGDf+y7IXSLp/LRVWXP3rG6kKQb3ZJf5I= 20241109194036_ext_ref_type_fix.sql h1:hvLOKWxV23ea20Po7TLLx0VVfevihIQmR2Ft9nX2Nis= @@ -8,3 +8,4 @@ h1:LsrssYsdcm8jjYaT6GHzhPlZ7soWyhOvqryWvUOkngA= 20250111185420_nodelist_edges_fix.sql h1:3N2FWm6V4ynDShFdVCvMDegJDCrRTul2DrT6hcoaqqk= 20250111195106_hashes_entries.sql h1:xjufIpuHDOznA58+Uk7sIDgtA7lDHTynVtui/iXYFJk= 20250111195831_identifiers_entries.sql h1:t+6QoPwVYJFuXnS8zPiFeL3F/NvQorfgi5sAxGcEn6c= +20250116171940_annotations_nillable_document_id.sql h1:m7rHNc6tZKrgqTH2QWYJ6x7cZheeS1r3pihYyHATV8U= diff --git a/internal/backends/ent/migrate/schema.go b/internal/backends/ent/migrate/schema.go index b350181..eed0bbb 100644 --- a/internal/backends/ent/migrate/schema.go +++ b/internal/backends/ent/migrate/schema.go @@ -30,7 +30,7 @@ var ( PrimaryKey: []*schema.Column{AnnotationsColumns[0]}, ForeignKeys: []*schema.ForeignKey{ { - Symbol: "annotations_documents_document", + Symbol: "annotations_documents_annotations", Columns: []*schema.Column{AnnotationsColumns[4]}, RefColumns: []*schema.Column{DocumentsColumns[0]}, OnDelete: schema.Cascade, @@ -43,6 +43,16 @@ var ( }, }, Indexes: []*schema.Index{ + { + Name: "idx_annotations_node_id", + Unique: false, + Columns: []*schema.Column{AnnotationsColumns[5]}, + }, + { + Name: "idx_annotations_document_id", + Unique: false, + Columns: []*schema.Column{AnnotationsColumns[4]}, + }, { Name: "idx_node_annotations", Unique: true, @@ -80,12 +90,28 @@ var ( // DocumentsColumns holds the columns for the "documents" table. DocumentsColumns = []*schema.Column{ {Name: "id", Type: field.TypeUUID, Unique: true}, + {Name: "metadata_id", Type: field.TypeUUID, Unique: true, Nullable: true}, + {Name: "node_list_id", Type: field.TypeUUID, Unique: true, Nullable: true}, } // DocumentsTable holds the schema information for the "documents" table. DocumentsTable = &schema.Table{ Name: "documents", Columns: DocumentsColumns, PrimaryKey: []*schema.Column{DocumentsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "documents_metadata_document", + Columns: []*schema.Column{DocumentsColumns[1]}, + RefColumns: []*schema.Column{MetadataColumns[0]}, + OnDelete: schema.SetNull, + }, + { + Symbol: "documents_node_lists_document", + Columns: []*schema.Column{DocumentsColumns[2]}, + RefColumns: []*schema.Column{NodeListsColumns[0]}, + OnDelete: schema.SetNull, + }, + }, } // DocumentTypesColumns holds the columns for the "document_types" table. DocumentTypesColumns = []*schema.Column{ @@ -260,21 +286,12 @@ var ( {Name: "name", Type: field.TypeString}, {Name: "date", Type: field.TypeTime}, {Name: "comment", Type: field.TypeString}, - {Name: "document_id", Type: field.TypeUUID, Unique: true}, } // MetadataTable holds the schema information for the "metadata" table. MetadataTable = &schema.Table{ Name: "metadata", Columns: MetadataColumns, PrimaryKey: []*schema.Column{MetadataColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "metadata_documents_metadata", - Columns: []*schema.Column{MetadataColumns[7]}, - RefColumns: []*schema.Column{DocumentsColumns[0]}, - OnDelete: schema.NoAction, - }, - }, Indexes: []*schema.Index{ { Name: "idx_metadata", @@ -336,21 +353,12 @@ var ( {Name: "id", Type: field.TypeUUID, Unique: true}, {Name: "proto_message", Type: field.TypeBytes}, {Name: "root_elements", Type: field.TypeJSON}, - {Name: "document_id", Type: field.TypeUUID, Unique: true}, } // NodeListsTable holds the schema information for the "node_lists" table. NodeListsTable = &schema.Table{ Name: "node_lists", Columns: NodeListsColumns, PrimaryKey: []*schema.Column{NodeListsColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "node_lists_documents_node_list", - Columns: []*schema.Column{NodeListsColumns[3]}, - RefColumns: []*schema.Column{DocumentsColumns[0]}, - OnDelete: schema.NoAction, - }, - }, } // PersonsColumns holds the columns for the "persons" table. PersonsColumns = []*schema.Column{ @@ -747,7 +755,8 @@ var ( func init() { AnnotationsTable.ForeignKeys[0].RefTable = DocumentsTable AnnotationsTable.ForeignKeys[1].RefTable = NodesTable - AnnotationsTable.Annotation = &entsql.Annotation{} + DocumentsTable.ForeignKeys[0].RefTable = MetadataTable + DocumentsTable.ForeignKeys[1].RefTable = NodeListsTable DocumentTypesTable.ForeignKeys[0].RefTable = DocumentsTable DocumentTypesTable.ForeignKeys[1].RefTable = MetadataTable DocumentTypesTable.Annotation = &entsql.Annotation{} @@ -761,10 +770,8 @@ func init() { HashesEntriesTable.Annotation = &entsql.Annotation{} IdentifiersEntriesTable.ForeignKeys[0].RefTable = DocumentsTable IdentifiersEntriesTable.Annotation = &entsql.Annotation{} - MetadataTable.ForeignKeys[0].RefTable = DocumentsTable NodesTable.ForeignKeys[0].RefTable = DocumentsTable NodesTable.Annotation = &entsql.Annotation{} - NodeListsTable.ForeignKeys[0].RefTable = DocumentsTable PersonsTable.ForeignKeys[0].RefTable = MetadataTable PersonsTable.ForeignKeys[1].RefTable = NodesTable PersonsTable.ForeignKeys[2].RefTable = NodesTable diff --git a/internal/backends/ent/mutation.go b/internal/backends/ent/mutation.go index 3cb7dd2..d3672ec 100644 --- a/internal/backends/ent/mutation.go +++ b/internal/backends/ent/mutation.go @@ -196,7 +196,7 @@ func (m *AnnotationMutation) DocumentID() (r uuid.UUID, exists bool) { // OldDocumentID returns the old "document_id" field's value of the Annotation entity. // If the Annotation object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *AnnotationMutation) OldDocumentID(ctx context.Context) (v uuid.UUID, err error) { +func (m *AnnotationMutation) OldDocumentID(ctx context.Context) (v *uuid.UUID, err error) { if !m.op.Is(OpUpdateOne) { return v, errors.New("OldDocumentID is only allowed on UpdateOne operations") } @@ -748,17 +748,20 @@ func (m *AnnotationMutation) ResetEdge(name string) error { // DocumentMutation represents an operation that mutates the Document nodes in the graph. type DocumentMutation struct { config - op Op - typ string - id *uuid.UUID - clearedFields map[string]struct{} - metadata *uuid.UUID - clearedmetadata bool - node_list *uuid.UUID - clearednode_list bool - done bool - oldValue func(context.Context) (*Document, error) - predicates []predicate.Document + op Op + typ string + id *uuid.UUID + clearedFields map[string]struct{} + annotations map[int]struct{} + removedannotations map[int]struct{} + clearedannotations bool + metadata *uuid.UUID + clearedmetadata bool + node_list *uuid.UUID + clearednode_list bool + done bool + oldValue func(context.Context) (*Document, error) + predicates []predicate.Document } var _ ent.Mutation = (*DocumentMutation)(nil) @@ -865,27 +868,167 @@ func (m *DocumentMutation) IDs(ctx context.Context) ([]uuid.UUID, error) { } } -// SetMetadataID sets the "metadata" edge to the Metadata entity by id. -func (m *DocumentMutation) SetMetadataID(id uuid.UUID) { - m.metadata = &id +// SetMetadataID sets the "metadata_id" field. +func (m *DocumentMutation) SetMetadataID(u uuid.UUID) { + m.metadata = &u +} + +// MetadataID returns the value of the "metadata_id" field in the mutation. +func (m *DocumentMutation) MetadataID() (r uuid.UUID, exists bool) { + v := m.metadata + if v == nil { + return + } + return *v, true +} + +// OldMetadataID returns the old "metadata_id" field's value of the Document entity. +// If the Document object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *DocumentMutation) OldMetadataID(ctx context.Context) (v uuid.UUID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldMetadataID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldMetadataID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldMetadataID: %w", err) + } + return oldValue.MetadataID, nil +} + +// ClearMetadataID clears the value of the "metadata_id" field. +func (m *DocumentMutation) ClearMetadataID() { + m.metadata = nil + m.clearedFields[document.FieldMetadataID] = struct{}{} +} + +// MetadataIDCleared returns if the "metadata_id" field was cleared in this mutation. +func (m *DocumentMutation) MetadataIDCleared() bool { + _, ok := m.clearedFields[document.FieldMetadataID] + return ok +} + +// ResetMetadataID resets all changes to the "metadata_id" field. +func (m *DocumentMutation) ResetMetadataID() { + m.metadata = nil + delete(m.clearedFields, document.FieldMetadataID) +} + +// SetNodeListID sets the "node_list_id" field. +func (m *DocumentMutation) SetNodeListID(u uuid.UUID) { + m.node_list = &u +} + +// NodeListID returns the value of the "node_list_id" field in the mutation. +func (m *DocumentMutation) NodeListID() (r uuid.UUID, exists bool) { + v := m.node_list + if v == nil { + return + } + return *v, true +} + +// OldNodeListID returns the old "node_list_id" field's value of the Document entity. +// If the Document object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *DocumentMutation) OldNodeListID(ctx context.Context) (v uuid.UUID, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldNodeListID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldNodeListID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldNodeListID: %w", err) + } + return oldValue.NodeListID, nil +} + +// ClearNodeListID clears the value of the "node_list_id" field. +func (m *DocumentMutation) ClearNodeListID() { + m.node_list = nil + m.clearedFields[document.FieldNodeListID] = struct{}{} +} + +// NodeListIDCleared returns if the "node_list_id" field was cleared in this mutation. +func (m *DocumentMutation) NodeListIDCleared() bool { + _, ok := m.clearedFields[document.FieldNodeListID] + return ok +} + +// ResetNodeListID resets all changes to the "node_list_id" field. +func (m *DocumentMutation) ResetNodeListID() { + m.node_list = nil + delete(m.clearedFields, document.FieldNodeListID) +} + +// AddAnnotationIDs adds the "annotations" edge to the Annotation entity by ids. +func (m *DocumentMutation) AddAnnotationIDs(ids ...int) { + if m.annotations == nil { + m.annotations = make(map[int]struct{}) + } + for i := range ids { + m.annotations[ids[i]] = struct{}{} + } +} + +// ClearAnnotations clears the "annotations" edge to the Annotation entity. +func (m *DocumentMutation) ClearAnnotations() { + m.clearedannotations = true +} + +// AnnotationsCleared reports if the "annotations" edge to the Annotation entity was cleared. +func (m *DocumentMutation) AnnotationsCleared() bool { + return m.clearedannotations +} + +// RemoveAnnotationIDs removes the "annotations" edge to the Annotation entity by IDs. +func (m *DocumentMutation) RemoveAnnotationIDs(ids ...int) { + if m.removedannotations == nil { + m.removedannotations = make(map[int]struct{}) + } + for i := range ids { + delete(m.annotations, ids[i]) + m.removedannotations[ids[i]] = struct{}{} + } +} + +// RemovedAnnotations returns the removed IDs of the "annotations" edge to the Annotation entity. +func (m *DocumentMutation) RemovedAnnotationsIDs() (ids []int) { + for id := range m.removedannotations { + ids = append(ids, id) + } + return +} + +// AnnotationsIDs returns the "annotations" edge IDs in the mutation. +func (m *DocumentMutation) AnnotationsIDs() (ids []int) { + for id := range m.annotations { + ids = append(ids, id) + } + return +} + +// ResetAnnotations resets all changes to the "annotations" edge. +func (m *DocumentMutation) ResetAnnotations() { + m.annotations = nil + m.clearedannotations = false + m.removedannotations = nil } // ClearMetadata clears the "metadata" edge to the Metadata entity. func (m *DocumentMutation) ClearMetadata() { m.clearedmetadata = true + m.clearedFields[document.FieldMetadataID] = struct{}{} } // MetadataCleared reports if the "metadata" edge to the Metadata entity was cleared. func (m *DocumentMutation) MetadataCleared() bool { - return m.clearedmetadata -} - -// MetadataID returns the "metadata" edge ID in the mutation. -func (m *DocumentMutation) MetadataID() (id uuid.UUID, exists bool) { - if m.metadata != nil { - return *m.metadata, true - } - return + return m.MetadataIDCleared() || m.clearedmetadata } // MetadataIDs returns the "metadata" edge IDs in the mutation. @@ -904,27 +1047,15 @@ func (m *DocumentMutation) ResetMetadata() { m.clearedmetadata = false } -// SetNodeListID sets the "node_list" edge to the NodeList entity by id. -func (m *DocumentMutation) SetNodeListID(id uuid.UUID) { - m.node_list = &id -} - // ClearNodeList clears the "node_list" edge to the NodeList entity. func (m *DocumentMutation) ClearNodeList() { m.clearednode_list = true + m.clearedFields[document.FieldNodeListID] = struct{}{} } // NodeListCleared reports if the "node_list" edge to the NodeList entity was cleared. func (m *DocumentMutation) NodeListCleared() bool { - return m.clearednode_list -} - -// NodeListID returns the "node_list" edge ID in the mutation. -func (m *DocumentMutation) NodeListID() (id uuid.UUID, exists bool) { - if m.node_list != nil { - return *m.node_list, true - } - return + return m.NodeListIDCleared() || m.clearednode_list } // NodeListIDs returns the "node_list" edge IDs in the mutation. @@ -977,7 +1108,13 @@ func (m *DocumentMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *DocumentMutation) Fields() []string { - fields := make([]string, 0, 0) + fields := make([]string, 0, 2) + if m.metadata != nil { + fields = append(fields, document.FieldMetadataID) + } + if m.node_list != nil { + fields = append(fields, document.FieldNodeListID) + } return fields } @@ -985,6 +1122,12 @@ func (m *DocumentMutation) Fields() []string { // return value indicates that this field was not set, or was not defined in the // schema. func (m *DocumentMutation) Field(name string) (ent.Value, bool) { + switch name { + case document.FieldMetadataID: + return m.MetadataID() + case document.FieldNodeListID: + return m.NodeListID() + } return nil, false } @@ -992,6 +1135,12 @@ func (m *DocumentMutation) Field(name string) (ent.Value, bool) { // returned if the mutation operation is not UpdateOne, or the query to the // database failed. func (m *DocumentMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case document.FieldMetadataID: + return m.OldMetadataID(ctx) + case document.FieldNodeListID: + return m.OldNodeListID(ctx) + } return nil, fmt.Errorf("unknown Document field %s", name) } @@ -1000,6 +1149,20 @@ func (m *DocumentMutation) OldField(ctx context.Context, name string) (ent.Value // type. func (m *DocumentMutation) SetField(name string, value ent.Value) error { switch name { + case document.FieldMetadataID: + v, ok := value.(uuid.UUID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetMetadataID(v) + return nil + case document.FieldNodeListID: + v, ok := value.(uuid.UUID) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetNodeListID(v) + return nil } return fmt.Errorf("unknown Document field %s", name) } @@ -1021,13 +1184,22 @@ func (m *DocumentMutation) AddedField(name string) (ent.Value, bool) { // the field is not defined in the schema, or if the type mismatched the field // type. func (m *DocumentMutation) AddField(name string, value ent.Value) error { + switch name { + } return fmt.Errorf("unknown Document numeric field %s", name) } // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *DocumentMutation) ClearedFields() []string { - return nil + var fields []string + if m.FieldCleared(document.FieldMetadataID) { + fields = append(fields, document.FieldMetadataID) + } + if m.FieldCleared(document.FieldNodeListID) { + fields = append(fields, document.FieldNodeListID) + } + return fields } // FieldCleared returns a boolean indicating if a field with the given name was @@ -1040,18 +1212,37 @@ func (m *DocumentMutation) FieldCleared(name string) bool { // ClearField clears the value of the field with the given name. It returns an // error if the field is not defined in the schema. func (m *DocumentMutation) ClearField(name string) error { + switch name { + case document.FieldMetadataID: + m.ClearMetadataID() + return nil + case document.FieldNodeListID: + m.ClearNodeListID() + return nil + } return fmt.Errorf("unknown Document nullable field %s", name) } // ResetField resets all changes in the mutation for the field with the given name. // It returns an error if the field is not defined in the schema. func (m *DocumentMutation) ResetField(name string) error { + switch name { + case document.FieldMetadataID: + m.ResetMetadataID() + return nil + case document.FieldNodeListID: + m.ResetNodeListID() + return nil + } return fmt.Errorf("unknown Document field %s", name) } // AddedEdges returns all edge names that were set/added in this mutation. func (m *DocumentMutation) AddedEdges() []string { - edges := make([]string, 0, 2) + edges := make([]string, 0, 3) + if m.annotations != nil { + edges = append(edges, document.EdgeAnnotations) + } if m.metadata != nil { edges = append(edges, document.EdgeMetadata) } @@ -1065,6 +1256,12 @@ func (m *DocumentMutation) AddedEdges() []string { // name in this mutation. func (m *DocumentMutation) AddedIDs(name string) []ent.Value { switch name { + case document.EdgeAnnotations: + ids := make([]ent.Value, 0, len(m.annotations)) + for id := range m.annotations { + ids = append(ids, id) + } + return ids case document.EdgeMetadata: if id := m.metadata; id != nil { return []ent.Value{*id} @@ -1079,19 +1276,33 @@ func (m *DocumentMutation) AddedIDs(name string) []ent.Value { // RemovedEdges returns all edge names that were removed in this mutation. func (m *DocumentMutation) RemovedEdges() []string { - edges := make([]string, 0, 2) + edges := make([]string, 0, 3) + if m.removedannotations != nil { + edges = append(edges, document.EdgeAnnotations) + } return edges } // RemovedIDs returns all IDs (to other nodes) that were removed for the edge with // the given name in this mutation. func (m *DocumentMutation) RemovedIDs(name string) []ent.Value { + switch name { + case document.EdgeAnnotations: + ids := make([]ent.Value, 0, len(m.removedannotations)) + for id := range m.removedannotations { + ids = append(ids, id) + } + return ids + } return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *DocumentMutation) ClearedEdges() []string { - edges := make([]string, 0, 2) + edges := make([]string, 0, 3) + if m.clearedannotations { + edges = append(edges, document.EdgeAnnotations) + } if m.clearedmetadata { edges = append(edges, document.EdgeMetadata) } @@ -1105,6 +1316,8 @@ func (m *DocumentMutation) ClearedEdges() []string { // was cleared in this mutation. func (m *DocumentMutation) EdgeCleared(name string) bool { switch name { + case document.EdgeAnnotations: + return m.clearedannotations case document.EdgeMetadata: return m.clearedmetadata case document.EdgeNodeList: @@ -1131,6 +1344,9 @@ func (m *DocumentMutation) ClearEdge(name string) error { // It returns an error if the edge is not defined in the schema. func (m *DocumentMutation) ResetEdge(name string) error { switch name { + case document.EdgeAnnotations: + m.ResetAnnotations() + return nil case document.EdgeMetadata: m.ResetMetadata() return nil @@ -4931,6 +5147,8 @@ type MetadataMutation struct { date *time.Time comment *string clearedFields map[string]struct{} + document *uuid.UUID + cleareddocument bool tools map[uuid.UUID]struct{} removedtools map[uuid.UUID]struct{} clearedtools bool @@ -4943,8 +5161,6 @@ type MetadataMutation struct { source_data map[uuid.UUID]struct{} removedsource_data map[uuid.UUID]struct{} clearedsource_data bool - document *uuid.UUID - cleareddocument bool done bool oldValue func(context.Context) (*Metadata, error) predicates []predicate.Metadata @@ -5090,42 +5306,6 @@ func (m *MetadataMutation) ResetProtoMessage() { m.proto_message = nil } -// SetDocumentID sets the "document_id" field. -func (m *MetadataMutation) SetDocumentID(u uuid.UUID) { - m.document = &u -} - -// DocumentID returns the value of the "document_id" field in the mutation. -func (m *MetadataMutation) DocumentID() (r uuid.UUID, exists bool) { - v := m.document - if v == nil { - return - } - return *v, true -} - -// OldDocumentID returns the old "document_id" field's value of the Metadata entity. -// If the Metadata object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *MetadataMutation) OldDocumentID(ctx context.Context) (v uuid.UUID, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldDocumentID is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldDocumentID requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldDocumentID: %w", err) - } - return oldValue.DocumentID, nil -} - -// ResetDocumentID resets all changes to the "document_id" field. -func (m *MetadataMutation) ResetDocumentID() { - m.document = nil -} - // SetNativeID sets the "native_id" field. func (m *MetadataMutation) SetNativeID(s string) { m.native_id = &s @@ -5306,6 +5486,45 @@ func (m *MetadataMutation) ResetComment() { m.comment = nil } +// SetDocumentID sets the "document" edge to the Document entity by id. +func (m *MetadataMutation) SetDocumentID(id uuid.UUID) { + m.document = &id +} + +// ClearDocument clears the "document" edge to the Document entity. +func (m *MetadataMutation) ClearDocument() { + m.cleareddocument = true +} + +// DocumentCleared reports if the "document" edge to the Document entity was cleared. +func (m *MetadataMutation) DocumentCleared() bool { + return m.cleareddocument +} + +// DocumentID returns the "document" edge ID in the mutation. +func (m *MetadataMutation) DocumentID() (id uuid.UUID, exists bool) { + if m.document != nil { + return *m.document, true + } + return +} + +// DocumentIDs returns the "document" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// DocumentID instead. It exists only for internal usage by the builders. +func (m *MetadataMutation) DocumentIDs() (ids []uuid.UUID) { + if id := m.document; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetDocument resets all changes to the "document" edge. +func (m *MetadataMutation) ResetDocument() { + m.document = nil + m.cleareddocument = false +} + // AddToolIDs adds the "tools" edge to the Tool entity by ids. func (m *MetadataMutation) AddToolIDs(ids ...uuid.UUID) { if m.tools == nil { @@ -5522,33 +5741,6 @@ func (m *MetadataMutation) ResetSourceData() { m.removedsource_data = nil } -// ClearDocument clears the "document" edge to the Document entity. -func (m *MetadataMutation) ClearDocument() { - m.cleareddocument = true - m.clearedFields[metadata.FieldDocumentID] = struct{}{} -} - -// DocumentCleared reports if the "document" edge to the Document entity was cleared. -func (m *MetadataMutation) DocumentCleared() bool { - return m.cleareddocument -} - -// DocumentIDs returns the "document" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// DocumentID instead. It exists only for internal usage by the builders. -func (m *MetadataMutation) DocumentIDs() (ids []uuid.UUID) { - if id := m.document; id != nil { - ids = append(ids, *id) - } - return -} - -// ResetDocument resets all changes to the "document" edge. -func (m *MetadataMutation) ResetDocument() { - m.document = nil - m.cleareddocument = false -} - // Where appends a list predicates to the MetadataMutation builder. func (m *MetadataMutation) Where(ps ...predicate.Metadata) { m.predicates = append(m.predicates, ps...) @@ -5583,13 +5775,10 @@ func (m *MetadataMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *MetadataMutation) Fields() []string { - fields := make([]string, 0, 7) + fields := make([]string, 0, 6) if m.proto_message != nil { fields = append(fields, metadata.FieldProtoMessage) } - if m.document != nil { - fields = append(fields, metadata.FieldDocumentID) - } if m.native_id != nil { fields = append(fields, metadata.FieldNativeID) } @@ -5615,8 +5804,6 @@ func (m *MetadataMutation) Field(name string) (ent.Value, bool) { switch name { case metadata.FieldProtoMessage: return m.ProtoMessage() - case metadata.FieldDocumentID: - return m.DocumentID() case metadata.FieldNativeID: return m.NativeID() case metadata.FieldVersion: @@ -5638,8 +5825,6 @@ func (m *MetadataMutation) OldField(ctx context.Context, name string) (ent.Value switch name { case metadata.FieldProtoMessage: return m.OldProtoMessage(ctx) - case metadata.FieldDocumentID: - return m.OldDocumentID(ctx) case metadata.FieldNativeID: return m.OldNativeID(ctx) case metadata.FieldVersion: @@ -5666,13 +5851,6 @@ func (m *MetadataMutation) SetField(name string, value ent.Value) error { } m.SetProtoMessage(v) return nil - case metadata.FieldDocumentID: - v, ok := value.(uuid.UUID) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetDocumentID(v) - return nil case metadata.FieldNativeID: v, ok := value.(string) if !ok { @@ -5760,9 +5938,6 @@ func (m *MetadataMutation) ResetField(name string) error { case metadata.FieldProtoMessage: m.ResetProtoMessage() return nil - case metadata.FieldDocumentID: - m.ResetDocumentID() - return nil case metadata.FieldNativeID: m.ResetNativeID() return nil @@ -5785,6 +5960,9 @@ func (m *MetadataMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *MetadataMutation) AddedEdges() []string { edges := make([]string, 0, 5) + if m.document != nil { + edges = append(edges, metadata.EdgeDocument) + } if m.tools != nil { edges = append(edges, metadata.EdgeTools) } @@ -5797,9 +5975,6 @@ func (m *MetadataMutation) AddedEdges() []string { if m.source_data != nil { edges = append(edges, metadata.EdgeSourceData) } - if m.document != nil { - edges = append(edges, metadata.EdgeDocument) - } return edges } @@ -5807,6 +5982,10 @@ func (m *MetadataMutation) AddedEdges() []string { // name in this mutation. func (m *MetadataMutation) AddedIDs(name string) []ent.Value { switch name { + case metadata.EdgeDocument: + if id := m.document; id != nil { + return []ent.Value{*id} + } case metadata.EdgeTools: ids := make([]ent.Value, 0, len(m.tools)) for id := range m.tools { @@ -5831,10 +6010,6 @@ func (m *MetadataMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids - case metadata.EdgeDocument: - if id := m.document; id != nil { - return []ent.Value{*id} - } } return nil } @@ -5892,6 +6067,9 @@ func (m *MetadataMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *MetadataMutation) ClearedEdges() []string { edges := make([]string, 0, 5) + if m.cleareddocument { + edges = append(edges, metadata.EdgeDocument) + } if m.clearedtools { edges = append(edges, metadata.EdgeTools) } @@ -5904,9 +6082,6 @@ func (m *MetadataMutation) ClearedEdges() []string { if m.clearedsource_data { edges = append(edges, metadata.EdgeSourceData) } - if m.cleareddocument { - edges = append(edges, metadata.EdgeDocument) - } return edges } @@ -5914,6 +6089,8 @@ func (m *MetadataMutation) ClearedEdges() []string { // was cleared in this mutation. func (m *MetadataMutation) EdgeCleared(name string) bool { switch name { + case metadata.EdgeDocument: + return m.cleareddocument case metadata.EdgeTools: return m.clearedtools case metadata.EdgeAuthors: @@ -5922,8 +6099,6 @@ func (m *MetadataMutation) EdgeCleared(name string) bool { return m.cleareddocument_types case metadata.EdgeSourceData: return m.clearedsource_data - case metadata.EdgeDocument: - return m.cleareddocument } return false } @@ -5943,6 +6118,9 @@ func (m *MetadataMutation) ClearEdge(name string) error { // It returns an error if the edge is not defined in the schema. func (m *MetadataMutation) ResetEdge(name string) error { switch name { + case metadata.EdgeDocument: + m.ResetDocument() + return nil case metadata.EdgeTools: m.ResetTools() return nil @@ -5955,9 +6133,6 @@ func (m *MetadataMutation) ResetEdge(name string) error { case metadata.EdgeSourceData: m.ResetSourceData() return nil - case metadata.EdgeDocument: - m.ResetDocument() - return nil } return fmt.Errorf("unknown Metadata edge %s", name) } @@ -8633,14 +8808,14 @@ type NodeListMutation struct { root_elements *[]string appendroot_elements []string clearedFields map[string]struct{} + document *uuid.UUID + cleareddocument bool edge_types map[uuid.UUID]struct{} removededge_types map[uuid.UUID]struct{} clearededge_types bool nodes map[uuid.UUID]struct{} removednodes map[uuid.UUID]struct{} clearednodes bool - document *uuid.UUID - cleareddocument bool done bool oldValue func(context.Context) (*NodeList, error) predicates []predicate.NodeList @@ -8786,42 +8961,6 @@ func (m *NodeListMutation) ResetProtoMessage() { m.proto_message = nil } -// SetDocumentID sets the "document_id" field. -func (m *NodeListMutation) SetDocumentID(u uuid.UUID) { - m.document = &u -} - -// DocumentID returns the value of the "document_id" field in the mutation. -func (m *NodeListMutation) DocumentID() (r uuid.UUID, exists bool) { - v := m.document - if v == nil { - return - } - return *v, true -} - -// OldDocumentID returns the old "document_id" field's value of the NodeList entity. -// If the NodeList object wasn't provided to the builder, the object is fetched from the database. -// An error is returned if the mutation operation is not UpdateOne, or the database query fails. -func (m *NodeListMutation) OldDocumentID(ctx context.Context) (v uuid.UUID, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldDocumentID is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldDocumentID requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldDocumentID: %w", err) - } - return oldValue.DocumentID, nil -} - -// ResetDocumentID resets all changes to the "document_id" field. -func (m *NodeListMutation) ResetDocumentID() { - m.document = nil -} - // SetRootElements sets the "root_elements" field. func (m *NodeListMutation) SetRootElements(s []string) { m.root_elements = &s @@ -8873,6 +9012,45 @@ func (m *NodeListMutation) ResetRootElements() { m.appendroot_elements = nil } +// SetDocumentID sets the "document" edge to the Document entity by id. +func (m *NodeListMutation) SetDocumentID(id uuid.UUID) { + m.document = &id +} + +// ClearDocument clears the "document" edge to the Document entity. +func (m *NodeListMutation) ClearDocument() { + m.cleareddocument = true +} + +// DocumentCleared reports if the "document" edge to the Document entity was cleared. +func (m *NodeListMutation) DocumentCleared() bool { + return m.cleareddocument +} + +// DocumentID returns the "document" edge ID in the mutation. +func (m *NodeListMutation) DocumentID() (id uuid.UUID, exists bool) { + if m.document != nil { + return *m.document, true + } + return +} + +// DocumentIDs returns the "document" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// DocumentID instead. It exists only for internal usage by the builders. +func (m *NodeListMutation) DocumentIDs() (ids []uuid.UUID) { + if id := m.document; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetDocument resets all changes to the "document" edge. +func (m *NodeListMutation) ResetDocument() { + m.document = nil + m.cleareddocument = false +} + // AddEdgeTypeIDs adds the "edge_types" edge to the EdgeType entity by ids. func (m *NodeListMutation) AddEdgeTypeIDs(ids ...uuid.UUID) { if m.edge_types == nil { @@ -8981,33 +9159,6 @@ func (m *NodeListMutation) ResetNodes() { m.removednodes = nil } -// ClearDocument clears the "document" edge to the Document entity. -func (m *NodeListMutation) ClearDocument() { - m.cleareddocument = true - m.clearedFields[nodelist.FieldDocumentID] = struct{}{} -} - -// DocumentCleared reports if the "document" edge to the Document entity was cleared. -func (m *NodeListMutation) DocumentCleared() bool { - return m.cleareddocument -} - -// DocumentIDs returns the "document" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// DocumentID instead. It exists only for internal usage by the builders. -func (m *NodeListMutation) DocumentIDs() (ids []uuid.UUID) { - if id := m.document; id != nil { - ids = append(ids, *id) - } - return -} - -// ResetDocument resets all changes to the "document" edge. -func (m *NodeListMutation) ResetDocument() { - m.document = nil - m.cleareddocument = false -} - // Where appends a list predicates to the NodeListMutation builder. func (m *NodeListMutation) Where(ps ...predicate.NodeList) { m.predicates = append(m.predicates, ps...) @@ -9042,13 +9193,10 @@ func (m *NodeListMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *NodeListMutation) Fields() []string { - fields := make([]string, 0, 3) + fields := make([]string, 0, 2) if m.proto_message != nil { fields = append(fields, nodelist.FieldProtoMessage) } - if m.document != nil { - fields = append(fields, nodelist.FieldDocumentID) - } if m.root_elements != nil { fields = append(fields, nodelist.FieldRootElements) } @@ -9062,8 +9210,6 @@ func (m *NodeListMutation) Field(name string) (ent.Value, bool) { switch name { case nodelist.FieldProtoMessage: return m.ProtoMessage() - case nodelist.FieldDocumentID: - return m.DocumentID() case nodelist.FieldRootElements: return m.RootElements() } @@ -9077,8 +9223,6 @@ func (m *NodeListMutation) OldField(ctx context.Context, name string) (ent.Value switch name { case nodelist.FieldProtoMessage: return m.OldProtoMessage(ctx) - case nodelist.FieldDocumentID: - return m.OldDocumentID(ctx) case nodelist.FieldRootElements: return m.OldRootElements(ctx) } @@ -9097,13 +9241,6 @@ func (m *NodeListMutation) SetField(name string, value ent.Value) error { } m.SetProtoMessage(v) return nil - case nodelist.FieldDocumentID: - v, ok := value.(uuid.UUID) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetDocumentID(v) - return nil case nodelist.FieldRootElements: v, ok := value.([]string) if !ok { @@ -9163,9 +9300,6 @@ func (m *NodeListMutation) ResetField(name string) error { case nodelist.FieldProtoMessage: m.ResetProtoMessage() return nil - case nodelist.FieldDocumentID: - m.ResetDocumentID() - return nil case nodelist.FieldRootElements: m.ResetRootElements() return nil @@ -9176,15 +9310,15 @@ func (m *NodeListMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *NodeListMutation) AddedEdges() []string { edges := make([]string, 0, 3) + if m.document != nil { + edges = append(edges, nodelist.EdgeDocument) + } if m.edge_types != nil { edges = append(edges, nodelist.EdgeEdgeTypes) } if m.nodes != nil { edges = append(edges, nodelist.EdgeNodes) } - if m.document != nil { - edges = append(edges, nodelist.EdgeDocument) - } return edges } @@ -9192,6 +9326,10 @@ func (m *NodeListMutation) AddedEdges() []string { // name in this mutation. func (m *NodeListMutation) AddedIDs(name string) []ent.Value { switch name { + case nodelist.EdgeDocument: + if id := m.document; id != nil { + return []ent.Value{*id} + } case nodelist.EdgeEdgeTypes: ids := make([]ent.Value, 0, len(m.edge_types)) for id := range m.edge_types { @@ -9204,10 +9342,6 @@ func (m *NodeListMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids - case nodelist.EdgeDocument: - if id := m.document; id != nil { - return []ent.Value{*id} - } } return nil } @@ -9247,15 +9381,15 @@ func (m *NodeListMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *NodeListMutation) ClearedEdges() []string { edges := make([]string, 0, 3) + if m.cleareddocument { + edges = append(edges, nodelist.EdgeDocument) + } if m.clearededge_types { edges = append(edges, nodelist.EdgeEdgeTypes) } if m.clearednodes { edges = append(edges, nodelist.EdgeNodes) } - if m.cleareddocument { - edges = append(edges, nodelist.EdgeDocument) - } return edges } @@ -9263,12 +9397,12 @@ func (m *NodeListMutation) ClearedEdges() []string { // was cleared in this mutation. func (m *NodeListMutation) EdgeCleared(name string) bool { switch name { + case nodelist.EdgeDocument: + return m.cleareddocument case nodelist.EdgeEdgeTypes: return m.clearededge_types case nodelist.EdgeNodes: return m.clearednodes - case nodelist.EdgeDocument: - return m.cleareddocument } return false } @@ -9288,15 +9422,15 @@ func (m *NodeListMutation) ClearEdge(name string) error { // It returns an error if the edge is not defined in the schema. func (m *NodeListMutation) ResetEdge(name string) error { switch name { + case nodelist.EdgeDocument: + m.ResetDocument() + return nil case nodelist.EdgeEdgeTypes: m.ResetEdgeTypes() return nil case nodelist.EdgeNodes: m.ResetNodes() return nil - case nodelist.EdgeDocument: - m.ResetDocument() - return nil } return fmt.Errorf("unknown NodeList edge %s", name) } diff --git a/internal/backends/ent/nodelist.go b/internal/backends/ent/nodelist.go index 5788d6b..b562235 100644 --- a/internal/backends/ent/nodelist.go +++ b/internal/backends/ent/nodelist.go @@ -27,8 +27,6 @@ type NodeList struct { ID uuid.UUID `json:"id,omitempty"` // ProtoMessage holds the value of the "proto_message" field. ProtoMessage *sbom.NodeList `json:"proto_message,omitempty"` - // DocumentID holds the value of the "document_id" field. - DocumentID uuid.UUID `json:"document_id,omitempty"` // RootElements holds the value of the "root_elements" field. RootElements []string `json:"root_elements,omitempty"` // Edges holds the relations/edges for other nodes in the graph. @@ -39,21 +37,32 @@ type NodeList struct { // NodeListEdges holds the relations/edges for other nodes in the graph. type NodeListEdges struct { + // Document holds the value of the document edge. + Document *Document `json:"document,omitempty"` // EdgeTypes holds the value of the edge_types edge. EdgeTypes []*EdgeType `json:"edge_types,omitempty"` // Nodes holds the value of the nodes edge. Nodes []*Node `json:"nodes,omitempty"` - // Document holds the value of the document edge. - Document *Document `json:"document,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. loadedTypes [3]bool } +// DocumentOrErr returns the Document value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e NodeListEdges) DocumentOrErr() (*Document, error) { + if e.Document != nil { + return e.Document, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: document.Label} + } + return nil, &NotLoadedError{edge: "document"} +} + // EdgeTypesOrErr returns the EdgeTypes value or an error if the edge // was not loaded in eager-loading. func (e NodeListEdges) EdgeTypesOrErr() ([]*EdgeType, error) { - if e.loadedTypes[0] { + if e.loadedTypes[1] { return e.EdgeTypes, nil } return nil, &NotLoadedError{edge: "edge_types"} @@ -62,23 +71,12 @@ func (e NodeListEdges) EdgeTypesOrErr() ([]*EdgeType, error) { // NodesOrErr returns the Nodes value or an error if the edge // was not loaded in eager-loading. func (e NodeListEdges) NodesOrErr() ([]*Node, error) { - if e.loadedTypes[1] { + if e.loadedTypes[2] { return e.Nodes, nil } return nil, &NotLoadedError{edge: "nodes"} } -// DocumentOrErr returns the Document value or an error if the edge -// was not loaded in eager-loading, or loaded but was not found. -func (e NodeListEdges) DocumentOrErr() (*Document, error) { - if e.Document != nil { - return e.Document, nil - } else if e.loadedTypes[2] { - return nil, &NotFoundError{label: document.Label} - } - return nil, &NotLoadedError{edge: "document"} -} - // scanValues returns the types for scanning values from sql.Rows. func (*NodeList) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) @@ -88,7 +86,7 @@ func (*NodeList) scanValues(columns []string) ([]any, error) { values[i] = &sql.NullScanner{S: new(sbom.NodeList)} case nodelist.FieldRootElements: values[i] = new([]byte) - case nodelist.FieldID, nodelist.FieldDocumentID: + case nodelist.FieldID: values[i] = new(uuid.UUID) default: values[i] = new(sql.UnknownType) @@ -117,12 +115,6 @@ func (nl *NodeList) assignValues(columns []string, values []any) error { } else if value.Valid { nl.ProtoMessage = value.S.(*sbom.NodeList) } - case nodelist.FieldDocumentID: - if value, ok := values[i].(*uuid.UUID); !ok { - return fmt.Errorf("unexpected type %T for field document_id", values[i]) - } else if value != nil { - nl.DocumentID = *value - } case nodelist.FieldRootElements: if value, ok := values[i].(*[]byte); !ok { return fmt.Errorf("unexpected type %T for field root_elements", values[i]) @@ -144,6 +136,11 @@ func (nl *NodeList) Value(name string) (ent.Value, error) { return nl.selectValues.Get(name) } +// QueryDocument queries the "document" edge of the NodeList entity. +func (nl *NodeList) QueryDocument() *DocumentQuery { + return NewNodeListClient(nl.config).QueryDocument(nl) +} + // QueryEdgeTypes queries the "edge_types" edge of the NodeList entity. func (nl *NodeList) QueryEdgeTypes() *EdgeTypeQuery { return NewNodeListClient(nl.config).QueryEdgeTypes(nl) @@ -154,11 +151,6 @@ func (nl *NodeList) QueryNodes() *NodeQuery { return NewNodeListClient(nl.config).QueryNodes(nl) } -// QueryDocument queries the "document" edge of the NodeList entity. -func (nl *NodeList) QueryDocument() *DocumentQuery { - return NewNodeListClient(nl.config).QueryDocument(nl) -} - // Update returns a builder for updating this NodeList. // Note that you need to call NodeList.Unwrap() before calling this method if this NodeList // was returned from a transaction, and the transaction was committed or rolled back. @@ -187,9 +179,6 @@ func (nl *NodeList) String() string { builder.WriteString(fmt.Sprintf("%v", *v)) } builder.WriteString(", ") - builder.WriteString("document_id=") - builder.WriteString(fmt.Sprintf("%v", nl.DocumentID)) - builder.WriteString(", ") builder.WriteString("root_elements=") builder.WriteString(fmt.Sprintf("%v", nl.RootElements)) builder.WriteByte(')') diff --git a/internal/backends/ent/nodelist/nodelist.go b/internal/backends/ent/nodelist/nodelist.go index 9ce5843..fcfa1d5 100644 --- a/internal/backends/ent/nodelist/nodelist.go +++ b/internal/backends/ent/nodelist/nodelist.go @@ -20,18 +20,23 @@ const ( FieldID = "id" // FieldProtoMessage holds the string denoting the proto_message field in the database. FieldProtoMessage = "proto_message" - // FieldDocumentID holds the string denoting the document_id field in the database. - FieldDocumentID = "document_id" // FieldRootElements holds the string denoting the root_elements field in the database. FieldRootElements = "root_elements" + // EdgeDocument holds the string denoting the document edge name in mutations. + EdgeDocument = "document" // EdgeEdgeTypes holds the string denoting the edge_types edge name in mutations. EdgeEdgeTypes = "edge_types" // EdgeNodes holds the string denoting the nodes edge name in mutations. EdgeNodes = "nodes" - // EdgeDocument holds the string denoting the document edge name in mutations. - EdgeDocument = "document" // Table holds the table name of the nodelist in the database. Table = "node_lists" + // DocumentTable is the table that holds the document relation/edge. + DocumentTable = "documents" + // DocumentInverseTable is the table name for the Document entity. + // It exists in this package in order to avoid circular dependency with the "document" package. + DocumentInverseTable = "documents" + // DocumentColumn is the table column denoting the document relation/edge. + DocumentColumn = "node_list_id" // EdgeTypesTable is the table that holds the edge_types relation/edge. The primary key declared below. EdgeTypesTable = "node_list_edges" // EdgeTypesInverseTable is the table name for the EdgeType entity. @@ -42,20 +47,12 @@ const ( // NodesInverseTable is the table name for the Node entity. // It exists in this package in order to avoid circular dependency with the "node" package. NodesInverseTable = "nodes" - // DocumentTable is the table that holds the document relation/edge. - DocumentTable = "node_lists" - // DocumentInverseTable is the table name for the Document entity. - // It exists in this package in order to avoid circular dependency with the "document" package. - DocumentInverseTable = "documents" - // DocumentColumn is the table column denoting the document relation/edge. - DocumentColumn = "document_id" ) // Columns holds all SQL columns for nodelist fields. var Columns = []string{ FieldID, FieldProtoMessage, - FieldDocumentID, FieldRootElements, } @@ -91,9 +88,11 @@ func ByID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldID, opts...).ToFunc() } -// ByDocumentID orders the results by the document_id field. -func ByDocumentID(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldDocumentID, opts...).ToFunc() +// ByDocumentField orders the results by document field. +func ByDocumentField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newDocumentStep(), sql.OrderByField(field, opts...)) + } } // ByEdgeTypesCount orders the results by edge_types count. @@ -123,12 +122,12 @@ func ByNodes(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { sqlgraph.OrderByNeighborTerms(s, newNodesStep(), append([]sql.OrderTerm{term}, terms...)...) } } - -// ByDocumentField orders the results by document field. -func ByDocumentField(field string, opts ...sql.OrderTermOption) OrderOption { - return func(s *sql.Selector) { - sqlgraph.OrderByNeighborTerms(s, newDocumentStep(), sql.OrderByField(field, opts...)) - } +func newDocumentStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(DocumentInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, DocumentTable, DocumentColumn), + ) } func newEdgeTypesStep() *sqlgraph.Step { return sqlgraph.NewStep( @@ -144,10 +143,3 @@ func newNodesStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.M2M, false, NodesTable, NodesPrimaryKey...), ) } -func newDocumentStep() *sqlgraph.Step { - return sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(DocumentInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, DocumentTable, DocumentColumn), - ) -} diff --git a/internal/backends/ent/nodelist/where.go b/internal/backends/ent/nodelist/where.go index 8510b86..19a5882 100644 --- a/internal/backends/ent/nodelist/where.go +++ b/internal/backends/ent/nodelist/where.go @@ -65,11 +65,6 @@ func ProtoMessage(v *sbom.NodeList) predicate.NodeList { return predicate.NodeList(sql.FieldEQ(FieldProtoMessage, v)) } -// DocumentID applies equality check predicate on the "document_id" field. It's identical to DocumentIDEQ. -func DocumentID(v uuid.UUID) predicate.NodeList { - return predicate.NodeList(sql.FieldEQ(FieldDocumentID, v)) -} - // ProtoMessageEQ applies the EQ predicate on the "proto_message" field. func ProtoMessageEQ(v *sbom.NodeList) predicate.NodeList { return predicate.NodeList(sql.FieldEQ(FieldProtoMessage, v)) @@ -110,41 +105,21 @@ func ProtoMessageLTE(v *sbom.NodeList) predicate.NodeList { return predicate.NodeList(sql.FieldLTE(FieldProtoMessage, v)) } -// DocumentIDEQ applies the EQ predicate on the "document_id" field. -func DocumentIDEQ(v uuid.UUID) predicate.NodeList { - return predicate.NodeList(sql.FieldEQ(FieldDocumentID, v)) -} - -// DocumentIDNEQ applies the NEQ predicate on the "document_id" field. -func DocumentIDNEQ(v uuid.UUID) predicate.NodeList { - return predicate.NodeList(sql.FieldNEQ(FieldDocumentID, v)) -} - -// DocumentIDIn applies the In predicate on the "document_id" field. -func DocumentIDIn(vs ...uuid.UUID) predicate.NodeList { - return predicate.NodeList(sql.FieldIn(FieldDocumentID, vs...)) -} - -// DocumentIDNotIn applies the NotIn predicate on the "document_id" field. -func DocumentIDNotIn(vs ...uuid.UUID) predicate.NodeList { - return predicate.NodeList(sql.FieldNotIn(FieldDocumentID, vs...)) -} - -// HasEdgeTypes applies the HasEdge predicate on the "edge_types" edge. -func HasEdgeTypes() predicate.NodeList { +// HasDocument applies the HasEdge predicate on the "document" edge. +func HasDocument() predicate.NodeList { return predicate.NodeList(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.M2M, false, EdgeTypesTable, EdgeTypesPrimaryKey...), + sqlgraph.Edge(sqlgraph.O2O, false, DocumentTable, DocumentColumn), ) sqlgraph.HasNeighbors(s, step) }) } -// HasEdgeTypesWith applies the HasEdge predicate on the "edge_types" edge with a given conditions (other predicates). -func HasEdgeTypesWith(preds ...predicate.EdgeType) predicate.NodeList { +// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates). +func HasDocumentWith(preds ...predicate.Document) predicate.NodeList { return predicate.NodeList(func(s *sql.Selector) { - step := newEdgeTypesStep() + step := newDocumentStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { p(s) @@ -153,21 +128,21 @@ func HasEdgeTypesWith(preds ...predicate.EdgeType) predicate.NodeList { }) } -// HasNodes applies the HasEdge predicate on the "nodes" edge. -func HasNodes() predicate.NodeList { +// HasEdgeTypes applies the HasEdge predicate on the "edge_types" edge. +func HasEdgeTypes() predicate.NodeList { return predicate.NodeList(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.M2M, false, NodesTable, NodesPrimaryKey...), + sqlgraph.Edge(sqlgraph.M2M, false, EdgeTypesTable, EdgeTypesPrimaryKey...), ) sqlgraph.HasNeighbors(s, step) }) } -// HasNodesWith applies the HasEdge predicate on the "nodes" edge with a given conditions (other predicates). -func HasNodesWith(preds ...predicate.Node) predicate.NodeList { +// HasEdgeTypesWith applies the HasEdge predicate on the "edge_types" edge with a given conditions (other predicates). +func HasEdgeTypesWith(preds ...predicate.EdgeType) predicate.NodeList { return predicate.NodeList(func(s *sql.Selector) { - step := newNodesStep() + step := newEdgeTypesStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { p(s) @@ -176,21 +151,21 @@ func HasNodesWith(preds ...predicate.Node) predicate.NodeList { }) } -// HasDocument applies the HasEdge predicate on the "document" edge. -func HasDocument() predicate.NodeList { +// HasNodes applies the HasEdge predicate on the "nodes" edge. +func HasNodes() predicate.NodeList { return predicate.NodeList(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, DocumentTable, DocumentColumn), + sqlgraph.Edge(sqlgraph.M2M, false, NodesTable, NodesPrimaryKey...), ) sqlgraph.HasNeighbors(s, step) }) } -// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates). -func HasDocumentWith(preds ...predicate.Document) predicate.NodeList { +// HasNodesWith applies the HasEdge predicate on the "nodes" edge with a given conditions (other predicates). +func HasNodesWith(preds ...predicate.Node) predicate.NodeList { return predicate.NodeList(func(s *sql.Selector) { - step := newDocumentStep() + step := newNodesStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { p(s) diff --git a/internal/backends/ent/nodelist_create.go b/internal/backends/ent/nodelist_create.go index 5d05cde..5fedd2a 100644 --- a/internal/backends/ent/nodelist_create.go +++ b/internal/backends/ent/nodelist_create.go @@ -38,12 +38,6 @@ func (nlc *NodeListCreate) SetProtoMessage(sl *sbom.NodeList) *NodeListCreate { return nlc } -// SetDocumentID sets the "document_id" field. -func (nlc *NodeListCreate) SetDocumentID(u uuid.UUID) *NodeListCreate { - nlc.mutation.SetDocumentID(u) - return nlc -} - // SetRootElements sets the "root_elements" field. func (nlc *NodeListCreate) SetRootElements(s []string) *NodeListCreate { nlc.mutation.SetRootElements(s) @@ -64,6 +58,17 @@ func (nlc *NodeListCreate) SetNillableID(u *uuid.UUID) *NodeListCreate { return nlc } +// SetDocumentID sets the "document" edge to the Document entity by ID. +func (nlc *NodeListCreate) SetDocumentID(id uuid.UUID) *NodeListCreate { + nlc.mutation.SetDocumentID(id) + return nlc +} + +// SetDocument sets the "document" edge to the Document entity. +func (nlc *NodeListCreate) SetDocument(d *Document) *NodeListCreate { + return nlc.SetDocumentID(d.ID) +} + // AddEdgeTypeIDs adds the "edge_types" edge to the EdgeType entity by IDs. func (nlc *NodeListCreate) AddEdgeTypeIDs(ids ...uuid.UUID) *NodeListCreate { nlc.mutation.AddEdgeTypeIDs(ids...) @@ -94,11 +99,6 @@ func (nlc *NodeListCreate) AddNodes(n ...*Node) *NodeListCreate { return nlc.AddNodeIDs(ids...) } -// SetDocument sets the "document" edge to the Document entity. -func (nlc *NodeListCreate) SetDocument(d *Document) *NodeListCreate { - return nlc.SetDocumentID(d.ID) -} - // Mutation returns the NodeListMutation object of the builder. func (nlc *NodeListCreate) Mutation() *NodeListMutation { return nlc.mutation @@ -145,9 +145,6 @@ func (nlc *NodeListCreate) check() error { if _, ok := nlc.mutation.ProtoMessage(); !ok { return &ValidationError{Name: "proto_message", err: errors.New(`ent: missing required field "NodeList.proto_message"`)} } - if _, ok := nlc.mutation.DocumentID(); !ok { - return &ValidationError{Name: "document_id", err: errors.New(`ent: missing required field "NodeList.document_id"`)} - } if _, ok := nlc.mutation.RootElements(); !ok { return &ValidationError{Name: "root_elements", err: errors.New(`ent: missing required field "NodeList.root_elements"`)} } @@ -198,15 +195,15 @@ func (nlc *NodeListCreate) createSpec() (*NodeList, *sqlgraph.CreateSpec) { _spec.SetField(nodelist.FieldRootElements, field.TypeJSON, value) _node.RootElements = value } - if nodes := nlc.mutation.EdgeTypesIDs(); len(nodes) > 0 { + if nodes := nlc.mutation.DocumentIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2M, + Rel: sqlgraph.O2O, Inverse: false, - Table: nodelist.EdgeTypesTable, - Columns: nodelist.EdgeTypesPrimaryKey, + Table: nodelist.DocumentTable, + Columns: []string{nodelist.DocumentColumn}, Bidi: false, Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(edgetype.FieldID, field.TypeUUID), + IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), }, } for _, k := range nodes { @@ -214,15 +211,15 @@ func (nlc *NodeListCreate) createSpec() (*NodeList, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := nlc.mutation.NodesIDs(); len(nodes) > 0 { + if nodes := nlc.mutation.EdgeTypesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2M, Inverse: false, - Table: nodelist.NodesTable, - Columns: nodelist.NodesPrimaryKey, + Table: nodelist.EdgeTypesTable, + Columns: nodelist.EdgeTypesPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(node.FieldID, field.TypeUUID), + IDSpec: sqlgraph.NewFieldSpec(edgetype.FieldID, field.TypeUUID), }, } for _, k := range nodes { @@ -230,21 +227,20 @@ func (nlc *NodeListCreate) createSpec() (*NodeList, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } - if nodes := nlc.mutation.DocumentIDs(); len(nodes) > 0 { + if nodes := nlc.mutation.NodesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2O, - Inverse: true, - Table: nodelist.DocumentTable, - Columns: []string{nodelist.DocumentColumn}, + Rel: sqlgraph.M2M, + Inverse: false, + Table: nodelist.NodesTable, + Columns: nodelist.NodesPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID), + IDSpec: sqlgraph.NewFieldSpec(node.FieldID, field.TypeUUID), }, } for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } - _node.DocumentID = nodes[0] _spec.Edges = append(_spec.Edges, edge) } return _node, _spec @@ -331,9 +327,6 @@ func (u *NodeListUpsertOne) UpdateNewValues() *NodeListUpsertOne { if _, exists := u.create.mutation.ProtoMessage(); exists { s.SetIgnore(nodelist.FieldProtoMessage) } - if _, exists := u.create.mutation.DocumentID(); exists { - s.SetIgnore(nodelist.FieldDocumentID) - } })) return u } @@ -565,9 +558,6 @@ func (u *NodeListUpsertBulk) UpdateNewValues() *NodeListUpsertBulk { if _, exists := b.mutation.ProtoMessage(); exists { s.SetIgnore(nodelist.FieldProtoMessage) } - if _, exists := b.mutation.DocumentID(); exists { - s.SetIgnore(nodelist.FieldDocumentID) - } } })) return u diff --git a/internal/backends/ent/nodelist_query.go b/internal/backends/ent/nodelist_query.go index 31252cf..4153f29 100644 --- a/internal/backends/ent/nodelist_query.go +++ b/internal/backends/ent/nodelist_query.go @@ -32,9 +32,9 @@ type NodeListQuery struct { order []nodelist.OrderOption inters []Interceptor predicates []predicate.NodeList + withDocument *DocumentQuery withEdgeTypes *EdgeTypeQuery withNodes *NodeQuery - withDocument *DocumentQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -71,9 +71,9 @@ func (nlq *NodeListQuery) Order(o ...nodelist.OrderOption) *NodeListQuery { return nlq } -// QueryEdgeTypes chains the current query on the "edge_types" edge. -func (nlq *NodeListQuery) QueryEdgeTypes() *EdgeTypeQuery { - query := (&EdgeTypeClient{config: nlq.config}).Query() +// QueryDocument chains the current query on the "document" edge. +func (nlq *NodeListQuery) QueryDocument() *DocumentQuery { + query := (&DocumentClient{config: nlq.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := nlq.prepareQuery(ctx); err != nil { return nil, err @@ -84,8 +84,8 @@ func (nlq *NodeListQuery) QueryEdgeTypes() *EdgeTypeQuery { } step := sqlgraph.NewStep( sqlgraph.From(nodelist.Table, nodelist.FieldID, selector), - sqlgraph.To(edgetype.Table, edgetype.FieldID), - sqlgraph.Edge(sqlgraph.M2M, false, nodelist.EdgeTypesTable, nodelist.EdgeTypesPrimaryKey...), + sqlgraph.To(document.Table, document.FieldID), + sqlgraph.Edge(sqlgraph.O2O, false, nodelist.DocumentTable, nodelist.DocumentColumn), ) fromU = sqlgraph.SetNeighbors(nlq.driver.Dialect(), step) return fromU, nil @@ -93,9 +93,9 @@ func (nlq *NodeListQuery) QueryEdgeTypes() *EdgeTypeQuery { return query } -// QueryNodes chains the current query on the "nodes" edge. -func (nlq *NodeListQuery) QueryNodes() *NodeQuery { - query := (&NodeClient{config: nlq.config}).Query() +// QueryEdgeTypes chains the current query on the "edge_types" edge. +func (nlq *NodeListQuery) QueryEdgeTypes() *EdgeTypeQuery { + query := (&EdgeTypeClient{config: nlq.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := nlq.prepareQuery(ctx); err != nil { return nil, err @@ -106,8 +106,8 @@ func (nlq *NodeListQuery) QueryNodes() *NodeQuery { } step := sqlgraph.NewStep( sqlgraph.From(nodelist.Table, nodelist.FieldID, selector), - sqlgraph.To(node.Table, node.FieldID), - sqlgraph.Edge(sqlgraph.M2M, false, nodelist.NodesTable, nodelist.NodesPrimaryKey...), + sqlgraph.To(edgetype.Table, edgetype.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, nodelist.EdgeTypesTable, nodelist.EdgeTypesPrimaryKey...), ) fromU = sqlgraph.SetNeighbors(nlq.driver.Dialect(), step) return fromU, nil @@ -115,9 +115,9 @@ func (nlq *NodeListQuery) QueryNodes() *NodeQuery { return query } -// QueryDocument chains the current query on the "document" edge. -func (nlq *NodeListQuery) QueryDocument() *DocumentQuery { - query := (&DocumentClient{config: nlq.config}).Query() +// QueryNodes chains the current query on the "nodes" edge. +func (nlq *NodeListQuery) QueryNodes() *NodeQuery { + query := (&NodeClient{config: nlq.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := nlq.prepareQuery(ctx); err != nil { return nil, err @@ -128,8 +128,8 @@ func (nlq *NodeListQuery) QueryDocument() *DocumentQuery { } step := sqlgraph.NewStep( sqlgraph.From(nodelist.Table, nodelist.FieldID, selector), - sqlgraph.To(document.Table, document.FieldID), - sqlgraph.Edge(sqlgraph.O2O, true, nodelist.DocumentTable, nodelist.DocumentColumn), + sqlgraph.To(node.Table, node.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, nodelist.NodesTable, nodelist.NodesPrimaryKey...), ) fromU = sqlgraph.SetNeighbors(nlq.driver.Dialect(), step) return fromU, nil @@ -329,15 +329,26 @@ func (nlq *NodeListQuery) Clone() *NodeListQuery { order: append([]nodelist.OrderOption{}, nlq.order...), inters: append([]Interceptor{}, nlq.inters...), predicates: append([]predicate.NodeList{}, nlq.predicates...), + withDocument: nlq.withDocument.Clone(), withEdgeTypes: nlq.withEdgeTypes.Clone(), withNodes: nlq.withNodes.Clone(), - withDocument: nlq.withDocument.Clone(), // clone intermediate query. sql: nlq.sql.Clone(), path: nlq.path, } } +// WithDocument tells the query-builder to eager-load the nodes that are connected to +// the "document" edge. The optional arguments are used to configure the query builder of the edge. +func (nlq *NodeListQuery) WithDocument(opts ...func(*DocumentQuery)) *NodeListQuery { + query := (&DocumentClient{config: nlq.config}).Query() + for _, opt := range opts { + opt(query) + } + nlq.withDocument = query + return nlq +} + // WithEdgeTypes tells the query-builder to eager-load the nodes that are connected to // the "edge_types" edge. The optional arguments are used to configure the query builder of the edge. func (nlq *NodeListQuery) WithEdgeTypes(opts ...func(*EdgeTypeQuery)) *NodeListQuery { @@ -360,17 +371,6 @@ func (nlq *NodeListQuery) WithNodes(opts ...func(*NodeQuery)) *NodeListQuery { return nlq } -// WithDocument tells the query-builder to eager-load the nodes that are connected to -// the "document" edge. The optional arguments are used to configure the query builder of the edge. -func (nlq *NodeListQuery) WithDocument(opts ...func(*DocumentQuery)) *NodeListQuery { - query := (&DocumentClient{config: nlq.config}).Query() - for _, opt := range opts { - opt(query) - } - nlq.withDocument = query - return nlq -} - // GroupBy is used to group vertices by one or more fields/columns. // It is often used with aggregate functions, like: count, max, mean, min, sum. // @@ -450,9 +450,9 @@ func (nlq *NodeListQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*No nodes = []*NodeList{} _spec = nlq.querySpec() loadedTypes = [3]bool{ + nlq.withDocument != nil, nlq.withEdgeTypes != nil, nlq.withNodes != nil, - nlq.withDocument != nil, } ) _spec.ScanValues = func(columns []string) ([]any, error) { @@ -473,6 +473,12 @@ func (nlq *NodeListQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*No if len(nodes) == 0 { return nodes, nil } + if query := nlq.withDocument; query != nil { + if err := nlq.loadDocument(ctx, query, nodes, nil, + func(n *NodeList, e *Document) { n.Edges.Document = e }); err != nil { + return nil, err + } + } if query := nlq.withEdgeTypes; query != nil { if err := nlq.loadEdgeTypes(ctx, query, nodes, func(n *NodeList) { n.Edges.EdgeTypes = []*EdgeType{} }, @@ -487,15 +493,36 @@ func (nlq *NodeListQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*No return nil, err } } - if query := nlq.withDocument; query != nil { - if err := nlq.loadDocument(ctx, query, nodes, nil, - func(n *NodeList, e *Document) { n.Edges.Document = e }); err != nil { - return nil, err - } - } return nodes, nil } +func (nlq *NodeListQuery) loadDocument(ctx context.Context, query *DocumentQuery, nodes []*NodeList, init func(*NodeList), assign func(*NodeList, *Document)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[uuid.UUID]*NodeList) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(document.FieldNodeListID) + } + query.Where(predicate.Document(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(nodelist.DocumentColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.NodeListID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "node_list_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} func (nlq *NodeListQuery) loadEdgeTypes(ctx context.Context, query *EdgeTypeQuery, nodes []*NodeList, init func(*NodeList), assign func(*NodeList, *EdgeType)) error { edgeIDs := make([]driver.Value, len(nodes)) byID := make(map[uuid.UUID]*NodeList) @@ -618,35 +645,6 @@ func (nlq *NodeListQuery) loadNodes(ctx context.Context, query *NodeQuery, nodes } return nil } -func (nlq *NodeListQuery) loadDocument(ctx context.Context, query *DocumentQuery, nodes []*NodeList, init func(*NodeList), assign func(*NodeList, *Document)) error { - ids := make([]uuid.UUID, 0, len(nodes)) - nodeids := make(map[uuid.UUID][]*NodeList) - for i := range nodes { - fk := nodes[i].DocumentID - if _, ok := nodeids[fk]; !ok { - ids = append(ids, fk) - } - nodeids[fk] = append(nodeids[fk], nodes[i]) - } - if len(ids) == 0 { - return nil - } - query.Where(document.IDIn(ids...)) - neighbors, err := query.All(ctx) - if err != nil { - return err - } - for _, n := range neighbors { - nodes, ok := nodeids[n.ID] - if !ok { - return fmt.Errorf(`unexpected foreign-key "document_id" returned %v`, n.ID) - } - for i := range nodes { - assign(nodes[i], n) - } - } - return nil -} func (nlq *NodeListQuery) sqlCount(ctx context.Context) (int, error) { _spec := nlq.querySpec() @@ -673,9 +671,6 @@ func (nlq *NodeListQuery) querySpec() *sqlgraph.QuerySpec { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } - if nlq.withDocument != nil { - _spec.Node.AddColumnOnce(nodelist.FieldDocumentID) - } } if ps := nlq.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { diff --git a/internal/backends/ent/runtime.go b/internal/backends/ent/runtime.go index 381c30e..5f0f101 100644 --- a/internal/backends/ent/runtime.go +++ b/internal/backends/ent/runtime.go @@ -31,17 +31,10 @@ import ( // (default values, validators, hooks and policies) and stitches it // to their package variables. func init() { - annotationMixin := schema.Annotation{}.Mixin() - annotationMixinFields0 := annotationMixin[0].Fields() - _ = annotationMixinFields0 annotationFields := schema.Annotation{}.Fields() _ = annotationFields - // annotationDescDocumentID is the schema descriptor for document_id field. - annotationDescDocumentID := annotationMixinFields0[0].Descriptor() - // annotation.DefaultDocumentID holds the default value on creation for the document_id field. - annotation.DefaultDocumentID = annotationDescDocumentID.Default.(func() uuid.UUID) // annotationDescIsUnique is the schema descriptor for is_unique field. - annotationDescIsUnique := annotationFields[3].Descriptor() + annotationDescIsUnique := annotationFields[4].Descriptor() // annotation.DefaultIsUnique holds the default value on creation for the is_unique field. annotation.DefaultIsUnique = annotationDescIsUnique.Default.(bool) documentMixin := schema.Document{}.Mixin() @@ -134,7 +127,7 @@ func init() { metadataFields := schema.Metadata{}.Fields() _ = metadataFields // metadataDescNativeID is the schema descriptor for native_id field. - metadataDescNativeID := metadataFields[1].Descriptor() + metadataDescNativeID := metadataFields[0].Descriptor() // metadata.NativeIDValidator is a validator for the "native_id" field. It is called by the builders before save. metadata.NativeIDValidator = metadataDescNativeID.Validators[0].(func(string) error) // metadataDescID is the schema descriptor for id field. diff --git a/internal/backends/ent/schema/annotation.go b/internal/backends/ent/schema/annotation.go index 47e7a88..26114b4 100644 --- a/internal/backends/ent/schema/annotation.go +++ b/internal/backends/ent/schema/annotation.go @@ -19,15 +19,14 @@ type Annotation struct { ent.Schema } -func (Annotation) Mixin() []ent.Mixin { - return []ent.Mixin{ - DocumentMixin{}, - } -} - func (Annotation) Fields() []ent.Field { return []ent.Field{ - field.UUID("node_id", uuid.UUID{}).Optional().Nillable(), + field.UUID("document_id", uuid.UUID{}). + Optional(). + Nillable(), + field.UUID("node_id", uuid.UUID{}). + Optional(). + Nillable(), field.String("name"), field.String("value"), field.Bool("is_unique").Default(false), @@ -36,6 +35,10 @@ func (Annotation) Fields() []ent.Field { func (Annotation) Edges() []ent.Edge { return []ent.Edge{ + edge.From("document", Document.Type). + Ref("annotations"). + Unique(). + Field("document_id"), edge.From("node", Node.Type). Ref("annotations"). Unique(). @@ -45,6 +48,10 @@ func (Annotation) Edges() []ent.Edge { func (Annotation) Indexes() []ent.Index { return []ent.Index{ + index.Fields("node_id"). + StorageKey("idx_annotations_node_id"), + index.Fields("document_id"). + StorageKey("idx_annotations_document_id"), index.Fields("node_id", "name", "value"). Unique(). Annotations(entsql.IndexWhere("node_id IS NOT NULL AND TRIM(node_id) != ''")). diff --git a/internal/backends/ent/schema/document.go b/internal/backends/ent/schema/document.go index 61f0f79..2d7b771 100644 --- a/internal/backends/ent/schema/document.go +++ b/internal/backends/ent/schema/document.go @@ -8,7 +8,10 @@ package schema import ( "entgo.io/ent" + "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "github.com/google/uuid" ) type Document struct { @@ -21,13 +24,36 @@ func (Document) Mixin() []ent.Mixin { } } +func (Document) Fields() []ent.Field { + return []ent.Field{ + field.UUID("metadata_id", uuid.UUID{}). + Unique(). + Immutable(). + Optional(), + field.UUID("node_list_id", uuid.UUID{}). + Unique(). + Immutable(). + Optional(), + } +} + func (Document) Edges() []ent.Edge { + const edgeRef = "document" + return []ent.Edge{ - edge.To("metadata", Metadata.Type). + edge.To("annotations", Annotation.Type). + Annotations(entsql.OnDelete(entsql.Cascade)), + edge.From("metadata", Metadata.Type). + Ref(edgeRef). Unique(). - Immutable(), - edge.To("node_list", NodeList.Type). + Immutable(). + Annotations(entsql.OnDelete(entsql.Cascade)). + Field("metadata_id"), + edge.From("node_list", NodeList.Type). + Ref(edgeRef). Unique(). - Immutable(), + Immutable(). + Annotations(entsql.OnDelete(entsql.Cascade)). + Field("node_list_id"), } } diff --git a/internal/backends/ent/schema/metadata.go b/internal/backends/ent/schema/metadata.go index 1db85ce..87b4dc3 100644 --- a/internal/backends/ent/schema/metadata.go +++ b/internal/backends/ent/schema/metadata.go @@ -12,7 +12,6 @@ import ( "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" - "github.com/google/uuid" "github.com/protobom/protobom/pkg/sbom" ) @@ -29,7 +28,6 @@ func (Metadata) Mixin() []ent.Mixin { func (Metadata) Fields() []ent.Field { return []ent.Field{ - field.UUID("document_id", uuid.UUID{}).Unique().Immutable(), field.String("native_id").NotEmpty().Immutable(), field.String("version"), field.String("name"), @@ -40,6 +38,10 @@ func (Metadata) Fields() []ent.Field { func (Metadata) Edges() []ent.Edge { return []ent.Edge{ + edge.To("document", Document.Type). + Required(). + Unique(). + Immutable(), edge.To("tools", Tool.Type). Annotations(entsql.OnDelete(entsql.Cascade)), edge.To("authors", Person.Type). @@ -48,13 +50,6 @@ func (Metadata) Edges() []ent.Edge { Annotations(entsql.OnDelete(entsql.Cascade)), edge.To("source_data", SourceData.Type). Annotations(entsql.OnDelete(entsql.Cascade)), - edge.From("document", Document.Type). - Ref("metadata"). - Required(). - Unique(). - Immutable(). - Annotations(entsql.OnDelete(entsql.Cascade)). - Field("document_id"), } } diff --git a/internal/backends/ent/schema/node_list.go b/internal/backends/ent/schema/node_list.go index 6f9df59..5bb81c9 100644 --- a/internal/backends/ent/schema/node_list.go +++ b/internal/backends/ent/schema/node_list.go @@ -11,7 +11,6 @@ import ( "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "github.com/google/uuid" "github.com/protobom/protobom/pkg/sbom" ) @@ -28,25 +27,21 @@ func (NodeList) Mixin() []ent.Mixin { func (NodeList) Fields() []ent.Field { return []ent.Field{ - field.UUID("document_id", uuid.UUID{}).Unique().Immutable(), field.Strings("root_elements"), } } func (NodeList) Edges() []ent.Edge { return []ent.Edge{ + edge.To("document", Document.Type). + Required(). + Unique(). + Immutable(), edge.To("edge_types", EdgeType.Type). StorageKey(edge.Table("node_list_edges"), edge.Columns("node_list_id", "edge_type_id")). Annotations(entsql.OnDelete(entsql.Cascade)), edge.To("nodes", Node.Type). StorageKey(edge.Table("node_list_nodes"), edge.Columns("node_list_id", "node_id")). Annotations(entsql.OnDelete(entsql.Cascade)), - edge.From("document", Document.Type). - Ref("node_list"). - Required(). - Unique(). - Immutable(). - Annotations(entsql.OnDelete(entsql.Cascade)). - Field("document_id"), } }