From 3b0a64a83055d8360561a13fa917af6c111d9cbb Mon Sep 17 00:00:00 2001 From: Kairo Araujo Date: Wed, 8 May 2024 17:37:59 +0200 Subject: [PATCH 1/2] feat: add metadata schema Signed-off-by: Kairo Araujo --- ent/schema/dsse.go | 1 + ent/schema/metadata.go | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 ent/schema/metadata.go diff --git a/ent/schema/dsse.go b/ent/schema/dsse.go index 71ed038a..7035ad86 100644 --- a/ent/schema/dsse.go +++ b/ent/schema/dsse.go @@ -41,6 +41,7 @@ func (Dsse) Edges() []ent.Edge { edge.To("statement", Statement.Type).Unique(), edge.To("signatures", Signature.Type), edge.To("payload_digests", PayloadDigest.Type), + edge.To("metadata", Metadata.Type), } } diff --git a/ent/schema/metadata.go b/ent/schema/metadata.go new file mode 100644 index 00000000..a5009b02 --- /dev/null +++ b/ent/schema/metadata.go @@ -0,0 +1,46 @@ +// Copyright 2022 The Archivista Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" + "entgo.io/ent/schema/index" +) + +type Metadata struct { + ent.Schema +} + +func (Metadata) Fields() []ent.Field { + return []ent.Field{ + field.String("key").NotEmpty().Comment("Key value for the metadata item"), + field.String("value").NotEmpty().Comment("Value for the metadata item"), + } +} + +func (Metadata) Indexes() []ent.Index { + return []ent.Index{ + index.Fields("key", "value").Unique(), + } +} + +func (Metadata) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("envelope", Dsse.Type). + Ref("metadata"), + } +} From 938a66fd52da47d35a15ce96e385453a50c3c66f Mon Sep 17 00:00:00 2001 From: Kairo Araujo Date: Wed, 8 May 2024 17:54:27 +0200 Subject: [PATCH 2/2] chore: ent generate + db migrations Signed-off-by: Kairo Araujo --- ent.graphql | 79 +- ent/client.go | 187 +++- ent/dsse.go | 45 +- ent/dsse/dsse.go | 34 + ent/dsse/where.go | 23 + ent/dsse_create.go | 32 + ent/dsse_query.go | 129 ++- ent/dsse_update.go | 163 ++++ ent/ent.go | 2 + ent/gql_collection.go | 244 +++-- ent/gql_edge.go | 24 + ent/gql_node.go | 219 +++-- ent/gql_pagination.go | 340 ++++++- ent/gql_where_input.go | 277 ++++++ ent/hook/hook.go | 12 + ent/metadata.go | 168 ++++ ent/metadata/metadata.go | 97 ++ ent/metadata/where.go | 232 +++++ ent/metadata_create.go | 238 +++++ ent/metadata_delete.go | 88 ++ ent/metadata_query.go | 671 ++++++++++++++ ent/metadata_update.go | 442 +++++++++ .../migrations/mysql/20240508160053_mysql.sql | 4 + ent/migrate/migrations/mysql/atlas.sum | 3 +- .../migrations/pgsql/20240508160101_pgsql.sql | 6 + ent/migrate/migrations/pgsql/atlas.sum | 3 +- ent/migrate/schema.go | 48 + ent/mutation.go | 564 +++++++++++- ent/predicate/predicate.go | 3 + ent/runtime.go | 11 + ent/schema/metadata.go | 2 +- ent/tx.go | 3 + generated.go | 851 +++++++++++++++++- 33 files changed, 5005 insertions(+), 239 deletions(-) create mode 100644 ent/metadata.go create mode 100644 ent/metadata/metadata.go create mode 100644 ent/metadata/where.go create mode 100644 ent/metadata_create.go create mode 100644 ent/metadata_delete.go create mode 100644 ent/metadata_query.go create mode 100644 ent/metadata_update.go create mode 100644 ent/migrate/migrations/mysql/20240508160053_mysql.sql create mode 100644 ent/migrate/migrations/pgsql/20240508160101_pgsql.sql diff --git a/ent.graphql b/ent.graphql index bc06dfc8..285f6d06 100644 --- a/ent.graphql +++ b/ent.graphql @@ -1,5 +1,5 @@ -directive @goField(forceResolver: Boolean, name: String) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION -directive @goModel(model: String, models: [String!]) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION +directive @goField(forceResolver: Boolean, name: String, omittable: Boolean) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @goModel(model: String, models: [String!], forceGenerate: Boolean) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION type Attestation implements Node { id: ID! type: String! @@ -186,6 +186,7 @@ type Dsse implements Node { statement: Statement signatures: [Signature!] payloadDigests: [PayloadDigest!] + metadata: [Metadata!] } """ A connection to a list of items. @@ -283,6 +284,80 @@ input DsseWhereInput { """ hasPayloadDigests: Boolean hasPayloadDigestsWith: [PayloadDigestWhereInput!] + """ + metadata edge predicates + """ + hasMetadata: Boolean + hasMetadataWith: [MetadataWhereInput!] +} +type Metadata implements Node { + id: ID! + """ + Key value for the metadata item + """ + key: String! + """ + Value for the metadata item + """ + value: String! + envelope: [Dsse!] +} +""" +MetadataWhereInput is used for filtering Metadata objects. +Input was generated by ent. +""" +input MetadataWhereInput { + not: MetadataWhereInput + and: [MetadataWhereInput!] + or: [MetadataWhereInput!] + """ + id field predicates + """ + id: ID + idNEQ: ID + idIn: [ID!] + idNotIn: [ID!] + idGT: ID + idGTE: ID + idLT: ID + idLTE: ID + """ + key field predicates + """ + key: String + keyNEQ: String + keyIn: [String!] + keyNotIn: [String!] + keyGT: String + keyGTE: String + keyLT: String + keyLTE: String + keyContains: String + keyHasPrefix: String + keyHasSuffix: String + keyEqualFold: String + keyContainsFold: String + """ + value field predicates + """ + value: String + valueNEQ: String + valueIn: [String!] + valueNotIn: [String!] + valueGT: String + valueGTE: String + valueLT: String + valueLTE: String + valueContains: String + valueHasPrefix: String + valueHasSuffix: String + valueEqualFold: String + valueContainsFold: String + """ + envelope edge predicates + """ + hasEnvelope: Boolean + hasEnvelopeWith: [DsseWhereInput!] } """ An object with an ID. diff --git a/ent/client.go b/ent/client.go index 81c42fdf..e1ce08c5 100644 --- a/ent/client.go +++ b/ent/client.go @@ -19,6 +19,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/signature" "github.com/in-toto/archivista/ent/statement" @@ -40,6 +41,8 @@ type Client struct { AttestationPolicy *AttestationPolicyClient // Dsse is the client for interacting with the Dsse builders. Dsse *DsseClient + // Metadata is the client for interacting with the Metadata builders. + Metadata *MetadataClient // PayloadDigest is the client for interacting with the PayloadDigest builders. PayloadDigest *PayloadDigestClient // Signature is the client for interacting with the Signature builders. @@ -69,6 +72,7 @@ func (c *Client) init() { c.AttestationCollection = NewAttestationCollectionClient(c.config) c.AttestationPolicy = NewAttestationPolicyClient(c.config) c.Dsse = NewDsseClient(c.config) + c.Metadata = NewMetadataClient(c.config) c.PayloadDigest = NewPayloadDigestClient(c.config) c.Signature = NewSignatureClient(c.config) c.Statement = NewStatementClient(c.config) @@ -171,6 +175,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { AttestationCollection: NewAttestationCollectionClient(cfg), AttestationPolicy: NewAttestationPolicyClient(cfg), Dsse: NewDsseClient(cfg), + Metadata: NewMetadataClient(cfg), PayloadDigest: NewPayloadDigestClient(cfg), Signature: NewSignatureClient(cfg), Statement: NewStatementClient(cfg), @@ -200,6 +205,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) AttestationCollection: NewAttestationCollectionClient(cfg), AttestationPolicy: NewAttestationPolicyClient(cfg), Dsse: NewDsseClient(cfg), + Metadata: NewMetadataClient(cfg), PayloadDigest: NewPayloadDigestClient(cfg), Signature: NewSignatureClient(cfg), Statement: NewStatementClient(cfg), @@ -235,7 +241,7 @@ func (c *Client) Close() error { // In order to add hooks to a specific client, call: `client.Node.Use(...)`. func (c *Client) Use(hooks ...Hook) { for _, n := range []interface{ Use(...Hook) }{ - c.Attestation, c.AttestationCollection, c.AttestationPolicy, c.Dsse, + c.Attestation, c.AttestationCollection, c.AttestationPolicy, c.Dsse, c.Metadata, c.PayloadDigest, c.Signature, c.Statement, c.Subject, c.SubjectDigest, c.Timestamp, } { @@ -247,7 +253,7 @@ func (c *Client) Use(hooks ...Hook) { // In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. func (c *Client) Intercept(interceptors ...Interceptor) { for _, n := range []interface{ Intercept(...Interceptor) }{ - c.Attestation, c.AttestationCollection, c.AttestationPolicy, c.Dsse, + c.Attestation, c.AttestationCollection, c.AttestationPolicy, c.Dsse, c.Metadata, c.PayloadDigest, c.Signature, c.Statement, c.Subject, c.SubjectDigest, c.Timestamp, } { @@ -266,6 +272,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { return c.AttestationPolicy.mutate(ctx, m) case *DsseMutation: return c.Dsse.mutate(ctx, m) + case *MetadataMutation: + return c.Metadata.mutate(ctx, m) case *PayloadDigestMutation: return c.PayloadDigest.mutate(ctx, m) case *SignatureMutation: @@ -902,6 +910,22 @@ func (c *DsseClient) QueryPayloadDigests(d *Dsse) *PayloadDigestQuery { return query } +// QueryMetadata queries the metadata edge of a Dsse. +func (c *DsseClient) QueryMetadata(d *Dsse) *MetadataQuery { + query := (&MetadataClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := d.ID + step := sqlgraph.NewStep( + sqlgraph.From(dsse.Table, dsse.FieldID, id), + sqlgraph.To(metadata.Table, metadata.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, dsse.MetadataTable, dsse.MetadataPrimaryKey...), + ) + fromV = sqlgraph.Neighbors(d.driver.Dialect(), step) + return fromV, nil + } + return query +} + // Hooks returns the client hooks. func (c *DsseClient) Hooks() []Hook { return c.hooks.Dsse @@ -927,6 +951,155 @@ func (c *DsseClient) mutate(ctx context.Context, m *DsseMutation) (Value, error) } } +// MetadataClient is a client for the Metadata schema. +type MetadataClient struct { + config +} + +// NewMetadataClient returns a client for the Metadata from the given config. +func NewMetadataClient(c config) *MetadataClient { + return &MetadataClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `metadata.Hooks(f(g(h())))`. +func (c *MetadataClient) Use(hooks ...Hook) { + c.hooks.Metadata = append(c.hooks.Metadata, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `metadata.Intercept(f(g(h())))`. +func (c *MetadataClient) Intercept(interceptors ...Interceptor) { + c.inters.Metadata = append(c.inters.Metadata, interceptors...) +} + +// Create returns a builder for creating a Metadata entity. +func (c *MetadataClient) Create() *MetadataCreate { + mutation := newMetadataMutation(c.config, OpCreate) + return &MetadataCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Metadata entities. +func (c *MetadataClient) CreateBulk(builders ...*MetadataCreate) *MetadataCreateBulk { + return &MetadataCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *MetadataClient) MapCreateBulk(slice any, setFunc func(*MetadataCreate, int)) *MetadataCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &MetadataCreateBulk{err: fmt.Errorf("calling to MetadataClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*MetadataCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &MetadataCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Metadata. +func (c *MetadataClient) Update() *MetadataUpdate { + mutation := newMetadataMutation(c.config, OpUpdate) + return &MetadataUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *MetadataClient) UpdateOne(m *Metadata) *MetadataUpdateOne { + mutation := newMetadataMutation(c.config, OpUpdateOne, withMetadata(m)) + return &MetadataUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *MetadataClient) UpdateOneID(id int) *MetadataUpdateOne { + mutation := newMetadataMutation(c.config, OpUpdateOne, withMetadataID(id)) + return &MetadataUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Metadata. +func (c *MetadataClient) Delete() *MetadataDelete { + mutation := newMetadataMutation(c.config, OpDelete) + return &MetadataDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *MetadataClient) DeleteOne(m *Metadata) *MetadataDeleteOne { + return c.DeleteOneID(m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *MetadataClient) DeleteOneID(id int) *MetadataDeleteOne { + builder := c.Delete().Where(metadata.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &MetadataDeleteOne{builder} +} + +// Query returns a query builder for Metadata. +func (c *MetadataClient) Query() *MetadataQuery { + return &MetadataQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeMetadata}, + inters: c.Interceptors(), + } +} + +// Get returns a Metadata entity by its id. +func (c *MetadataClient) Get(ctx context.Context, id int) (*Metadata, error) { + return c.Query().Where(metadata.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *MetadataClient) GetX(ctx context.Context, id int) *Metadata { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryEnvelope queries the envelope edge of a Metadata. +func (c *MetadataClient) QueryEnvelope(m *Metadata) *DsseQuery { + query := (&DsseClient{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(dsse.Table, dsse.FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, metadata.EnvelopeTable, metadata.EnvelopePrimaryKey...), + ) + 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 +} + +// Interceptors returns the client interceptors. +func (c *MetadataClient) Interceptors() []Interceptor { + return c.inters.Metadata +} + +func (c *MetadataClient) mutate(ctx context.Context, m *MetadataMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&MetadataCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&MetadataUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&MetadataUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&MetadataDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown Metadata mutation op: %q", m.Op()) + } +} + // PayloadDigestClient is a client for the PayloadDigest schema. type PayloadDigestClient struct { config @@ -1904,11 +2077,13 @@ func (c *TimestampClient) mutate(ctx context.Context, m *TimestampMutation) (Val // hooks and interceptors per client, for fast access. type ( hooks struct { - Attestation, AttestationCollection, AttestationPolicy, Dsse, PayloadDigest, - Signature, Statement, Subject, SubjectDigest, Timestamp []ent.Hook + Attestation, AttestationCollection, AttestationPolicy, Dsse, Metadata, + PayloadDigest, Signature, Statement, Subject, SubjectDigest, + Timestamp []ent.Hook } inters struct { - Attestation, AttestationCollection, AttestationPolicy, Dsse, PayloadDigest, - Signature, Statement, Subject, SubjectDigest, Timestamp []ent.Interceptor + Attestation, AttestationCollection, AttestationPolicy, Dsse, Metadata, + PayloadDigest, Signature, Statement, Subject, SubjectDigest, + Timestamp []ent.Interceptor } ) diff --git a/ent/dsse.go b/ent/dsse.go index 402e71fe..07f05afd 100644 --- a/ent/dsse.go +++ b/ent/dsse.go @@ -36,14 +36,17 @@ type DsseEdges struct { Signatures []*Signature `json:"signatures,omitempty"` // PayloadDigests holds the value of the payload_digests edge. PayloadDigests []*PayloadDigest `json:"payload_digests,omitempty"` + // Metadata holds the value of the metadata edge. + Metadata []*Metadata `json:"metadata,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [3]bool + loadedTypes [4]bool // totalCount holds the count of the edges above. - totalCount [3]map[string]int + totalCount [4]map[string]int namedSignatures map[string][]*Signature namedPayloadDigests map[string][]*PayloadDigest + namedMetadata map[string][]*Metadata } // StatementOrErr returns the Statement value or an error if the edge @@ -75,6 +78,15 @@ func (e DsseEdges) PayloadDigestsOrErr() ([]*PayloadDigest, error) { return nil, &NotLoadedError{edge: "payload_digests"} } +// MetadataOrErr returns the Metadata value or an error if the edge +// was not loaded in eager-loading. +func (e DsseEdges) MetadataOrErr() ([]*Metadata, error) { + if e.loadedTypes[3] { + return e.Metadata, nil + } + return nil, &NotLoadedError{edge: "metadata"} +} + // scanValues returns the types for scanning values from sql.Rows. func (*Dsse) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) @@ -154,6 +166,11 @@ func (d *Dsse) QueryPayloadDigests() *PayloadDigestQuery { return NewDsseClient(d.config).QueryPayloadDigests(d) } +// QueryMetadata queries the "metadata" edge of the Dsse entity. +func (d *Dsse) QueryMetadata() *MetadataQuery { + return NewDsseClient(d.config).QueryMetadata(d) +} + // Update returns a builder for updating this Dsse. // Note that you need to call Dsse.Unwrap() before calling this method if this Dsse // was returned from a transaction, and the transaction was committed or rolled back. @@ -234,5 +251,29 @@ func (d *Dsse) appendNamedPayloadDigests(name string, edges ...*PayloadDigest) { } } +// NamedMetadata returns the Metadata named value or an error if the edge was not +// loaded in eager-loading with this name. +func (d *Dsse) NamedMetadata(name string) ([]*Metadata, error) { + if d.Edges.namedMetadata == nil { + return nil, &NotLoadedError{edge: name} + } + nodes, ok := d.Edges.namedMetadata[name] + if !ok { + return nil, &NotLoadedError{edge: name} + } + return nodes, nil +} + +func (d *Dsse) appendNamedMetadata(name string, edges ...*Metadata) { + if d.Edges.namedMetadata == nil { + d.Edges.namedMetadata = make(map[string][]*Metadata) + } + if len(edges) == 0 { + d.Edges.namedMetadata[name] = []*Metadata{} + } else { + d.Edges.namedMetadata[name] = append(d.Edges.namedMetadata[name], edges...) + } +} + // Dsses is a parsable slice of Dsse. type Dsses []*Dsse diff --git a/ent/dsse/dsse.go b/ent/dsse/dsse.go index 41c063ce..a09745dd 100644 --- a/ent/dsse/dsse.go +++ b/ent/dsse/dsse.go @@ -22,6 +22,8 @@ const ( EdgeSignatures = "signatures" // EdgePayloadDigests holds the string denoting the payload_digests edge name in mutations. EdgePayloadDigests = "payload_digests" + // EdgeMetadata holds the string denoting the metadata edge name in mutations. + EdgeMetadata = "metadata" // Table holds the table name of the dsse in the database. Table = "dsses" // StatementTable is the table that holds the statement relation/edge. @@ -45,6 +47,11 @@ const ( PayloadDigestsInverseTable = "payload_digests" // PayloadDigestsColumn is the table column denoting the payload_digests relation/edge. PayloadDigestsColumn = "dsse_payload_digests" + // MetadataTable is the table that holds the metadata relation/edge. The primary key declared below. + MetadataTable = "dsse_metadata" + // 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" ) // Columns holds all SQL columns for dsse fields. @@ -60,6 +67,12 @@ var ForeignKeys = []string{ "dsse_statement", } +var ( + // MetadataPrimaryKey and MetadataColumn2 are the table columns denoting the + // primary key for the metadata relation (M2M). + MetadataPrimaryKey = []string{"dsse_id", "metadata_id"} +) + // ValidColumn reports if the column name is valid (part of the table columns). func ValidColumn(column string) bool { for i := range Columns { @@ -134,6 +147,20 @@ func ByPayloadDigests(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { sqlgraph.OrderByNeighborTerms(s, newPayloadDigestsStep(), append([]sql.OrderTerm{term}, terms...)...) } } + +// ByMetadataCount orders the results by metadata count. +func ByMetadataCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newMetadataStep(), opts...) + } +} + +// ByMetadata orders the results by metadata terms. +func ByMetadata(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newMetadataStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} func newStatementStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), @@ -155,3 +182,10 @@ func newPayloadDigestsStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.O2M, false, PayloadDigestsTable, PayloadDigestsColumn), ) } +func newMetadataStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(MetadataInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, MetadataTable, MetadataPrimaryKey...), + ) +} diff --git a/ent/dsse/where.go b/ent/dsse/where.go index 20f207ab..e6b0a136 100644 --- a/ent/dsse/where.go +++ b/ent/dsse/where.go @@ -262,6 +262,29 @@ func HasPayloadDigestsWith(preds ...predicate.PayloadDigest) predicate.Dsse { }) } +// HasMetadata applies the HasEdge predicate on the "metadata" edge. +func HasMetadata() predicate.Dsse { + return predicate.Dsse(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, MetadataTable, MetadataPrimaryKey...), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasMetadataWith applies the HasEdge predicate on the "metadata" edge with a given conditions (other predicates). +func HasMetadataWith(preds ...predicate.Metadata) predicate.Dsse { + return predicate.Dsse(func(s *sql.Selector) { + step := newMetadataStep() + 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.Dsse) predicate.Dsse { return predicate.Dsse(sql.AndPredicates(predicates...)) diff --git a/ent/dsse_create.go b/ent/dsse_create.go index dbd38fe3..ba350410 100644 --- a/ent/dsse_create.go +++ b/ent/dsse_create.go @@ -10,6 +10,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/signature" "github.com/in-toto/archivista/ent/statement" @@ -83,6 +84,21 @@ func (dc *DsseCreate) AddPayloadDigests(p ...*PayloadDigest) *DsseCreate { return dc.AddPayloadDigestIDs(ids...) } +// AddMetadatumIDs adds the "metadata" edge to the Metadata entity by IDs. +func (dc *DsseCreate) AddMetadatumIDs(ids ...int) *DsseCreate { + dc.mutation.AddMetadatumIDs(ids...) + return dc +} + +// AddMetadata adds the "metadata" edges to the Metadata entity. +func (dc *DsseCreate) AddMetadata(m ...*Metadata) *DsseCreate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return dc.AddMetadatumIDs(ids...) +} + // Mutation returns the DsseMutation object of the builder. func (dc *DsseCreate) Mutation() *DsseMutation { return dc.mutation @@ -216,6 +232,22 @@ func (dc *DsseCreate) createSpec() (*Dsse, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := dc.mutation.MetadataIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } return _node, _spec } diff --git a/ent/dsse_query.go b/ent/dsse_query.go index c639b715..8b1461dc 100644 --- a/ent/dsse_query.go +++ b/ent/dsse_query.go @@ -12,6 +12,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/predicate" "github.com/in-toto/archivista/ent/signature" @@ -28,11 +29,13 @@ type DsseQuery struct { withStatement *StatementQuery withSignatures *SignatureQuery withPayloadDigests *PayloadDigestQuery + withMetadata *MetadataQuery withFKs bool modifiers []func(*sql.Selector) loadTotal []func(context.Context, []*Dsse) error withNamedSignatures map[string]*SignatureQuery withNamedPayloadDigests map[string]*PayloadDigestQuery + withNamedMetadata map[string]*MetadataQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -135,6 +138,28 @@ func (dq *DsseQuery) QueryPayloadDigests() *PayloadDigestQuery { return query } +// QueryMetadata chains the current query on the "metadata" edge. +func (dq *DsseQuery) QueryMetadata() *MetadataQuery { + query := (&MetadataClient{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(dsse.Table, dsse.FieldID, selector), + sqlgraph.To(metadata.Table, metadata.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, dsse.MetadataTable, dsse.MetadataPrimaryKey...), + ) + fromU = sqlgraph.SetNeighbors(dq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // First returns the first Dsse entity from the query. // Returns a *NotFoundError when no Dsse was found. func (dq *DsseQuery) First(ctx context.Context) (*Dsse, error) { @@ -330,6 +355,7 @@ func (dq *DsseQuery) Clone() *DsseQuery { withStatement: dq.withStatement.Clone(), withSignatures: dq.withSignatures.Clone(), withPayloadDigests: dq.withPayloadDigests.Clone(), + withMetadata: dq.withMetadata.Clone(), // clone intermediate query. sql: dq.sql.Clone(), path: dq.path, @@ -369,6 +395,17 @@ func (dq *DsseQuery) WithPayloadDigests(opts ...func(*PayloadDigestQuery)) *Dsse 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 *DsseQuery) WithMetadata(opts ...func(*MetadataQuery)) *DsseQuery { + query := (&MetadataClient{config: dq.config}).Query() + for _, opt := range opts { + opt(query) + } + dq.withMetadata = query + return dq +} + // 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. // @@ -448,10 +485,11 @@ func (dq *DsseQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Dsse, e nodes = []*Dsse{} withFKs = dq.withFKs _spec = dq.querySpec() - loadedTypes = [3]bool{ + loadedTypes = [4]bool{ dq.withStatement != nil, dq.withSignatures != nil, dq.withPayloadDigests != nil, + dq.withMetadata != nil, } ) if dq.withStatement != nil { @@ -501,6 +539,13 @@ func (dq *DsseQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Dsse, e return nil, err } } + if query := dq.withMetadata; query != nil { + if err := dq.loadMetadata(ctx, query, nodes, + func(n *Dsse) { n.Edges.Metadata = []*Metadata{} }, + func(n *Dsse, e *Metadata) { n.Edges.Metadata = append(n.Edges.Metadata, e) }); err != nil { + return nil, err + } + } for name, query := range dq.withNamedSignatures { if err := dq.loadSignatures(ctx, query, nodes, func(n *Dsse) { n.appendNamedSignatures(name) }, @@ -515,6 +560,13 @@ func (dq *DsseQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Dsse, e return nil, err } } + for name, query := range dq.withNamedMetadata { + if err := dq.loadMetadata(ctx, query, nodes, + func(n *Dsse) { n.appendNamedMetadata(name) }, + func(n *Dsse, e *Metadata) { n.appendNamedMetadata(name, e) }); err != nil { + return nil, err + } + } for i := range dq.loadTotal { if err := dq.loadTotal[i](ctx, nodes); err != nil { return nil, err @@ -617,6 +669,67 @@ func (dq *DsseQuery) loadPayloadDigests(ctx context.Context, query *PayloadDiges } return nil } +func (dq *DsseQuery) loadMetadata(ctx context.Context, query *MetadataQuery, nodes []*Dsse, init func(*Dsse), assign func(*Dsse, *Metadata)) error { + edgeIDs := make([]driver.Value, len(nodes)) + byID := make(map[int]*Dsse) + nids := make(map[int]map[*Dsse]struct{}) + for i, node := range nodes { + edgeIDs[i] = node.ID + byID[node.ID] = node + if init != nil { + init(node) + } + } + query.Where(func(s *sql.Selector) { + joinT := sql.Table(dsse.MetadataTable) + s.Join(joinT).On(s.C(metadata.FieldID), joinT.C(dsse.MetadataPrimaryKey[1])) + s.Where(sql.InValues(joinT.C(dsse.MetadataPrimaryKey[0]), edgeIDs...)) + columns := s.SelectedColumns() + s.Select(joinT.C(dsse.MetadataPrimaryKey[0])) + s.AppendSelect(columns...) + s.SetDistinct(false) + }) + if err := query.prepareQuery(ctx); err != nil { + return err + } + qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) { + assign := spec.Assign + values := spec.ScanValues + spec.ScanValues = func(columns []string) ([]any, error) { + values, err := values(columns[1:]) + if err != nil { + return nil, err + } + return append([]any{new(sql.NullInt64)}, values...), nil + } + spec.Assign = func(columns []string, values []any) error { + outValue := int(values[0].(*sql.NullInt64).Int64) + inValue := int(values[1].(*sql.NullInt64).Int64) + if nids[inValue] == nil { + nids[inValue] = map[*Dsse]struct{}{byID[outValue]: {}} + return assign(columns[1:], values[1:]) + } + nids[inValue][byID[outValue]] = struct{}{} + return nil + } + }) + }) + neighbors, err := withInterceptors[[]*Metadata](ctx, query, qr, query.inters) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nids[n.ID] + if !ok { + return fmt.Errorf(`unexpected "metadata" node returned %v`, n.ID) + } + for kn := range nodes { + assign(kn, n) + } + } + return nil +} func (dq *DsseQuery) sqlCount(ctx context.Context) (int, error) { _spec := dq.querySpec() @@ -730,6 +843,20 @@ func (dq *DsseQuery) WithNamedPayloadDigests(name string, opts ...func(*PayloadD return dq } +// WithNamedMetadata tells the query-builder to eager-load the nodes that are connected to the "metadata" +// edge with the given name. The optional arguments are used to configure the query builder of the edge. +func (dq *DsseQuery) WithNamedMetadata(name string, opts ...func(*MetadataQuery)) *DsseQuery { + query := (&MetadataClient{config: dq.config}).Query() + for _, opt := range opts { + opt(query) + } + if dq.withNamedMetadata == nil { + dq.withNamedMetadata = make(map[string]*MetadataQuery) + } + dq.withNamedMetadata[name] = query + return dq +} + // DsseGroupBy is the group-by builder for Dsse entities. type DsseGroupBy struct { selector diff --git a/ent/dsse_update.go b/ent/dsse_update.go index e025033f..54e25b59 100644 --- a/ent/dsse_update.go +++ b/ent/dsse_update.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/predicate" "github.com/in-toto/archivista/ent/signature" @@ -107,6 +108,21 @@ func (du *DsseUpdate) AddPayloadDigests(p ...*PayloadDigest) *DsseUpdate { return du.AddPayloadDigestIDs(ids...) } +// AddMetadatumIDs adds the "metadata" edge to the Metadata entity by IDs. +func (du *DsseUpdate) AddMetadatumIDs(ids ...int) *DsseUpdate { + du.mutation.AddMetadatumIDs(ids...) + return du +} + +// AddMetadata adds the "metadata" edges to the Metadata entity. +func (du *DsseUpdate) AddMetadata(m ...*Metadata) *DsseUpdate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return du.AddMetadatumIDs(ids...) +} + // Mutation returns the DsseMutation object of the builder. func (du *DsseUpdate) Mutation() *DsseMutation { return du.mutation @@ -160,6 +176,27 @@ func (du *DsseUpdate) RemovePayloadDigests(p ...*PayloadDigest) *DsseUpdate { return du.RemovePayloadDigestIDs(ids...) } +// ClearMetadata clears all "metadata" edges to the Metadata entity. +func (du *DsseUpdate) ClearMetadata() *DsseUpdate { + du.mutation.ClearMetadata() + return du +} + +// RemoveMetadatumIDs removes the "metadata" edge to Metadata entities by IDs. +func (du *DsseUpdate) RemoveMetadatumIDs(ids ...int) *DsseUpdate { + du.mutation.RemoveMetadatumIDs(ids...) + return du +} + +// RemoveMetadata removes "metadata" edges to Metadata entities. +func (du *DsseUpdate) RemoveMetadata(m ...*Metadata) *DsseUpdate { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return du.RemoveMetadatumIDs(ids...) +} + // Save executes the query and returns the number of nodes affected by the update operation. func (du *DsseUpdate) Save(ctx context.Context) (int, error) { return withHooks(ctx, du.sqlSave, du.mutation, du.hooks) @@ -339,6 +376,51 @@ func (du *DsseUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if du.mutation.MetadataCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := du.mutation.RemovedMetadataIDs(); len(nodes) > 0 && !du.mutation.MetadataCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.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.MetadataIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.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{dsse.Label} @@ -436,6 +518,21 @@ func (duo *DsseUpdateOne) AddPayloadDigests(p ...*PayloadDigest) *DsseUpdateOne return duo.AddPayloadDigestIDs(ids...) } +// AddMetadatumIDs adds the "metadata" edge to the Metadata entity by IDs. +func (duo *DsseUpdateOne) AddMetadatumIDs(ids ...int) *DsseUpdateOne { + duo.mutation.AddMetadatumIDs(ids...) + return duo +} + +// AddMetadata adds the "metadata" edges to the Metadata entity. +func (duo *DsseUpdateOne) AddMetadata(m ...*Metadata) *DsseUpdateOne { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return duo.AddMetadatumIDs(ids...) +} + // Mutation returns the DsseMutation object of the builder. func (duo *DsseUpdateOne) Mutation() *DsseMutation { return duo.mutation @@ -489,6 +586,27 @@ func (duo *DsseUpdateOne) RemovePayloadDigests(p ...*PayloadDigest) *DsseUpdateO return duo.RemovePayloadDigestIDs(ids...) } +// ClearMetadata clears all "metadata" edges to the Metadata entity. +func (duo *DsseUpdateOne) ClearMetadata() *DsseUpdateOne { + duo.mutation.ClearMetadata() + return duo +} + +// RemoveMetadatumIDs removes the "metadata" edge to Metadata entities by IDs. +func (duo *DsseUpdateOne) RemoveMetadatumIDs(ids ...int) *DsseUpdateOne { + duo.mutation.RemoveMetadatumIDs(ids...) + return duo +} + +// RemoveMetadata removes "metadata" edges to Metadata entities. +func (duo *DsseUpdateOne) RemoveMetadata(m ...*Metadata) *DsseUpdateOne { + ids := make([]int, len(m)) + for i := range m { + ids[i] = m[i].ID + } + return duo.RemoveMetadatumIDs(ids...) +} + // Where appends a list predicates to the DsseUpdate builder. func (duo *DsseUpdateOne) Where(ps ...predicate.Dsse) *DsseUpdateOne { duo.mutation.Where(ps...) @@ -698,6 +816,51 @@ func (duo *DsseUpdateOne) sqlSave(ctx context.Context) (_node *Dsse, err error) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if duo.mutation.MetadataCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := duo.mutation.RemovedMetadataIDs(); len(nodes) > 0 && !duo.mutation.MetadataCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.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.MetadataIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: dsse.MetadataTable, + Columns: dsse.MetadataPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &Dsse{config: duo.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/ent/ent.go b/ent/ent.go index a84a145b..e870c271 100644 --- a/ent/ent.go +++ b/ent/ent.go @@ -16,6 +16,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/signature" "github.com/in-toto/archivista/ent/statement" @@ -86,6 +87,7 @@ func checkColumn(table, column string) error { attestationcollection.Table: attestationcollection.ValidColumn, attestationpolicy.Table: attestationpolicy.ValidColumn, dsse.Table: dsse.ValidColumn, + metadata.Table: metadata.ValidColumn, payloaddigest.Table: payloaddigest.ValidColumn, signature.Table: signature.ValidColumn, statement.Table: statement.ValidColumn, diff --git a/ent/gql_collection.go b/ent/gql_collection.go index 282c69f5..f1bc2d21 100644 --- a/ent/gql_collection.go +++ b/ent/gql_collection.go @@ -7,12 +7,14 @@ import ( "database/sql/driver" "fmt" + "entgo.io/contrib/entgql" "entgo.io/ent/dialect/sql" "github.com/99designs/gqlgen/graphql" "github.com/in-toto/archivista/ent/attestation" "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/signature" "github.com/in-toto/archivista/ent/statement" @@ -27,13 +29,13 @@ func (a *AttestationQuery) CollectFields(ctx context.Context, satisfies ...strin if fc == nil { return a, nil } - if err := a.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := a.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return a, nil } -func (a *AttestationQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (a *AttestationQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -42,13 +44,14 @@ func (a *AttestationQuery) collectField(ctx context.Context, opCtx *graphql.Oper ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "attestationCollection": var ( alias = field.Alias path = append(path, alias) query = (&AttestationCollectionClient{config: a.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, attestationcollectionImplementors)...); err != nil { return err } a.withAttestationCollection = query @@ -104,13 +107,13 @@ func (ac *AttestationCollectionQuery) CollectFields(ctx context.Context, satisfi if fc == nil { return ac, nil } - if err := ac.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := ac.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return ac, nil } -func (ac *AttestationCollectionQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (ac *AttestationCollectionQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -119,25 +122,27 @@ func (ac *AttestationCollectionQuery) collectField(ctx context.Context, opCtx *g ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "attestations": var ( alias = field.Alias path = append(path, alias) query = (&AttestationClient{config: ac.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, attestationImplementors)...); err != nil { return err } ac.WithNamedAttestations(alias, func(wq *AttestationQuery) { *wq = *query }) + case "statement": var ( alias = field.Alias path = append(path, alias) query = (&StatementClient{config: ac.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, statementImplementors)...); err != nil { return err } ac.withStatement = query @@ -193,13 +198,13 @@ func (ap *AttestationPolicyQuery) CollectFields(ctx context.Context, satisfies . if fc == nil { return ap, nil } - if err := ap.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := ap.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return ap, nil } -func (ap *AttestationPolicyQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (ap *AttestationPolicyQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -208,13 +213,14 @@ func (ap *AttestationPolicyQuery) collectField(ctx context.Context, opCtx *graph ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "statement": var ( alias = field.Alias path = append(path, alias) query = (&StatementClient{config: ap.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, statementImplementors)...); err != nil { return err } ap.withStatement = query @@ -270,13 +276,13 @@ func (d *DsseQuery) CollectFields(ctx context.Context, satisfies ...string) (*Ds if fc == nil { return d, nil } - if err := d.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := d.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return d, nil } -func (d *DsseQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (d *DsseQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -285,40 +291,56 @@ func (d *DsseQuery) collectField(ctx context.Context, opCtx *graphql.OperationCo ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "statement": var ( alias = field.Alias path = append(path, alias) query = (&StatementClient{config: d.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, statementImplementors)...); err != nil { return err } d.withStatement = query + case "signatures": var ( alias = field.Alias path = append(path, alias) query = (&SignatureClient{config: d.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, signatureImplementors)...); err != nil { return err } d.WithNamedSignatures(alias, func(wq *SignatureQuery) { *wq = *query }) + case "payloadDigests": var ( alias = field.Alias path = append(path, alias) query = (&PayloadDigestClient{config: d.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, payloaddigestImplementors)...); err != nil { return err } d.WithNamedPayloadDigests(alias, func(wq *PayloadDigestQuery) { *wq = *query }) + + case "metadata": + var ( + alias = field.Alias + path = append(path, alias) + query = (&MetadataClient{config: d.config}).Query() + ) + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, metadataImplementors)...); err != nil { + return err + } + d.WithNamedMetadata(alias, func(wq *MetadataQuery) { + *wq = *query + }) case "gitoidSha256": if _, ok := fieldSeen[dsse.FieldGitoidSha256]; !ok { selectedFields = append(selectedFields, dsse.FieldGitoidSha256) @@ -370,19 +392,104 @@ func newDssePaginateArgs(rv map[string]any) *dssePaginateArgs { return args } +// CollectFields tells the query-builder to eagerly load connected nodes by resolver context. +func (m *MetadataQuery) CollectFields(ctx context.Context, satisfies ...string) (*MetadataQuery, error) { + fc := graphql.GetFieldContext(ctx) + if fc == nil { + return m, nil + } + if err := m.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + return nil, err + } + return m, nil +} + +func (m *MetadataQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { + path = append([]string(nil), path...) + var ( + unknownSeen bool + fieldSeen = make(map[string]struct{}, len(metadata.Columns)) + selectedFields = []string{metadata.FieldID} + ) + for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { + switch field.Name { + + case "envelope": + var ( + alias = field.Alias + path = append(path, alias) + query = (&DsseClient{config: m.config}).Query() + ) + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, dsseImplementors)...); err != nil { + return err + } + m.WithNamedEnvelope(alias, func(wq *DsseQuery) { + *wq = *query + }) + case "key": + if _, ok := fieldSeen[metadata.FieldKey]; !ok { + selectedFields = append(selectedFields, metadata.FieldKey) + fieldSeen[metadata.FieldKey] = struct{}{} + } + case "value": + if _, ok := fieldSeen[metadata.FieldValue]; !ok { + selectedFields = append(selectedFields, metadata.FieldValue) + fieldSeen[metadata.FieldValue] = struct{}{} + } + case "id": + case "__typename": + default: + unknownSeen = true + } + } + if !unknownSeen { + m.Select(selectedFields...) + } + return nil +} + +type metadataPaginateArgs struct { + first, last *int + after, before *Cursor + opts []MetadataPaginateOption +} + +func newMetadataPaginateArgs(rv map[string]any) *metadataPaginateArgs { + args := &metadataPaginateArgs{} + if rv == nil { + return args + } + if v := rv[firstField]; v != nil { + args.first = v.(*int) + } + if v := rv[lastField]; v != nil { + args.last = v.(*int) + } + if v := rv[afterField]; v != nil { + args.after = v.(*Cursor) + } + if v := rv[beforeField]; v != nil { + args.before = v.(*Cursor) + } + if v, ok := rv[whereField].(*MetadataWhereInput); ok { + args.opts = append(args.opts, WithMetadataFilter(v.Filter)) + } + return args +} + // CollectFields tells the query-builder to eagerly load connected nodes by resolver context. func (pd *PayloadDigestQuery) CollectFields(ctx context.Context, satisfies ...string) (*PayloadDigestQuery, error) { fc := graphql.GetFieldContext(ctx) if fc == nil { return pd, nil } - if err := pd.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := pd.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return pd, nil } -func (pd *PayloadDigestQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (pd *PayloadDigestQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -391,13 +498,14 @@ func (pd *PayloadDigestQuery) collectField(ctx context.Context, opCtx *graphql.O ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "dsse": var ( alias = field.Alias path = append(path, alias) query = (&DsseClient{config: pd.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, dsseImplementors)...); err != nil { return err } pd.withDsse = query @@ -458,13 +566,13 @@ func (s *SignatureQuery) CollectFields(ctx context.Context, satisfies ...string) if fc == nil { return s, nil } - if err := s.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := s.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return s, nil } -func (s *SignatureQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (s *SignatureQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -473,23 +581,25 @@ func (s *SignatureQuery) collectField(ctx context.Context, opCtx *graphql.Operat ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "dsse": var ( alias = field.Alias path = append(path, alias) query = (&DsseClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, dsseImplementors)...); err != nil { return err } s.withDsse = query + case "timestamps": var ( alias = field.Alias path = append(path, alias) query = (&TimestampClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, timestampImplementors)...); err != nil { return err } s.WithNamedTimestamps(alias, func(wq *TimestampQuery) { @@ -552,13 +662,13 @@ func (s *StatementQuery) CollectFields(ctx context.Context, satisfies ...string) if fc == nil { return s, nil } - if err := s.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := s.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return s, nil } -func (s *StatementQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (s *StatementQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -567,6 +677,7 @@ func (s *StatementQuery) collectField(ctx context.Context, opCtx *graphql.Operat ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "subjects": var ( alias = field.Alias @@ -638,46 +749,53 @@ func (s *StatementQuery) collectField(ctx context.Context, opCtx *graphql.Operat } path = append(path, edgesField, nodeField) if field := collectedField(ctx, path...); field != nil { - if err := query.collectField(ctx, opCtx, *field, path, mayAddCondition(satisfies, "Subject")...); err != nil { + if err := query.collectField(ctx, false, opCtx, *field, path, mayAddCondition(satisfies, subjectImplementors)...); err != nil { return err } } if limit := paginateLimit(args.first, args.last); limit > 0 { - modify := limitRows(statement.SubjectsColumn, limit, pager.orderExpr(query)) - query.modifiers = append(query.modifiers, modify) + if oneNode { + pager.applyOrder(query.Limit(limit)) + } else { + modify := entgql.LimitPerRow(statement.SubjectsColumn, limit, pager.orderExpr(query)) + query.modifiers = append(query.modifiers, modify) + } } else { query = pager.applyOrder(query) } s.WithNamedSubjects(alias, func(wq *SubjectQuery) { *wq = *query }) + case "policy": var ( alias = field.Alias path = append(path, alias) query = (&AttestationPolicyClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, attestationpolicyImplementors)...); err != nil { return err } s.withPolicy = query + case "attestationCollections": var ( alias = field.Alias path = append(path, alias) query = (&AttestationCollectionClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, attestationcollectionImplementors)...); err != nil { return err } s.withAttestationCollections = query + case "dsse": var ( alias = field.Alias path = append(path, alias) query = (&DsseClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, dsseImplementors)...); err != nil { return err } s.WithNamedDsse(alias, func(wq *DsseQuery) { @@ -735,13 +853,13 @@ func (s *SubjectQuery) CollectFields(ctx context.Context, satisfies ...string) ( if fc == nil { return s, nil } - if err := s.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := s.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return s, nil } -func (s *SubjectQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (s *SubjectQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -750,25 +868,27 @@ func (s *SubjectQuery) collectField(ctx context.Context, opCtx *graphql.Operatio ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "subjectDigests": var ( alias = field.Alias path = append(path, alias) query = (&SubjectDigestClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, false, opCtx, field, path, mayAddCondition(satisfies, subjectdigestImplementors)...); err != nil { return err } s.WithNamedSubjectDigests(alias, func(wq *SubjectDigestQuery) { *wq = *query }) + case "statement": var ( alias = field.Alias path = append(path, alias) query = (&StatementClient{config: s.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, statementImplementors)...); err != nil { return err } s.withStatement = query @@ -824,13 +944,13 @@ func (sd *SubjectDigestQuery) CollectFields(ctx context.Context, satisfies ...st if fc == nil { return sd, nil } - if err := sd.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := sd.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return sd, nil } -func (sd *SubjectDigestQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (sd *SubjectDigestQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -839,13 +959,14 @@ func (sd *SubjectDigestQuery) collectField(ctx context.Context, opCtx *graphql.O ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "subject": var ( alias = field.Alias path = append(path, alias) query = (&SubjectClient{config: sd.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, subjectImplementors)...); err != nil { return err } sd.withSubject = query @@ -906,13 +1027,13 @@ func (t *TimestampQuery) CollectFields(ctx context.Context, satisfies ...string) if fc == nil { return t, nil } - if err := t.collectField(ctx, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { + if err := t.collectField(ctx, false, graphql.GetOperationContext(ctx), fc.Field, nil, satisfies...); err != nil { return nil, err } return t, nil } -func (t *TimestampQuery) collectField(ctx context.Context, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { +func (t *TimestampQuery) collectField(ctx context.Context, oneNode bool, opCtx *graphql.OperationContext, collected graphql.CollectedField, path []string, satisfies ...string) error { path = append([]string(nil), path...) var ( unknownSeen bool @@ -921,13 +1042,14 @@ func (t *TimestampQuery) collectField(ctx context.Context, opCtx *graphql.Operat ) for _, field := range graphql.CollectFields(opCtx, collected.Selections, satisfies) { switch field.Name { + case "signature": var ( alias = field.Alias path = append(path, alias) query = (&SignatureClient{config: t.config}).Query() ) - if err := query.collectField(ctx, opCtx, field, path, satisfies...); err != nil { + if err := query.collectField(ctx, oneNode, opCtx, field, path, mayAddCondition(satisfies, signatureImplementors)...); err != nil { return err } t.withSignature = query @@ -1034,39 +1156,17 @@ func unmarshalArgs(ctx context.Context, whereInput any, args map[string]any) map return args } -func limitRows(partitionBy string, limit int, orderBy ...sql.Querier) func(s *sql.Selector) { - return func(s *sql.Selector) { - d := sql.Dialect(s.Dialect()) - s.SetDistinct(false) - with := d.With("src_query"). - As(s.Clone()). - With("limited_query"). - As( - d.Select("*"). - AppendSelectExprAs( - sql.RowNumber().PartitionBy(partitionBy).OrderExpr(orderBy...), - "row_number", - ). - From(d.Table("src_query")), - ) - t := d.Table("limited_query").As(s.TableName()) - *s = *d.Select(s.UnqualifiedColumns()...). - From(t). - Where(sql.LTE(t.C("row_number"), limit)). - Prefix(with) - } -} - // mayAddCondition appends another type condition to the satisfies list -// if condition is enabled (Node/Nodes) and it does not exist in the list. -func mayAddCondition(satisfies []string, typeCond string) []string { - if len(satisfies) == 0 { - return satisfies - } - for _, s := range satisfies { - if typeCond == s { - return satisfies +// if it does not exist in the list. +func mayAddCondition(satisfies []string, typeCond []string) []string { +Cond: + for _, c := range typeCond { + for _, s := range satisfies { + if c == s { + continue Cond + } } + satisfies = append(satisfies, c) } - return append(satisfies, typeCond) + return satisfies } diff --git a/ent/gql_edge.go b/ent/gql_edge.go index 19957b71..234d7d14 100644 --- a/ent/gql_edge.go +++ b/ent/gql_edge.go @@ -76,6 +76,30 @@ func (d *Dsse) PayloadDigests(ctx context.Context) (result []*PayloadDigest, err return result, err } +func (d *Dsse) Metadata(ctx context.Context) (result []*Metadata, err error) { + if fc := graphql.GetFieldContext(ctx); fc != nil && fc.Field.Alias != "" { + result, err = d.NamedMetadata(graphql.GetFieldContext(ctx).Field.Alias) + } else { + result, err = d.Edges.MetadataOrErr() + } + if IsNotLoaded(err) { + result, err = d.QueryMetadata().All(ctx) + } + return result, err +} + +func (m *Metadata) Envelope(ctx context.Context) (result []*Dsse, err error) { + if fc := graphql.GetFieldContext(ctx); fc != nil && fc.Field.Alias != "" { + result, err = m.NamedEnvelope(graphql.GetFieldContext(ctx).Field.Alias) + } else { + result, err = m.Edges.EnvelopeOrErr() + } + if IsNotLoaded(err) { + result, err = m.QueryEnvelope().All(ctx) + } + return result, err +} + func (pd *PayloadDigest) Dsse(ctx context.Context) (*Dsse, error) { result, err := pd.Edges.DsseOrErr() if IsNotLoaded(err) { diff --git a/ent/gql_node.go b/ent/gql_node.go index fa4943fa..1fe257f5 100644 --- a/ent/gql_node.go +++ b/ent/gql_node.go @@ -18,6 +18,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/signature" "github.com/in-toto/archivista/ent/statement" @@ -32,35 +33,60 @@ type Noder interface { IsNode() } +var attestationImplementors = []string{"Attestation", "Node"} + // IsNode implements the Node interface check for GQLGen. -func (n *Attestation) IsNode() {} +func (*Attestation) IsNode() {} + +var attestationcollectionImplementors = []string{"AttestationCollection", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *AttestationCollection) IsNode() {} +func (*AttestationCollection) IsNode() {} + +var attestationpolicyImplementors = []string{"AttestationPolicy", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *AttestationPolicy) IsNode() {} +func (*AttestationPolicy) IsNode() {} + +var dsseImplementors = []string{"Dsse", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *Dsse) IsNode() {} +func (*Dsse) IsNode() {} + +var metadataImplementors = []string{"Metadata", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *PayloadDigest) IsNode() {} +func (*Metadata) IsNode() {} + +var payloaddigestImplementors = []string{"PayloadDigest", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *Signature) IsNode() {} +func (*PayloadDigest) IsNode() {} + +var signatureImplementors = []string{"Signature", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *Statement) IsNode() {} +func (*Signature) IsNode() {} + +var statementImplementors = []string{"Statement", "Node"} + +// IsNode implements the Node interface check for GQLGen. +func (*Statement) IsNode() {} + +var subjectImplementors = []string{"Subject", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *Subject) IsNode() {} +func (*Subject) IsNode() {} + +var subjectdigestImplementors = []string{"SubjectDigest", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *SubjectDigest) IsNode() {} +func (*SubjectDigest) IsNode() {} + +var timestampImplementors = []string{"Timestamp", "Node"} // IsNode implements the Node interface check for GQLGen. -func (n *Timestamp) IsNode() {} +func (*Timestamp) IsNode() {} var errNodeInvalidID = &NotFoundError{"node"} @@ -123,123 +149,102 @@ func (c *Client) noder(ctx context.Context, table string, id int) (Noder, error) case attestation.Table: query := c.Attestation.Query(). Where(attestation.ID(id)) - query, err := query.CollectFields(ctx, "Attestation") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, attestationImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case attestationcollection.Table: query := c.AttestationCollection.Query(). Where(attestationcollection.ID(id)) - query, err := query.CollectFields(ctx, "AttestationCollection") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, attestationcollectionImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case attestationpolicy.Table: query := c.AttestationPolicy.Query(). Where(attestationpolicy.ID(id)) - query, err := query.CollectFields(ctx, "AttestationPolicy") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, attestationpolicyImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case dsse.Table: query := c.Dsse.Query(). Where(dsse.ID(id)) - query, err := query.CollectFields(ctx, "Dsse") - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, dsseImplementors...); err != nil { + return nil, err + } } - n, err := query.Only(ctx) - if err != nil { - return nil, err + return query.Only(ctx) + case metadata.Table: + query := c.Metadata.Query(). + Where(metadata.ID(id)) + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, metadataImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case payloaddigest.Table: query := c.PayloadDigest.Query(). Where(payloaddigest.ID(id)) - query, err := query.CollectFields(ctx, "PayloadDigest") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, payloaddigestImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case signature.Table: query := c.Signature.Query(). Where(signature.ID(id)) - query, err := query.CollectFields(ctx, "Signature") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, signatureImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case statement.Table: query := c.Statement.Query(). Where(statement.ID(id)) - query, err := query.CollectFields(ctx, "Statement") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, statementImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case subject.Table: query := c.Subject.Query(). Where(subject.ID(id)) - query, err := query.CollectFields(ctx, "Subject") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, subjectImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case subjectdigest.Table: query := c.SubjectDigest.Query(). Where(subjectdigest.ID(id)) - query, err := query.CollectFields(ctx, "SubjectDigest") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, subjectdigestImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) case timestamp.Table: query := c.Timestamp.Query(). Where(timestamp.ID(id)) - query, err := query.CollectFields(ctx, "Timestamp") - if err != nil { - return nil, err - } - n, err := query.Only(ctx) - if err != nil { - return nil, err + if fc := graphql.GetFieldContext(ctx); fc != nil { + if err := query.collectField(ctx, true, graphql.GetOperationContext(ctx), fc.Field, nil, timestampImplementors...); err != nil { + return nil, err + } } - return n, nil + return query.Only(ctx) default: return nil, fmt.Errorf("cannot resolve noder from table %q: %w", table, errNodeInvalidID) } @@ -316,7 +321,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case attestation.Table: query := c.Attestation.Query(). Where(attestation.IDIn(ids...)) - query, err := query.CollectFields(ctx, "Attestation") + query, err := query.CollectFields(ctx, attestationImplementors...) if err != nil { return nil, err } @@ -332,7 +337,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case attestationcollection.Table: query := c.AttestationCollection.Query(). Where(attestationcollection.IDIn(ids...)) - query, err := query.CollectFields(ctx, "AttestationCollection") + query, err := query.CollectFields(ctx, attestationcollectionImplementors...) if err != nil { return nil, err } @@ -348,7 +353,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case attestationpolicy.Table: query := c.AttestationPolicy.Query(). Where(attestationpolicy.IDIn(ids...)) - query, err := query.CollectFields(ctx, "AttestationPolicy") + query, err := query.CollectFields(ctx, attestationpolicyImplementors...) if err != nil { return nil, err } @@ -364,7 +369,23 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case dsse.Table: query := c.Dsse.Query(). Where(dsse.IDIn(ids...)) - query, err := query.CollectFields(ctx, "Dsse") + query, err := query.CollectFields(ctx, dsseImplementors...) + if err != nil { + return nil, err + } + nodes, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, node := range nodes { + for _, noder := range idmap[node.ID] { + *noder = node + } + } + case metadata.Table: + query := c.Metadata.Query(). + Where(metadata.IDIn(ids...)) + query, err := query.CollectFields(ctx, metadataImplementors...) if err != nil { return nil, err } @@ -380,7 +401,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case payloaddigest.Table: query := c.PayloadDigest.Query(). Where(payloaddigest.IDIn(ids...)) - query, err := query.CollectFields(ctx, "PayloadDigest") + query, err := query.CollectFields(ctx, payloaddigestImplementors...) if err != nil { return nil, err } @@ -396,7 +417,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case signature.Table: query := c.Signature.Query(). Where(signature.IDIn(ids...)) - query, err := query.CollectFields(ctx, "Signature") + query, err := query.CollectFields(ctx, signatureImplementors...) if err != nil { return nil, err } @@ -412,7 +433,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case statement.Table: query := c.Statement.Query(). Where(statement.IDIn(ids...)) - query, err := query.CollectFields(ctx, "Statement") + query, err := query.CollectFields(ctx, statementImplementors...) if err != nil { return nil, err } @@ -428,7 +449,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case subject.Table: query := c.Subject.Query(). Where(subject.IDIn(ids...)) - query, err := query.CollectFields(ctx, "Subject") + query, err := query.CollectFields(ctx, subjectImplementors...) if err != nil { return nil, err } @@ -444,7 +465,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case subjectdigest.Table: query := c.SubjectDigest.Query(). Where(subjectdigest.IDIn(ids...)) - query, err := query.CollectFields(ctx, "SubjectDigest") + query, err := query.CollectFields(ctx, subjectdigestImplementors...) if err != nil { return nil, err } @@ -460,7 +481,7 @@ func (c *Client) noders(ctx context.Context, table string, ids []int) ([]Noder, case timestamp.Table: query := c.Timestamp.Query(). Where(timestamp.IDIn(ids...)) - query, err := query.CollectFields(ctx, "Timestamp") + query, err := query.CollectFields(ctx, timestampImplementors...) if err != nil { return nil, err } diff --git a/ent/gql_pagination.go b/ent/gql_pagination.go index 28104ef8..08d9e80e 100644 --- a/ent/gql_pagination.go +++ b/ent/gql_pagination.go @@ -15,6 +15,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/signature" "github.com/in-toto/archivista/ent/statement" @@ -279,7 +280,9 @@ func (a *AttestationQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = a.Clone().Count(ctx); err != nil { + c := a.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -292,11 +295,12 @@ func (a *AttestationQuery) Paginate( if a, err = pager.applyCursors(a, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { a.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := a.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := a.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -525,7 +529,9 @@ func (ac *AttestationCollectionQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = ac.Clone().Count(ctx); err != nil { + c := ac.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -538,11 +544,12 @@ func (ac *AttestationCollectionQuery) Paginate( if ac, err = pager.applyCursors(ac, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { ac.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := ac.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := ac.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -771,7 +778,9 @@ func (ap *AttestationPolicyQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = ap.Clone().Count(ctx); err != nil { + c := ap.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -784,11 +793,12 @@ func (ap *AttestationPolicyQuery) Paginate( if ap, err = pager.applyCursors(ap, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { ap.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := ap.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := ap.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -1017,7 +1027,9 @@ func (d *DsseQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = d.Clone().Count(ctx); err != nil { + c := d.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -1030,11 +1042,12 @@ func (d *DsseQuery) Paginate( if d, err = pager.applyCursors(d, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { d.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := d.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := d.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -1088,6 +1101,255 @@ func (d *Dsse) ToEdge(order *DsseOrder) *DsseEdge { } } +// MetadataEdge is the edge representation of Metadata. +type MetadataEdge struct { + Node *Metadata `json:"node"` + Cursor Cursor `json:"cursor"` +} + +// MetadataConnection is the connection containing edges to Metadata. +type MetadataConnection struct { + Edges []*MetadataEdge `json:"edges"` + PageInfo PageInfo `json:"pageInfo"` + TotalCount int `json:"totalCount"` +} + +func (c *MetadataConnection) build(nodes []*Metadata, pager *metadataPager, after *Cursor, first *int, before *Cursor, last *int) { + c.PageInfo.HasNextPage = before != nil + c.PageInfo.HasPreviousPage = after != nil + if first != nil && *first+1 == len(nodes) { + c.PageInfo.HasNextPage = true + nodes = nodes[:len(nodes)-1] + } else if last != nil && *last+1 == len(nodes) { + c.PageInfo.HasPreviousPage = true + nodes = nodes[:len(nodes)-1] + } + var nodeAt func(int) *Metadata + if last != nil { + n := len(nodes) - 1 + nodeAt = func(i int) *Metadata { + return nodes[n-i] + } + } else { + nodeAt = func(i int) *Metadata { + return nodes[i] + } + } + c.Edges = make([]*MetadataEdge, len(nodes)) + for i := range nodes { + node := nodeAt(i) + c.Edges[i] = &MetadataEdge{ + Node: node, + Cursor: pager.toCursor(node), + } + } + if l := len(c.Edges); l > 0 { + c.PageInfo.StartCursor = &c.Edges[0].Cursor + c.PageInfo.EndCursor = &c.Edges[l-1].Cursor + } + if c.TotalCount == 0 { + c.TotalCount = len(nodes) + } +} + +// MetadataPaginateOption enables pagination customization. +type MetadataPaginateOption func(*metadataPager) error + +// WithMetadataOrder configures pagination ordering. +func WithMetadataOrder(order *MetadataOrder) MetadataPaginateOption { + if order == nil { + order = DefaultMetadataOrder + } + o := *order + return func(pager *metadataPager) error { + if err := o.Direction.Validate(); err != nil { + return err + } + if o.Field == nil { + o.Field = DefaultMetadataOrder.Field + } + pager.order = &o + return nil + } +} + +// WithMetadataFilter configures pagination filter. +func WithMetadataFilter(filter func(*MetadataQuery) (*MetadataQuery, error)) MetadataPaginateOption { + return func(pager *metadataPager) error { + if filter == nil { + return errors.New("MetadataQuery filter cannot be nil") + } + pager.filter = filter + return nil + } +} + +type metadataPager struct { + reverse bool + order *MetadataOrder + filter func(*MetadataQuery) (*MetadataQuery, error) +} + +func newMetadataPager(opts []MetadataPaginateOption, reverse bool) (*metadataPager, error) { + pager := &metadataPager{reverse: reverse} + for _, opt := range opts { + if err := opt(pager); err != nil { + return nil, err + } + } + if pager.order == nil { + pager.order = DefaultMetadataOrder + } + return pager, nil +} + +func (p *metadataPager) applyFilter(query *MetadataQuery) (*MetadataQuery, error) { + if p.filter != nil { + return p.filter(query) + } + return query, nil +} + +func (p *metadataPager) toCursor(m *Metadata) Cursor { + return p.order.Field.toCursor(m) +} + +func (p *metadataPager) applyCursors(query *MetadataQuery, after, before *Cursor) (*MetadataQuery, error) { + direction := p.order.Direction + if p.reverse { + direction = direction.Reverse() + } + for _, predicate := range entgql.CursorsPredicate(after, before, DefaultMetadataOrder.Field.column, p.order.Field.column, direction) { + query = query.Where(predicate) + } + return query, nil +} + +func (p *metadataPager) applyOrder(query *MetadataQuery) *MetadataQuery { + direction := p.order.Direction + if p.reverse { + direction = direction.Reverse() + } + query = query.Order(p.order.Field.toTerm(direction.OrderTermOption())) + if p.order.Field != DefaultMetadataOrder.Field { + query = query.Order(DefaultMetadataOrder.Field.toTerm(direction.OrderTermOption())) + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(p.order.Field.column) + } + return query +} + +func (p *metadataPager) orderExpr(query *MetadataQuery) sql.Querier { + direction := p.order.Direction + if p.reverse { + direction = direction.Reverse() + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(p.order.Field.column) + } + return sql.ExprFunc(func(b *sql.Builder) { + b.Ident(p.order.Field.column).Pad().WriteString(string(direction)) + if p.order.Field != DefaultMetadataOrder.Field { + b.Comma().Ident(DefaultMetadataOrder.Field.column).Pad().WriteString(string(direction)) + } + }) +} + +// Paginate executes the query and returns a relay based cursor connection to Metadata. +func (m *MetadataQuery) Paginate( + ctx context.Context, after *Cursor, first *int, + before *Cursor, last *int, opts ...MetadataPaginateOption, +) (*MetadataConnection, error) { + if err := validateFirstLast(first, last); err != nil { + return nil, err + } + pager, err := newMetadataPager(opts, last != nil) + if err != nil { + return nil, err + } + if m, err = pager.applyFilter(m); err != nil { + return nil, err + } + conn := &MetadataConnection{Edges: []*MetadataEdge{}} + ignoredEdges := !hasCollectedField(ctx, edgesField) + if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { + hasPagination := after != nil || first != nil || before != nil || last != nil + if hasPagination || ignoredEdges { + c := m.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { + return nil, err + } + conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 + conn.PageInfo.HasPreviousPage = last != nil && conn.TotalCount > 0 + } + } + if ignoredEdges || (first != nil && *first == 0) || (last != nil && *last == 0) { + return conn, nil + } + if m, err = pager.applyCursors(m, after, before); err != nil { + return nil, err + } + limit := paginateLimit(first, last) + if limit != 0 { + m.Limit(limit) + } + if field := collectedField(ctx, edgesField, nodeField); field != nil { + if err := m.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + return nil, err + } + } + m = pager.applyOrder(m) + nodes, err := m.All(ctx) + if err != nil { + return nil, err + } + conn.build(nodes, pager, after, first, before, last) + return conn, nil +} + +// MetadataOrderField defines the ordering field of Metadata. +type MetadataOrderField struct { + // Value extracts the ordering value from the given Metadata. + Value func(*Metadata) (ent.Value, error) + column string // field or computed. + toTerm func(...sql.OrderTermOption) metadata.OrderOption + toCursor func(*Metadata) Cursor +} + +// MetadataOrder defines the ordering of Metadata. +type MetadataOrder struct { + Direction OrderDirection `json:"direction"` + Field *MetadataOrderField `json:"field"` +} + +// DefaultMetadataOrder is the default ordering of Metadata. +var DefaultMetadataOrder = &MetadataOrder{ + Direction: entgql.OrderDirectionAsc, + Field: &MetadataOrderField{ + Value: func(m *Metadata) (ent.Value, error) { + return m.ID, nil + }, + column: metadata.FieldID, + toTerm: metadata.ByID, + toCursor: func(m *Metadata) Cursor { + return Cursor{ID: m.ID} + }, + }, +} + +// ToEdge converts Metadata into MetadataEdge. +func (m *Metadata) ToEdge(order *MetadataOrder) *MetadataEdge { + if order == nil { + order = DefaultMetadataOrder + } + return &MetadataEdge{ + Node: m, + Cursor: order.Field.toCursor(m), + } +} + // PayloadDigestEdge is the edge representation of PayloadDigest. type PayloadDigestEdge struct { Node *PayloadDigest `json:"node"` @@ -1263,7 +1525,9 @@ func (pd *PayloadDigestQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = pd.Clone().Count(ctx); err != nil { + c := pd.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -1276,11 +1540,12 @@ func (pd *PayloadDigestQuery) Paginate( if pd, err = pager.applyCursors(pd, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { pd.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := pd.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := pd.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -1509,7 +1774,9 @@ func (s *SignatureQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = s.Clone().Count(ctx); err != nil { + c := s.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -1522,11 +1789,12 @@ func (s *SignatureQuery) Paginate( if s, err = pager.applyCursors(s, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { s.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := s.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := s.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -1755,7 +2023,9 @@ func (s *StatementQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = s.Clone().Count(ctx); err != nil { + c := s.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -1768,11 +2038,12 @@ func (s *StatementQuery) Paginate( if s, err = pager.applyCursors(s, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { s.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := s.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := s.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -2001,7 +2272,9 @@ func (s *SubjectQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = s.Clone().Count(ctx); err != nil { + c := s.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -2014,11 +2287,12 @@ func (s *SubjectQuery) Paginate( if s, err = pager.applyCursors(s, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { s.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := s.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := s.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -2247,7 +2521,9 @@ func (sd *SubjectDigestQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = sd.Clone().Count(ctx); err != nil { + c := sd.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -2260,11 +2536,12 @@ func (sd *SubjectDigestQuery) Paginate( if sd, err = pager.applyCursors(sd, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { sd.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := sd.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := sd.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } @@ -2493,7 +2770,9 @@ func (t *TimestampQuery) Paginate( if hasCollectedField(ctx, totalCountField) || hasCollectedField(ctx, pageInfoField) { hasPagination := after != nil || first != nil || before != nil || last != nil if hasPagination || ignoredEdges { - if conn.TotalCount, err = t.Clone().Count(ctx); err != nil { + c := t.Clone() + c.ctx.Fields = nil + if conn.TotalCount, err = c.Count(ctx); err != nil { return nil, err } conn.PageInfo.HasNextPage = first != nil && conn.TotalCount > 0 @@ -2506,11 +2785,12 @@ func (t *TimestampQuery) Paginate( if t, err = pager.applyCursors(t, after, before); err != nil { return nil, err } - if limit := paginateLimit(first, last); limit != 0 { + limit := paginateLimit(first, last) + if limit != 0 { t.Limit(limit) } if field := collectedField(ctx, edgesField, nodeField); field != nil { - if err := t.collectField(ctx, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { + if err := t.collectField(ctx, limit == 1, graphql.GetOperationContext(ctx), *field, []string{edgesField, nodeField}); err != nil { return nil, err } } diff --git a/ent/gql_where_input.go b/ent/gql_where_input.go index 4e511031..afcd745e 100644 --- a/ent/gql_where_input.go +++ b/ent/gql_where_input.go @@ -11,6 +11,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/predicate" "github.com/in-toto/archivista/ent/signature" @@ -700,6 +701,10 @@ type DsseWhereInput struct { // "payload_digests" edge predicates. HasPayloadDigests *bool `json:"hasPayloadDigests,omitempty"` HasPayloadDigestsWith []*PayloadDigestWhereInput `json:"hasPayloadDigestsWith,omitempty"` + + // "metadata" edge predicates. + HasMetadata *bool `json:"hasMetadata,omitempty"` + HasMetadataWith []*MetadataWhereInput `json:"hasMetadataWith,omitempty"` } // AddPredicates adds custom predicates to the where input to be used during the filtering phase. @@ -930,6 +935,24 @@ func (i *DsseWhereInput) P() (predicate.Dsse, error) { } predicates = append(predicates, dsse.HasPayloadDigestsWith(with...)) } + if i.HasMetadata != nil { + p := dsse.HasMetadata() + if !*i.HasMetadata { + p = dsse.Not(p) + } + predicates = append(predicates, p) + } + if len(i.HasMetadataWith) > 0 { + with := make([]predicate.Metadata, 0, len(i.HasMetadataWith)) + for _, w := range i.HasMetadataWith { + p, err := w.P() + if err != nil { + return nil, fmt.Errorf("%w: field 'HasMetadataWith'", err) + } + with = append(with, p) + } + predicates = append(predicates, dsse.HasMetadataWith(with...)) + } switch len(predicates) { case 0: return nil, ErrEmptyDsseWhereInput @@ -940,6 +963,260 @@ func (i *DsseWhereInput) P() (predicate.Dsse, error) { } } +// MetadataWhereInput represents a where input for filtering Metadata queries. +type MetadataWhereInput struct { + Predicates []predicate.Metadata `json:"-"` + Not *MetadataWhereInput `json:"not,omitempty"` + Or []*MetadataWhereInput `json:"or,omitempty"` + And []*MetadataWhereInput `json:"and,omitempty"` + + // "id" field predicates. + ID *int `json:"id,omitempty"` + IDNEQ *int `json:"idNEQ,omitempty"` + IDIn []int `json:"idIn,omitempty"` + IDNotIn []int `json:"idNotIn,omitempty"` + IDGT *int `json:"idGT,omitempty"` + IDGTE *int `json:"idGTE,omitempty"` + IDLT *int `json:"idLT,omitempty"` + IDLTE *int `json:"idLTE,omitempty"` + + // "key" field predicates. + Key *string `json:"key,omitempty"` + KeyNEQ *string `json:"keyNEQ,omitempty"` + KeyIn []string `json:"keyIn,omitempty"` + KeyNotIn []string `json:"keyNotIn,omitempty"` + KeyGT *string `json:"keyGT,omitempty"` + KeyGTE *string `json:"keyGTE,omitempty"` + KeyLT *string `json:"keyLT,omitempty"` + KeyLTE *string `json:"keyLTE,omitempty"` + KeyContains *string `json:"keyContains,omitempty"` + KeyHasPrefix *string `json:"keyHasPrefix,omitempty"` + KeyHasSuffix *string `json:"keyHasSuffix,omitempty"` + KeyEqualFold *string `json:"keyEqualFold,omitempty"` + KeyContainsFold *string `json:"keyContainsFold,omitempty"` + + // "value" field predicates. + Value *string `json:"value,omitempty"` + ValueNEQ *string `json:"valueNEQ,omitempty"` + ValueIn []string `json:"valueIn,omitempty"` + ValueNotIn []string `json:"valueNotIn,omitempty"` + ValueGT *string `json:"valueGT,omitempty"` + ValueGTE *string `json:"valueGTE,omitempty"` + ValueLT *string `json:"valueLT,omitempty"` + ValueLTE *string `json:"valueLTE,omitempty"` + ValueContains *string `json:"valueContains,omitempty"` + ValueHasPrefix *string `json:"valueHasPrefix,omitempty"` + ValueHasSuffix *string `json:"valueHasSuffix,omitempty"` + ValueEqualFold *string `json:"valueEqualFold,omitempty"` + ValueContainsFold *string `json:"valueContainsFold,omitempty"` + + // "envelope" edge predicates. + HasEnvelope *bool `json:"hasEnvelope,omitempty"` + HasEnvelopeWith []*DsseWhereInput `json:"hasEnvelopeWith,omitempty"` +} + +// AddPredicates adds custom predicates to the where input to be used during the filtering phase. +func (i *MetadataWhereInput) AddPredicates(predicates ...predicate.Metadata) { + i.Predicates = append(i.Predicates, predicates...) +} + +// Filter applies the MetadataWhereInput filter on the MetadataQuery builder. +func (i *MetadataWhereInput) Filter(q *MetadataQuery) (*MetadataQuery, error) { + if i == nil { + return q, nil + } + p, err := i.P() + if err != nil { + if err == ErrEmptyMetadataWhereInput { + return q, nil + } + return nil, err + } + return q.Where(p), nil +} + +// ErrEmptyMetadataWhereInput is returned in case the MetadataWhereInput is empty. +var ErrEmptyMetadataWhereInput = errors.New("ent: empty predicate MetadataWhereInput") + +// P returns a predicate for filtering metadataslice. +// An error is returned if the input is empty or invalid. +func (i *MetadataWhereInput) P() (predicate.Metadata, error) { + var predicates []predicate.Metadata + if i.Not != nil { + p, err := i.Not.P() + if err != nil { + return nil, fmt.Errorf("%w: field 'not'", err) + } + predicates = append(predicates, metadata.Not(p)) + } + switch n := len(i.Or); { + case n == 1: + p, err := i.Or[0].P() + if err != nil { + return nil, fmt.Errorf("%w: field 'or'", err) + } + predicates = append(predicates, p) + case n > 1: + or := make([]predicate.Metadata, 0, n) + for _, w := range i.Or { + p, err := w.P() + if err != nil { + return nil, fmt.Errorf("%w: field 'or'", err) + } + or = append(or, p) + } + predicates = append(predicates, metadata.Or(or...)) + } + switch n := len(i.And); { + case n == 1: + p, err := i.And[0].P() + if err != nil { + return nil, fmt.Errorf("%w: field 'and'", err) + } + predicates = append(predicates, p) + case n > 1: + and := make([]predicate.Metadata, 0, n) + for _, w := range i.And { + p, err := w.P() + if err != nil { + return nil, fmt.Errorf("%w: field 'and'", err) + } + and = append(and, p) + } + predicates = append(predicates, metadata.And(and...)) + } + predicates = append(predicates, i.Predicates...) + if i.ID != nil { + predicates = append(predicates, metadata.IDEQ(*i.ID)) + } + if i.IDNEQ != nil { + predicates = append(predicates, metadata.IDNEQ(*i.IDNEQ)) + } + if len(i.IDIn) > 0 { + predicates = append(predicates, metadata.IDIn(i.IDIn...)) + } + if len(i.IDNotIn) > 0 { + predicates = append(predicates, metadata.IDNotIn(i.IDNotIn...)) + } + if i.IDGT != nil { + predicates = append(predicates, metadata.IDGT(*i.IDGT)) + } + if i.IDGTE != nil { + predicates = append(predicates, metadata.IDGTE(*i.IDGTE)) + } + if i.IDLT != nil { + predicates = append(predicates, metadata.IDLT(*i.IDLT)) + } + if i.IDLTE != nil { + predicates = append(predicates, metadata.IDLTE(*i.IDLTE)) + } + if i.Key != nil { + predicates = append(predicates, metadata.KeyEQ(*i.Key)) + } + if i.KeyNEQ != nil { + predicates = append(predicates, metadata.KeyNEQ(*i.KeyNEQ)) + } + if len(i.KeyIn) > 0 { + predicates = append(predicates, metadata.KeyIn(i.KeyIn...)) + } + if len(i.KeyNotIn) > 0 { + predicates = append(predicates, metadata.KeyNotIn(i.KeyNotIn...)) + } + if i.KeyGT != nil { + predicates = append(predicates, metadata.KeyGT(*i.KeyGT)) + } + if i.KeyGTE != nil { + predicates = append(predicates, metadata.KeyGTE(*i.KeyGTE)) + } + if i.KeyLT != nil { + predicates = append(predicates, metadata.KeyLT(*i.KeyLT)) + } + if i.KeyLTE != nil { + predicates = append(predicates, metadata.KeyLTE(*i.KeyLTE)) + } + if i.KeyContains != nil { + predicates = append(predicates, metadata.KeyContains(*i.KeyContains)) + } + if i.KeyHasPrefix != nil { + predicates = append(predicates, metadata.KeyHasPrefix(*i.KeyHasPrefix)) + } + if i.KeyHasSuffix != nil { + predicates = append(predicates, metadata.KeyHasSuffix(*i.KeyHasSuffix)) + } + if i.KeyEqualFold != nil { + predicates = append(predicates, metadata.KeyEqualFold(*i.KeyEqualFold)) + } + if i.KeyContainsFold != nil { + predicates = append(predicates, metadata.KeyContainsFold(*i.KeyContainsFold)) + } + if i.Value != nil { + predicates = append(predicates, metadata.ValueEQ(*i.Value)) + } + if i.ValueNEQ != nil { + predicates = append(predicates, metadata.ValueNEQ(*i.ValueNEQ)) + } + if len(i.ValueIn) > 0 { + predicates = append(predicates, metadata.ValueIn(i.ValueIn...)) + } + if len(i.ValueNotIn) > 0 { + predicates = append(predicates, metadata.ValueNotIn(i.ValueNotIn...)) + } + if i.ValueGT != nil { + predicates = append(predicates, metadata.ValueGT(*i.ValueGT)) + } + if i.ValueGTE != nil { + predicates = append(predicates, metadata.ValueGTE(*i.ValueGTE)) + } + if i.ValueLT != nil { + predicates = append(predicates, metadata.ValueLT(*i.ValueLT)) + } + if i.ValueLTE != nil { + predicates = append(predicates, metadata.ValueLTE(*i.ValueLTE)) + } + if i.ValueContains != nil { + predicates = append(predicates, metadata.ValueContains(*i.ValueContains)) + } + if i.ValueHasPrefix != nil { + predicates = append(predicates, metadata.ValueHasPrefix(*i.ValueHasPrefix)) + } + if i.ValueHasSuffix != nil { + predicates = append(predicates, metadata.ValueHasSuffix(*i.ValueHasSuffix)) + } + if i.ValueEqualFold != nil { + predicates = append(predicates, metadata.ValueEqualFold(*i.ValueEqualFold)) + } + if i.ValueContainsFold != nil { + predicates = append(predicates, metadata.ValueContainsFold(*i.ValueContainsFold)) + } + + if i.HasEnvelope != nil { + p := metadata.HasEnvelope() + if !*i.HasEnvelope { + p = metadata.Not(p) + } + predicates = append(predicates, p) + } + if len(i.HasEnvelopeWith) > 0 { + with := make([]predicate.Dsse, 0, len(i.HasEnvelopeWith)) + for _, w := range i.HasEnvelopeWith { + p, err := w.P() + if err != nil { + return nil, fmt.Errorf("%w: field 'HasEnvelopeWith'", err) + } + with = append(with, p) + } + predicates = append(predicates, metadata.HasEnvelopeWith(with...)) + } + switch len(predicates) { + case 0: + return nil, ErrEmptyMetadataWhereInput + case 1: + return predicates[0], nil + default: + return metadata.And(predicates...), nil + } +} + // PayloadDigestWhereInput represents a where input for filtering PayloadDigest queries. type PayloadDigestWhereInput struct { Predicates []predicate.PayloadDigest `json:"-"` diff --git a/ent/hook/hook.go b/ent/hook/hook.go index a4f9b6f4..77a0ba3a 100644 --- a/ent/hook/hook.go +++ b/ent/hook/hook.go @@ -57,6 +57,18 @@ func (f DsseFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.DsseMutation", m) } +// The MetadataFunc type is an adapter to allow the use of ordinary +// function as Metadata mutator. +type MetadataFunc func(context.Context, *ent.MetadataMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f MetadataFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.MetadataMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.MetadataMutation", m) +} + // The PayloadDigestFunc type is an adapter to allow the use of ordinary // function as PayloadDigest mutator. type PayloadDigestFunc func(context.Context, *ent.PayloadDigestMutation) (ent.Value, error) diff --git a/ent/metadata.go b/ent/metadata.go new file mode 100644 index 00000000..87b88dc2 --- /dev/null +++ b/ent/metadata.go @@ -0,0 +1,168 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "github.com/in-toto/archivista/ent/metadata" +) + +// Metadata is the model entity for the Metadata schema. +type Metadata struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // Key value for the metadata item + Key string `json:"key,omitempty"` + // Value for the metadata item + Value string `json:"value,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the MetadataQuery when eager-loading is set. + Edges MetadataEdges `json:"edges"` + selectValues sql.SelectValues +} + +// MetadataEdges holds the relations/edges for other nodes in the graph. +type MetadataEdges struct { + // Envelope holds the value of the envelope edge. + Envelope []*Dsse `json:"envelope,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool + // totalCount holds the count of the edges above. + totalCount [1]map[string]int + + namedEnvelope map[string][]*Dsse +} + +// EnvelopeOrErr returns the Envelope value or an error if the edge +// was not loaded in eager-loading. +func (e MetadataEdges) EnvelopeOrErr() ([]*Dsse, error) { + if e.loadedTypes[0] { + return e.Envelope, nil + } + return nil, &NotLoadedError{edge: "envelope"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Metadata) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case metadata.FieldID: + values[i] = new(sql.NullInt64) + case metadata.FieldKey, metadata.FieldValue: + values[i] = new(sql.NullString) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Metadata fields. +func (m *Metadata) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case metadata.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + m.ID = int(value.Int64) + case metadata.FieldKey: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field key", values[i]) + } else if value.Valid { + m.Key = value.String + } + case metadata.FieldValue: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field value", values[i]) + } else if value.Valid { + m.Value = value.String + } + default: + m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// GetValue returns the ent.Value that was dynamically selected and assigned to the Metadata. +// This includes values selected through modifiers, order, etc. +func (m *Metadata) GetValue(name string) (ent.Value, error) { + return m.selectValues.Get(name) +} + +// QueryEnvelope queries the "envelope" edge of the Metadata entity. +func (m *Metadata) QueryEnvelope() *DsseQuery { + return NewMetadataClient(m.config).QueryEnvelope(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. +func (m *Metadata) Update() *MetadataUpdateOne { + return NewMetadataClient(m.config).UpdateOne(m) +} + +// Unwrap unwraps the Metadata entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (m *Metadata) Unwrap() *Metadata { + _tx, ok := m.config.driver.(*txDriver) + if !ok { + panic("ent: Metadata is not a transactional entity") + } + m.config.driver = _tx.drv + return m +} + +// String implements the fmt.Stringer. +func (m *Metadata) String() string { + var builder strings.Builder + builder.WriteString("Metadata(") + builder.WriteString(fmt.Sprintf("id=%v, ", m.ID)) + builder.WriteString("key=") + builder.WriteString(m.Key) + builder.WriteString(", ") + builder.WriteString("value=") + builder.WriteString(m.Value) + builder.WriteByte(')') + return builder.String() +} + +// NamedEnvelope returns the Envelope named value or an error if the edge was not +// loaded in eager-loading with this name. +func (m *Metadata) NamedEnvelope(name string) ([]*Dsse, error) { + if m.Edges.namedEnvelope == nil { + return nil, &NotLoadedError{edge: name} + } + nodes, ok := m.Edges.namedEnvelope[name] + if !ok { + return nil, &NotLoadedError{edge: name} + } + return nodes, nil +} + +func (m *Metadata) appendNamedEnvelope(name string, edges ...*Dsse) { + if m.Edges.namedEnvelope == nil { + m.Edges.namedEnvelope = make(map[string][]*Dsse) + } + if len(edges) == 0 { + m.Edges.namedEnvelope[name] = []*Dsse{} + } else { + m.Edges.namedEnvelope[name] = append(m.Edges.namedEnvelope[name], edges...) + } +} + +// MetadataSlice is a parsable slice of Metadata. +type MetadataSlice []*Metadata diff --git a/ent/metadata/metadata.go b/ent/metadata/metadata.go new file mode 100644 index 00000000..a7de0e63 --- /dev/null +++ b/ent/metadata/metadata.go @@ -0,0 +1,97 @@ +// Code generated by ent, DO NOT EDIT. + +package metadata + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the metadata type in the database. + Label = "metadata" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldKey holds the string denoting the key field in the database. + FieldKey = "key" + // FieldValue holds the string denoting the value field in the database. + FieldValue = "value" + // EdgeEnvelope holds the string denoting the envelope edge name in mutations. + EdgeEnvelope = "envelope" + // Table holds the table name of the metadata in the database. + Table = "metadata" + // EnvelopeTable is the table that holds the envelope relation/edge. The primary key declared below. + EnvelopeTable = "dsse_metadata" + // EnvelopeInverseTable is the table name for the Dsse entity. + // It exists in this package in order to avoid circular dependency with the "dsse" package. + EnvelopeInverseTable = "dsses" +) + +// Columns holds all SQL columns for metadata fields. +var Columns = []string{ + FieldID, + FieldKey, + FieldValue, +} + +var ( + // EnvelopePrimaryKey and EnvelopeColumn2 are the table columns denoting the + // primary key for the envelope relation (M2M). + EnvelopePrimaryKey = []string{"dsse_id", "metadata_id"} +) + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // KeyValidator is a validator for the "key" field. It is called by the builders before save. + KeyValidator func(string) error + // ValueValidator is a validator for the "value" field. It is called by the builders before save. + ValueValidator func(string) error +) + +// OrderOption defines the ordering options for the Metadata queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByKey orders the results by the key field. +func ByKey(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldKey, opts...).ToFunc() +} + +// ByValue orders the results by the value field. +func ByValue(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldValue, opts...).ToFunc() +} + +// ByEnvelopeCount orders the results by envelope count. +func ByEnvelopeCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newEnvelopeStep(), opts...) + } +} + +// ByEnvelope orders the results by envelope terms. +func ByEnvelope(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newEnvelopeStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newEnvelopeStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(EnvelopeInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, EnvelopeTable, EnvelopePrimaryKey...), + ) +} diff --git a/ent/metadata/where.go b/ent/metadata/where.go new file mode 100644 index 00000000..a5a301e0 --- /dev/null +++ b/ent/metadata/where.go @@ -0,0 +1,232 @@ +// Code generated by ent, DO NOT EDIT. + +package metadata + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/in-toto/archivista/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.Metadata { + return predicate.Metadata(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.Metadata { + return predicate.Metadata(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.Metadata { + return predicate.Metadata(sql.FieldLTE(FieldID, id)) +} + +// Key applies equality check predicate on the "key" field. It's identical to KeyEQ. +func Key(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldEQ(FieldKey, v)) +} + +// Value applies equality check predicate on the "value" field. It's identical to ValueEQ. +func Value(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldEQ(FieldValue, v)) +} + +// KeyEQ applies the EQ predicate on the "key" field. +func KeyEQ(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldEQ(FieldKey, v)) +} + +// KeyNEQ applies the NEQ predicate on the "key" field. +func KeyNEQ(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldNEQ(FieldKey, v)) +} + +// KeyIn applies the In predicate on the "key" field. +func KeyIn(vs ...string) predicate.Metadata { + return predicate.Metadata(sql.FieldIn(FieldKey, vs...)) +} + +// KeyNotIn applies the NotIn predicate on the "key" field. +func KeyNotIn(vs ...string) predicate.Metadata { + return predicate.Metadata(sql.FieldNotIn(FieldKey, vs...)) +} + +// KeyGT applies the GT predicate on the "key" field. +func KeyGT(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldGT(FieldKey, v)) +} + +// KeyGTE applies the GTE predicate on the "key" field. +func KeyGTE(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldGTE(FieldKey, v)) +} + +// KeyLT applies the LT predicate on the "key" field. +func KeyLT(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldLT(FieldKey, v)) +} + +// KeyLTE applies the LTE predicate on the "key" field. +func KeyLTE(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldLTE(FieldKey, v)) +} + +// KeyContains applies the Contains predicate on the "key" field. +func KeyContains(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldContains(FieldKey, v)) +} + +// KeyHasPrefix applies the HasPrefix predicate on the "key" field. +func KeyHasPrefix(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldHasPrefix(FieldKey, v)) +} + +// KeyHasSuffix applies the HasSuffix predicate on the "key" field. +func KeyHasSuffix(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldHasSuffix(FieldKey, v)) +} + +// KeyEqualFold applies the EqualFold predicate on the "key" field. +func KeyEqualFold(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldEqualFold(FieldKey, v)) +} + +// KeyContainsFold applies the ContainsFold predicate on the "key" field. +func KeyContainsFold(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldContainsFold(FieldKey, v)) +} + +// ValueEQ applies the EQ predicate on the "value" field. +func ValueEQ(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldEQ(FieldValue, v)) +} + +// ValueNEQ applies the NEQ predicate on the "value" field. +func ValueNEQ(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldNEQ(FieldValue, v)) +} + +// ValueIn applies the In predicate on the "value" field. +func ValueIn(vs ...string) predicate.Metadata { + return predicate.Metadata(sql.FieldIn(FieldValue, vs...)) +} + +// ValueNotIn applies the NotIn predicate on the "value" field. +func ValueNotIn(vs ...string) predicate.Metadata { + return predicate.Metadata(sql.FieldNotIn(FieldValue, vs...)) +} + +// ValueGT applies the GT predicate on the "value" field. +func ValueGT(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldGT(FieldValue, v)) +} + +// ValueGTE applies the GTE predicate on the "value" field. +func ValueGTE(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldGTE(FieldValue, v)) +} + +// ValueLT applies the LT predicate on the "value" field. +func ValueLT(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldLT(FieldValue, v)) +} + +// ValueLTE applies the LTE predicate on the "value" field. +func ValueLTE(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldLTE(FieldValue, v)) +} + +// ValueContains applies the Contains predicate on the "value" field. +func ValueContains(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldContains(FieldValue, v)) +} + +// ValueHasPrefix applies the HasPrefix predicate on the "value" field. +func ValueHasPrefix(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldHasPrefix(FieldValue, v)) +} + +// ValueHasSuffix applies the HasSuffix predicate on the "value" field. +func ValueHasSuffix(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldHasSuffix(FieldValue, v)) +} + +// ValueEqualFold applies the EqualFold predicate on the "value" field. +func ValueEqualFold(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldEqualFold(FieldValue, v)) +} + +// ValueContainsFold applies the ContainsFold predicate on the "value" field. +func ValueContainsFold(v string) predicate.Metadata { + return predicate.Metadata(sql.FieldContainsFold(FieldValue, v)) +} + +// HasEnvelope applies the HasEdge predicate on the "envelope" edge. +func HasEnvelope() predicate.Metadata { + return predicate.Metadata(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, EnvelopeTable, EnvelopePrimaryKey...), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasEnvelopeWith applies the HasEdge predicate on the "envelope" edge with a given conditions (other predicates). +func HasEnvelopeWith(preds ...predicate.Dsse) predicate.Metadata { + return predicate.Metadata(func(s *sql.Selector) { + step := newEnvelopeStep() + 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...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Metadata) predicate.Metadata { + return predicate.Metadata(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Metadata) predicate.Metadata { + return predicate.Metadata(sql.NotPredicates(p)) +} diff --git a/ent/metadata_create.go b/ent/metadata_create.go new file mode 100644 index 00000000..fe0a682a --- /dev/null +++ b/ent/metadata_create.go @@ -0,0 +1,238 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" +) + +// MetadataCreate is the builder for creating a Metadata entity. +type MetadataCreate struct { + config + mutation *MetadataMutation + hooks []Hook +} + +// SetKey sets the "key" field. +func (mc *MetadataCreate) SetKey(s string) *MetadataCreate { + mc.mutation.SetKey(s) + return mc +} + +// SetValue sets the "value" field. +func (mc *MetadataCreate) SetValue(s string) *MetadataCreate { + mc.mutation.SetValue(s) + return mc +} + +// AddEnvelopeIDs adds the "envelope" edge to the Dsse entity by IDs. +func (mc *MetadataCreate) AddEnvelopeIDs(ids ...int) *MetadataCreate { + mc.mutation.AddEnvelopeIDs(ids...) + return mc +} + +// AddEnvelope adds the "envelope" edges to the Dsse entity. +func (mc *MetadataCreate) AddEnvelope(d ...*Dsse) *MetadataCreate { + ids := make([]int, len(d)) + for i := range d { + ids[i] = d[i].ID + } + return mc.AddEnvelopeIDs(ids...) +} + +// Mutation returns the MetadataMutation object of the builder. +func (mc *MetadataCreate) Mutation() *MetadataMutation { + return mc.mutation +} + +// Save creates the Metadata in the database. +func (mc *MetadataCreate) Save(ctx context.Context) (*Metadata, error) { + return withHooks(ctx, mc.sqlSave, mc.mutation, mc.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (mc *MetadataCreate) SaveX(ctx context.Context) *Metadata { + v, err := mc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mc *MetadataCreate) Exec(ctx context.Context) error { + _, err := mc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mc *MetadataCreate) ExecX(ctx context.Context) { + if err := mc.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mc *MetadataCreate) check() error { + if _, ok := mc.mutation.Key(); !ok { + return &ValidationError{Name: "key", err: errors.New(`ent: missing required field "Metadata.key"`)} + } + if v, ok := mc.mutation.Key(); ok { + if err := metadata.KeyValidator(v); err != nil { + return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Metadata.key": %w`, err)} + } + } + if _, ok := mc.mutation.Value(); !ok { + return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "Metadata.value"`)} + } + if v, ok := mc.mutation.Value(); ok { + if err := metadata.ValueValidator(v); err != nil { + return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Metadata.value": %w`, err)} + } + } + return nil +} + +func (mc *MetadataCreate) sqlSave(ctx context.Context) (*Metadata, error) { + if err := mc.check(); err != nil { + return nil, err + } + _node, _spec := mc.createSpec() + if err := sqlgraph.CreateNode(ctx, mc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int(id) + mc.mutation.id = &_node.ID + mc.mutation.done = true + return _node, nil +} + +func (mc *MetadataCreate) createSpec() (*Metadata, *sqlgraph.CreateSpec) { + var ( + _node = &Metadata{config: mc.config} + _spec = sqlgraph.NewCreateSpec(metadata.Table, sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt)) + ) + if value, ok := mc.mutation.Key(); ok { + _spec.SetField(metadata.FieldKey, field.TypeString, value) + _node.Key = value + } + if value, ok := mc.mutation.Value(); ok { + _spec.SetField(metadata.FieldValue, field.TypeString, value) + _node.Value = value + } + if nodes := mc.mutation.EnvelopeIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// MetadataCreateBulk is the builder for creating many Metadata entities in bulk. +type MetadataCreateBulk struct { + config + err error + builders []*MetadataCreate +} + +// Save creates the Metadata entities in the database. +func (mcb *MetadataCreateBulk) Save(ctx context.Context) ([]*Metadata, error) { + if mcb.err != nil { + return nil, mcb.err + } + specs := make([]*sqlgraph.CreateSpec, len(mcb.builders)) + nodes := make([]*Metadata, len(mcb.builders)) + mutators := make([]Mutator, len(mcb.builders)) + for i := range mcb.builders { + func(i int, root context.Context) { + builder := mcb.builders[i] + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*MetadataMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, mcb.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, mcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, mcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (mcb *MetadataCreateBulk) SaveX(ctx context.Context) []*Metadata { + v, err := mcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (mcb *MetadataCreateBulk) Exec(ctx context.Context) error { + _, err := mcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mcb *MetadataCreateBulk) ExecX(ctx context.Context) { + if err := mcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/metadata_delete.go b/ent/metadata_delete.go new file mode 100644 index 00000000..586463c3 --- /dev/null +++ b/ent/metadata_delete.go @@ -0,0 +1,88 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/in-toto/archivista/ent/metadata" + "github.com/in-toto/archivista/ent/predicate" +) + +// MetadataDelete is the builder for deleting a Metadata entity. +type MetadataDelete struct { + config + hooks []Hook + mutation *MetadataMutation +} + +// Where appends a list predicates to the MetadataDelete builder. +func (md *MetadataDelete) Where(ps ...predicate.Metadata) *MetadataDelete { + md.mutation.Where(ps...) + return md +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (md *MetadataDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, md.sqlExec, md.mutation, md.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (md *MetadataDelete) ExecX(ctx context.Context) int { + n, err := md.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (md *MetadataDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(metadata.Table, sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt)) + if ps := md.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, md.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + md.mutation.done = true + return affected, err +} + +// MetadataDeleteOne is the builder for deleting a single Metadata entity. +type MetadataDeleteOne struct { + md *MetadataDelete +} + +// Where appends a list predicates to the MetadataDelete builder. +func (mdo *MetadataDeleteOne) Where(ps ...predicate.Metadata) *MetadataDeleteOne { + mdo.md.mutation.Where(ps...) + return mdo +} + +// Exec executes the deletion query. +func (mdo *MetadataDeleteOne) Exec(ctx context.Context) error { + n, err := mdo.md.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{metadata.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (mdo *MetadataDeleteOne) ExecX(ctx context.Context) { + if err := mdo.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/metadata_query.go b/ent/metadata_query.go new file mode 100644 index 00000000..13ba68f9 --- /dev/null +++ b/ent/metadata_query.go @@ -0,0 +1,671 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" + "github.com/in-toto/archivista/ent/predicate" +) + +// MetadataQuery is the builder for querying Metadata entities. +type MetadataQuery struct { + config + ctx *QueryContext + order []metadata.OrderOption + inters []Interceptor + predicates []predicate.Metadata + withEnvelope *DsseQuery + modifiers []func(*sql.Selector) + loadTotal []func(context.Context, []*Metadata) error + withNamedEnvelope map[string]*DsseQuery + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the MetadataQuery builder. +func (mq *MetadataQuery) Where(ps ...predicate.Metadata) *MetadataQuery { + mq.predicates = append(mq.predicates, ps...) + return mq +} + +// Limit the number of records to be returned by this query. +func (mq *MetadataQuery) Limit(limit int) *MetadataQuery { + mq.ctx.Limit = &limit + return mq +} + +// Offset to start from. +func (mq *MetadataQuery) Offset(offset int) *MetadataQuery { + mq.ctx.Offset = &offset + return mq +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (mq *MetadataQuery) Unique(unique bool) *MetadataQuery { + mq.ctx.Unique = &unique + return mq +} + +// Order specifies how the records should be ordered. +func (mq *MetadataQuery) Order(o ...metadata.OrderOption) *MetadataQuery { + mq.order = append(mq.order, o...) + return mq +} + +// QueryEnvelope chains the current query on the "envelope" edge. +func (mq *MetadataQuery) QueryEnvelope() *DsseQuery { + query := (&DsseClient{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(dsse.Table, dsse.FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, metadata.EnvelopeTable, metadata.EnvelopePrimaryKey...), + ) + 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) { + nodes, err := mq.Limit(1).All(setContextOp(ctx, mq.ctx, "First")) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{metadata.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (mq *MetadataQuery) FirstX(ctx context.Context) *Metadata { + node, err := mq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Metadata ID from the query. +// Returns a *NotFoundError when no Metadata ID was found. +func (mq *MetadataQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = mq.Limit(1).IDs(setContextOp(ctx, mq.ctx, "FirstID")); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{metadata.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (mq *MetadataQuery) FirstIDX(ctx context.Context) int { + id, err := mq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Metadata entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one Metadata entity is found. +// Returns a *NotFoundError when no Metadata entities are found. +func (mq *MetadataQuery) Only(ctx context.Context) (*Metadata, error) { + nodes, err := mq.Limit(2).All(setContextOp(ctx, mq.ctx, "Only")) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{metadata.Label} + default: + return nil, &NotSingularError{metadata.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (mq *MetadataQuery) OnlyX(ctx context.Context) *Metadata { + node, err := mq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Metadata ID in the query. +// Returns a *NotSingularError when more than one Metadata ID is found. +// Returns a *NotFoundError when no entities are found. +func (mq *MetadataQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = mq.Limit(2).IDs(setContextOp(ctx, mq.ctx, "OnlyID")); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{metadata.Label} + default: + err = &NotSingularError{metadata.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (mq *MetadataQuery) OnlyIDX(ctx context.Context) int { + id, err := mq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of MetadataSlice. +func (mq *MetadataQuery) All(ctx context.Context) ([]*Metadata, error) { + ctx = setContextOp(ctx, mq.ctx, "All") + if err := mq.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*Metadata, *MetadataQuery]() + return withInterceptors[[]*Metadata](ctx, mq, qr, mq.inters) +} + +// AllX is like All, but panics if an error occurs. +func (mq *MetadataQuery) AllX(ctx context.Context) []*Metadata { + nodes, err := mq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Metadata IDs. +func (mq *MetadataQuery) IDs(ctx context.Context) (ids []int, err error) { + if mq.ctx.Unique == nil && mq.path != nil { + mq.Unique(true) + } + ctx = setContextOp(ctx, mq.ctx, "IDs") + if err = mq.Select(metadata.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (mq *MetadataQuery) IDsX(ctx context.Context) []int { + ids, err := mq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (mq *MetadataQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, mq.ctx, "Count") + if err := mq.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, mq, querierCount[*MetadataQuery](), mq.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (mq *MetadataQuery) CountX(ctx context.Context) int { + count, err := mq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (mq *MetadataQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, mq.ctx, "Exist") + switch _, err := mq.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (mq *MetadataQuery) ExistX(ctx context.Context) bool { + exist, err := mq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the MetadataQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (mq *MetadataQuery) Clone() *MetadataQuery { + if mq == nil { + return nil + } + return &MetadataQuery{ + config: mq.config, + ctx: mq.ctx.Clone(), + order: append([]metadata.OrderOption{}, mq.order...), + inters: append([]Interceptor{}, mq.inters...), + predicates: append([]predicate.Metadata{}, mq.predicates...), + withEnvelope: mq.withEnvelope.Clone(), + // clone intermediate query. + sql: mq.sql.Clone(), + path: mq.path, + } +} + +// WithEnvelope tells the query-builder to eager-load the nodes that are connected to +// the "envelope" edge. The optional arguments are used to configure the query builder of the edge. +func (mq *MetadataQuery) WithEnvelope(opts ...func(*DsseQuery)) *MetadataQuery { + query := (&DsseClient{config: mq.config}).Query() + for _, opt := range opts { + opt(query) + } + mq.withEnvelope = 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. +// +// Example: +// +// var v []struct { +// Key string `json:"key,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Metadata.Query(). +// GroupBy(metadata.FieldKey). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (mq *MetadataQuery) GroupBy(field string, fields ...string) *MetadataGroupBy { + mq.ctx.Fields = append([]string{field}, fields...) + grbuild := &MetadataGroupBy{build: mq} + grbuild.flds = &mq.ctx.Fields + grbuild.label = metadata.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// 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 { +// Key string `json:"key,omitempty"` +// } +// +// client.Metadata.Query(). +// Select(metadata.FieldKey). +// Scan(ctx, &v) +func (mq *MetadataQuery) Select(fields ...string) *MetadataSelect { + mq.ctx.Fields = append(mq.ctx.Fields, fields...) + sbuild := &MetadataSelect{MetadataQuery: mq} + sbuild.label = metadata.Label + sbuild.flds, sbuild.scan = &mq.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a MetadataSelect configured with the given aggregations. +func (mq *MetadataQuery) Aggregate(fns ...AggregateFunc) *MetadataSelect { + return mq.Select().Aggregate(fns...) +} + +func (mq *MetadataQuery) prepareQuery(ctx context.Context) error { + for _, inter := range mq.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, mq); err != nil { + return err + } + } + } + for _, f := range mq.ctx.Fields { + if !metadata.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if mq.path != nil { + prev, err := mq.path(ctx) + if err != nil { + return err + } + mq.sql = prev + } + return nil +} + +func (mq *MetadataQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Metadata, error) { + var ( + nodes = []*Metadata{} + _spec = mq.querySpec() + loadedTypes = [1]bool{ + mq.withEnvelope != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*Metadata).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &Metadata{config: mq.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + if len(mq.modifiers) > 0 { + _spec.Modifiers = mq.modifiers + } + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, mq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := mq.withEnvelope; query != nil { + if err := mq.loadEnvelope(ctx, query, nodes, + func(n *Metadata) { n.Edges.Envelope = []*Dsse{} }, + func(n *Metadata, e *Dsse) { n.Edges.Envelope = append(n.Edges.Envelope, e) }); err != nil { + return nil, err + } + } + for name, query := range mq.withNamedEnvelope { + if err := mq.loadEnvelope(ctx, query, nodes, + func(n *Metadata) { n.appendNamedEnvelope(name) }, + func(n *Metadata, e *Dsse) { n.appendNamedEnvelope(name, e) }); err != nil { + return nil, err + } + } + for i := range mq.loadTotal { + if err := mq.loadTotal[i](ctx, nodes); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (mq *MetadataQuery) loadEnvelope(ctx context.Context, query *DsseQuery, nodes []*Metadata, init func(*Metadata), assign func(*Metadata, *Dsse)) error { + edgeIDs := make([]driver.Value, len(nodes)) + byID := make(map[int]*Metadata) + nids := make(map[int]map[*Metadata]struct{}) + for i, node := range nodes { + edgeIDs[i] = node.ID + byID[node.ID] = node + if init != nil { + init(node) + } + } + query.Where(func(s *sql.Selector) { + joinT := sql.Table(metadata.EnvelopeTable) + s.Join(joinT).On(s.C(dsse.FieldID), joinT.C(metadata.EnvelopePrimaryKey[0])) + s.Where(sql.InValues(joinT.C(metadata.EnvelopePrimaryKey[1]), edgeIDs...)) + columns := s.SelectedColumns() + s.Select(joinT.C(metadata.EnvelopePrimaryKey[1])) + s.AppendSelect(columns...) + s.SetDistinct(false) + }) + if err := query.prepareQuery(ctx); err != nil { + return err + } + qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) { + assign := spec.Assign + values := spec.ScanValues + spec.ScanValues = func(columns []string) ([]any, error) { + values, err := values(columns[1:]) + if err != nil { + return nil, err + } + return append([]any{new(sql.NullInt64)}, values...), nil + } + spec.Assign = func(columns []string, values []any) error { + outValue := int(values[0].(*sql.NullInt64).Int64) + inValue := int(values[1].(*sql.NullInt64).Int64) + if nids[inValue] == nil { + nids[inValue] = map[*Metadata]struct{}{byID[outValue]: {}} + return assign(columns[1:], values[1:]) + } + nids[inValue][byID[outValue]] = struct{}{} + return nil + } + }) + }) + neighbors, err := withInterceptors[[]*Dsse](ctx, query, qr, query.inters) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nids[n.ID] + if !ok { + return fmt.Errorf(`unexpected "envelope" node returned %v`, n.ID) + } + for kn := range nodes { + assign(kn, n) + } + } + return nil +} + +func (mq *MetadataQuery) sqlCount(ctx context.Context) (int, error) { + _spec := mq.querySpec() + if len(mq.modifiers) > 0 { + _spec.Modifiers = mq.modifiers + } + _spec.Node.Columns = mq.ctx.Fields + if len(mq.ctx.Fields) > 0 { + _spec.Unique = mq.ctx.Unique != nil && *mq.ctx.Unique + } + return sqlgraph.CountNodes(ctx, mq.driver, _spec) +} + +func (mq *MetadataQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(metadata.Table, metadata.Columns, sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt)) + _spec.From = mq.sql + if unique := mq.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if mq.path != nil { + _spec.Unique = true + } + if fields := mq.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, metadata.FieldID) + for i := range fields { + if fields[i] != metadata.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := mq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := mq.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := mq.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := mq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (mq *MetadataQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(mq.driver.Dialect()) + t1 := builder.Table(metadata.Table) + columns := mq.ctx.Fields + if len(columns) == 0 { + columns = metadata.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if mq.sql != nil { + selector = mq.sql + selector.Select(selector.Columns(columns...)...) + } + if mq.ctx.Unique != nil && *mq.ctx.Unique { + selector.Distinct() + } + for _, p := range mq.predicates { + p(selector) + } + for _, p := range mq.order { + p(selector) + } + if offset := mq.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := mq.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// WithNamedEnvelope tells the query-builder to eager-load the nodes that are connected to the "envelope" +// edge with the given name. The optional arguments are used to configure the query builder of the edge. +func (mq *MetadataQuery) WithNamedEnvelope(name string, opts ...func(*DsseQuery)) *MetadataQuery { + query := (&DsseClient{config: mq.config}).Query() + for _, opt := range opts { + opt(query) + } + if mq.withNamedEnvelope == nil { + mq.withNamedEnvelope = make(map[string]*DsseQuery) + } + mq.withNamedEnvelope[name] = query + return mq +} + +// MetadataGroupBy is the group-by builder for Metadata entities. +type MetadataGroupBy struct { + selector + build *MetadataQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (mgb *MetadataGroupBy) Aggregate(fns ...AggregateFunc) *MetadataGroupBy { + mgb.fns = append(mgb.fns, fns...) + return mgb +} + +// Scan applies the selector query and scans the result into the given value. +func (mgb *MetadataGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, mgb.build.ctx, "GroupBy") + if err := mgb.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MetadataQuery, *MetadataGroupBy](ctx, mgb.build, mgb, mgb.build.inters, v) +} + +func (mgb *MetadataGroupBy) sqlScan(ctx context.Context, root *MetadataQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(mgb.fns)) + for _, fn := range mgb.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*mgb.flds)+len(mgb.fns)) + for _, f := range *mgb.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*mgb.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := mgb.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// MetadataSelect is the builder for selecting fields of Metadata entities. +type MetadataSelect struct { + *MetadataQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (ms *MetadataSelect) Aggregate(fns ...AggregateFunc) *MetadataSelect { + ms.fns = append(ms.fns, fns...) + return ms +} + +// Scan applies the selector query and scans the result into the given value. +func (ms *MetadataSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, ms.ctx, "Select") + if err := ms.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*MetadataQuery, *MetadataSelect](ctx, ms.MetadataQuery, ms, ms.inters, v) +} + +func (ms *MetadataSelect) sqlScan(ctx context.Context, root *MetadataQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(ms.fns)) + for _, fn := range ms.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*ms.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := ms.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/metadata_update.go b/ent/metadata_update.go new file mode 100644 index 00000000..9cef90d4 --- /dev/null +++ b/ent/metadata_update.go @@ -0,0 +1,442 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" + "github.com/in-toto/archivista/ent/predicate" +) + +// MetadataUpdate is the builder for updating Metadata entities. +type MetadataUpdate struct { + config + hooks []Hook + mutation *MetadataMutation +} + +// Where appends a list predicates to the MetadataUpdate builder. +func (mu *MetadataUpdate) Where(ps ...predicate.Metadata) *MetadataUpdate { + mu.mutation.Where(ps...) + return mu +} + +// SetKey sets the "key" field. +func (mu *MetadataUpdate) SetKey(s string) *MetadataUpdate { + mu.mutation.SetKey(s) + return mu +} + +// SetNillableKey sets the "key" field if the given value is not nil. +func (mu *MetadataUpdate) SetNillableKey(s *string) *MetadataUpdate { + if s != nil { + mu.SetKey(*s) + } + return mu +} + +// SetValue sets the "value" field. +func (mu *MetadataUpdate) SetValue(s string) *MetadataUpdate { + mu.mutation.SetValue(s) + return mu +} + +// SetNillableValue sets the "value" field if the given value is not nil. +func (mu *MetadataUpdate) SetNillableValue(s *string) *MetadataUpdate { + if s != nil { + mu.SetValue(*s) + } + return mu +} + +// AddEnvelopeIDs adds the "envelope" edge to the Dsse entity by IDs. +func (mu *MetadataUpdate) AddEnvelopeIDs(ids ...int) *MetadataUpdate { + mu.mutation.AddEnvelopeIDs(ids...) + return mu +} + +// AddEnvelope adds the "envelope" edges to the Dsse entity. +func (mu *MetadataUpdate) AddEnvelope(d ...*Dsse) *MetadataUpdate { + ids := make([]int, len(d)) + for i := range d { + ids[i] = d[i].ID + } + return mu.AddEnvelopeIDs(ids...) +} + +// Mutation returns the MetadataMutation object of the builder. +func (mu *MetadataUpdate) Mutation() *MetadataMutation { + return mu.mutation +} + +// ClearEnvelope clears all "envelope" edges to the Dsse entity. +func (mu *MetadataUpdate) ClearEnvelope() *MetadataUpdate { + mu.mutation.ClearEnvelope() + return mu +} + +// RemoveEnvelopeIDs removes the "envelope" edge to Dsse entities by IDs. +func (mu *MetadataUpdate) RemoveEnvelopeIDs(ids ...int) *MetadataUpdate { + mu.mutation.RemoveEnvelopeIDs(ids...) + return mu +} + +// RemoveEnvelope removes "envelope" edges to Dsse entities. +func (mu *MetadataUpdate) RemoveEnvelope(d ...*Dsse) *MetadataUpdate { + ids := make([]int, len(d)) + for i := range d { + ids[i] = d[i].ID + } + return mu.RemoveEnvelopeIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (mu *MetadataUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, mu.sqlSave, mu.mutation, mu.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (mu *MetadataUpdate) SaveX(ctx context.Context) int { + affected, err := mu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (mu *MetadataUpdate) Exec(ctx context.Context) error { + _, err := mu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (mu *MetadataUpdate) ExecX(ctx context.Context) { + if err := mu.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (mu *MetadataUpdate) check() error { + if v, ok := mu.mutation.Key(); ok { + if err := metadata.KeyValidator(v); err != nil { + return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Metadata.key": %w`, err)} + } + } + if v, ok := mu.mutation.Value(); ok { + if err := metadata.ValueValidator(v); err != nil { + return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Metadata.value": %w`, err)} + } + } + return nil +} + +func (mu *MetadataUpdate) sqlSave(ctx context.Context) (n int, err error) { + if err := mu.check(); err != nil { + return n, err + } + _spec := sqlgraph.NewUpdateSpec(metadata.Table, metadata.Columns, sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt)) + if ps := mu.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := mu.mutation.Key(); ok { + _spec.SetField(metadata.FieldKey, field.TypeString, value) + } + if value, ok := mu.mutation.Value(); ok { + _spec.SetField(metadata.FieldValue, field.TypeString, value) + } + if mu.mutation.EnvelopeCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := mu.mutation.RemovedEnvelopeIDs(); len(nodes) > 0 && !mu.mutation.EnvelopeCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.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 := mu.mutation.EnvelopeIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.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, mu.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{metadata.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + mu.mutation.done = true + return n, nil +} + +// MetadataUpdateOne is the builder for updating a single Metadata entity. +type MetadataUpdateOne struct { + config + fields []string + hooks []Hook + mutation *MetadataMutation +} + +// SetKey sets the "key" field. +func (muo *MetadataUpdateOne) SetKey(s string) *MetadataUpdateOne { + muo.mutation.SetKey(s) + return muo +} + +// SetNillableKey sets the "key" field if the given value is not nil. +func (muo *MetadataUpdateOne) SetNillableKey(s *string) *MetadataUpdateOne { + if s != nil { + muo.SetKey(*s) + } + return muo +} + +// SetValue sets the "value" field. +func (muo *MetadataUpdateOne) SetValue(s string) *MetadataUpdateOne { + muo.mutation.SetValue(s) + return muo +} + +// SetNillableValue sets the "value" field if the given value is not nil. +func (muo *MetadataUpdateOne) SetNillableValue(s *string) *MetadataUpdateOne { + if s != nil { + muo.SetValue(*s) + } + return muo +} + +// AddEnvelopeIDs adds the "envelope" edge to the Dsse entity by IDs. +func (muo *MetadataUpdateOne) AddEnvelopeIDs(ids ...int) *MetadataUpdateOne { + muo.mutation.AddEnvelopeIDs(ids...) + return muo +} + +// AddEnvelope adds the "envelope" edges to the Dsse entity. +func (muo *MetadataUpdateOne) AddEnvelope(d ...*Dsse) *MetadataUpdateOne { + ids := make([]int, len(d)) + for i := range d { + ids[i] = d[i].ID + } + return muo.AddEnvelopeIDs(ids...) +} + +// Mutation returns the MetadataMutation object of the builder. +func (muo *MetadataUpdateOne) Mutation() *MetadataMutation { + return muo.mutation +} + +// ClearEnvelope clears all "envelope" edges to the Dsse entity. +func (muo *MetadataUpdateOne) ClearEnvelope() *MetadataUpdateOne { + muo.mutation.ClearEnvelope() + return muo +} + +// RemoveEnvelopeIDs removes the "envelope" edge to Dsse entities by IDs. +func (muo *MetadataUpdateOne) RemoveEnvelopeIDs(ids ...int) *MetadataUpdateOne { + muo.mutation.RemoveEnvelopeIDs(ids...) + return muo +} + +// RemoveEnvelope removes "envelope" edges to Dsse entities. +func (muo *MetadataUpdateOne) RemoveEnvelope(d ...*Dsse) *MetadataUpdateOne { + ids := make([]int, len(d)) + for i := range d { + ids[i] = d[i].ID + } + return muo.RemoveEnvelopeIDs(ids...) +} + +// Where appends a list predicates to the MetadataUpdate builder. +func (muo *MetadataUpdateOne) Where(ps ...predicate.Metadata) *MetadataUpdateOne { + muo.mutation.Where(ps...) + return muo +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (muo *MetadataUpdateOne) Select(field string, fields ...string) *MetadataUpdateOne { + muo.fields = append([]string{field}, fields...) + return muo +} + +// Save executes the query and returns the updated Metadata entity. +func (muo *MetadataUpdateOne) Save(ctx context.Context) (*Metadata, error) { + return withHooks(ctx, muo.sqlSave, muo.mutation, muo.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (muo *MetadataUpdateOne) SaveX(ctx context.Context) *Metadata { + node, err := muo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (muo *MetadataUpdateOne) Exec(ctx context.Context) error { + _, err := muo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (muo *MetadataUpdateOne) ExecX(ctx context.Context) { + if err := muo.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (muo *MetadataUpdateOne) check() error { + if v, ok := muo.mutation.Key(); ok { + if err := metadata.KeyValidator(v); err != nil { + return &ValidationError{Name: "key", err: fmt.Errorf(`ent: validator failed for field "Metadata.key": %w`, err)} + } + } + if v, ok := muo.mutation.Value(); ok { + if err := metadata.ValueValidator(v); err != nil { + return &ValidationError{Name: "value", err: fmt.Errorf(`ent: validator failed for field "Metadata.value": %w`, err)} + } + } + return nil +} + +func (muo *MetadataUpdateOne) sqlSave(ctx context.Context) (_node *Metadata, err error) { + if err := muo.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(metadata.Table, metadata.Columns, sqlgraph.NewFieldSpec(metadata.FieldID, field.TypeInt)) + id, ok := muo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Metadata.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := muo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, metadata.FieldID) + for _, f := range fields { + if !metadata.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != metadata.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := muo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := muo.mutation.Key(); ok { + _spec.SetField(metadata.FieldKey, field.TypeString, value) + } + if value, ok := muo.mutation.Value(); ok { + _spec.SetField(metadata.FieldValue, field.TypeString, value) + } + if muo.mutation.EnvelopeCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := muo.mutation.RemovedEnvelopeIDs(); len(nodes) > 0 && !muo.mutation.EnvelopeCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.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 := muo.mutation.EnvelopeIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: metadata.EnvelopeTable, + Columns: metadata.EnvelopePrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(dsse.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &Metadata{config: muo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, muo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{metadata.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + muo.mutation.done = true + return _node, nil +} diff --git a/ent/migrate/migrations/mysql/20240508160053_mysql.sql b/ent/migrate/migrations/mysql/20240508160053_mysql.sql new file mode 100644 index 00000000..690f8c76 --- /dev/null +++ b/ent/migrate/migrations/mysql/20240508160053_mysql.sql @@ -0,0 +1,4 @@ +-- Create "metadata" table +CREATE TABLE `metadata` (`id` bigint NOT NULL AUTO_INCREMENT, `key` varchar(255) NOT NULL, `value` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE INDEX `metadata_key_value` (`key`, `value`)) CHARSET utf8mb4 COLLATE utf8mb4_bin; +-- Create "dsse_metadata" table +CREATE TABLE `dsse_metadata` (`dsse_id` bigint NOT NULL, `metadata_id` bigint NOT NULL, PRIMARY KEY (`dsse_id`, `metadata_id`), INDEX `dsse_metadata_metadata_id` (`metadata_id`), CONSTRAINT `dsse_metadata_dsse_id` FOREIGN KEY (`dsse_id`) REFERENCES `dsses` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT `dsse_metadata_metadata_id` FOREIGN KEY (`metadata_id`) REFERENCES `metadata` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE) CHARSET utf8mb4 COLLATE utf8mb4_bin; diff --git a/ent/migrate/migrations/mysql/atlas.sum b/ent/migrate/migrations/mysql/atlas.sum index a9adf4e2..48d4bf9d 100644 --- a/ent/migrate/migrations/mysql/atlas.sum +++ b/ent/migrate/migrations/mysql/atlas.sum @@ -1,3 +1,4 @@ -h1:1Ow/eZVMLy44Vylv2ewQF1uQtT3+kvN1yTCa+4JQ5MI= +h1:h4+//Zp70uy0uOntRmMD0NOZkoYipGI5CfesuOBAaKQ= 20231214165639_mysql.sql h1:rqSqoXUOtdEpJT04rLCzyyPJC+NYRjQj9jXHZW+Oq9Q= 20240412085222_mysql.sql h1:V7ePmRzeLat9gKTFnWvZnZIZe+r6OBu0bCS/xeVMPg8= +20240508160053_mysql.sql h1:wVeJo1aeTRJuOWhs8wxS1s7BkP9zdjUk+zUPzvTYa24= diff --git a/ent/migrate/migrations/pgsql/20240508160101_pgsql.sql b/ent/migrate/migrations/pgsql/20240508160101_pgsql.sql new file mode 100644 index 00000000..4d259219 --- /dev/null +++ b/ent/migrate/migrations/pgsql/20240508160101_pgsql.sql @@ -0,0 +1,6 @@ +-- Create "metadata" table +CREATE TABLE "metadata" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "key" character varying NOT NULL, "value" character varying NOT NULL, PRIMARY KEY ("id")); +-- Create index "metadata_key_value" to table: "metadata" +CREATE UNIQUE INDEX "metadata_key_value" ON "metadata" ("key", "value"); +-- Create "dsse_metadata" table +CREATE TABLE "dsse_metadata" ("dsse_id" bigint NOT NULL, "metadata_id" bigint NOT NULL, PRIMARY KEY ("dsse_id", "metadata_id"), CONSTRAINT "dsse_metadata_dsse_id" FOREIGN KEY ("dsse_id") REFERENCES "dsses" ("id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "dsse_metadata_metadata_id" FOREIGN KEY ("metadata_id") REFERENCES "metadata" ("id") ON UPDATE NO ACTION ON DELETE CASCADE); diff --git a/ent/migrate/migrations/pgsql/atlas.sum b/ent/migrate/migrations/pgsql/atlas.sum index 033e45fa..997e8244 100644 --- a/ent/migrate/migrations/pgsql/atlas.sum +++ b/ent/migrate/migrations/pgsql/atlas.sum @@ -1,3 +1,4 @@ -h1:D/veOuP9Sr5oRpHC8Ow9Td7h4BufsLknJawwIfzTdN0= +h1:6UtAiynkbRjb21BxXi9OhLWP7sxPh7C5lJ4vGLbJRxI= 20231214165922_pgsql.sql h1:AZaZD6/98yKVFL6svm7gPpKlD1EL6fk8juLh+SW765I= 20240412085224_pgsql.sql h1:OLX7vanfNS1O24Gp8Jeb/1pQJWJKs9cghXJNZ5pwTUc= +20240508160101_pgsql.sql h1:RZrQJ7ACznI1mDmeU37vLvkCjqJD78QComVw/7IUWMg= diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index 20ab26cb..e9abe2c0 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -110,6 +110,25 @@ var ( }, }, } + // MetadataColumns holds the columns for the "metadata" table. + MetadataColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "key", Type: field.TypeString}, + {Name: "value", Type: field.TypeString}, + } + // MetadataTable holds the schema information for the "metadata" table. + MetadataTable = &schema.Table{ + Name: "metadata", + Columns: MetadataColumns, + PrimaryKey: []*schema.Column{MetadataColumns[0]}, + Indexes: []*schema.Index{ + { + Name: "metadata_key_value", + Unique: true, + Columns: []*schema.Column{MetadataColumns[1], MetadataColumns[2]}, + }, + }, + } // PayloadDigestsColumns holds the columns for the "payload_digests" table. PayloadDigestsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, @@ -260,18 +279,45 @@ var ( }, }, } + // DsseMetadataColumns holds the columns for the "dsse_metadata" table. + DsseMetadataColumns = []*schema.Column{ + {Name: "dsse_id", Type: field.TypeInt}, + {Name: "metadata_id", Type: field.TypeInt}, + } + // DsseMetadataTable holds the schema information for the "dsse_metadata" table. + DsseMetadataTable = &schema.Table{ + Name: "dsse_metadata", + Columns: DsseMetadataColumns, + PrimaryKey: []*schema.Column{DsseMetadataColumns[0], DsseMetadataColumns[1]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "dsse_metadata_dsse_id", + Columns: []*schema.Column{DsseMetadataColumns[0]}, + RefColumns: []*schema.Column{DssesColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "dsse_metadata_metadata_id", + Columns: []*schema.Column{DsseMetadataColumns[1]}, + RefColumns: []*schema.Column{MetadataColumns[0]}, + OnDelete: schema.Cascade, + }, + }, + } // Tables holds all the tables in the schema. Tables = []*schema.Table{ AttestationsTable, AttestationCollectionsTable, AttestationPoliciesTable, DssesTable, + MetadataTable, PayloadDigestsTable, SignaturesTable, StatementsTable, SubjectsTable, SubjectDigestsTable, TimestampsTable, + DsseMetadataTable, } ) @@ -285,4 +331,6 @@ func init() { SubjectsTable.ForeignKeys[0].RefTable = StatementsTable SubjectDigestsTable.ForeignKeys[0].RefTable = SubjectsTable TimestampsTable.ForeignKeys[0].RefTable = SignaturesTable + DsseMetadataTable.ForeignKeys[0].RefTable = DssesTable + DsseMetadataTable.ForeignKeys[1].RefTable = MetadataTable } diff --git a/ent/mutation.go b/ent/mutation.go index 699c685d..17c7c025 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -15,6 +15,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/predicate" "github.com/in-toto/archivista/ent/signature" @@ -37,6 +38,7 @@ const ( TypeAttestationCollection = "AttestationCollection" TypeAttestationPolicy = "AttestationPolicy" TypeDsse = "Dsse" + TypeMetadata = "Metadata" TypePayloadDigest = "PayloadDigest" TypeSignature = "Signature" TypeStatement = "Statement" @@ -1326,6 +1328,9 @@ type DsseMutation struct { payload_digests map[int]struct{} removedpayload_digests map[int]struct{} clearedpayload_digests bool + metadata map[int]struct{} + removedmetadata map[int]struct{} + clearedmetadata bool done bool oldValue func(context.Context) (*Dsse, error) predicates []predicate.Dsse @@ -1648,6 +1653,60 @@ func (m *DsseMutation) ResetPayloadDigests() { m.removedpayload_digests = nil } +// AddMetadatumIDs adds the "metadata" edge to the Metadata entity by ids. +func (m *DsseMutation) AddMetadatumIDs(ids ...int) { + if m.metadata == nil { + m.metadata = make(map[int]struct{}) + } + for i := range ids { + m.metadata[ids[i]] = struct{}{} + } +} + +// ClearMetadata clears the "metadata" edge to the Metadata entity. +func (m *DsseMutation) ClearMetadata() { + m.clearedmetadata = true +} + +// MetadataCleared reports if the "metadata" edge to the Metadata entity was cleared. +func (m *DsseMutation) MetadataCleared() bool { + return m.clearedmetadata +} + +// RemoveMetadatumIDs removes the "metadata" edge to the Metadata entity by IDs. +func (m *DsseMutation) RemoveMetadatumIDs(ids ...int) { + if m.removedmetadata == nil { + m.removedmetadata = make(map[int]struct{}) + } + for i := range ids { + delete(m.metadata, ids[i]) + m.removedmetadata[ids[i]] = struct{}{} + } +} + +// RemovedMetadata returns the removed IDs of the "metadata" edge to the Metadata entity. +func (m *DsseMutation) RemovedMetadataIDs() (ids []int) { + for id := range m.removedmetadata { + ids = append(ids, id) + } + return +} + +// MetadataIDs returns the "metadata" edge IDs in the mutation. +func (m *DsseMutation) MetadataIDs() (ids []int) { + for id := range m.metadata { + ids = append(ids, id) + } + return +} + +// ResetMetadata resets all changes to the "metadata" edge. +func (m *DsseMutation) ResetMetadata() { + m.metadata = nil + m.clearedmetadata = false + m.removedmetadata = nil +} + // Where appends a list predicates to the DsseMutation builder. func (m *DsseMutation) Where(ps ...predicate.Dsse) { m.predicates = append(m.predicates, ps...) @@ -1798,7 +1857,7 @@ func (m *DsseMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *DsseMutation) AddedEdges() []string { - edges := make([]string, 0, 3) + edges := make([]string, 0, 4) if m.statement != nil { edges = append(edges, dsse.EdgeStatement) } @@ -1808,6 +1867,9 @@ func (m *DsseMutation) AddedEdges() []string { if m.payload_digests != nil { edges = append(edges, dsse.EdgePayloadDigests) } + if m.metadata != nil { + edges = append(edges, dsse.EdgeMetadata) + } return edges } @@ -1831,19 +1893,28 @@ func (m *DsseMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case dsse.EdgeMetadata: + ids := make([]ent.Value, 0, len(m.metadata)) + for id := range m.metadata { + ids = append(ids, id) + } + return ids } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *DsseMutation) RemovedEdges() []string { - edges := make([]string, 0, 3) + edges := make([]string, 0, 4) if m.removedsignatures != nil { edges = append(edges, dsse.EdgeSignatures) } if m.removedpayload_digests != nil { edges = append(edges, dsse.EdgePayloadDigests) } + if m.removedmetadata != nil { + edges = append(edges, dsse.EdgeMetadata) + } return edges } @@ -1863,13 +1934,19 @@ func (m *DsseMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case dsse.EdgeMetadata: + ids := make([]ent.Value, 0, len(m.removedmetadata)) + for id := range m.removedmetadata { + ids = append(ids, id) + } + return ids } return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *DsseMutation) ClearedEdges() []string { - edges := make([]string, 0, 3) + edges := make([]string, 0, 4) if m.clearedstatement { edges = append(edges, dsse.EdgeStatement) } @@ -1879,6 +1956,9 @@ func (m *DsseMutation) ClearedEdges() []string { if m.clearedpayload_digests { edges = append(edges, dsse.EdgePayloadDigests) } + if m.clearedmetadata { + edges = append(edges, dsse.EdgeMetadata) + } return edges } @@ -1892,6 +1972,8 @@ func (m *DsseMutation) EdgeCleared(name string) bool { return m.clearedsignatures case dsse.EdgePayloadDigests: return m.clearedpayload_digests + case dsse.EdgeMetadata: + return m.clearedmetadata } return false } @@ -1920,10 +2002,486 @@ func (m *DsseMutation) ResetEdge(name string) error { case dsse.EdgePayloadDigests: m.ResetPayloadDigests() return nil + case dsse.EdgeMetadata: + m.ResetMetadata() + return nil } return fmt.Errorf("unknown Dsse edge %s", name) } +// MetadataMutation represents an operation that mutates the Metadata nodes in the graph. +type MetadataMutation struct { + config + op Op + typ string + id *int + key *string + value *string + clearedFields map[string]struct{} + envelope map[int]struct{} + removedenvelope map[int]struct{} + clearedenvelope bool + done bool + oldValue func(context.Context) (*Metadata, error) + predicates []predicate.Metadata +} + +var _ ent.Mutation = (*MetadataMutation)(nil) + +// metadataOption allows management of the mutation configuration using functional options. +type metadataOption func(*MetadataMutation) + +// newMetadataMutation creates new mutation for the Metadata entity. +func newMetadataMutation(c config, op Op, opts ...metadataOption) *MetadataMutation { + m := &MetadataMutation{ + config: c, + op: op, + typ: TypeMetadata, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withMetadataID sets the ID field of the mutation. +func withMetadataID(id int) metadataOption { + return func(m *MetadataMutation) { + var ( + err error + once sync.Once + value *Metadata + ) + m.oldValue = func(ctx context.Context) (*Metadata, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().Metadata.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withMetadata sets the old Metadata of the mutation. +func withMetadata(node *Metadata) metadataOption { + return func(m *MetadataMutation) { + m.oldValue = func(context.Context) (*Metadata, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m MetadataMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m MetadataMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *MetadataMutation) ID() (id int, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *MetadataMutation) IDs(ctx context.Context) ([]int, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().Metadata.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetKey sets the "key" field. +func (m *MetadataMutation) SetKey(s string) { + m.key = &s +} + +// Key returns the value of the "key" field in the mutation. +func (m *MetadataMutation) Key() (r string, exists bool) { + v := m.key + if v == nil { + return + } + return *v, true +} + +// OldKey returns the old "key" 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) OldKey(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldKey is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldKey requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldKey: %w", err) + } + return oldValue.Key, nil +} + +// ResetKey resets all changes to the "key" field. +func (m *MetadataMutation) ResetKey() { + m.key = nil +} + +// SetValue sets the "value" field. +func (m *MetadataMutation) SetValue(s string) { + m.value = &s +} + +// Value returns the value of the "value" field in the mutation. +func (m *MetadataMutation) Value() (r string, exists bool) { + v := m.value + if v == nil { + return + } + return *v, true +} + +// OldValue returns the old "value" 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) OldValue(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldValue is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldValue requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldValue: %w", err) + } + return oldValue.Value, nil +} + +// ResetValue resets all changes to the "value" field. +func (m *MetadataMutation) ResetValue() { + m.value = nil +} + +// AddEnvelopeIDs adds the "envelope" edge to the Dsse entity by ids. +func (m *MetadataMutation) AddEnvelopeIDs(ids ...int) { + if m.envelope == nil { + m.envelope = make(map[int]struct{}) + } + for i := range ids { + m.envelope[ids[i]] = struct{}{} + } +} + +// ClearEnvelope clears the "envelope" edge to the Dsse entity. +func (m *MetadataMutation) ClearEnvelope() { + m.clearedenvelope = true +} + +// EnvelopeCleared reports if the "envelope" edge to the Dsse entity was cleared. +func (m *MetadataMutation) EnvelopeCleared() bool { + return m.clearedenvelope +} + +// RemoveEnvelopeIDs removes the "envelope" edge to the Dsse entity by IDs. +func (m *MetadataMutation) RemoveEnvelopeIDs(ids ...int) { + if m.removedenvelope == nil { + m.removedenvelope = make(map[int]struct{}) + } + for i := range ids { + delete(m.envelope, ids[i]) + m.removedenvelope[ids[i]] = struct{}{} + } +} + +// RemovedEnvelope returns the removed IDs of the "envelope" edge to the Dsse entity. +func (m *MetadataMutation) RemovedEnvelopeIDs() (ids []int) { + for id := range m.removedenvelope { + ids = append(ids, id) + } + return +} + +// EnvelopeIDs returns the "envelope" edge IDs in the mutation. +func (m *MetadataMutation) EnvelopeIDs() (ids []int) { + for id := range m.envelope { + ids = append(ids, id) + } + return +} + +// ResetEnvelope resets all changes to the "envelope" edge. +func (m *MetadataMutation) ResetEnvelope() { + m.envelope = nil + m.clearedenvelope = false + m.removedenvelope = nil +} + +// Where appends a list predicates to the MetadataMutation builder. +func (m *MetadataMutation) Where(ps ...predicate.Metadata) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the MetadataMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *MetadataMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Metadata, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *MetadataMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *MetadataMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (Metadata). +func (m *MetadataMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *MetadataMutation) Fields() []string { + fields := make([]string, 0, 2) + if m.key != nil { + fields = append(fields, metadata.FieldKey) + } + if m.value != nil { + fields = append(fields, metadata.FieldValue) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *MetadataMutation) Field(name string) (ent.Value, bool) { + switch name { + case metadata.FieldKey: + return m.Key() + case metadata.FieldValue: + return m.Value() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *MetadataMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case metadata.FieldKey: + return m.OldKey(ctx) + case metadata.FieldValue: + return m.OldValue(ctx) + } + return nil, fmt.Errorf("unknown Metadata field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MetadataMutation) SetField(name string, value ent.Value) error { + switch name { + case metadata.FieldKey: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetKey(v) + return nil + case metadata.FieldValue: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetValue(v) + return nil + } + return fmt.Errorf("unknown Metadata field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *MetadataMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *MetadataMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *MetadataMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Metadata numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *MetadataMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *MetadataMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// 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 *MetadataMutation) ClearField(name string) error { + return fmt.Errorf("unknown Metadata 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 *MetadataMutation) ResetField(name string) error { + switch name { + case metadata.FieldKey: + m.ResetKey() + return nil + case metadata.FieldValue: + m.ResetValue() + return nil + } + return fmt.Errorf("unknown Metadata field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *MetadataMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.envelope != nil { + edges = append(edges, metadata.EdgeEnvelope) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *MetadataMutation) AddedIDs(name string) []ent.Value { + switch name { + case metadata.EdgeEnvelope: + ids := make([]ent.Value, 0, len(m.envelope)) + for id := range m.envelope { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *MetadataMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedenvelope != nil { + edges = append(edges, metadata.EdgeEnvelope) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *MetadataMutation) RemovedIDs(name string) []ent.Value { + switch name { + case metadata.EdgeEnvelope: + ids := make([]ent.Value, 0, len(m.removedenvelope)) + for id := range m.removedenvelope { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *MetadataMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedenvelope { + edges = append(edges, metadata.EdgeEnvelope) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *MetadataMutation) EdgeCleared(name string) bool { + switch name { + case metadata.EdgeEnvelope: + return m.clearedenvelope + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *MetadataMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Metadata unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *MetadataMutation) ResetEdge(name string) error { + switch name { + case metadata.EdgeEnvelope: + m.ResetEnvelope() + return nil + } + return fmt.Errorf("unknown Metadata edge %s", name) +} + // PayloadDigestMutation represents an operation that mutates the PayloadDigest nodes in the graph. type PayloadDigestMutation struct { config diff --git a/ent/predicate/predicate.go b/ent/predicate/predicate.go index 3306c827..53c04705 100644 --- a/ent/predicate/predicate.go +++ b/ent/predicate/predicate.go @@ -18,6 +18,9 @@ type AttestationPolicy func(*sql.Selector) // Dsse is the predicate function for dsse builders. type Dsse func(*sql.Selector) +// Metadata is the predicate function for metadata builders. +type Metadata func(*sql.Selector) + // PayloadDigest is the predicate function for payloaddigest builders. type PayloadDigest func(*sql.Selector) diff --git a/ent/runtime.go b/ent/runtime.go index 06f23d34..b3f1eb93 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -7,6 +7,7 @@ import ( "github.com/in-toto/archivista/ent/attestationcollection" "github.com/in-toto/archivista/ent/attestationpolicy" "github.com/in-toto/archivista/ent/dsse" + "github.com/in-toto/archivista/ent/metadata" "github.com/in-toto/archivista/ent/payloaddigest" "github.com/in-toto/archivista/ent/schema" "github.com/in-toto/archivista/ent/signature" @@ -47,6 +48,16 @@ func init() { dsseDescPayloadType := dsseFields[1].Descriptor() // dsse.PayloadTypeValidator is a validator for the "payload_type" field. It is called by the builders before save. dsse.PayloadTypeValidator = dsseDescPayloadType.Validators[0].(func(string) error) + metadataFields := schema.Metadata{}.Fields() + _ = metadataFields + // metadataDescKey is the schema descriptor for key field. + metadataDescKey := metadataFields[0].Descriptor() + // metadata.KeyValidator is a validator for the "key" field. It is called by the builders before save. + metadata.KeyValidator = metadataDescKey.Validators[0].(func(string) error) + // metadataDescValue is the schema descriptor for value field. + metadataDescValue := metadataFields[1].Descriptor() + // metadata.ValueValidator is a validator for the "value" field. It is called by the builders before save. + metadata.ValueValidator = metadataDescValue.Validators[0].(func(string) error) payloaddigestFields := schema.PayloadDigest{}.Fields() _ = payloaddigestFields // payloaddigestDescAlgorithm is the schema descriptor for algorithm field. diff --git a/ent/schema/metadata.go b/ent/schema/metadata.go index a5009b02..f1549b1f 100644 --- a/ent/schema/metadata.go +++ b/ent/schema/metadata.go @@ -1,4 +1,4 @@ -// Copyright 2022 The Archivista Contributors +// Copyright 2024 The Archivista Contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/ent/tx.go b/ent/tx.go index 8a1f4cd8..ec512ff4 100644 --- a/ent/tx.go +++ b/ent/tx.go @@ -20,6 +20,8 @@ type Tx struct { AttestationPolicy *AttestationPolicyClient // Dsse is the client for interacting with the Dsse builders. Dsse *DsseClient + // Metadata is the client for interacting with the Metadata builders. + Metadata *MetadataClient // PayloadDigest is the client for interacting with the PayloadDigest builders. PayloadDigest *PayloadDigestClient // Signature is the client for interacting with the Signature builders. @@ -167,6 +169,7 @@ func (tx *Tx) init() { tx.AttestationCollection = NewAttestationCollectionClient(tx.config) tx.AttestationPolicy = NewAttestationPolicyClient(tx.config) tx.Dsse = NewDsseClient(tx.config) + tx.Metadata = NewMetadataClient(tx.config) tx.PayloadDigest = NewPayloadDigestClient(tx.config) tx.Signature = NewSignatureClient(tx.config) tx.Statement = NewStatementClient(tx.config) diff --git a/generated.go b/generated.go index a3187b6d..c04ac993 100644 --- a/generated.go +++ b/generated.go @@ -81,6 +81,7 @@ type ComplexityRoot struct { Dsse struct { GitoidSha256 func(childComplexity int) int ID func(childComplexity int) int + Metadata func(childComplexity int) int PayloadDigests func(childComplexity int) int PayloadType func(childComplexity int) int Signatures func(childComplexity int) int @@ -98,6 +99,13 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + Metadata struct { + Envelope func(childComplexity int) int + ID func(childComplexity int) int + Key func(childComplexity int) int + Value func(childComplexity int) int + } + PageInfo struct { EndCursor func(childComplexity int) int HasNextPage func(childComplexity int) int @@ -316,6 +324,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Dsse.ID(childComplexity), true + case "Dsse.metadata": + if e.complexity.Dsse.Metadata == nil { + break + } + + return e.complexity.Dsse.Metadata(childComplexity), true + case "Dsse.payloadDigests": if e.complexity.Dsse.PayloadDigests == nil { break @@ -379,6 +394,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.DsseEdge.Node(childComplexity), true + case "Metadata.envelope": + if e.complexity.Metadata.Envelope == nil { + break + } + + return e.complexity.Metadata.Envelope(childComplexity), true + + case "Metadata.id": + if e.complexity.Metadata.ID == nil { + break + } + + return e.complexity.Metadata.ID(childComplexity), true + + case "Metadata.key": + if e.complexity.Metadata.Key == nil { + break + } + + return e.complexity.Metadata.Key(childComplexity), true + + case "Metadata.value": + if e.complexity.Metadata.Value == nil { + break + } + + return e.complexity.Metadata.Value(childComplexity), true + case "PageInfo.endCursor": if e.complexity.PageInfo.EndCursor == nil { break @@ -708,6 +751,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputAttestationPolicyWhereInput, ec.unmarshalInputAttestationWhereInput, ec.unmarshalInputDsseWhereInput, + ec.unmarshalInputMetadataWhereInput, ec.unmarshalInputPayloadDigestWhereInput, ec.unmarshalInputSignatureWhereInput, ec.unmarshalInputStatementWhereInput, @@ -2112,6 +2156,57 @@ func (ec *executionContext) fieldContext_Dsse_payloadDigests(ctx context.Context return fc, nil } +func (ec *executionContext) _Dsse_metadata(ctx context.Context, field graphql.CollectedField, obj *ent.Dsse) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Dsse_metadata(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Metadata(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*ent.Metadata) + fc.Result = res + return ec.marshalOMetadata2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Dsse_metadata(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Dsse", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Metadata_id(ctx, field) + case "key": + return ec.fieldContext_Metadata_key(ctx, field) + case "value": + return ec.fieldContext_Metadata_value(ctx, field) + case "envelope": + return ec.fieldContext_Metadata_envelope(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Metadata", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _DsseConnection_edges(ctx context.Context, field graphql.CollectedField, obj *ent.DsseConnection) (ret graphql.Marshaler) { fc, err := ec.fieldContext_DsseConnection_edges(ctx, field) if err != nil { @@ -2305,6 +2400,8 @@ func (ec *executionContext) fieldContext_DsseEdge_node(ctx context.Context, fiel return ec.fieldContext_Dsse_signatures(ctx, field) case "payloadDigests": return ec.fieldContext_Dsse_payloadDigests(ctx, field) + case "metadata": + return ec.fieldContext_Dsse_metadata(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Dsse", field.Name) }, @@ -2356,6 +2453,195 @@ func (ec *executionContext) fieldContext_DsseEdge_cursor(ctx context.Context, fi return fc, nil } +func (ec *executionContext) _Metadata_id(ctx context.Context, field graphql.CollectedField, obj *ent.Metadata) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metadata_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNID2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metadata_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metadata", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metadata_key(ctx context.Context, field graphql.CollectedField, obj *ent.Metadata) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metadata_key(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Key, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metadata_key(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metadata", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metadata_value(ctx context.Context, field graphql.CollectedField, obj *ent.Metadata) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metadata_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metadata_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metadata", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Metadata_envelope(ctx context.Context, field graphql.CollectedField, obj *ent.Metadata) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Metadata_envelope(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Envelope(ctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*ent.Dsse) + fc.Result = res + return ec.marshalODsse2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐDsseᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Metadata_envelope(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Metadata", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Dsse_id(ctx, field) + case "gitoidSha256": + return ec.fieldContext_Dsse_gitoidSha256(ctx, field) + case "payloadType": + return ec.fieldContext_Dsse_payloadType(ctx, field) + case "statement": + return ec.fieldContext_Dsse_statement(ctx, field) + case "signatures": + return ec.fieldContext_Dsse_signatures(ctx, field) + case "payloadDigests": + return ec.fieldContext_Dsse_payloadDigests(ctx, field) + case "metadata": + return ec.fieldContext_Dsse_metadata(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Dsse", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _PageInfo_hasNextPage(ctx context.Context, field graphql.CollectedField, obj *entgql.PageInfo[int]) (ret graphql.Marshaler) { fc, err := ec.fieldContext_PageInfo_hasNextPage(ctx, field) if err != nil { @@ -2706,6 +2992,8 @@ func (ec *executionContext) fieldContext_PayloadDigest_dsse(ctx context.Context, return ec.fieldContext_Dsse_signatures(ctx, field) case "payloadDigests": return ec.fieldContext_Dsse_payloadDigests(ctx, field) + case "metadata": + return ec.fieldContext_Dsse_metadata(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Dsse", field.Name) }, @@ -3318,6 +3606,8 @@ func (ec *executionContext) fieldContext_Signature_dsse(ctx context.Context, fie return ec.fieldContext_Dsse_signatures(ctx, field) case "payloadDigests": return ec.fieldContext_Dsse_payloadDigests(ctx, field) + case "metadata": + return ec.fieldContext_Dsse_metadata(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Dsse", field.Name) }, @@ -3675,6 +3965,8 @@ func (ec *executionContext) fieldContext_Statement_dsse(ctx context.Context, fie return ec.fieldContext_Dsse_signatures(ctx, field) case "payloadDigests": return ec.fieldContext_Dsse_payloadDigests(ctx, field) + case "metadata": + return ec.fieldContext_Dsse_metadata(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Dsse", field.Name) }, @@ -6884,7 +7176,7 @@ func (ec *executionContext) unmarshalInputDsseWhereInput(ctx context.Context, ob asMap[k] = v } - fieldsInOrder := [...]string{"not", "and", "or", "id", "idNEQ", "idIn", "idNotIn", "idGT", "idGTE", "idLT", "idLTE", "gitoidSha256", "gitoidSha256NEQ", "gitoidSha256In", "gitoidSha256NotIn", "gitoidSha256GT", "gitoidSha256GTE", "gitoidSha256LT", "gitoidSha256LTE", "gitoidSha256Contains", "gitoidSha256HasPrefix", "gitoidSha256HasSuffix", "gitoidSha256EqualFold", "gitoidSha256ContainsFold", "payloadType", "payloadTypeNEQ", "payloadTypeIn", "payloadTypeNotIn", "payloadTypeGT", "payloadTypeGTE", "payloadTypeLT", "payloadTypeLTE", "payloadTypeContains", "payloadTypeHasPrefix", "payloadTypeHasSuffix", "payloadTypeEqualFold", "payloadTypeContainsFold", "hasStatement", "hasStatementWith", "hasSignatures", "hasSignaturesWith", "hasPayloadDigests", "hasPayloadDigestsWith"} + fieldsInOrder := [...]string{"not", "and", "or", "id", "idNEQ", "idIn", "idNotIn", "idGT", "idGTE", "idLT", "idLTE", "gitoidSha256", "gitoidSha256NEQ", "gitoidSha256In", "gitoidSha256NotIn", "gitoidSha256GT", "gitoidSha256GTE", "gitoidSha256LT", "gitoidSha256LTE", "gitoidSha256Contains", "gitoidSha256HasPrefix", "gitoidSha256HasSuffix", "gitoidSha256EqualFold", "gitoidSha256ContainsFold", "payloadType", "payloadTypeNEQ", "payloadTypeIn", "payloadTypeNotIn", "payloadTypeGT", "payloadTypeGTE", "payloadTypeLT", "payloadTypeLTE", "payloadTypeContains", "payloadTypeHasPrefix", "payloadTypeHasSuffix", "payloadTypeEqualFold", "payloadTypeContainsFold", "hasStatement", "hasStatementWith", "hasSignatures", "hasSignaturesWith", "hasPayloadDigests", "hasPayloadDigestsWith", "hasMetadata", "hasMetadataWith"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -7192,20 +7484,34 @@ func (ec *executionContext) unmarshalInputDsseWhereInput(ctx context.Context, ob return it, err } it.HasPayloadDigestsWith = data + case "hasMetadata": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("hasMetadata")) + data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + it.HasMetadata = data + case "hasMetadataWith": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("hasMetadataWith")) + data, err := ec.unmarshalOMetadataWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInputᚄ(ctx, v) + if err != nil { + return it, err + } + it.HasMetadataWith = data } } return it, nil } -func (ec *executionContext) unmarshalInputPayloadDigestWhereInput(ctx context.Context, obj interface{}) (ent.PayloadDigestWhereInput, error) { - var it ent.PayloadDigestWhereInput +func (ec *executionContext) unmarshalInputMetadataWhereInput(ctx context.Context, obj interface{}) (ent.MetadataWhereInput, error) { + var it ent.MetadataWhereInput asMap := map[string]interface{}{} for k, v := range obj.(map[string]interface{}) { asMap[k] = v } - fieldsInOrder := [...]string{"not", "and", "or", "id", "idNEQ", "idIn", "idNotIn", "idGT", "idGTE", "idLT", "idLTE", "algorithm", "algorithmNEQ", "algorithmIn", "algorithmNotIn", "algorithmGT", "algorithmGTE", "algorithmLT", "algorithmLTE", "algorithmContains", "algorithmHasPrefix", "algorithmHasSuffix", "algorithmEqualFold", "algorithmContainsFold", "value", "valueNEQ", "valueIn", "valueNotIn", "valueGT", "valueGTE", "valueLT", "valueLTE", "valueContains", "valueHasPrefix", "valueHasSuffix", "valueEqualFold", "valueContainsFold", "hasDsse", "hasDsseWith"} + fieldsInOrder := [...]string{"not", "and", "or", "id", "idNEQ", "idIn", "idNotIn", "idGT", "idGTE", "idLT", "idLTE", "key", "keyNEQ", "keyIn", "keyNotIn", "keyGT", "keyGTE", "keyLT", "keyLTE", "keyContains", "keyHasPrefix", "keyHasSuffix", "keyEqualFold", "keyContainsFold", "value", "valueNEQ", "valueIn", "valueNotIn", "valueGT", "valueGTE", "valueLT", "valueLTE", "valueContains", "valueHasPrefix", "valueHasSuffix", "valueEqualFold", "valueContainsFold", "hasEnvelope", "hasEnvelopeWith"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -7214,21 +7520,21 @@ func (ec *executionContext) unmarshalInputPayloadDigestWhereInput(ctx context.Co switch k { case "not": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("not")) - data, err := ec.unmarshalOPayloadDigestWhereInput2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐPayloadDigestWhereInput(ctx, v) + data, err := ec.unmarshalOMetadataWhereInput2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInput(ctx, v) if err != nil { return it, err } it.Not = data case "and": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("and")) - data, err := ec.unmarshalOPayloadDigestWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐPayloadDigestWhereInputᚄ(ctx, v) + data, err := ec.unmarshalOMetadataWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInputᚄ(ctx, v) if err != nil { return it, err } it.And = data case "or": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("or")) - data, err := ec.unmarshalOPayloadDigestWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐPayloadDigestWhereInputᚄ(ctx, v) + data, err := ec.unmarshalOMetadataWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInputᚄ(ctx, v) if err != nil { return it, err } @@ -7289,36 +7595,329 @@ func (ec *executionContext) unmarshalInputPayloadDigestWhereInput(ctx context.Co return it, err } it.IDLTE = data - case "algorithm": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithm")) + case "key": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) data, err := ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err } - it.Algorithm = data - case "algorithmNEQ": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmNEQ")) + it.Key = data + case "keyNEQ": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyNEQ")) data, err := ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err } - it.AlgorithmNEQ = data - case "algorithmIn": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmIn")) + it.KeyNEQ = data + case "keyIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyIn")) data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) if err != nil { return it, err } - it.AlgorithmIn = data - case "algorithmNotIn": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmNotIn")) + it.KeyIn = data + case "keyNotIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyNotIn")) data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) if err != nil { return it, err } - it.AlgorithmNotIn = data - case "algorithmGT": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmGT")) + it.KeyNotIn = data + case "keyGT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyGT")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyGT = data + case "keyGTE": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyGTE")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyGTE = data + case "keyLT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyLT")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyLT = data + case "keyLTE": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyLTE")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyLTE = data + case "keyContains": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyContains")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyContains = data + case "keyHasPrefix": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyHasPrefix")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyHasPrefix = data + case "keyHasSuffix": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyHasSuffix")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyHasSuffix = data + case "keyEqualFold": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyEqualFold")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyEqualFold = data + case "keyContainsFold": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("keyContainsFold")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.KeyContainsFold = data + case "value": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("value")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Value = data + case "valueNEQ": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueNEQ")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueNEQ = data + case "valueIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueIn")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.ValueIn = data + case "valueNotIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueNotIn")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.ValueNotIn = data + case "valueGT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueGT")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueGT = data + case "valueGTE": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueGTE")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueGTE = data + case "valueLT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueLT")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueLT = data + case "valueLTE": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueLTE")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueLTE = data + case "valueContains": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueContains")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueContains = data + case "valueHasPrefix": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueHasPrefix")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueHasPrefix = data + case "valueHasSuffix": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueHasSuffix")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueHasSuffix = data + case "valueEqualFold": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueEqualFold")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueEqualFold = data + case "valueContainsFold": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("valueContainsFold")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ValueContainsFold = data + case "hasEnvelope": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("hasEnvelope")) + data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + it.HasEnvelope = data + case "hasEnvelopeWith": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("hasEnvelopeWith")) + data, err := ec.unmarshalODsseWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐDsseWhereInputᚄ(ctx, v) + if err != nil { + return it, err + } + it.HasEnvelopeWith = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputPayloadDigestWhereInput(ctx context.Context, obj interface{}) (ent.PayloadDigestWhereInput, error) { + var it ent.PayloadDigestWhereInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"not", "and", "or", "id", "idNEQ", "idIn", "idNotIn", "idGT", "idGTE", "idLT", "idLTE", "algorithm", "algorithmNEQ", "algorithmIn", "algorithmNotIn", "algorithmGT", "algorithmGTE", "algorithmLT", "algorithmLTE", "algorithmContains", "algorithmHasPrefix", "algorithmHasSuffix", "algorithmEqualFold", "algorithmContainsFold", "value", "valueNEQ", "valueIn", "valueNotIn", "valueGT", "valueGTE", "valueLT", "valueLTE", "valueContains", "valueHasPrefix", "valueHasSuffix", "valueEqualFold", "valueContainsFold", "hasDsse", "hasDsseWith"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "not": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("not")) + data, err := ec.unmarshalOPayloadDigestWhereInput2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐPayloadDigestWhereInput(ctx, v) + if err != nil { + return it, err + } + it.Not = data + case "and": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("and")) + data, err := ec.unmarshalOPayloadDigestWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐPayloadDigestWhereInputᚄ(ctx, v) + if err != nil { + return it, err + } + it.And = data + case "or": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("or")) + data, err := ec.unmarshalOPayloadDigestWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐPayloadDigestWhereInputᚄ(ctx, v) + if err != nil { + return it, err + } + it.Or = data + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalOID2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "idNEQ": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idNEQ")) + data, err := ec.unmarshalOID2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.IDNEQ = data + case "idIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idIn")) + data, err := ec.unmarshalOID2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + it.IDIn = data + case "idNotIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idNotIn")) + data, err := ec.unmarshalOID2ᚕintᚄ(ctx, v) + if err != nil { + return it, err + } + it.IDNotIn = data + case "idGT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idGT")) + data, err := ec.unmarshalOID2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.IDGT = data + case "idGTE": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idGTE")) + data, err := ec.unmarshalOID2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.IDGTE = data + case "idLT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idLT")) + data, err := ec.unmarshalOID2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.IDLT = data + case "idLTE": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idLTE")) + data, err := ec.unmarshalOID2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.IDLTE = data + case "algorithm": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithm")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Algorithm = data + case "algorithmNEQ": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmNEQ")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.AlgorithmNEQ = data + case "algorithmIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmIn")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.AlgorithmIn = data + case "algorithmNotIn": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmNotIn")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.AlgorithmNotIn = data + case "algorithmGT": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("algorithmGT")) data, err := ec.unmarshalOString2ᚖstring(ctx, v) if err != nil { return it, err @@ -8837,6 +9436,11 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._Dsse(ctx, sel, obj) + case *ent.Metadata: + if obj == nil { + return graphql.Null + } + return ec._Metadata(ctx, sel, obj) case *ent.PayloadDigest: if obj == nil { return graphql.Null @@ -9357,6 +9961,39 @@ func (ec *executionContext) _Dsse(ctx context.Context, sel ast.SelectionSet, obj continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "metadata": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Dsse_metadata(ctx, field, obj) + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -9468,6 +10105,88 @@ func (ec *executionContext) _DsseEdge(ctx context.Context, sel ast.SelectionSet, return out } +var metadataImplementors = []string{"Metadata", "Node"} + +func (ec *executionContext) _Metadata(ctx context.Context, sel ast.SelectionSet, obj *ent.Metadata) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, metadataImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Metadata") + case "id": + out.Values[i] = ec._Metadata_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "key": + out.Values[i] = ec._Metadata_key(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "value": + out.Values[i] = ec._Metadata_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "envelope": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Metadata_envelope(ctx, field, obj) + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var pageInfoImplementors = []string{"PageInfo"} func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, obj *entgql.PageInfo[int]) graphql.Marshaler { @@ -10901,6 +11620,21 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } +func (ec *executionContext) marshalNMetadata2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadata(ctx context.Context, sel ast.SelectionSet, v *ent.Metadata) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Metadata(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNMetadataWhereInput2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInput(ctx context.Context, v interface{}) (*ent.MetadataWhereInput, error) { + res, err := ec.unmarshalInputMetadataWhereInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalNNode2ᚕgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐNoder(ctx context.Context, sel ast.SelectionSet, v []ent.Noder) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -11755,6 +12489,81 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele return res } +func (ec *executionContext) marshalOMetadata2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataᚄ(ctx context.Context, sel ast.SelectionSet, v []*ent.Metadata) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNMetadata2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadata(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOMetadataWhereInput2ᚕᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInputᚄ(ctx context.Context, v interface{}) ([]*ent.MetadataWhereInput, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*ent.MetadataWhereInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNMetadataWhereInput2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalOMetadataWhereInput2ᚖgithubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐMetadataWhereInput(ctx context.Context, v interface{}) (*ent.MetadataWhereInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputMetadataWhereInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalONode2githubᚗcomᚋinᚑtotoᚋarchivistaᚋentᚐNoder(ctx context.Context, sel ast.SelectionSet, v ent.Noder) graphql.Marshaler { if v == nil { return graphql.Null