From ee750954b21168a98870aa286162ef19fa4cad64 Mon Sep 17 00:00:00 2001 From: noah Date: Mon, 1 Nov 2021 19:57:55 +0900 Subject: [PATCH 01/13] Add Review schema --- ent/client.go | 193 ++++++ ent/config.go | 1 + ent/deployment.go | 22 +- ent/deployment/deployment.go | 9 + ent/deployment/where.go | 28 + ent/deployment_create.go | 35 + ent/deployment_query.go | 64 +- ent/deployment_update.go | 181 +++++ ent/ent.go | 2 + ent/event.go | 38 +- ent/event/event.go | 15 +- ent/event/where.go | 97 +++ ent/event_create.go | 40 ++ ent/event_query.go | 65 +- ent/event_update.go | 133 ++++ ent/hook/hook.go | 13 + ent/migrate/schema.go | 42 +- ent/mutation.go | 1224 ++++++++++++++++++++++++++++++---- ent/predicate/predicate.go | 3 + ent/review.go | 212 ++++++ ent/review/review.go | 110 +++ ent/review/where.go | 534 +++++++++++++++ ent/review_create.go | 413 ++++++++++++ ent/review_delete.go | 111 +++ ent/review_query.go | 1146 +++++++++++++++++++++++++++++++ ent/review_update.go | 803 ++++++++++++++++++++++ ent/runtime.go | 13 + ent/schema/deployment.go | 4 + ent/schema/event.go | 7 + ent/schema/review.go | 54 ++ ent/schema/user.go | 1 + ent/tx.go | 3 + ent/user.go | 20 +- ent/user/user.go | 9 + ent/user/where.go | 28 + ent/user_create.go | 35 + ent/user_query.go | 64 +- ent/user_update.go | 181 +++++ 38 files changed, 5818 insertions(+), 135 deletions(-) create mode 100644 ent/review.go create mode 100644 ent/review/review.go create mode 100644 ent/review/where.go create mode 100644 ent/review_create.go create mode 100644 ent/review_delete.go create mode 100644 ent/review_query.go create mode 100644 ent/review_update.go create mode 100644 ent/schema/review.go diff --git a/ent/client.go b/ent/client.go index ad4a6c81..b127b093 100644 --- a/ent/client.go +++ b/ent/client.go @@ -20,6 +20,7 @@ import ( "github.com/gitploy-io/gitploy/ent/notificationrecord" "github.com/gitploy-io/gitploy/ent/perm" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" "entgo.io/ent/dialect" @@ -54,6 +55,8 @@ type Client struct { Perm *PermClient // Repo is the client for interacting with the Repo builders. Repo *RepoClient + // Review is the client for interacting with the Review builders. + Review *ReviewClient // User is the client for interacting with the User builders. User *UserClient } @@ -80,6 +83,7 @@ func (c *Client) init() { c.NotificationRecord = NewNotificationRecordClient(c.config) c.Perm = NewPermClient(c.config) c.Repo = NewRepoClient(c.config) + c.Review = NewReviewClient(c.config) c.User = NewUserClient(c.config) } @@ -125,6 +129,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) { NotificationRecord: NewNotificationRecordClient(cfg), Perm: NewPermClient(cfg), Repo: NewRepoClient(cfg), + Review: NewReviewClient(cfg), User: NewUserClient(cfg), }, nil } @@ -155,6 +160,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) NotificationRecord: NewNotificationRecordClient(cfg), Perm: NewPermClient(cfg), Repo: NewRepoClient(cfg), + Review: NewReviewClient(cfg), User: NewUserClient(cfg), }, nil } @@ -196,6 +202,7 @@ func (c *Client) Use(hooks ...Hook) { c.NotificationRecord.Use(hooks...) c.Perm.Use(hooks...) c.Repo.Use(hooks...) + c.Review.Use(hooks...) c.User.Use(hooks...) } @@ -682,6 +689,22 @@ func (c *DeploymentClient) QueryApprovals(d *Deployment) *ApprovalQuery { return query } +// QueryReviews queries the reviews edge of a Deployment. +func (c *DeploymentClient) QueryReviews(d *Deployment) *ReviewQuery { + query := &ReviewQuery{config: c.config} + query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { + id := d.ID + step := sqlgraph.NewStep( + sqlgraph.From(deployment.Table, deployment.FieldID, id), + sqlgraph.To(review.Table, review.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, deployment.ReviewsTable, deployment.ReviewsColumn), + ) + fromV = sqlgraph.Neighbors(d.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryDeploymentStatuses queries the deployment_statuses edge of a Deployment. func (c *DeploymentClient) QueryDeploymentStatuses(d *Deployment) *DeploymentStatusQuery { query := &DeploymentStatusQuery{config: c.config} @@ -1048,6 +1071,22 @@ func (c *EventClient) QueryApproval(e *Event) *ApprovalQuery { return query } +// QueryReview queries the review edge of a Event. +func (c *EventClient) QueryReview(e *Event) *ReviewQuery { + query := &ReviewQuery{config: c.config} + query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { + id := e.ID + step := sqlgraph.NewStep( + sqlgraph.From(event.Table, event.FieldID, id), + sqlgraph.To(review.Table, review.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, event.ReviewTable, event.ReviewColumn), + ) + fromV = sqlgraph.Neighbors(e.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryNotificationRecord queries the notification_record edge of a Event. func (c *EventClient) QueryNotificationRecord(e *Event) *NotificationRecordQuery { query := &NotificationRecordQuery{config: c.config} @@ -1589,6 +1628,144 @@ func (c *RepoClient) Hooks() []Hook { return c.hooks.Repo } +// ReviewClient is a client for the Review schema. +type ReviewClient struct { + config +} + +// NewReviewClient returns a client for the Review from the given config. +func NewReviewClient(c config) *ReviewClient { + return &ReviewClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `review.Hooks(f(g(h())))`. +func (c *ReviewClient) Use(hooks ...Hook) { + c.hooks.Review = append(c.hooks.Review, hooks...) +} + +// Create returns a create builder for Review. +func (c *ReviewClient) Create() *ReviewCreate { + mutation := newReviewMutation(c.config, OpCreate) + return &ReviewCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Review entities. +func (c *ReviewClient) CreateBulk(builders ...*ReviewCreate) *ReviewCreateBulk { + return &ReviewCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Review. +func (c *ReviewClient) Update() *ReviewUpdate { + mutation := newReviewMutation(c.config, OpUpdate) + return &ReviewUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *ReviewClient) UpdateOne(r *Review) *ReviewUpdateOne { + mutation := newReviewMutation(c.config, OpUpdateOne, withReview(r)) + return &ReviewUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *ReviewClient) UpdateOneID(id int) *ReviewUpdateOne { + mutation := newReviewMutation(c.config, OpUpdateOne, withReviewID(id)) + return &ReviewUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Review. +func (c *ReviewClient) Delete() *ReviewDelete { + mutation := newReviewMutation(c.config, OpDelete) + return &ReviewDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a delete builder for the given entity. +func (c *ReviewClient) DeleteOne(r *Review) *ReviewDeleteOne { + return c.DeleteOneID(r.ID) +} + +// DeleteOneID returns a delete builder for the given id. +func (c *ReviewClient) DeleteOneID(id int) *ReviewDeleteOne { + builder := c.Delete().Where(review.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &ReviewDeleteOne{builder} +} + +// Query returns a query builder for Review. +func (c *ReviewClient) Query() *ReviewQuery { + return &ReviewQuery{ + config: c.config, + } +} + +// Get returns a Review entity by its id. +func (c *ReviewClient) Get(ctx context.Context, id int) (*Review, error) { + return c.Query().Where(review.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *ReviewClient) GetX(ctx context.Context, id int) *Review { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QueryUser queries the user edge of a Review. +func (c *ReviewClient) QueryUser(r *Review) *UserQuery { + query := &UserQuery{config: c.config} + query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { + id := r.ID + step := sqlgraph.NewStep( + sqlgraph.From(review.Table, review.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, review.UserTable, review.UserColumn), + ) + fromV = sqlgraph.Neighbors(r.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryDeployment queries the deployment edge of a Review. +func (c *ReviewClient) QueryDeployment(r *Review) *DeploymentQuery { + query := &DeploymentQuery{config: c.config} + query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { + id := r.ID + step := sqlgraph.NewStep( + sqlgraph.From(review.Table, review.FieldID, id), + sqlgraph.To(deployment.Table, deployment.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, review.DeploymentTable, review.DeploymentColumn), + ) + fromV = sqlgraph.Neighbors(r.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryEvent queries the event edge of a Review. +func (c *ReviewClient) QueryEvent(r *Review) *EventQuery { + query := &EventQuery{config: c.config} + query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { + id := r.ID + step := sqlgraph.NewStep( + sqlgraph.From(review.Table, review.FieldID, id), + sqlgraph.To(event.Table, event.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, review.EventTable, review.EventColumn), + ) + fromV = sqlgraph.Neighbors(r.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *ReviewClient) Hooks() []Hook { + return c.hooks.Review +} + // UserClient is a client for the User schema. type UserClient struct { config @@ -1738,6 +1915,22 @@ func (c *UserClient) QueryApprovals(u *User) *ApprovalQuery { return query } +// QueryReviews queries the reviews edge of a User. +func (c *UserClient) QueryReviews(u *User) *ReviewQuery { + query := &ReviewQuery{config: c.config} + query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) { + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(review.Table, review.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.ReviewsTable, user.ReviewsColumn), + ) + fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) + return fromV, nil + } + return query +} + // QueryLocks queries the locks edge of a User. func (c *UserClient) QueryLocks(u *User) *LockQuery { query := &LockQuery{config: c.config} diff --git a/ent/config.go b/ent/config.go index c37af045..90453484 100644 --- a/ent/config.go +++ b/ent/config.go @@ -35,6 +35,7 @@ type hooks struct { NotificationRecord []ent.Hook Perm []ent.Hook Repo []ent.Hook + Review []ent.Hook User []ent.Hook } diff --git a/ent/deployment.go b/ent/deployment.go index c736f41c..190dca9e 100644 --- a/ent/deployment.go +++ b/ent/deployment.go @@ -63,13 +63,15 @@ type DeploymentEdges struct { Repo *Repo `json:"repo,omitempty"` // Approvals holds the value of the approvals edge. Approvals []*Approval `json:"approvals,omitempty"` + // Reviews holds the value of the reviews edge. + Reviews []*Review `json:"reviews,omitempty"` // DeploymentStatuses holds the value of the deployment_statuses edge. DeploymentStatuses []*DeploymentStatus `json:"deployment_statuses,omitempty"` // Event holds the value of the event edge. Event []*Event `json:"event,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [5]bool + loadedTypes [6]bool } // UserOrErr returns the User value or an error if the edge @@ -109,10 +111,19 @@ func (e DeploymentEdges) ApprovalsOrErr() ([]*Approval, error) { return nil, &NotLoadedError{edge: "approvals"} } +// ReviewsOrErr returns the Reviews value or an error if the edge +// was not loaded in eager-loading. +func (e DeploymentEdges) ReviewsOrErr() ([]*Review, error) { + if e.loadedTypes[3] { + return e.Reviews, nil + } + return nil, &NotLoadedError{edge: "reviews"} +} + // DeploymentStatusesOrErr returns the DeploymentStatuses value or an error if the edge // was not loaded in eager-loading. func (e DeploymentEdges) DeploymentStatusesOrErr() ([]*DeploymentStatus, error) { - if e.loadedTypes[3] { + if e.loadedTypes[4] { return e.DeploymentStatuses, nil } return nil, &NotLoadedError{edge: "deployment_statuses"} @@ -121,7 +132,7 @@ func (e DeploymentEdges) DeploymentStatusesOrErr() ([]*DeploymentStatus, error) // EventOrErr returns the Event value or an error if the edge // was not loaded in eager-loading. func (e DeploymentEdges) EventOrErr() ([]*Event, error) { - if e.loadedTypes[4] { + if e.loadedTypes[5] { return e.Event, nil } return nil, &NotLoadedError{edge: "event"} @@ -277,6 +288,11 @@ func (d *Deployment) QueryApprovals() *ApprovalQuery { return (&DeploymentClient{config: d.config}).QueryApprovals(d) } +// QueryReviews queries the "reviews" edge of the Deployment entity. +func (d *Deployment) QueryReviews() *ReviewQuery { + return (&DeploymentClient{config: d.config}).QueryReviews(d) +} + // QueryDeploymentStatuses queries the "deployment_statuses" edge of the Deployment entity. func (d *Deployment) QueryDeploymentStatuses() *DeploymentStatusQuery { return (&DeploymentClient{config: d.config}).QueryDeploymentStatuses(d) diff --git a/ent/deployment/deployment.go b/ent/deployment/deployment.go index 1a694c35..bd1b1ad0 100644 --- a/ent/deployment/deployment.go +++ b/ent/deployment/deployment.go @@ -50,6 +50,8 @@ const ( EdgeRepo = "repo" // EdgeApprovals holds the string denoting the approvals edge name in mutations. EdgeApprovals = "approvals" + // EdgeReviews holds the string denoting the reviews edge name in mutations. + EdgeReviews = "reviews" // EdgeDeploymentStatuses holds the string denoting the deployment_statuses edge name in mutations. EdgeDeploymentStatuses = "deployment_statuses" // EdgeEvent holds the string denoting the event edge name in mutations. @@ -77,6 +79,13 @@ const ( ApprovalsInverseTable = "approvals" // ApprovalsColumn is the table column denoting the approvals relation/edge. ApprovalsColumn = "deployment_id" + // ReviewsTable is the table that holds the reviews relation/edge. + ReviewsTable = "reviews" + // ReviewsInverseTable is the table name for the Review entity. + // It exists in this package in order to avoid circular dependency with the "review" package. + ReviewsInverseTable = "reviews" + // ReviewsColumn is the table column denoting the reviews relation/edge. + ReviewsColumn = "deployment_id" // DeploymentStatusesTable is the table that holds the deployment_statuses relation/edge. DeploymentStatusesTable = "deployment_status" // DeploymentStatusesInverseTable is the table name for the DeploymentStatus entity. diff --git a/ent/deployment/where.go b/ent/deployment/where.go index 46554dd1..0422f39a 100644 --- a/ent/deployment/where.go +++ b/ent/deployment/where.go @@ -1375,6 +1375,34 @@ func HasApprovalsWith(preds ...predicate.Approval) predicate.Deployment { }) } +// HasReviews applies the HasEdge predicate on the "reviews" edge. +func HasReviews() predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ReviewsTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, ReviewsTable, ReviewsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasReviewsWith applies the HasEdge predicate on the "reviews" edge with a given conditions (other predicates). +func HasReviewsWith(preds ...predicate.Review) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ReviewsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, ReviewsTable, ReviewsColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasDeploymentStatuses applies the HasEdge predicate on the "deployment_statuses" edge. func HasDeploymentStatuses() predicate.Deployment { return predicate.Deployment(func(s *sql.Selector) { diff --git a/ent/deployment_create.go b/ent/deployment_create.go index 2ea27bfe..a24e157c 100644 --- a/ent/deployment_create.go +++ b/ent/deployment_create.go @@ -15,6 +15,7 @@ import ( "github.com/gitploy-io/gitploy/ent/deploymentstatus" "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -234,6 +235,21 @@ func (dc *DeploymentCreate) AddApprovals(a ...*Approval) *DeploymentCreate { return dc.AddApprovalIDs(ids...) } +// AddReviewIDs adds the "reviews" edge to the Review entity by IDs. +func (dc *DeploymentCreate) AddReviewIDs(ids ...int) *DeploymentCreate { + dc.mutation.AddReviewIDs(ids...) + return dc +} + +// AddReviews adds the "reviews" edges to the Review entity. +func (dc *DeploymentCreate) AddReviews(r ...*Review) *DeploymentCreate { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return dc.AddReviewIDs(ids...) +} + // AddDeploymentStatusIDs adds the "deployment_statuses" edge to the DeploymentStatus entity by IDs. func (dc *DeploymentCreate) AddDeploymentStatusIDs(ids ...int) *DeploymentCreate { dc.mutation.AddDeploymentStatusIDs(ids...) @@ -629,6 +645,25 @@ func (dc *DeploymentCreate) createSpec() (*Deployment, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := dc.mutation.ReviewsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } if nodes := dc.mutation.DeploymentStatusesIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/ent/deployment_query.go b/ent/deployment_query.go index 1665e162..f7085ad0 100644 --- a/ent/deployment_query.go +++ b/ent/deployment_query.go @@ -19,6 +19,7 @@ import ( "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/predicate" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -35,6 +36,7 @@ type DeploymentQuery struct { withUser *UserQuery withRepo *RepoQuery withApprovals *ApprovalQuery + withReviews *ReviewQuery withDeploymentStatuses *DeploymentStatusQuery withEvent *EventQuery modifiers []func(s *sql.Selector) @@ -140,6 +142,28 @@ func (dq *DeploymentQuery) QueryApprovals() *ApprovalQuery { return query } +// QueryReviews chains the current query on the "reviews" edge. +func (dq *DeploymentQuery) QueryReviews() *ReviewQuery { + query := &ReviewQuery{config: dq.config} + 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(deployment.Table, deployment.FieldID, selector), + sqlgraph.To(review.Table, review.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, deployment.ReviewsTable, deployment.ReviewsColumn), + ) + fromU = sqlgraph.SetNeighbors(dq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryDeploymentStatuses chains the current query on the "deployment_statuses" edge. func (dq *DeploymentQuery) QueryDeploymentStatuses() *DeploymentStatusQuery { query := &DeploymentStatusQuery{config: dq.config} @@ -368,6 +392,7 @@ func (dq *DeploymentQuery) Clone() *DeploymentQuery { withUser: dq.withUser.Clone(), withRepo: dq.withRepo.Clone(), withApprovals: dq.withApprovals.Clone(), + withReviews: dq.withReviews.Clone(), withDeploymentStatuses: dq.withDeploymentStatuses.Clone(), withEvent: dq.withEvent.Clone(), // clone intermediate query. @@ -409,6 +434,17 @@ func (dq *DeploymentQuery) WithApprovals(opts ...func(*ApprovalQuery)) *Deployme return dq } +// WithReviews tells the query-builder to eager-load the nodes that are connected to +// the "reviews" edge. The optional arguments are used to configure the query builder of the edge. +func (dq *DeploymentQuery) WithReviews(opts ...func(*ReviewQuery)) *DeploymentQuery { + query := &ReviewQuery{config: dq.config} + for _, opt := range opts { + opt(query) + } + dq.withReviews = query + return dq +} + // WithDeploymentStatuses tells the query-builder to eager-load the nodes that are connected to // the "deployment_statuses" edge. The optional arguments are used to configure the query builder of the edge. func (dq *DeploymentQuery) WithDeploymentStatuses(opts ...func(*DeploymentStatusQuery)) *DeploymentQuery { @@ -496,10 +532,11 @@ func (dq *DeploymentQuery) sqlAll(ctx context.Context) ([]*Deployment, error) { var ( nodes = []*Deployment{} _spec = dq.querySpec() - loadedTypes = [5]bool{ + loadedTypes = [6]bool{ dq.withUser != nil, dq.withRepo != nil, dq.withApprovals != nil, + dq.withReviews != nil, dq.withDeploymentStatuses != nil, dq.withEvent != nil, } @@ -604,6 +641,31 @@ func (dq *DeploymentQuery) sqlAll(ctx context.Context) ([]*Deployment, error) { } } + if query := dq.withReviews; query != nil { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int]*Deployment) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + nodes[i].Edges.Reviews = []*Review{} + } + query.Where(predicate.Review(func(s *sql.Selector) { + s.Where(sql.InValues(deployment.ReviewsColumn, fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + fk := n.DeploymentID + node, ok := nodeids[fk] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "deployment_id" returned %v for node %v`, fk, n.ID) + } + node.Edges.Reviews = append(node.Edges.Reviews, n) + } + } + if query := dq.withDeploymentStatuses; query != nil { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int]*Deployment) diff --git a/ent/deployment_update.go b/ent/deployment_update.go index 756e0621..ef1dd72b 100644 --- a/ent/deployment_update.go +++ b/ent/deployment_update.go @@ -17,6 +17,7 @@ import ( "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/predicate" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -273,6 +274,21 @@ func (du *DeploymentUpdate) AddApprovals(a ...*Approval) *DeploymentUpdate { return du.AddApprovalIDs(ids...) } +// AddReviewIDs adds the "reviews" edge to the Review entity by IDs. +func (du *DeploymentUpdate) AddReviewIDs(ids ...int) *DeploymentUpdate { + du.mutation.AddReviewIDs(ids...) + return du +} + +// AddReviews adds the "reviews" edges to the Review entity. +func (du *DeploymentUpdate) AddReviews(r ...*Review) *DeploymentUpdate { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return du.AddReviewIDs(ids...) +} + // AddDeploymentStatusIDs adds the "deployment_statuses" edge to the DeploymentStatus entity by IDs. func (du *DeploymentUpdate) AddDeploymentStatusIDs(ids ...int) *DeploymentUpdate { du.mutation.AddDeploymentStatusIDs(ids...) @@ -341,6 +357,27 @@ func (du *DeploymentUpdate) RemoveApprovals(a ...*Approval) *DeploymentUpdate { return du.RemoveApprovalIDs(ids...) } +// ClearReviews clears all "reviews" edges to the Review entity. +func (du *DeploymentUpdate) ClearReviews() *DeploymentUpdate { + du.mutation.ClearReviews() + return du +} + +// RemoveReviewIDs removes the "reviews" edge to Review entities by IDs. +func (du *DeploymentUpdate) RemoveReviewIDs(ids ...int) *DeploymentUpdate { + du.mutation.RemoveReviewIDs(ids...) + return du +} + +// RemoveReviews removes "reviews" edges to Review entities. +func (du *DeploymentUpdate) RemoveReviews(r ...*Review) *DeploymentUpdate { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return du.RemoveReviewIDs(ids...) +} + // ClearDeploymentStatuses clears all "deployment_statuses" edges to the DeploymentStatus entity. func (du *DeploymentUpdate) ClearDeploymentStatuses() *DeploymentUpdate { du.mutation.ClearDeploymentStatuses() @@ -757,6 +794,60 @@ func (du *DeploymentUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if du.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := du.mutation.RemovedReviewsIDs(); len(nodes) > 0 && !du.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := du.mutation.ReviewsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if du.mutation.DeploymentStatusesCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -1124,6 +1215,21 @@ func (duo *DeploymentUpdateOne) AddApprovals(a ...*Approval) *DeploymentUpdateOn return duo.AddApprovalIDs(ids...) } +// AddReviewIDs adds the "reviews" edge to the Review entity by IDs. +func (duo *DeploymentUpdateOne) AddReviewIDs(ids ...int) *DeploymentUpdateOne { + duo.mutation.AddReviewIDs(ids...) + return duo +} + +// AddReviews adds the "reviews" edges to the Review entity. +func (duo *DeploymentUpdateOne) AddReviews(r ...*Review) *DeploymentUpdateOne { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return duo.AddReviewIDs(ids...) +} + // AddDeploymentStatusIDs adds the "deployment_statuses" edge to the DeploymentStatus entity by IDs. func (duo *DeploymentUpdateOne) AddDeploymentStatusIDs(ids ...int) *DeploymentUpdateOne { duo.mutation.AddDeploymentStatusIDs(ids...) @@ -1192,6 +1298,27 @@ func (duo *DeploymentUpdateOne) RemoveApprovals(a ...*Approval) *DeploymentUpdat return duo.RemoveApprovalIDs(ids...) } +// ClearReviews clears all "reviews" edges to the Review entity. +func (duo *DeploymentUpdateOne) ClearReviews() *DeploymentUpdateOne { + duo.mutation.ClearReviews() + return duo +} + +// RemoveReviewIDs removes the "reviews" edge to Review entities by IDs. +func (duo *DeploymentUpdateOne) RemoveReviewIDs(ids ...int) *DeploymentUpdateOne { + duo.mutation.RemoveReviewIDs(ids...) + return duo +} + +// RemoveReviews removes "reviews" edges to Review entities. +func (duo *DeploymentUpdateOne) RemoveReviews(r ...*Review) *DeploymentUpdateOne { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return duo.RemoveReviewIDs(ids...) +} + // ClearDeploymentStatuses clears all "deployment_statuses" edges to the DeploymentStatus entity. func (duo *DeploymentUpdateOne) ClearDeploymentStatuses() *DeploymentUpdateOne { duo.mutation.ClearDeploymentStatuses() @@ -1632,6 +1759,60 @@ func (duo *DeploymentUpdateOne) sqlSave(ctx context.Context) (_node *Deployment, } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if duo.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := duo.mutation.RemovedReviewsIDs(); len(nodes) > 0 && !duo.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := duo.mutation.ReviewsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: deployment.ReviewsTable, + Columns: []string{deployment.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if duo.mutation.DeploymentStatusesCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/ent/ent.go b/ent/ent.go index 6f6e854d..641d1ab3 100644 --- a/ent/ent.go +++ b/ent/ent.go @@ -19,6 +19,7 @@ import ( "github.com/gitploy-io/gitploy/ent/notificationrecord" "github.com/gitploy-io/gitploy/ent/perm" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -51,6 +52,7 @@ func columnChecker(table string) func(string) error { notificationrecord.Table: notificationrecord.ValidColumn, perm.Table: perm.ValidColumn, repo.Table: repo.ValidColumn, + review.Table: review.ValidColumn, user.Table: user.ValidColumn, } check, ok := checks[table] diff --git a/ent/event.go b/ent/event.go index 93e217a7..cf306f9c 100644 --- a/ent/event.go +++ b/ent/event.go @@ -12,6 +12,7 @@ import ( "github.com/gitploy-io/gitploy/ent/deployment" "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/notificationrecord" + "github.com/gitploy-io/gitploy/ent/review" ) // Event is the model entity for the Event schema. @@ -29,6 +30,8 @@ type Event struct { DeploymentID int `json:"deployment_id,omitemtpy"` // ApprovalID holds the value of the "approval_id" field. ApprovalID int `json:"approval_id,omitemtpy"` + // ReviewID holds the value of the "review_id" field. + ReviewID int `json:"review_id,omitemtpy"` // DeletedID holds the value of the "deleted_id" field. DeletedID int `json:"deleted_id,omitemtpy"` // Edges holds the relations/edges for other nodes in the graph. @@ -42,11 +45,13 @@ type EventEdges struct { Deployment *Deployment `json:"deployment,omitempty"` // Approval holds the value of the approval edge. Approval *Approval `json:"approval,omitempty"` + // Review holds the value of the review edge. + Review *Review `json:"review,omitempty"` // NotificationRecord holds the value of the notification_record edge. NotificationRecord *NotificationRecord `json:"notification_record,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 } // DeploymentOrErr returns the Deployment value or an error if the edge @@ -77,10 +82,24 @@ func (e EventEdges) ApprovalOrErr() (*Approval, error) { return nil, &NotLoadedError{edge: "approval"} } +// ReviewOrErr returns the Review value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e EventEdges) ReviewOrErr() (*Review, error) { + if e.loadedTypes[2] { + if e.Review == nil { + // The edge review was loaded in eager-loading, + // but was not found. + return nil, &NotFoundError{label: review.Label} + } + return e.Review, nil + } + return nil, &NotLoadedError{edge: "review"} +} + // NotificationRecordOrErr returns the NotificationRecord value or an error if the edge // was not loaded in eager-loading, or loaded but was not found. func (e EventEdges) NotificationRecordOrErr() (*NotificationRecord, error) { - if e.loadedTypes[2] { + if e.loadedTypes[3] { if e.NotificationRecord == nil { // The edge notification_record was loaded in eager-loading, // but was not found. @@ -96,7 +115,7 @@ func (*Event) scanValues(columns []string) ([]interface{}, error) { values := make([]interface{}, len(columns)) for i := range columns { switch columns[i] { - case event.FieldID, event.FieldDeploymentID, event.FieldApprovalID, event.FieldDeletedID: + case event.FieldID, event.FieldDeploymentID, event.FieldApprovalID, event.FieldReviewID, event.FieldDeletedID: values[i] = new(sql.NullInt64) case event.FieldKind, event.FieldType: values[i] = new(sql.NullString) @@ -153,6 +172,12 @@ func (e *Event) assignValues(columns []string, values []interface{}) error { } else if value.Valid { e.ApprovalID = int(value.Int64) } + case event.FieldReviewID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field review_id", values[i]) + } else if value.Valid { + e.ReviewID = int(value.Int64) + } case event.FieldDeletedID: if value, ok := values[i].(*sql.NullInt64); !ok { return fmt.Errorf("unexpected type %T for field deleted_id", values[i]) @@ -174,6 +199,11 @@ func (e *Event) QueryApproval() *ApprovalQuery { return (&EventClient{config: e.config}).QueryApproval(e) } +// QueryReview queries the "review" edge of the Event entity. +func (e *Event) QueryReview() *ReviewQuery { + return (&EventClient{config: e.config}).QueryReview(e) +} + // QueryNotificationRecord queries the "notification_record" edge of the Event entity. func (e *Event) QueryNotificationRecord() *NotificationRecordQuery { return (&EventClient{config: e.config}).QueryNotificationRecord(e) @@ -212,6 +242,8 @@ func (e *Event) String() string { builder.WriteString(fmt.Sprintf("%v", e.DeploymentID)) builder.WriteString(", approval_id=") builder.WriteString(fmt.Sprintf("%v", e.ApprovalID)) + builder.WriteString(", review_id=") + builder.WriteString(fmt.Sprintf("%v", e.ReviewID)) builder.WriteString(", deleted_id=") builder.WriteString(fmt.Sprintf("%v", e.DeletedID)) builder.WriteByte(')') diff --git a/ent/event/event.go b/ent/event/event.go index 069788ee..fe304402 100644 --- a/ent/event/event.go +++ b/ent/event/event.go @@ -22,12 +22,16 @@ const ( FieldDeploymentID = "deployment_id" // FieldApprovalID holds the string denoting the approval_id field in the database. FieldApprovalID = "approval_id" + // FieldReviewID holds the string denoting the review_id field in the database. + FieldReviewID = "review_id" // FieldDeletedID holds the string denoting the deleted_id field in the database. FieldDeletedID = "deleted_id" // EdgeDeployment holds the string denoting the deployment edge name in mutations. EdgeDeployment = "deployment" // EdgeApproval holds the string denoting the approval edge name in mutations. EdgeApproval = "approval" + // EdgeReview holds the string denoting the review edge name in mutations. + EdgeReview = "review" // EdgeNotificationRecord holds the string denoting the notification_record edge name in mutations. EdgeNotificationRecord = "notification_record" // Table holds the table name of the event in the database. @@ -46,6 +50,13 @@ const ( ApprovalInverseTable = "approvals" // ApprovalColumn is the table column denoting the approval relation/edge. ApprovalColumn = "approval_id" + // ReviewTable is the table that holds the review relation/edge. + ReviewTable = "events" + // ReviewInverseTable is the table name for the Review entity. + // It exists in this package in order to avoid circular dependency with the "review" package. + ReviewInverseTable = "reviews" + // ReviewColumn is the table column denoting the review relation/edge. + ReviewColumn = "review_id" // NotificationRecordTable is the table that holds the notification_record relation/edge. NotificationRecordTable = "notification_records" // NotificationRecordInverseTable is the table name for the NotificationRecord entity. @@ -63,6 +74,7 @@ var Columns = []string{ FieldCreatedAt, FieldDeploymentID, FieldApprovalID, + FieldReviewID, FieldDeletedID, } @@ -88,6 +100,7 @@ type Kind string const ( KindDeployment Kind = "deployment" KindApproval Kind = "approval" + KindReview Kind = "review" ) func (k Kind) String() string { @@ -97,7 +110,7 @@ func (k Kind) String() string { // KindValidator is a validator for the "kind" field enum values. It is called by the builders before save. func KindValidator(k Kind) error { switch k { - case KindDeployment, KindApproval: + case KindDeployment, KindApproval, KindReview: return nil default: return fmt.Errorf("event: invalid enum value for kind field: %q", k) diff --git a/ent/event/where.go b/ent/event/where.go index e383720a..490e2b8a 100644 --- a/ent/event/where.go +++ b/ent/event/where.go @@ -114,6 +114,13 @@ func ApprovalID(v int) predicate.Event { }) } +// ReviewID applies equality check predicate on the "review_id" field. It's identical to ReviewIDEQ. +func ReviewID(v int) predicate.Event { + return predicate.Event(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldReviewID), v)) + }) +} + // DeletedID applies equality check predicate on the "deleted_id" field. It's identical to DeletedIDEQ. func DeletedID(v int) predicate.Event { return predicate.Event(func(s *sql.Selector) { @@ -417,6 +424,68 @@ func ApprovalIDNotNil() predicate.Event { }) } +// ReviewIDEQ applies the EQ predicate on the "review_id" field. +func ReviewIDEQ(v int) predicate.Event { + return predicate.Event(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldReviewID), v)) + }) +} + +// ReviewIDNEQ applies the NEQ predicate on the "review_id" field. +func ReviewIDNEQ(v int) predicate.Event { + return predicate.Event(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldReviewID), v)) + }) +} + +// ReviewIDIn applies the In predicate on the "review_id" field. +func ReviewIDIn(vs ...int) predicate.Event { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Event(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldReviewID), v...)) + }) +} + +// ReviewIDNotIn applies the NotIn predicate on the "review_id" field. +func ReviewIDNotIn(vs ...int) predicate.Event { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Event(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldReviewID), v...)) + }) +} + +// ReviewIDIsNil applies the IsNil predicate on the "review_id" field. +func ReviewIDIsNil() predicate.Event { + return predicate.Event(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldReviewID))) + }) +} + +// ReviewIDNotNil applies the NotNil predicate on the "review_id" field. +func ReviewIDNotNil() predicate.Event { + return predicate.Event(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldReviewID))) + }) +} + // DeletedIDEQ applies the EQ predicate on the "deleted_id" field. func DeletedIDEQ(v int) predicate.Event { return predicate.Event(func(s *sql.Selector) { @@ -563,6 +632,34 @@ func HasApprovalWith(preds ...predicate.Approval) predicate.Event { }) } +// HasReview applies the HasEdge predicate on the "review" edge. +func HasReview() predicate.Event { + return predicate.Event(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ReviewTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, ReviewTable, ReviewColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasReviewWith applies the HasEdge predicate on the "review" edge with a given conditions (other predicates). +func HasReviewWith(preds ...predicate.Review) predicate.Event { + return predicate.Event(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ReviewInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, ReviewTable, ReviewColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasNotificationRecord applies the HasEdge predicate on the "notification_record" edge. func HasNotificationRecord() predicate.Event { return predicate.Event(func(s *sql.Selector) { diff --git a/ent/event_create.go b/ent/event_create.go index b29f82a3..82471d83 100644 --- a/ent/event_create.go +++ b/ent/event_create.go @@ -14,6 +14,7 @@ import ( "github.com/gitploy-io/gitploy/ent/deployment" "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/notificationrecord" + "github.com/gitploy-io/gitploy/ent/review" ) // EventCreate is the builder for creating a Event entity. @@ -77,6 +78,20 @@ func (ec *EventCreate) SetNillableApprovalID(i *int) *EventCreate { return ec } +// SetReviewID sets the "review_id" field. +func (ec *EventCreate) SetReviewID(i int) *EventCreate { + ec.mutation.SetReviewID(i) + return ec +} + +// SetNillableReviewID sets the "review_id" field if the given value is not nil. +func (ec *EventCreate) SetNillableReviewID(i *int) *EventCreate { + if i != nil { + ec.SetReviewID(*i) + } + return ec +} + // SetDeletedID sets the "deleted_id" field. func (ec *EventCreate) SetDeletedID(i int) *EventCreate { ec.mutation.SetDeletedID(i) @@ -101,6 +116,11 @@ func (ec *EventCreate) SetApproval(a *Approval) *EventCreate { return ec.SetApprovalID(a.ID) } +// SetReview sets the "review" edge to the Review entity. +func (ec *EventCreate) SetReview(r *Review) *EventCreate { + return ec.SetReviewID(r.ID) +} + // SetNotificationRecordID sets the "notification_record" edge to the NotificationRecord entity by ID. func (ec *EventCreate) SetNotificationRecordID(id int) *EventCreate { ec.mutation.SetNotificationRecordID(id) @@ -317,6 +337,26 @@ func (ec *EventCreate) createSpec() (*Event, *sqlgraph.CreateSpec) { _node.ApprovalID = nodes[0] _spec.Edges = append(_spec.Edges, edge) } + if nodes := ec.mutation.ReviewIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: event.ReviewTable, + Columns: []string{event.ReviewColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.ReviewID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } if nodes := ec.mutation.NotificationRecordIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, diff --git a/ent/event_query.go b/ent/event_query.go index 7f7758e4..9ec93fd0 100644 --- a/ent/event_query.go +++ b/ent/event_query.go @@ -18,6 +18,7 @@ import ( "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/notificationrecord" "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" ) // EventQuery is the builder for querying Event entities. @@ -32,6 +33,7 @@ type EventQuery struct { // eager-loading edges. withDeployment *DeploymentQuery withApproval *ApprovalQuery + withReview *ReviewQuery withNotificationRecord *NotificationRecordQuery modifiers []func(s *sql.Selector) // intermediate query (i.e. traversal path). @@ -114,6 +116,28 @@ func (eq *EventQuery) QueryApproval() *ApprovalQuery { return query } +// QueryReview chains the current query on the "review" edge. +func (eq *EventQuery) QueryReview() *ReviewQuery { + query := &ReviewQuery{config: eq.config} + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := eq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := eq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(event.Table, event.FieldID, selector), + sqlgraph.To(review.Table, review.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, event.ReviewTable, event.ReviewColumn), + ) + fromU = sqlgraph.SetNeighbors(eq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryNotificationRecord chains the current query on the "notification_record" edge. func (eq *EventQuery) QueryNotificationRecord() *NotificationRecordQuery { query := &NotificationRecordQuery{config: eq.config} @@ -319,6 +343,7 @@ func (eq *EventQuery) Clone() *EventQuery { predicates: append([]predicate.Event{}, eq.predicates...), withDeployment: eq.withDeployment.Clone(), withApproval: eq.withApproval.Clone(), + withReview: eq.withReview.Clone(), withNotificationRecord: eq.withNotificationRecord.Clone(), // clone intermediate query. sql: eq.sql.Clone(), @@ -348,6 +373,17 @@ func (eq *EventQuery) WithApproval(opts ...func(*ApprovalQuery)) *EventQuery { return eq } +// WithReview tells the query-builder to eager-load the nodes that are connected to +// the "review" edge. The optional arguments are used to configure the query builder of the edge. +func (eq *EventQuery) WithReview(opts ...func(*ReviewQuery)) *EventQuery { + query := &ReviewQuery{config: eq.config} + for _, opt := range opts { + opt(query) + } + eq.withReview = query + return eq +} + // WithNotificationRecord tells the query-builder to eager-load the nodes that are connected to // the "notification_record" edge. The optional arguments are used to configure the query builder of the edge. func (eq *EventQuery) WithNotificationRecord(opts ...func(*NotificationRecordQuery)) *EventQuery { @@ -424,9 +460,10 @@ func (eq *EventQuery) sqlAll(ctx context.Context) ([]*Event, error) { var ( nodes = []*Event{} _spec = eq.querySpec() - loadedTypes = [3]bool{ + loadedTypes = [4]bool{ eq.withDeployment != nil, eq.withApproval != nil, + eq.withReview != nil, eq.withNotificationRecord != nil, } ) @@ -505,6 +542,32 @@ func (eq *EventQuery) sqlAll(ctx context.Context) ([]*Event, error) { } } + if query := eq.withReview; query != nil { + ids := make([]int, 0, len(nodes)) + nodeids := make(map[int][]*Event) + for i := range nodes { + fk := nodes[i].ReviewID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + query.Where(review.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "review_id" returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.Review = n + } + } + } + if query := eq.withNotificationRecord; query != nil { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int]*Event) diff --git a/ent/event_update.go b/ent/event_update.go index d7b50bce..8dee6fc8 100644 --- a/ent/event_update.go +++ b/ent/event_update.go @@ -15,6 +15,7 @@ import ( "github.com/gitploy-io/gitploy/ent/event" "github.com/gitploy-io/gitploy/ent/notificationrecord" "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" ) // EventUpdate is the builder for updating Event entities. @@ -96,6 +97,26 @@ func (eu *EventUpdate) ClearApprovalID() *EventUpdate { return eu } +// SetReviewID sets the "review_id" field. +func (eu *EventUpdate) SetReviewID(i int) *EventUpdate { + eu.mutation.SetReviewID(i) + return eu +} + +// SetNillableReviewID sets the "review_id" field if the given value is not nil. +func (eu *EventUpdate) SetNillableReviewID(i *int) *EventUpdate { + if i != nil { + eu.SetReviewID(*i) + } + return eu +} + +// ClearReviewID clears the value of the "review_id" field. +func (eu *EventUpdate) ClearReviewID() *EventUpdate { + eu.mutation.ClearReviewID() + return eu +} + // SetDeletedID sets the "deleted_id" field. func (eu *EventUpdate) SetDeletedID(i int) *EventUpdate { eu.mutation.ResetDeletedID() @@ -133,6 +154,11 @@ func (eu *EventUpdate) SetApproval(a *Approval) *EventUpdate { return eu.SetApprovalID(a.ID) } +// SetReview sets the "review" edge to the Review entity. +func (eu *EventUpdate) SetReview(r *Review) *EventUpdate { + return eu.SetReviewID(r.ID) +} + // SetNotificationRecordID sets the "notification_record" edge to the NotificationRecord entity by ID. func (eu *EventUpdate) SetNotificationRecordID(id int) *EventUpdate { eu.mutation.SetNotificationRecordID(id) @@ -169,6 +195,12 @@ func (eu *EventUpdate) ClearApproval() *EventUpdate { return eu } +// ClearReview clears the "review" edge to the Review entity. +func (eu *EventUpdate) ClearReview() *EventUpdate { + eu.mutation.ClearReview() + return eu +} + // ClearNotificationRecord clears the "notification_record" edge to the NotificationRecord entity. func (eu *EventUpdate) ClearNotificationRecord() *EventUpdate { eu.mutation.ClearNotificationRecord() @@ -379,6 +411,41 @@ func (eu *EventUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if eu.mutation.ReviewCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: event.ReviewTable, + Columns: []string{event.ReviewColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := eu.mutation.ReviewIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: event.ReviewTable, + Columns: []string{event.ReviewColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if eu.mutation.NotificationRecordCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, @@ -499,6 +566,26 @@ func (euo *EventUpdateOne) ClearApprovalID() *EventUpdateOne { return euo } +// SetReviewID sets the "review_id" field. +func (euo *EventUpdateOne) SetReviewID(i int) *EventUpdateOne { + euo.mutation.SetReviewID(i) + return euo +} + +// SetNillableReviewID sets the "review_id" field if the given value is not nil. +func (euo *EventUpdateOne) SetNillableReviewID(i *int) *EventUpdateOne { + if i != nil { + euo.SetReviewID(*i) + } + return euo +} + +// ClearReviewID clears the value of the "review_id" field. +func (euo *EventUpdateOne) ClearReviewID() *EventUpdateOne { + euo.mutation.ClearReviewID() + return euo +} + // SetDeletedID sets the "deleted_id" field. func (euo *EventUpdateOne) SetDeletedID(i int) *EventUpdateOne { euo.mutation.ResetDeletedID() @@ -536,6 +623,11 @@ func (euo *EventUpdateOne) SetApproval(a *Approval) *EventUpdateOne { return euo.SetApprovalID(a.ID) } +// SetReview sets the "review" edge to the Review entity. +func (euo *EventUpdateOne) SetReview(r *Review) *EventUpdateOne { + return euo.SetReviewID(r.ID) +} + // SetNotificationRecordID sets the "notification_record" edge to the NotificationRecord entity by ID. func (euo *EventUpdateOne) SetNotificationRecordID(id int) *EventUpdateOne { euo.mutation.SetNotificationRecordID(id) @@ -572,6 +664,12 @@ func (euo *EventUpdateOne) ClearApproval() *EventUpdateOne { return euo } +// ClearReview clears the "review" edge to the Review entity. +func (euo *EventUpdateOne) ClearReview() *EventUpdateOne { + euo.mutation.ClearReview() + return euo +} + // ClearNotificationRecord clears the "notification_record" edge to the NotificationRecord entity. func (euo *EventUpdateOne) ClearNotificationRecord() *EventUpdateOne { euo.mutation.ClearNotificationRecord() @@ -806,6 +904,41 @@ func (euo *EventUpdateOne) sqlSave(ctx context.Context) (_node *Event, err error } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if euo.mutation.ReviewCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: event.ReviewTable, + Columns: []string{event.ReviewColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := euo.mutation.ReviewIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: event.ReviewTable, + Columns: []string{event.ReviewColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if euo.mutation.NotificationRecordCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2O, diff --git a/ent/hook/hook.go b/ent/hook/hook.go index 76577f9f..2b313b9f 100644 --- a/ent/hook/hook.go +++ b/ent/hook/hook.go @@ -152,6 +152,19 @@ func (f RepoFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) return f(ctx, mv) } +// The ReviewFunc type is an adapter to allow the use of ordinary +// function as Review mutator. +type ReviewFunc func(context.Context, *ent.ReviewMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f ReviewFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + mv, ok := m.(*ent.ReviewMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReviewMutation", m) + } + return f(ctx, mv) +} + // The UserFunc type is an adapter to allow the use of ordinary // function as User mutator. type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index fa9ba499..9f4a7784 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -225,12 +225,13 @@ var ( // EventsColumns holds the columns for the "events" table. EventsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "kind", Type: field.TypeEnum, Enums: []string{"deployment", "approval"}}, + {Name: "kind", Type: field.TypeEnum, Enums: []string{"deployment", "approval", "review"}}, {Name: "type", Type: field.TypeEnum, Enums: []string{"created", "updated", "deleted"}}, {Name: "created_at", Type: field.TypeTime}, {Name: "deleted_id", Type: field.TypeInt, Nullable: true}, {Name: "approval_id", Type: field.TypeInt, Nullable: true}, {Name: "deployment_id", Type: field.TypeInt, Nullable: true}, + {Name: "review_id", Type: field.TypeInt, Nullable: true}, } // EventsTable holds the schema information for the "events" table. EventsTable = &schema.Table{ @@ -250,6 +251,12 @@ var ( RefColumns: []*schema.Column{DeploymentsColumns[0]}, OnDelete: schema.Cascade, }, + { + Symbol: "events_reviews_event", + Columns: []*schema.Column{EventsColumns[7]}, + RefColumns: []*schema.Column{ReviewsColumns[0]}, + OnDelete: schema.Cascade, + }, }, Indexes: []*schema.Index{ { @@ -392,6 +399,35 @@ var ( }, }, } + // ReviewsColumns holds the columns for the "reviews" table. + ReviewsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + {Name: "status", Type: field.TypeEnum, Enums: []string{"pending", "rejected", "approved"}, Default: "pending"}, + {Name: "created_at", Type: field.TypeTime}, + {Name: "updated_at", Type: field.TypeTime}, + {Name: "deployment_id", Type: field.TypeInt, Nullable: true}, + {Name: "user_id", Type: field.TypeInt64, Nullable: true}, + } + // ReviewsTable holds the schema information for the "reviews" table. + ReviewsTable = &schema.Table{ + Name: "reviews", + Columns: ReviewsColumns, + PrimaryKey: []*schema.Column{ReviewsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "reviews_deployments_reviews", + Columns: []*schema.Column{ReviewsColumns[4]}, + RefColumns: []*schema.Column{DeploymentsColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "reviews_users_reviews", + Columns: []*schema.Column{ReviewsColumns[5]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.SetNull, + }, + }, + } // UsersColumns holds the columns for the "users" table. UsersColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt64, Increment: true}, @@ -424,6 +460,7 @@ var ( NotificationRecordsTable, PermsTable, ReposTable, + ReviewsTable, UsersTable, } ) @@ -439,9 +476,12 @@ func init() { DeploymentStatusTable.ForeignKeys[0].RefTable = DeploymentsTable EventsTable.ForeignKeys[0].RefTable = ApprovalsTable EventsTable.ForeignKeys[1].RefTable = DeploymentsTable + EventsTable.ForeignKeys[2].RefTable = ReviewsTable LocksTable.ForeignKeys[0].RefTable = ReposTable LocksTable.ForeignKeys[1].RefTable = UsersTable NotificationRecordsTable.ForeignKeys[0].RefTable = EventsTable PermsTable.ForeignKeys[0].RefTable = ReposTable PermsTable.ForeignKeys[1].RefTable = UsersTable + ReviewsTable.ForeignKeys[0].RefTable = DeploymentsTable + ReviewsTable.ForeignKeys[1].RefTable = UsersTable } diff --git a/ent/mutation.go b/ent/mutation.go index 1bb2c52d..de2dc1eb 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -20,6 +20,7 @@ import ( "github.com/gitploy-io/gitploy/ent/perm" "github.com/gitploy-io/gitploy/ent/predicate" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" "entgo.io/ent" @@ -45,6 +46,7 @@ const ( TypeNotificationRecord = "NotificationRecord" TypePerm = "Perm" TypeRepo = "Repo" + TypeReview = "Review" TypeUser = "User" ) @@ -2019,6 +2021,9 @@ type DeploymentMutation struct { approvals map[int]struct{} removedapprovals map[int]struct{} clearedapprovals bool + reviews map[int]struct{} + removedreviews map[int]struct{} + clearedreviews bool deployment_statuses map[int]struct{} removeddeployment_statuses map[int]struct{} cleareddeployment_statuses bool @@ -2891,6 +2896,60 @@ func (m *DeploymentMutation) ResetApprovals() { m.removedapprovals = nil } +// AddReviewIDs adds the "reviews" edge to the Review entity by ids. +func (m *DeploymentMutation) AddReviewIDs(ids ...int) { + if m.reviews == nil { + m.reviews = make(map[int]struct{}) + } + for i := range ids { + m.reviews[ids[i]] = struct{}{} + } +} + +// ClearReviews clears the "reviews" edge to the Review entity. +func (m *DeploymentMutation) ClearReviews() { + m.clearedreviews = true +} + +// ReviewsCleared reports if the "reviews" edge to the Review entity was cleared. +func (m *DeploymentMutation) ReviewsCleared() bool { + return m.clearedreviews +} + +// RemoveReviewIDs removes the "reviews" edge to the Review entity by IDs. +func (m *DeploymentMutation) RemoveReviewIDs(ids ...int) { + if m.removedreviews == nil { + m.removedreviews = make(map[int]struct{}) + } + for i := range ids { + delete(m.reviews, ids[i]) + m.removedreviews[ids[i]] = struct{}{} + } +} + +// RemovedReviews returns the removed IDs of the "reviews" edge to the Review entity. +func (m *DeploymentMutation) RemovedReviewsIDs() (ids []int) { + for id := range m.removedreviews { + ids = append(ids, id) + } + return +} + +// ReviewsIDs returns the "reviews" edge IDs in the mutation. +func (m *DeploymentMutation) ReviewsIDs() (ids []int) { + for id := range m.reviews { + ids = append(ids, id) + } + return +} + +// ResetReviews resets all changes to the "reviews" edge. +func (m *DeploymentMutation) ResetReviews() { + m.reviews = nil + m.clearedreviews = false + m.removedreviews = nil +} + // AddDeploymentStatusIDs adds the "deployment_statuses" edge to the DeploymentStatus entity by ids. func (m *DeploymentMutation) AddDeploymentStatusIDs(ids ...int) { if m.deployment_statuses == nil { @@ -3432,7 +3491,7 @@ func (m *DeploymentMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *DeploymentMutation) AddedEdges() []string { - edges := make([]string, 0, 5) + edges := make([]string, 0, 6) if m.user != nil { edges = append(edges, deployment.EdgeUser) } @@ -3442,6 +3501,9 @@ func (m *DeploymentMutation) AddedEdges() []string { if m.approvals != nil { edges = append(edges, deployment.EdgeApprovals) } + if m.reviews != nil { + edges = append(edges, deployment.EdgeReviews) + } if m.deployment_statuses != nil { edges = append(edges, deployment.EdgeDeploymentStatuses) } @@ -3469,6 +3531,12 @@ func (m *DeploymentMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case deployment.EdgeReviews: + ids := make([]ent.Value, 0, len(m.reviews)) + for id := range m.reviews { + ids = append(ids, id) + } + return ids case deployment.EdgeDeploymentStatuses: ids := make([]ent.Value, 0, len(m.deployment_statuses)) for id := range m.deployment_statuses { @@ -3487,10 +3555,13 @@ func (m *DeploymentMutation) AddedIDs(name string) []ent.Value { // RemovedEdges returns all edge names that were removed in this mutation. func (m *DeploymentMutation) RemovedEdges() []string { - edges := make([]string, 0, 5) + edges := make([]string, 0, 6) if m.removedapprovals != nil { edges = append(edges, deployment.EdgeApprovals) } + if m.removedreviews != nil { + edges = append(edges, deployment.EdgeReviews) + } if m.removeddeployment_statuses != nil { edges = append(edges, deployment.EdgeDeploymentStatuses) } @@ -3510,6 +3581,12 @@ func (m *DeploymentMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case deployment.EdgeReviews: + ids := make([]ent.Value, 0, len(m.removedreviews)) + for id := range m.removedreviews { + ids = append(ids, id) + } + return ids case deployment.EdgeDeploymentStatuses: ids := make([]ent.Value, 0, len(m.removeddeployment_statuses)) for id := range m.removeddeployment_statuses { @@ -3528,7 +3605,7 @@ func (m *DeploymentMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *DeploymentMutation) ClearedEdges() []string { - edges := make([]string, 0, 5) + edges := make([]string, 0, 6) if m.cleareduser { edges = append(edges, deployment.EdgeUser) } @@ -3538,6 +3615,9 @@ func (m *DeploymentMutation) ClearedEdges() []string { if m.clearedapprovals { edges = append(edges, deployment.EdgeApprovals) } + if m.clearedreviews { + edges = append(edges, deployment.EdgeReviews) + } if m.cleareddeployment_statuses { edges = append(edges, deployment.EdgeDeploymentStatuses) } @@ -3557,6 +3637,8 @@ func (m *DeploymentMutation) EdgeCleared(name string) bool { return m.clearedrepo case deployment.EdgeApprovals: return m.clearedapprovals + case deployment.EdgeReviews: + return m.clearedreviews case deployment.EdgeDeploymentStatuses: return m.cleareddeployment_statuses case deployment.EdgeEvent: @@ -3592,6 +3674,9 @@ func (m *DeploymentMutation) ResetEdge(name string) error { case deployment.EdgeApprovals: m.ResetApprovals() return nil + case deployment.EdgeReviews: + m.ResetReviews() + return nil case deployment.EdgeDeploymentStatuses: m.ResetDeploymentStatuses() return nil @@ -5400,6 +5485,8 @@ type EventMutation struct { cleareddeployment bool approval *int clearedapproval bool + review *int + clearedreview bool notification_record *int clearednotification_record bool done bool @@ -5692,6 +5779,55 @@ func (m *EventMutation) ResetApprovalID() { delete(m.clearedFields, event.FieldApprovalID) } +// SetReviewID sets the "review_id" field. +func (m *EventMutation) SetReviewID(i int) { + m.review = &i +} + +// ReviewID returns the value of the "review_id" field in the mutation. +func (m *EventMutation) ReviewID() (r int, exists bool) { + v := m.review + if v == nil { + return + } + return *v, true +} + +// OldReviewID returns the old "review_id" field's value of the Event entity. +// If the Event 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 *EventMutation) OldReviewID(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldReviewID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldReviewID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldReviewID: %w", err) + } + return oldValue.ReviewID, nil +} + +// ClearReviewID clears the value of the "review_id" field. +func (m *EventMutation) ClearReviewID() { + m.review = nil + m.clearedFields[event.FieldReviewID] = struct{}{} +} + +// ReviewIDCleared returns if the "review_id" field was cleared in this mutation. +func (m *EventMutation) ReviewIDCleared() bool { + _, ok := m.clearedFields[event.FieldReviewID] + return ok +} + +// ResetReviewID resets all changes to the "review_id" field. +func (m *EventMutation) ResetReviewID() { + m.review = nil + delete(m.clearedFields, event.FieldReviewID) +} + // SetDeletedID sets the "deleted_id" field. func (m *EventMutation) SetDeletedID(i int) { m.deleted_id = &i @@ -5814,6 +5950,32 @@ func (m *EventMutation) ResetApproval() { m.clearedapproval = false } +// ClearReview clears the "review" edge to the Review entity. +func (m *EventMutation) ClearReview() { + m.clearedreview = true +} + +// ReviewCleared reports if the "review" edge to the Review entity was cleared. +func (m *EventMutation) ReviewCleared() bool { + return m.ReviewIDCleared() || m.clearedreview +} + +// ReviewIDs returns the "review" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// ReviewID instead. It exists only for internal usage by the builders. +func (m *EventMutation) ReviewIDs() (ids []int) { + if id := m.review; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetReview resets all changes to the "review" edge. +func (m *EventMutation) ResetReview() { + m.review = nil + m.clearedreview = false +} + // SetNotificationRecordID sets the "notification_record" edge to the NotificationRecord entity by id. func (m *EventMutation) SetNotificationRecordID(id int) { m.notification_record = &id @@ -5872,7 +6034,7 @@ func (m *EventMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *EventMutation) Fields() []string { - fields := make([]string, 0, 6) + fields := make([]string, 0, 7) if m.kind != nil { fields = append(fields, event.FieldKind) } @@ -5888,6 +6050,9 @@ func (m *EventMutation) Fields() []string { if m.approval != nil { fields = append(fields, event.FieldApprovalID) } + if m.review != nil { + fields = append(fields, event.FieldReviewID) + } if m.deleted_id != nil { fields = append(fields, event.FieldDeletedID) } @@ -5909,6 +6074,8 @@ func (m *EventMutation) Field(name string) (ent.Value, bool) { return m.DeploymentID() case event.FieldApprovalID: return m.ApprovalID() + case event.FieldReviewID: + return m.ReviewID() case event.FieldDeletedID: return m.DeletedID() } @@ -5930,6 +6097,8 @@ func (m *EventMutation) OldField(ctx context.Context, name string) (ent.Value, e return m.OldDeploymentID(ctx) case event.FieldApprovalID: return m.OldApprovalID(ctx) + case event.FieldReviewID: + return m.OldReviewID(ctx) case event.FieldDeletedID: return m.OldDeletedID(ctx) } @@ -5976,6 +6145,13 @@ func (m *EventMutation) SetField(name string, value ent.Value) error { } m.SetApprovalID(v) return nil + case event.FieldReviewID: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetReviewID(v) + return nil case event.FieldDeletedID: v, ok := value.(int) if !ok { @@ -6034,6 +6210,9 @@ func (m *EventMutation) ClearedFields() []string { if m.FieldCleared(event.FieldApprovalID) { fields = append(fields, event.FieldApprovalID) } + if m.FieldCleared(event.FieldReviewID) { + fields = append(fields, event.FieldReviewID) + } if m.FieldCleared(event.FieldDeletedID) { fields = append(fields, event.FieldDeletedID) } @@ -6057,6 +6236,9 @@ func (m *EventMutation) ClearField(name string) error { case event.FieldApprovalID: m.ClearApprovalID() return nil + case event.FieldReviewID: + m.ClearReviewID() + return nil case event.FieldDeletedID: m.ClearDeletedID() return nil @@ -6083,6 +6265,9 @@ func (m *EventMutation) ResetField(name string) error { case event.FieldApprovalID: m.ResetApprovalID() return nil + case event.FieldReviewID: + m.ResetReviewID() + return nil case event.FieldDeletedID: m.ResetDeletedID() return nil @@ -6092,13 +6277,16 @@ func (m *EventMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *EventMutation) AddedEdges() []string { - edges := make([]string, 0, 3) + edges := make([]string, 0, 4) if m.deployment != nil { edges = append(edges, event.EdgeDeployment) } if m.approval != nil { edges = append(edges, event.EdgeApproval) } + if m.review != nil { + edges = append(edges, event.EdgeReview) + } if m.notification_record != nil { edges = append(edges, event.EdgeNotificationRecord) } @@ -6117,6 +6305,10 @@ func (m *EventMutation) AddedIDs(name string) []ent.Value { if id := m.approval; id != nil { return []ent.Value{*id} } + case event.EdgeReview: + if id := m.review; id != nil { + return []ent.Value{*id} + } case event.EdgeNotificationRecord: if id := m.notification_record; id != nil { return []ent.Value{*id} @@ -6127,7 +6319,7 @@ func (m *EventMutation) AddedIDs(name string) []ent.Value { // RemovedEdges returns all edge names that were removed in this mutation. func (m *EventMutation) RemovedEdges() []string { - edges := make([]string, 0, 3) + edges := make([]string, 0, 4) return edges } @@ -6141,13 +6333,16 @@ func (m *EventMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *EventMutation) ClearedEdges() []string { - edges := make([]string, 0, 3) + edges := make([]string, 0, 4) if m.cleareddeployment { edges = append(edges, event.EdgeDeployment) } if m.clearedapproval { edges = append(edges, event.EdgeApproval) } + if m.clearedreview { + edges = append(edges, event.EdgeReview) + } if m.clearednotification_record { edges = append(edges, event.EdgeNotificationRecord) } @@ -6162,6 +6357,8 @@ func (m *EventMutation) EdgeCleared(name string) bool { return m.cleareddeployment case event.EdgeApproval: return m.clearedapproval + case event.EdgeReview: + return m.clearedreview case event.EdgeNotificationRecord: return m.clearednotification_record } @@ -6178,6 +6375,9 @@ func (m *EventMutation) ClearEdge(name string) error { case event.EdgeApproval: m.ClearApproval() return nil + case event.EdgeReview: + m.ClearReview() + return nil case event.EdgeNotificationRecord: m.ClearNotificationRecord() return nil @@ -6195,6 +6395,9 @@ func (m *EventMutation) ResetEdge(name string) error { case event.EdgeApproval: m.ResetApproval() return nil + case event.EdgeReview: + m.ResetReview() + return nil case event.EdgeNotificationRecord: m.ResetNotificationRecord() return nil @@ -9105,52 +9308,39 @@ func (m *RepoMutation) ResetEdge(name string) error { return fmt.Errorf("unknown Repo edge %s", name) } -// UserMutation represents an operation that mutates the User nodes in the graph. -type UserMutation struct { +// ReviewMutation represents an operation that mutates the Review nodes in the graph. +type ReviewMutation struct { config - op Op - typ string - id *int64 - login *string - avatar *string - admin *bool - token *string - refresh *string - expiry *time.Time - hash *string - created_at *time.Time - updated_at *time.Time - clearedFields map[string]struct{} - chat_user *string - clearedchat_user bool - perms map[int]struct{} - removedperms map[int]struct{} - clearedperms bool - deployments map[int]struct{} - removeddeployments map[int]struct{} - cleareddeployments bool - approvals map[int]struct{} - removedapprovals map[int]struct{} - clearedapprovals bool - locks map[int]struct{} - removedlocks map[int]struct{} - clearedlocks bool - done bool - oldValue func(context.Context) (*User, error) - predicates []predicate.User + op Op + typ string + id *int + status *review.Status + created_at *time.Time + updated_at *time.Time + clearedFields map[string]struct{} + user *int64 + cleareduser bool + deployment *int + cleareddeployment bool + event map[int]struct{} + removedevent map[int]struct{} + clearedevent bool + done bool + oldValue func(context.Context) (*Review, error) + predicates []predicate.Review } -var _ ent.Mutation = (*UserMutation)(nil) +var _ ent.Mutation = (*ReviewMutation)(nil) -// userOption allows management of the mutation configuration using functional options. -type userOption func(*UserMutation) +// reviewOption allows management of the mutation configuration using functional options. +type reviewOption func(*ReviewMutation) -// newUserMutation creates new mutation for the User entity. -func newUserMutation(c config, op Op, opts ...userOption) *UserMutation { - m := &UserMutation{ +// newReviewMutation creates new mutation for the Review entity. +func newReviewMutation(c config, op Op, opts ...reviewOption) *ReviewMutation { + m := &ReviewMutation{ config: c, op: op, - typ: TypeUser, + typ: TypeReview, clearedFields: make(map[string]struct{}), } for _, opt := range opts { @@ -9159,20 +9349,20 @@ func newUserMutation(c config, op Op, opts ...userOption) *UserMutation { return m } -// withUserID sets the ID field of the mutation. -func withUserID(id int64) userOption { - return func(m *UserMutation) { +// withReviewID sets the ID field of the mutation. +func withReviewID(id int) reviewOption { + return func(m *ReviewMutation) { var ( err error once sync.Once - value *User + value *Review ) - m.oldValue = func(ctx context.Context) (*User, error) { + m.oldValue = func(ctx context.Context) (*Review, error) { once.Do(func() { if m.done { err = fmt.Errorf("querying old values post mutation is not allowed") } else { - value, err = m.Client().User.Get(ctx, id) + value, err = m.Client().Review.Get(ctx, id) } }) return value, err @@ -9181,10 +9371,10 @@ func withUserID(id int64) userOption { } } -// withUser sets the old User of the mutation. -func withUser(node *User) userOption { - return func(m *UserMutation) { - m.oldValue = func(context.Context) (*User, error) { +// withReview sets the old Review of the mutation. +func withReview(node *Review) reviewOption { + return func(m *ReviewMutation) { + m.oldValue = func(context.Context) (*Review, error) { return node, nil } m.id = &node.ID @@ -9193,7 +9383,7 @@ func withUser(node *User) userOption { // 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 UserMutation) Client() *Client { +func (m ReviewMutation) Client() *Client { client := &Client{config: m.config} client.init() return client @@ -9201,7 +9391,7 @@ func (m UserMutation) Client() *Client { // Tx returns an `ent.Tx` for mutations that were executed in transactions; // it returns an error otherwise. -func (m UserMutation) Tx() (*Tx, error) { +func (m ReviewMutation) Tx() (*Tx, error) { if _, ok := m.driver.(*txDriver); !ok { return nil, fmt.Errorf("ent: mutation is not running in a transaction") } @@ -9210,137 +9400,847 @@ func (m UserMutation) Tx() (*Tx, error) { return tx, nil } -// SetID sets the value of the id field. Note that this -// operation is only accepted on creation of User entities. -func (m *UserMutation) SetID(id int64) { - m.id = &id -} - // 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 *UserMutation) ID() (id int64, exists bool) { +func (m *ReviewMutation) ID() (id int, exists bool) { if m.id == nil { return } return *m.id, true } -// SetLogin sets the "login" field. -func (m *UserMutation) SetLogin(s string) { - m.login = &s +// SetStatus sets the "status" field. +func (m *ReviewMutation) SetStatus(r review.Status) { + m.status = &r } -// Login returns the value of the "login" field in the mutation. -func (m *UserMutation) Login() (r string, exists bool) { - v := m.login +// Status returns the value of the "status" field in the mutation. +func (m *ReviewMutation) Status() (r review.Status, exists bool) { + v := m.status if v == nil { return } return *v, true } -// OldLogin returns the old "login" field's value of the User entity. -// If the User object wasn't provided to the builder, the object is fetched from the database. +// OldStatus returns the old "status" field's value of the Review entity. +// If the Review 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 *UserMutation) OldLogin(ctx context.Context) (v string, err error) { +func (m *ReviewMutation) OldStatus(ctx context.Context) (v review.Status, err error) { if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldLogin is only allowed on UpdateOne operations") + return v, fmt.Errorf("OldStatus is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldLogin requires an ID field in the mutation") + return v, fmt.Errorf("OldStatus requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldLogin: %w", err) + return v, fmt.Errorf("querying old value for OldStatus: %w", err) } - return oldValue.Login, nil + return oldValue.Status, nil } -// ResetLogin resets all changes to the "login" field. -func (m *UserMutation) ResetLogin() { - m.login = nil +// ResetStatus resets all changes to the "status" field. +func (m *ReviewMutation) ResetStatus() { + m.status = nil } -// SetAvatar sets the "avatar" field. -func (m *UserMutation) SetAvatar(s string) { - m.avatar = &s +// SetCreatedAt sets the "created_at" field. +func (m *ReviewMutation) SetCreatedAt(t time.Time) { + m.created_at = &t } -// Avatar returns the value of the "avatar" field in the mutation. -func (m *UserMutation) Avatar() (r string, exists bool) { - v := m.avatar +// CreatedAt returns the value of the "created_at" field in the mutation. +func (m *ReviewMutation) CreatedAt() (r time.Time, exists bool) { + v := m.created_at if v == nil { return } return *v, true } -// OldAvatar returns the old "avatar" field's value of the User entity. -// If the User object wasn't provided to the builder, the object is fetched from the database. +// OldCreatedAt returns the old "created_at" field's value of the Review entity. +// If the Review 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 *UserMutation) OldAvatar(ctx context.Context) (v string, err error) { +func (m *ReviewMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldAvatar is only allowed on UpdateOne operations") + return v, fmt.Errorf("OldCreatedAt is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldAvatar requires an ID field in the mutation") + return v, fmt.Errorf("OldCreatedAt requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldAvatar: %w", err) + return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) } - return oldValue.Avatar, nil + return oldValue.CreatedAt, nil } -// ResetAvatar resets all changes to the "avatar" field. -func (m *UserMutation) ResetAvatar() { - m.avatar = nil +// ResetCreatedAt resets all changes to the "created_at" field. +func (m *ReviewMutation) ResetCreatedAt() { + m.created_at = nil } -// SetAdmin sets the "admin" field. -func (m *UserMutation) SetAdmin(b bool) { - m.admin = &b +// SetUpdatedAt sets the "updated_at" field. +func (m *ReviewMutation) SetUpdatedAt(t time.Time) { + m.updated_at = &t } -// Admin returns the value of the "admin" field in the mutation. -func (m *UserMutation) Admin() (r bool, exists bool) { - v := m.admin +// UpdatedAt returns the value of the "updated_at" field in the mutation. +func (m *ReviewMutation) UpdatedAt() (r time.Time, exists bool) { + v := m.updated_at if v == nil { return } return *v, true } -// OldAdmin returns the old "admin" field's value of the User entity. -// If the User object wasn't provided to the builder, the object is fetched from the database. +// OldUpdatedAt returns the old "updated_at" field's value of the Review entity. +// If the Review 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 *UserMutation) OldAdmin(ctx context.Context) (v bool, err error) { +func (m *ReviewMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) { if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldAdmin is only allowed on UpdateOne operations") + return v, fmt.Errorf("OldUpdatedAt is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldAdmin requires an ID field in the mutation") + return v, fmt.Errorf("OldUpdatedAt requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldAdmin: %w", err) + return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err) } - return oldValue.Admin, nil + return oldValue.UpdatedAt, nil } -// ResetAdmin resets all changes to the "admin" field. -func (m *UserMutation) ResetAdmin() { - m.admin = nil +// ResetUpdatedAt resets all changes to the "updated_at" field. +func (m *ReviewMutation) ResetUpdatedAt() { + m.updated_at = nil } -// SetToken sets the "token" field. -func (m *UserMutation) SetToken(s string) { - m.token = &s +// SetUserID sets the "user_id" field. +func (m *ReviewMutation) SetUserID(i int64) { + m.user = &i } -// Token returns the value of the "token" field in the mutation. -func (m *UserMutation) Token() (r string, exists bool) { - v := m.token +// UserID returns the value of the "user_id" field in the mutation. +func (m *ReviewMutation) UserID() (r int64, exists bool) { + v := m.user + if v == nil { + return + } + return *v, true +} + +// OldUserID returns the old "user_id" field's value of the Review entity. +// If the Review 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 *ReviewMutation) OldUserID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldUserID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldUserID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldUserID: %w", err) + } + return oldValue.UserID, nil +} + +// ResetUserID resets all changes to the "user_id" field. +func (m *ReviewMutation) ResetUserID() { + m.user = nil +} + +// SetDeploymentID sets the "deployment_id" field. +func (m *ReviewMutation) SetDeploymentID(i int) { + m.deployment = &i +} + +// DeploymentID returns the value of the "deployment_id" field in the mutation. +func (m *ReviewMutation) DeploymentID() (r int, exists bool) { + v := m.deployment + if v == nil { + return + } + return *v, true +} + +// OldDeploymentID returns the old "deployment_id" field's value of the Review entity. +// If the Review 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 *ReviewMutation) OldDeploymentID(ctx context.Context) (v int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldDeploymentID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldDeploymentID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDeploymentID: %w", err) + } + return oldValue.DeploymentID, nil +} + +// ResetDeploymentID resets all changes to the "deployment_id" field. +func (m *ReviewMutation) ResetDeploymentID() { + m.deployment = nil +} + +// ClearUser clears the "user" edge to the User entity. +func (m *ReviewMutation) ClearUser() { + m.cleareduser = true +} + +// UserCleared reports if the "user" edge to the User entity was cleared. +func (m *ReviewMutation) UserCleared() bool { + return m.cleareduser +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *ReviewMutation) UserIDs() (ids []int64) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *ReviewMutation) ResetUser() { + m.user = nil + m.cleareduser = false +} + +// ClearDeployment clears the "deployment" edge to the Deployment entity. +func (m *ReviewMutation) ClearDeployment() { + m.cleareddeployment = true +} + +// DeploymentCleared reports if the "deployment" edge to the Deployment entity was cleared. +func (m *ReviewMutation) DeploymentCleared() bool { + return m.cleareddeployment +} + +// DeploymentIDs returns the "deployment" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// DeploymentID instead. It exists only for internal usage by the builders. +func (m *ReviewMutation) DeploymentIDs() (ids []int) { + if id := m.deployment; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetDeployment resets all changes to the "deployment" edge. +func (m *ReviewMutation) ResetDeployment() { + m.deployment = nil + m.cleareddeployment = false +} + +// AddEventIDs adds the "event" edge to the Event entity by ids. +func (m *ReviewMutation) AddEventIDs(ids ...int) { + if m.event == nil { + m.event = make(map[int]struct{}) + } + for i := range ids { + m.event[ids[i]] = struct{}{} + } +} + +// ClearEvent clears the "event" edge to the Event entity. +func (m *ReviewMutation) ClearEvent() { + m.clearedevent = true +} + +// EventCleared reports if the "event" edge to the Event entity was cleared. +func (m *ReviewMutation) EventCleared() bool { + return m.clearedevent +} + +// RemoveEventIDs removes the "event" edge to the Event entity by IDs. +func (m *ReviewMutation) RemoveEventIDs(ids ...int) { + if m.removedevent == nil { + m.removedevent = make(map[int]struct{}) + } + for i := range ids { + delete(m.event, ids[i]) + m.removedevent[ids[i]] = struct{}{} + } +} + +// RemovedEvent returns the removed IDs of the "event" edge to the Event entity. +func (m *ReviewMutation) RemovedEventIDs() (ids []int) { + for id := range m.removedevent { + ids = append(ids, id) + } + return +} + +// EventIDs returns the "event" edge IDs in the mutation. +func (m *ReviewMutation) EventIDs() (ids []int) { + for id := range m.event { + ids = append(ids, id) + } + return +} + +// ResetEvent resets all changes to the "event" edge. +func (m *ReviewMutation) ResetEvent() { + m.event = nil + m.clearedevent = false + m.removedevent = nil +} + +// Where appends a list predicates to the ReviewMutation builder. +func (m *ReviewMutation) Where(ps ...predicate.Review) { + m.predicates = append(m.predicates, ps...) +} + +// Op returns the operation name. +func (m *ReviewMutation) Op() Op { + return m.op +} + +// Type returns the node type of this mutation (Review). +func (m *ReviewMutation) 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 *ReviewMutation) Fields() []string { + fields := make([]string, 0, 5) + if m.status != nil { + fields = append(fields, review.FieldStatus) + } + if m.created_at != nil { + fields = append(fields, review.FieldCreatedAt) + } + if m.updated_at != nil { + fields = append(fields, review.FieldUpdatedAt) + } + if m.user != nil { + fields = append(fields, review.FieldUserID) + } + if m.deployment != nil { + fields = append(fields, review.FieldDeploymentID) + } + 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 *ReviewMutation) Field(name string) (ent.Value, bool) { + switch name { + case review.FieldStatus: + return m.Status() + case review.FieldCreatedAt: + return m.CreatedAt() + case review.FieldUpdatedAt: + return m.UpdatedAt() + case review.FieldUserID: + return m.UserID() + case review.FieldDeploymentID: + return m.DeploymentID() + } + 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 *ReviewMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case review.FieldStatus: + return m.OldStatus(ctx) + case review.FieldCreatedAt: + return m.OldCreatedAt(ctx) + case review.FieldUpdatedAt: + return m.OldUpdatedAt(ctx) + case review.FieldUserID: + return m.OldUserID(ctx) + case review.FieldDeploymentID: + return m.OldDeploymentID(ctx) + } + return nil, fmt.Errorf("unknown Review 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 *ReviewMutation) SetField(name string, value ent.Value) error { + switch name { + case review.FieldStatus: + v, ok := value.(review.Status) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetStatus(v) + return nil + case review.FieldCreatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetCreatedAt(v) + return nil + case review.FieldUpdatedAt: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUpdatedAt(v) + return nil + case review.FieldUserID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetUserID(v) + return nil + case review.FieldDeploymentID: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDeploymentID(v) + return nil + } + return fmt.Errorf("unknown Review field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *ReviewMutation) AddedFields() []string { + var fields []string + return fields +} + +// 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 *ReviewMutation) AddedField(name string) (ent.Value, bool) { + switch name { + } + 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 *ReviewMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Review numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *ReviewMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *ReviewMutation) 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 *ReviewMutation) ClearField(name string) error { + return fmt.Errorf("unknown Review 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 *ReviewMutation) ResetField(name string) error { + switch name { + case review.FieldStatus: + m.ResetStatus() + return nil + case review.FieldCreatedAt: + m.ResetCreatedAt() + return nil + case review.FieldUpdatedAt: + m.ResetUpdatedAt() + return nil + case review.FieldUserID: + m.ResetUserID() + return nil + case review.FieldDeploymentID: + m.ResetDeploymentID() + return nil + } + return fmt.Errorf("unknown Review field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *ReviewMutation) AddedEdges() []string { + edges := make([]string, 0, 3) + if m.user != nil { + edges = append(edges, review.EdgeUser) + } + if m.deployment != nil { + edges = append(edges, review.EdgeDeployment) + } + if m.event != nil { + edges = append(edges, review.EdgeEvent) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *ReviewMutation) AddedIDs(name string) []ent.Value { + switch name { + case review.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } + case review.EdgeDeployment: + if id := m.deployment; id != nil { + return []ent.Value{*id} + } + case review.EdgeEvent: + ids := make([]ent.Value, 0, len(m.event)) + for id := range m.event { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *ReviewMutation) RemovedEdges() []string { + edges := make([]string, 0, 3) + if m.removedevent != nil { + edges = append(edges, review.EdgeEvent) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *ReviewMutation) RemovedIDs(name string) []ent.Value { + switch name { + case review.EdgeEvent: + ids := make([]ent.Value, 0, len(m.removedevent)) + for id := range m.removedevent { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *ReviewMutation) ClearedEdges() []string { + edges := make([]string, 0, 3) + if m.cleareduser { + edges = append(edges, review.EdgeUser) + } + if m.cleareddeployment { + edges = append(edges, review.EdgeDeployment) + } + if m.clearedevent { + edges = append(edges, review.EdgeEvent) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *ReviewMutation) EdgeCleared(name string) bool { + switch name { + case review.EdgeUser: + return m.cleareduser + case review.EdgeDeployment: + return m.cleareddeployment + case review.EdgeEvent: + return m.clearedevent + } + 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 *ReviewMutation) ClearEdge(name string) error { + switch name { + case review.EdgeUser: + m.ClearUser() + return nil + case review.EdgeDeployment: + m.ClearDeployment() + return nil + } + return fmt.Errorf("unknown Review 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 *ReviewMutation) ResetEdge(name string) error { + switch name { + case review.EdgeUser: + m.ResetUser() + return nil + case review.EdgeDeployment: + m.ResetDeployment() + return nil + case review.EdgeEvent: + m.ResetEvent() + return nil + } + return fmt.Errorf("unknown Review edge %s", name) +} + +// UserMutation represents an operation that mutates the User nodes in the graph. +type UserMutation struct { + config + op Op + typ string + id *int64 + login *string + avatar *string + admin *bool + token *string + refresh *string + expiry *time.Time + hash *string + created_at *time.Time + updated_at *time.Time + clearedFields map[string]struct{} + chat_user *string + clearedchat_user bool + perms map[int]struct{} + removedperms map[int]struct{} + clearedperms bool + deployments map[int]struct{} + removeddeployments map[int]struct{} + cleareddeployments bool + approvals map[int]struct{} + removedapprovals map[int]struct{} + clearedapprovals bool + reviews map[int]struct{} + removedreviews map[int]struct{} + clearedreviews bool + locks map[int]struct{} + removedlocks map[int]struct{} + clearedlocks bool + done bool + oldValue func(context.Context) (*User, error) + predicates []predicate.User +} + +var _ ent.Mutation = (*UserMutation)(nil) + +// userOption allows management of the mutation configuration using functional options. +type userOption func(*UserMutation) + +// newUserMutation creates new mutation for the User entity. +func newUserMutation(c config, op Op, opts ...userOption) *UserMutation { + m := &UserMutation{ + config: c, + op: op, + typ: TypeUser, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withUserID sets the ID field of the mutation. +func withUserID(id int64) userOption { + return func(m *UserMutation) { + var ( + err error + once sync.Once + value *User + ) + m.oldValue = func(ctx context.Context) (*User, error) { + once.Do(func() { + if m.done { + err = fmt.Errorf("querying old values post mutation is not allowed") + } else { + value, err = m.Client().User.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withUser sets the old User of the mutation. +func withUser(node *User) userOption { + return func(m *UserMutation) { + m.oldValue = func(context.Context) (*User, 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 UserMutation) 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 UserMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, fmt.Errorf("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of User entities. +func (m *UserMutation) SetID(id int64) { + m.id = &id +} + +// 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 *UserMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// SetLogin sets the "login" field. +func (m *UserMutation) SetLogin(s string) { + m.login = &s +} + +// Login returns the value of the "login" field in the mutation. +func (m *UserMutation) Login() (r string, exists bool) { + v := m.login + if v == nil { + return + } + return *v, true +} + +// OldLogin returns the old "login" field's value of the User entity. +// If the User 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 *UserMutation) OldLogin(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldLogin is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldLogin requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLogin: %w", err) + } + return oldValue.Login, nil +} + +// ResetLogin resets all changes to the "login" field. +func (m *UserMutation) ResetLogin() { + m.login = nil +} + +// SetAvatar sets the "avatar" field. +func (m *UserMutation) SetAvatar(s string) { + m.avatar = &s +} + +// Avatar returns the value of the "avatar" field in the mutation. +func (m *UserMutation) Avatar() (r string, exists bool) { + v := m.avatar + if v == nil { + return + } + return *v, true +} + +// OldAvatar returns the old "avatar" field's value of the User entity. +// If the User 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 *UserMutation) OldAvatar(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldAvatar is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldAvatar requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAvatar: %w", err) + } + return oldValue.Avatar, nil +} + +// ResetAvatar resets all changes to the "avatar" field. +func (m *UserMutation) ResetAvatar() { + m.avatar = nil +} + +// SetAdmin sets the "admin" field. +func (m *UserMutation) SetAdmin(b bool) { + m.admin = &b +} + +// Admin returns the value of the "admin" field in the mutation. +func (m *UserMutation) Admin() (r bool, exists bool) { + v := m.admin + if v == nil { + return + } + return *v, true +} + +// OldAdmin returns the old "admin" field's value of the User entity. +// If the User 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 *UserMutation) OldAdmin(ctx context.Context) (v bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldAdmin is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldAdmin requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAdmin: %w", err) + } + return oldValue.Admin, nil +} + +// ResetAdmin resets all changes to the "admin" field. +func (m *UserMutation) ResetAdmin() { + m.admin = nil +} + +// SetToken sets the "token" field. +func (m *UserMutation) SetToken(s string) { + m.token = &s +} + +// Token returns the value of the "token" field in the mutation. +func (m *UserMutation) Token() (r string, exists bool) { + v := m.token if v == nil { return } @@ -9750,6 +10650,60 @@ func (m *UserMutation) ResetApprovals() { m.removedapprovals = nil } +// AddReviewIDs adds the "reviews" edge to the Review entity by ids. +func (m *UserMutation) AddReviewIDs(ids ...int) { + if m.reviews == nil { + m.reviews = make(map[int]struct{}) + } + for i := range ids { + m.reviews[ids[i]] = struct{}{} + } +} + +// ClearReviews clears the "reviews" edge to the Review entity. +func (m *UserMutation) ClearReviews() { + m.clearedreviews = true +} + +// ReviewsCleared reports if the "reviews" edge to the Review entity was cleared. +func (m *UserMutation) ReviewsCleared() bool { + return m.clearedreviews +} + +// RemoveReviewIDs removes the "reviews" edge to the Review entity by IDs. +func (m *UserMutation) RemoveReviewIDs(ids ...int) { + if m.removedreviews == nil { + m.removedreviews = make(map[int]struct{}) + } + for i := range ids { + delete(m.reviews, ids[i]) + m.removedreviews[ids[i]] = struct{}{} + } +} + +// RemovedReviews returns the removed IDs of the "reviews" edge to the Review entity. +func (m *UserMutation) RemovedReviewsIDs() (ids []int) { + for id := range m.removedreviews { + ids = append(ids, id) + } + return +} + +// ReviewsIDs returns the "reviews" edge IDs in the mutation. +func (m *UserMutation) ReviewsIDs() (ids []int) { + for id := range m.reviews { + ids = append(ids, id) + } + return +} + +// ResetReviews resets all changes to the "reviews" edge. +func (m *UserMutation) ResetReviews() { + m.reviews = nil + m.clearedreviews = false + m.removedreviews = nil +} + // AddLockIDs adds the "locks" edge to the Lock entity by ids. func (m *UserMutation) AddLockIDs(ids ...int) { if m.locks == nil { @@ -10058,7 +11012,7 @@ func (m *UserMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *UserMutation) AddedEdges() []string { - edges := make([]string, 0, 5) + edges := make([]string, 0, 6) if m.chat_user != nil { edges = append(edges, user.EdgeChatUser) } @@ -10071,6 +11025,9 @@ func (m *UserMutation) AddedEdges() []string { if m.approvals != nil { edges = append(edges, user.EdgeApprovals) } + if m.reviews != nil { + edges = append(edges, user.EdgeReviews) + } if m.locks != nil { edges = append(edges, user.EdgeLocks) } @@ -10103,6 +11060,12 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgeReviews: + ids := make([]ent.Value, 0, len(m.reviews)) + for id := range m.reviews { + ids = append(ids, id) + } + return ids case user.EdgeLocks: ids := make([]ent.Value, 0, len(m.locks)) for id := range m.locks { @@ -10115,7 +11078,7 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserMutation) RemovedEdges() []string { - edges := make([]string, 0, 5) + edges := make([]string, 0, 6) if m.removedperms != nil { edges = append(edges, user.EdgePerms) } @@ -10125,6 +11088,9 @@ func (m *UserMutation) RemovedEdges() []string { if m.removedapprovals != nil { edges = append(edges, user.EdgeApprovals) } + if m.removedreviews != nil { + edges = append(edges, user.EdgeReviews) + } if m.removedlocks != nil { edges = append(edges, user.EdgeLocks) } @@ -10153,6 +11119,12 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgeReviews: + ids := make([]ent.Value, 0, len(m.removedreviews)) + for id := range m.removedreviews { + ids = append(ids, id) + } + return ids case user.EdgeLocks: ids := make([]ent.Value, 0, len(m.removedlocks)) for id := range m.removedlocks { @@ -10165,7 +11137,7 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserMutation) ClearedEdges() []string { - edges := make([]string, 0, 5) + edges := make([]string, 0, 6) if m.clearedchat_user { edges = append(edges, user.EdgeChatUser) } @@ -10178,6 +11150,9 @@ func (m *UserMutation) ClearedEdges() []string { if m.clearedapprovals { edges = append(edges, user.EdgeApprovals) } + if m.clearedreviews { + edges = append(edges, user.EdgeReviews) + } if m.clearedlocks { edges = append(edges, user.EdgeLocks) } @@ -10196,6 +11171,8 @@ func (m *UserMutation) EdgeCleared(name string) bool { return m.cleareddeployments case user.EdgeApprovals: return m.clearedapprovals + case user.EdgeReviews: + return m.clearedreviews case user.EdgeLocks: return m.clearedlocks } @@ -10229,6 +11206,9 @@ func (m *UserMutation) ResetEdge(name string) error { case user.EdgeApprovals: m.ResetApprovals() return nil + case user.EdgeReviews: + m.ResetReviews() + return nil case user.EdgeLocks: m.ResetLocks() return nil diff --git a/ent/predicate/predicate.go b/ent/predicate/predicate.go index 1c6cf729..4415fa93 100644 --- a/ent/predicate/predicate.go +++ b/ent/predicate/predicate.go @@ -39,5 +39,8 @@ type Perm func(*sql.Selector) // Repo is the predicate function for repo builders. type Repo func(*sql.Selector) +// Review is the predicate function for review builders. +type Review func(*sql.Selector) + // User is the predicate function for user builders. type User func(*sql.Selector) diff --git a/ent/review.go b/ent/review.go new file mode 100644 index 00000000..1c9afa3e --- /dev/null +++ b/ent/review.go @@ -0,0 +1,212 @@ +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent/dialect/sql" + "github.com/gitploy-io/gitploy/ent/deployment" + "github.com/gitploy-io/gitploy/ent/review" + "github.com/gitploy-io/gitploy/ent/user" +) + +// Review is the model entity for the Review schema. +type Review struct { + config `json:"-"` + // ID of the ent. + ID int `json:"id,omitempty"` + // Status holds the value of the "status" field. + Status review.Status `json:"status"` + // CreatedAt holds the value of the "created_at" field. + CreatedAt time.Time `json:"created_at"` + // UpdatedAt holds the value of the "updated_at" field. + UpdatedAt time.Time `json:"updated_at"` + // UserID holds the value of the "user_id" field. + UserID int64 `json:"user_id"` + // DeploymentID holds the value of the "deployment_id" field. + DeploymentID int `json:"deployment_id"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the ReviewQuery when eager-loading is set. + Edges ReviewEdges `json:"edges"` +} + +// ReviewEdges holds the relations/edges for other nodes in the graph. +type ReviewEdges struct { + // User holds the value of the user edge. + User *User `json:"user,omitempty"` + // Deployment holds the value of the deployment edge. + Deployment *Deployment `json:"deployment,omitempty"` + // Event holds the value of the event edge. + Event []*Event `json:"event,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [3]bool +} + +// UserOrErr returns the User value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e ReviewEdges) UserOrErr() (*User, error) { + if e.loadedTypes[0] { + if e.User == nil { + // The edge user was loaded in eager-loading, + // but was not found. + return nil, &NotFoundError{label: user.Label} + } + return e.User, nil + } + return nil, &NotLoadedError{edge: "user"} +} + +// DeploymentOrErr returns the Deployment value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e ReviewEdges) DeploymentOrErr() (*Deployment, error) { + if e.loadedTypes[1] { + if e.Deployment == nil { + // The edge deployment was loaded in eager-loading, + // but was not found. + return nil, &NotFoundError{label: deployment.Label} + } + return e.Deployment, nil + } + return nil, &NotLoadedError{edge: "deployment"} +} + +// EventOrErr returns the Event value or an error if the edge +// was not loaded in eager-loading. +func (e ReviewEdges) EventOrErr() ([]*Event, error) { + if e.loadedTypes[2] { + return e.Event, nil + } + return nil, &NotLoadedError{edge: "event"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Review) scanValues(columns []string) ([]interface{}, error) { + values := make([]interface{}, len(columns)) + for i := range columns { + switch columns[i] { + case review.FieldID, review.FieldUserID, review.FieldDeploymentID: + values[i] = new(sql.NullInt64) + case review.FieldStatus: + values[i] = new(sql.NullString) + case review.FieldCreatedAt, review.FieldUpdatedAt: + values[i] = new(sql.NullTime) + default: + return nil, fmt.Errorf("unexpected column %q for type Review", columns[i]) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Review fields. +func (r *Review) assignValues(columns []string, values []interface{}) 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 review.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + r.ID = int(value.Int64) + case review.FieldStatus: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field status", values[i]) + } else if value.Valid { + r.Status = review.Status(value.String) + } + case review.FieldCreatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field created_at", values[i]) + } else if value.Valid { + r.CreatedAt = value.Time + } + case review.FieldUpdatedAt: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field updated_at", values[i]) + } else if value.Valid { + r.UpdatedAt = value.Time + } + case review.FieldUserID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field user_id", values[i]) + } else if value.Valid { + r.UserID = value.Int64 + } + case review.FieldDeploymentID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field deployment_id", values[i]) + } else if value.Valid { + r.DeploymentID = int(value.Int64) + } + } + } + return nil +} + +// QueryUser queries the "user" edge of the Review entity. +func (r *Review) QueryUser() *UserQuery { + return (&ReviewClient{config: r.config}).QueryUser(r) +} + +// QueryDeployment queries the "deployment" edge of the Review entity. +func (r *Review) QueryDeployment() *DeploymentQuery { + return (&ReviewClient{config: r.config}).QueryDeployment(r) +} + +// QueryEvent queries the "event" edge of the Review entity. +func (r *Review) QueryEvent() *EventQuery { + return (&ReviewClient{config: r.config}).QueryEvent(r) +} + +// Update returns a builder for updating this Review. +// Note that you need to call Review.Unwrap() before calling this method if this Review +// was returned from a transaction, and the transaction was committed or rolled back. +func (r *Review) Update() *ReviewUpdateOne { + return (&ReviewClient{config: r.config}).UpdateOne(r) +} + +// Unwrap unwraps the Review 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 (r *Review) Unwrap() *Review { + tx, ok := r.config.driver.(*txDriver) + if !ok { + panic("ent: Review is not a transactional entity") + } + r.config.driver = tx.drv + return r +} + +// String implements the fmt.Stringer. +func (r *Review) String() string { + var builder strings.Builder + builder.WriteString("Review(") + builder.WriteString(fmt.Sprintf("id=%v", r.ID)) + builder.WriteString(", status=") + builder.WriteString(fmt.Sprintf("%v", r.Status)) + builder.WriteString(", created_at=") + builder.WriteString(r.CreatedAt.Format(time.ANSIC)) + builder.WriteString(", updated_at=") + builder.WriteString(r.UpdatedAt.Format(time.ANSIC)) + builder.WriteString(", user_id=") + builder.WriteString(fmt.Sprintf("%v", r.UserID)) + builder.WriteString(", deployment_id=") + builder.WriteString(fmt.Sprintf("%v", r.DeploymentID)) + builder.WriteByte(')') + return builder.String() +} + +// Reviews is a parsable slice of Review. +type Reviews []*Review + +func (r Reviews) config(cfg config) { + for _i := range r { + r[_i].config = cfg + } +} diff --git a/ent/review/review.go b/ent/review/review.go new file mode 100644 index 00000000..f29dc884 --- /dev/null +++ b/ent/review/review.go @@ -0,0 +1,110 @@ +// Code generated by entc, DO NOT EDIT. + +package review + +import ( + "fmt" + "time" +) + +const ( + // Label holds the string label denoting the review type in the database. + Label = "review" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldStatus holds the string denoting the status field in the database. + FieldStatus = "status" + // FieldCreatedAt holds the string denoting the created_at field in the database. + FieldCreatedAt = "created_at" + // FieldUpdatedAt holds the string denoting the updated_at field in the database. + FieldUpdatedAt = "updated_at" + // FieldUserID holds the string denoting the user_id field in the database. + FieldUserID = "user_id" + // FieldDeploymentID holds the string denoting the deployment_id field in the database. + FieldDeploymentID = "deployment_id" + // EdgeUser holds the string denoting the user edge name in mutations. + EdgeUser = "user" + // EdgeDeployment holds the string denoting the deployment edge name in mutations. + EdgeDeployment = "deployment" + // EdgeEvent holds the string denoting the event edge name in mutations. + EdgeEvent = "event" + // Table holds the table name of the review in the database. + Table = "reviews" + // UserTable is the table that holds the user relation/edge. + UserTable = "reviews" + // UserInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UserInverseTable = "users" + // UserColumn is the table column denoting the user relation/edge. + UserColumn = "user_id" + // DeploymentTable is the table that holds the deployment relation/edge. + DeploymentTable = "reviews" + // DeploymentInverseTable is the table name for the Deployment entity. + // It exists in this package in order to avoid circular dependency with the "deployment" package. + DeploymentInverseTable = "deployments" + // DeploymentColumn is the table column denoting the deployment relation/edge. + DeploymentColumn = "deployment_id" + // EventTable is the table that holds the event relation/edge. + EventTable = "events" + // EventInverseTable is the table name for the Event entity. + // It exists in this package in order to avoid circular dependency with the "event" package. + EventInverseTable = "events" + // EventColumn is the table column denoting the event relation/edge. + EventColumn = "review_id" +) + +// Columns holds all SQL columns for review fields. +var Columns = []string{ + FieldID, + FieldStatus, + FieldCreatedAt, + FieldUpdatedAt, + FieldUserID, + FieldDeploymentID, +} + +// 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 ( + // DefaultCreatedAt holds the default value on creation for the "created_at" field. + DefaultCreatedAt func() time.Time + // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. + DefaultUpdatedAt func() time.Time + // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. + UpdateDefaultUpdatedAt func() time.Time +) + +// Status defines the type for the "status" enum field. +type Status string + +// StatusPending is the default value of the Status enum. +const DefaultStatus = StatusPending + +// Status values. +const ( + StatusPending Status = "pending" + StatusRejected Status = "rejected" + StatusApproved Status = "approved" +) + +func (s Status) String() string { + return string(s) +} + +// StatusValidator is a validator for the "status" field enum values. It is called by the builders before save. +func StatusValidator(s Status) error { + switch s { + case StatusPending, StatusRejected, StatusApproved: + return nil + default: + return fmt.Errorf("review: invalid enum value for status field: %q", s) + } +} diff --git a/ent/review/where.go b/ent/review/where.go new file mode 100644 index 00000000..6647c386 --- /dev/null +++ b/ent/review/where.go @@ -0,0 +1,534 @@ +// Code generated by entc, DO NOT EDIT. + +package review + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/gitploy-io/gitploy/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldID), id)) + }) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.In(s.C(FieldID), v...)) + }) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.NotIn(s.C(FieldID), v...)) + }) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldID), id)) + }) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldID), id)) + }) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldID), id)) + }) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldID), id)) + }) +} + +// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. +func CreatedAt(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldCreatedAt), v)) + }) +} + +// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ. +func UpdatedAt(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldUpdatedAt), v)) + }) +} + +// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ. +func UserID(v int64) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldUserID), v)) + }) +} + +// DeploymentID applies equality check predicate on the "deployment_id" field. It's identical to DeploymentIDEQ. +func DeploymentID(v int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldDeploymentID), v)) + }) +} + +// StatusEQ applies the EQ predicate on the "status" field. +func StatusEQ(v Status) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldStatus), v)) + }) +} + +// StatusNEQ applies the NEQ predicate on the "status" field. +func StatusNEQ(v Status) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldStatus), v)) + }) +} + +// StatusIn applies the In predicate on the "status" field. +func StatusIn(vs ...Status) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldStatus), v...)) + }) +} + +// StatusNotIn applies the NotIn predicate on the "status" field. +func StatusNotIn(vs ...Status) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldStatus), v...)) + }) +} + +// CreatedAtEQ applies the EQ predicate on the "created_at" field. +func CreatedAtEQ(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. +func CreatedAtNEQ(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtIn applies the In predicate on the "created_at" field. +func CreatedAtIn(vs ...time.Time) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldCreatedAt), v...)) + }) +} + +// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. +func CreatedAtNotIn(vs ...time.Time) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldCreatedAt), v...)) + }) +} + +// CreatedAtGT applies the GT predicate on the "created_at" field. +func CreatedAtGT(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtGTE applies the GTE predicate on the "created_at" field. +func CreatedAtGTE(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtLT applies the LT predicate on the "created_at" field. +func CreatedAtLT(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldCreatedAt), v)) + }) +} + +// CreatedAtLTE applies the LTE predicate on the "created_at" field. +func CreatedAtLTE(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldCreatedAt), v)) + }) +} + +// UpdatedAtEQ applies the EQ predicate on the "updated_at" field. +func UpdatedAtEQ(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldUpdatedAt), v)) + }) +} + +// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field. +func UpdatedAtNEQ(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldUpdatedAt), v)) + }) +} + +// UpdatedAtIn applies the In predicate on the "updated_at" field. +func UpdatedAtIn(vs ...time.Time) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldUpdatedAt), v...)) + }) +} + +// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field. +func UpdatedAtNotIn(vs ...time.Time) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...)) + }) +} + +// UpdatedAtGT applies the GT predicate on the "updated_at" field. +func UpdatedAtGT(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldUpdatedAt), v)) + }) +} + +// UpdatedAtGTE applies the GTE predicate on the "updated_at" field. +func UpdatedAtGTE(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldUpdatedAt), v)) + }) +} + +// UpdatedAtLT applies the LT predicate on the "updated_at" field. +func UpdatedAtLT(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldUpdatedAt), v)) + }) +} + +// UpdatedAtLTE applies the LTE predicate on the "updated_at" field. +func UpdatedAtLTE(v time.Time) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldUpdatedAt), v)) + }) +} + +// UserIDEQ applies the EQ predicate on the "user_id" field. +func UserIDEQ(v int64) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldUserID), v)) + }) +} + +// UserIDNEQ applies the NEQ predicate on the "user_id" field. +func UserIDNEQ(v int64) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldUserID), v)) + }) +} + +// UserIDIn applies the In predicate on the "user_id" field. +func UserIDIn(vs ...int64) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldUserID), v...)) + }) +} + +// UserIDNotIn applies the NotIn predicate on the "user_id" field. +func UserIDNotIn(vs ...int64) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldUserID), v...)) + }) +} + +// DeploymentIDEQ applies the EQ predicate on the "deployment_id" field. +func DeploymentIDEQ(v int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldDeploymentID), v)) + }) +} + +// DeploymentIDNEQ applies the NEQ predicate on the "deployment_id" field. +func DeploymentIDNEQ(v int) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldDeploymentID), v)) + }) +} + +// DeploymentIDIn applies the In predicate on the "deployment_id" field. +func DeploymentIDIn(vs ...int) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldDeploymentID), v...)) + }) +} + +// DeploymentIDNotIn applies the NotIn predicate on the "deployment_id" field. +func DeploymentIDNotIn(vs ...int) predicate.Review { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Review(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldDeploymentID), v...)) + }) +} + +// HasUser applies the HasEdge predicate on the "user" edge. +func HasUser() predicate.Review { + return predicate.Review(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). +func HasUserWith(preds ...predicate.User) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasDeployment applies the HasEdge predicate on the "deployment" edge. +func HasDeployment() predicate.Review { + return predicate.Review(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(DeploymentTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, DeploymentTable, DeploymentColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasDeploymentWith applies the HasEdge predicate on the "deployment" edge with a given conditions (other predicates). +func HasDeploymentWith(preds ...predicate.Deployment) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(DeploymentInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, DeploymentTable, DeploymentColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasEvent applies the HasEdge predicate on the "event" edge. +func HasEvent() predicate.Review { + return predicate.Review(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(EventTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, EventTable, EventColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasEventWith applies the HasEdge predicate on the "event" edge with a given conditions (other predicates). +func HasEventWith(preds ...predicate.Event) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(EventInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, EventTable, EventColumn), + ) + 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.Review) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for _, p := range predicates { + p(s1) + } + s.Where(s1.P()) + }) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Review) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for i, p := range predicates { + if i > 0 { + s1.Or() + } + p(s1) + } + s.Where(s1.P()) + }) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Review) predicate.Review { + return predicate.Review(func(s *sql.Selector) { + p(s.Not()) + }) +} diff --git a/ent/review_create.go b/ent/review_create.go new file mode 100644 index 00000000..dacf6f7d --- /dev/null +++ b/ent/review_create.go @@ -0,0 +1,413 @@ +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/gitploy-io/gitploy/ent/deployment" + "github.com/gitploy-io/gitploy/ent/event" + "github.com/gitploy-io/gitploy/ent/review" + "github.com/gitploy-io/gitploy/ent/user" +) + +// ReviewCreate is the builder for creating a Review entity. +type ReviewCreate struct { + config + mutation *ReviewMutation + hooks []Hook +} + +// SetStatus sets the "status" field. +func (rc *ReviewCreate) SetStatus(r review.Status) *ReviewCreate { + rc.mutation.SetStatus(r) + return rc +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (rc *ReviewCreate) SetNillableStatus(r *review.Status) *ReviewCreate { + if r != nil { + rc.SetStatus(*r) + } + return rc +} + +// SetCreatedAt sets the "created_at" field. +func (rc *ReviewCreate) SetCreatedAt(t time.Time) *ReviewCreate { + rc.mutation.SetCreatedAt(t) + return rc +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (rc *ReviewCreate) SetNillableCreatedAt(t *time.Time) *ReviewCreate { + if t != nil { + rc.SetCreatedAt(*t) + } + return rc +} + +// SetUpdatedAt sets the "updated_at" field. +func (rc *ReviewCreate) SetUpdatedAt(t time.Time) *ReviewCreate { + rc.mutation.SetUpdatedAt(t) + return rc +} + +// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil. +func (rc *ReviewCreate) SetNillableUpdatedAt(t *time.Time) *ReviewCreate { + if t != nil { + rc.SetUpdatedAt(*t) + } + return rc +} + +// SetUserID sets the "user_id" field. +func (rc *ReviewCreate) SetUserID(i int64) *ReviewCreate { + rc.mutation.SetUserID(i) + return rc +} + +// SetDeploymentID sets the "deployment_id" field. +func (rc *ReviewCreate) SetDeploymentID(i int) *ReviewCreate { + rc.mutation.SetDeploymentID(i) + return rc +} + +// SetUser sets the "user" edge to the User entity. +func (rc *ReviewCreate) SetUser(u *User) *ReviewCreate { + return rc.SetUserID(u.ID) +} + +// SetDeployment sets the "deployment" edge to the Deployment entity. +func (rc *ReviewCreate) SetDeployment(d *Deployment) *ReviewCreate { + return rc.SetDeploymentID(d.ID) +} + +// AddEventIDs adds the "event" edge to the Event entity by IDs. +func (rc *ReviewCreate) AddEventIDs(ids ...int) *ReviewCreate { + rc.mutation.AddEventIDs(ids...) + return rc +} + +// AddEvent adds the "event" edges to the Event entity. +func (rc *ReviewCreate) AddEvent(e ...*Event) *ReviewCreate { + ids := make([]int, len(e)) + for i := range e { + ids[i] = e[i].ID + } + return rc.AddEventIDs(ids...) +} + +// Mutation returns the ReviewMutation object of the builder. +func (rc *ReviewCreate) Mutation() *ReviewMutation { + return rc.mutation +} + +// Save creates the Review in the database. +func (rc *ReviewCreate) Save(ctx context.Context) (*Review, error) { + var ( + err error + node *Review + ) + rc.defaults() + if len(rc.hooks) == 0 { + if err = rc.check(); err != nil { + return nil, err + } + node, err = rc.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ReviewMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err = rc.check(); err != nil { + return nil, err + } + rc.mutation = mutation + if node, err = rc.sqlSave(ctx); err != nil { + return nil, err + } + mutation.id = &node.ID + mutation.done = true + return node, err + }) + for i := len(rc.hooks) - 1; i >= 0; i-- { + if rc.hooks[i] == nil { + return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = rc.hooks[i](mut) + } + if _, err := mut.Mutate(ctx, rc.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX calls Save and panics if Save returns an error. +func (rc *ReviewCreate) SaveX(ctx context.Context) *Review { + v, err := rc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rc *ReviewCreate) Exec(ctx context.Context) error { + _, err := rc.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rc *ReviewCreate) ExecX(ctx context.Context) { + if err := rc.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (rc *ReviewCreate) defaults() { + if _, ok := rc.mutation.Status(); !ok { + v := review.DefaultStatus + rc.mutation.SetStatus(v) + } + if _, ok := rc.mutation.CreatedAt(); !ok { + v := review.DefaultCreatedAt() + rc.mutation.SetCreatedAt(v) + } + if _, ok := rc.mutation.UpdatedAt(); !ok { + v := review.DefaultUpdatedAt() + rc.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (rc *ReviewCreate) check() error { + if _, ok := rc.mutation.Status(); !ok { + return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "status"`)} + } + if v, ok := rc.mutation.Status(); ok { + if err := review.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "status": %w`, err)} + } + } + if _, ok := rc.mutation.CreatedAt(); !ok { + return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)} + } + if _, ok := rc.mutation.UpdatedAt(); !ok { + return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "updated_at"`)} + } + if _, ok := rc.mutation.UserID(); !ok { + return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "user_id"`)} + } + if _, ok := rc.mutation.DeploymentID(); !ok { + return &ValidationError{Name: "deployment_id", err: errors.New(`ent: missing required field "deployment_id"`)} + } + if _, ok := rc.mutation.UserID(); !ok { + return &ValidationError{Name: "user", err: errors.New("ent: missing required edge \"user\"")} + } + if _, ok := rc.mutation.DeploymentID(); !ok { + return &ValidationError{Name: "deployment", err: errors.New("ent: missing required edge \"deployment\"")} + } + return nil +} + +func (rc *ReviewCreate) sqlSave(ctx context.Context) (*Review, error) { + _node, _spec := rc.createSpec() + if err := sqlgraph.CreateNode(ctx, rc.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{err.Error(), err} + } + return nil, err + } + id := _spec.ID.Value.(int64) + _node.ID = int(id) + return _node, nil +} + +func (rc *ReviewCreate) createSpec() (*Review, *sqlgraph.CreateSpec) { + var ( + _node = &Review{config: rc.config} + _spec = &sqlgraph.CreateSpec{ + Table: review.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + } + ) + if value, ok := rc.mutation.Status(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Value: value, + Column: review.FieldStatus, + }) + _node.Status = value + } + if value, ok := rc.mutation.CreatedAt(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: review.FieldCreatedAt, + }) + _node.CreatedAt = value + } + if value, ok := rc.mutation.UpdatedAt(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: review.FieldUpdatedAt, + }) + _node.UpdatedAt = value + } + if nodes := rc.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.UserTable, + Columns: []string{review.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt64, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.UserID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := rc.mutation.DeploymentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.DeploymentTable, + Columns: []string{review.DeploymentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.DeploymentID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := rc.mutation.EventIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// ReviewCreateBulk is the builder for creating many Review entities in bulk. +type ReviewCreateBulk struct { + config + builders []*ReviewCreate +} + +// Save creates the Review entities in the database. +func (rcb *ReviewCreateBulk) Save(ctx context.Context) ([]*Review, error) { + specs := make([]*sqlgraph.CreateSpec, len(rcb.builders)) + nodes := make([]*Review, len(rcb.builders)) + mutators := make([]Mutator, len(rcb.builders)) + for i := range rcb.builders { + func(i int, root context.Context) { + builder := rcb.builders[i] + builder.defaults() + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ReviewMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + nodes[i], specs[i] = builder.createSpec() + var err error + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, rcb.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, rcb.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{err.Error(), err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + mutation.done = true + if specs[i].ID.Value != nil { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int(id) + } + 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, rcb.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (rcb *ReviewCreateBulk) SaveX(ctx context.Context) []*Review { + v, err := rcb.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (rcb *ReviewCreateBulk) Exec(ctx context.Context) error { + _, err := rcb.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rcb *ReviewCreateBulk) ExecX(ctx context.Context) { + if err := rcb.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/ent/review_delete.go b/ent/review_delete.go new file mode 100644 index 00000000..456eb6a7 --- /dev/null +++ b/ent/review_delete.go @@ -0,0 +1,111 @@ +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" +) + +// ReviewDelete is the builder for deleting a Review entity. +type ReviewDelete struct { + config + hooks []Hook + mutation *ReviewMutation +} + +// Where appends a list predicates to the ReviewDelete builder. +func (rd *ReviewDelete) Where(ps ...predicate.Review) *ReviewDelete { + rd.mutation.Where(ps...) + return rd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (rd *ReviewDelete) Exec(ctx context.Context) (int, error) { + var ( + err error + affected int + ) + if len(rd.hooks) == 0 { + affected, err = rd.sqlExec(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ReviewMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + rd.mutation = mutation + affected, err = rd.sqlExec(ctx) + mutation.done = true + return affected, err + }) + for i := len(rd.hooks) - 1; i >= 0; i-- { + if rd.hooks[i] == nil { + return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = rd.hooks[i](mut) + } + if _, err := mut.Mutate(ctx, rd.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// ExecX is like Exec, but panics if an error occurs. +func (rd *ReviewDelete) ExecX(ctx context.Context) int { + n, err := rd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (rd *ReviewDelete) sqlExec(ctx context.Context) (int, error) { + _spec := &sqlgraph.DeleteSpec{ + Node: &sqlgraph.NodeSpec{ + Table: review.Table, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + if ps := rd.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return sqlgraph.DeleteNodes(ctx, rd.driver, _spec) +} + +// ReviewDeleteOne is the builder for deleting a single Review entity. +type ReviewDeleteOne struct { + rd *ReviewDelete +} + +// Exec executes the deletion query. +func (rdo *ReviewDeleteOne) Exec(ctx context.Context) error { + n, err := rdo.rd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{review.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (rdo *ReviewDeleteOne) ExecX(ctx context.Context) { + rdo.rd.ExecX(ctx) +} diff --git a/ent/review_query.go b/ent/review_query.go new file mode 100644 index 00000000..9d08ae58 --- /dev/null +++ b/ent/review_query.go @@ -0,0 +1,1146 @@ +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "errors" + "fmt" + "math" + + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/gitploy-io/gitploy/ent/deployment" + "github.com/gitploy-io/gitploy/ent/event" + "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" + "github.com/gitploy-io/gitploy/ent/user" +) + +// ReviewQuery is the builder for querying Review entities. +type ReviewQuery struct { + config + limit *int + offset *int + unique *bool + order []OrderFunc + fields []string + predicates []predicate.Review + // eager-loading edges. + withUser *UserQuery + withDeployment *DeploymentQuery + withEvent *EventQuery + modifiers []func(s *sql.Selector) + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the ReviewQuery builder. +func (rq *ReviewQuery) Where(ps ...predicate.Review) *ReviewQuery { + rq.predicates = append(rq.predicates, ps...) + return rq +} + +// Limit adds a limit step to the query. +func (rq *ReviewQuery) Limit(limit int) *ReviewQuery { + rq.limit = &limit + return rq +} + +// Offset adds an offset step to the query. +func (rq *ReviewQuery) Offset(offset int) *ReviewQuery { + rq.offset = &offset + return rq +} + +// 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 (rq *ReviewQuery) Unique(unique bool) *ReviewQuery { + rq.unique = &unique + return rq +} + +// Order adds an order step to the query. +func (rq *ReviewQuery) Order(o ...OrderFunc) *ReviewQuery { + rq.order = append(rq.order, o...) + return rq +} + +// QueryUser chains the current query on the "user" edge. +func (rq *ReviewQuery) QueryUser() *UserQuery { + query := &UserQuery{config: rq.config} + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(review.Table, review.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, review.UserTable, review.UserColumn), + ) + fromU = sqlgraph.SetNeighbors(rq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryDeployment chains the current query on the "deployment" edge. +func (rq *ReviewQuery) QueryDeployment() *DeploymentQuery { + query := &DeploymentQuery{config: rq.config} + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(review.Table, review.FieldID, selector), + sqlgraph.To(deployment.Table, deployment.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, review.DeploymentTable, review.DeploymentColumn), + ) + fromU = sqlgraph.SetNeighbors(rq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryEvent chains the current query on the "event" edge. +func (rq *ReviewQuery) QueryEvent() *EventQuery { + query := &EventQuery{config: rq.config} + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := rq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := rq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(review.Table, review.FieldID, selector), + sqlgraph.To(event.Table, event.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, review.EventTable, review.EventColumn), + ) + fromU = sqlgraph.SetNeighbors(rq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first Review entity from the query. +// Returns a *NotFoundError when no Review was found. +func (rq *ReviewQuery) First(ctx context.Context) (*Review, error) { + nodes, err := rq.Limit(1).All(ctx) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{review.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (rq *ReviewQuery) FirstX(ctx context.Context) *Review { + node, err := rq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Review ID from the query. +// Returns a *NotFoundError when no Review ID was found. +func (rq *ReviewQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = rq.Limit(1).IDs(ctx); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{review.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (rq *ReviewQuery) FirstIDX(ctx context.Context) int { + id, err := rq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Review entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when exactly one Review entity is not found. +// Returns a *NotFoundError when no Review entities are found. +func (rq *ReviewQuery) Only(ctx context.Context) (*Review, error) { + nodes, err := rq.Limit(2).All(ctx) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{review.Label} + default: + return nil, &NotSingularError{review.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (rq *ReviewQuery) OnlyX(ctx context.Context) *Review { + node, err := rq.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Review ID in the query. +// Returns a *NotSingularError when exactly one Review ID is not found. +// Returns a *NotFoundError when no entities are found. +func (rq *ReviewQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = rq.Limit(2).IDs(ctx); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{review.Label} + default: + err = &NotSingularError{review.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (rq *ReviewQuery) OnlyIDX(ctx context.Context) int { + id, err := rq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Reviews. +func (rq *ReviewQuery) All(ctx context.Context) ([]*Review, error) { + if err := rq.prepareQuery(ctx); err != nil { + return nil, err + } + return rq.sqlAll(ctx) +} + +// AllX is like All, but panics if an error occurs. +func (rq *ReviewQuery) AllX(ctx context.Context) []*Review { + nodes, err := rq.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Review IDs. +func (rq *ReviewQuery) IDs(ctx context.Context) ([]int, error) { + var ids []int + if err := rq.Select(review.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (rq *ReviewQuery) IDsX(ctx context.Context) []int { + ids, err := rq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (rq *ReviewQuery) Count(ctx context.Context) (int, error) { + if err := rq.prepareQuery(ctx); err != nil { + return 0, err + } + return rq.sqlCount(ctx) +} + +// CountX is like Count, but panics if an error occurs. +func (rq *ReviewQuery) CountX(ctx context.Context) int { + count, err := rq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (rq *ReviewQuery) Exist(ctx context.Context) (bool, error) { + if err := rq.prepareQuery(ctx); err != nil { + return false, err + } + return rq.sqlExist(ctx) +} + +// ExistX is like Exist, but panics if an error occurs. +func (rq *ReviewQuery) ExistX(ctx context.Context) bool { + exist, err := rq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the ReviewQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (rq *ReviewQuery) Clone() *ReviewQuery { + if rq == nil { + return nil + } + return &ReviewQuery{ + config: rq.config, + limit: rq.limit, + offset: rq.offset, + order: append([]OrderFunc{}, rq.order...), + predicates: append([]predicate.Review{}, rq.predicates...), + withUser: rq.withUser.Clone(), + withDeployment: rq.withDeployment.Clone(), + withEvent: rq.withEvent.Clone(), + // clone intermediate query. + sql: rq.sql.Clone(), + path: rq.path, + } +} + +// WithUser tells the query-builder to eager-load the nodes that are connected to +// the "user" edge. The optional arguments are used to configure the query builder of the edge. +func (rq *ReviewQuery) WithUser(opts ...func(*UserQuery)) *ReviewQuery { + query := &UserQuery{config: rq.config} + for _, opt := range opts { + opt(query) + } + rq.withUser = query + return rq +} + +// WithDeployment tells the query-builder to eager-load the nodes that are connected to +// the "deployment" edge. The optional arguments are used to configure the query builder of the edge. +func (rq *ReviewQuery) WithDeployment(opts ...func(*DeploymentQuery)) *ReviewQuery { + query := &DeploymentQuery{config: rq.config} + for _, opt := range opts { + opt(query) + } + rq.withDeployment = query + return rq +} + +// WithEvent tells the query-builder to eager-load the nodes that are connected to +// the "event" edge. The optional arguments are used to configure the query builder of the edge. +func (rq *ReviewQuery) WithEvent(opts ...func(*EventQuery)) *ReviewQuery { + query := &EventQuery{config: rq.config} + for _, opt := range opts { + opt(query) + } + rq.withEvent = query + return rq +} + +// 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 { +// Status review.Status `json:"status"` +// Count int `json:"count,omitempty"` +// } +// +// client.Review.Query(). +// GroupBy(review.FieldStatus). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +// +func (rq *ReviewQuery) GroupBy(field string, fields ...string) *ReviewGroupBy { + group := &ReviewGroupBy{config: rq.config} + group.fields = append([]string{field}, fields...) + group.path = func(ctx context.Context) (prev *sql.Selector, err error) { + if err := rq.prepareQuery(ctx); err != nil { + return nil, err + } + return rq.sqlQuery(ctx), nil + } + return group +} + +// 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 { +// Status review.Status `json:"status"` +// } +// +// client.Review.Query(). +// Select(review.FieldStatus). +// Scan(ctx, &v) +// +func (rq *ReviewQuery) Select(fields ...string) *ReviewSelect { + rq.fields = append(rq.fields, fields...) + return &ReviewSelect{ReviewQuery: rq} +} + +func (rq *ReviewQuery) prepareQuery(ctx context.Context) error { + for _, f := range rq.fields { + if !review.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if rq.path != nil { + prev, err := rq.path(ctx) + if err != nil { + return err + } + rq.sql = prev + } + return nil +} + +func (rq *ReviewQuery) sqlAll(ctx context.Context) ([]*Review, error) { + var ( + nodes = []*Review{} + _spec = rq.querySpec() + loadedTypes = [3]bool{ + rq.withUser != nil, + rq.withDeployment != nil, + rq.withEvent != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]interface{}, error) { + node := &Review{config: rq.config} + nodes = append(nodes, node) + return node.scanValues(columns) + } + _spec.Assign = func(columns []string, values []interface{}) error { + if len(nodes) == 0 { + return fmt.Errorf("ent: Assign called without calling ScanValues") + } + node := nodes[len(nodes)-1] + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + if len(rq.modifiers) > 0 { + _spec.Modifiers = rq.modifiers + } + if err := sqlgraph.QueryNodes(ctx, rq.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + + if query := rq.withUser; query != nil { + ids := make([]int64, 0, len(nodes)) + nodeids := make(map[int64][]*Review) + for i := range nodes { + fk := nodes[i].UserID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "user_id" returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.User = n + } + } + } + + if query := rq.withDeployment; query != nil { + ids := make([]int, 0, len(nodes)) + nodeids := make(map[int][]*Review) + for i := range nodes { + fk := nodes[i].DeploymentID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + query.Where(deployment.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "deployment_id" returned %v`, n.ID) + } + for i := range nodes { + nodes[i].Edges.Deployment = n + } + } + } + + if query := rq.withEvent; query != nil { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int]*Review) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + nodes[i].Edges.Event = []*Event{} + } + query.Where(predicate.Event(func(s *sql.Selector) { + s.Where(sql.InValues(review.EventColumn, fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + fk := n.ReviewID + node, ok := nodeids[fk] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "review_id" returned %v for node %v`, fk, n.ID) + } + node.Edges.Event = append(node.Edges.Event, n) + } + } + + return nodes, nil +} + +func (rq *ReviewQuery) sqlCount(ctx context.Context) (int, error) { + _spec := rq.querySpec() + if len(rq.modifiers) > 0 { + _spec.Modifiers = rq.modifiers + } + return sqlgraph.CountNodes(ctx, rq.driver, _spec) +} + +func (rq *ReviewQuery) sqlExist(ctx context.Context) (bool, error) { + n, err := rq.sqlCount(ctx) + if err != nil { + return false, fmt.Errorf("ent: check existence: %w", err) + } + return n > 0, nil +} + +func (rq *ReviewQuery) querySpec() *sqlgraph.QuerySpec { + _spec := &sqlgraph.QuerySpec{ + Node: &sqlgraph.NodeSpec{ + Table: review.Table, + Columns: review.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + From: rq.sql, + Unique: true, + } + if unique := rq.unique; unique != nil { + _spec.Unique = *unique + } + if fields := rq.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, review.FieldID) + for i := range fields { + if fields[i] != review.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := rq.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := rq.limit; limit != nil { + _spec.Limit = *limit + } + if offset := rq.offset; offset != nil { + _spec.Offset = *offset + } + if ps := rq.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (rq *ReviewQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(rq.driver.Dialect()) + t1 := builder.Table(review.Table) + columns := rq.fields + if len(columns) == 0 { + columns = review.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if rq.sql != nil { + selector = rq.sql + selector.Select(selector.Columns(columns...)...) + } + for _, m := range rq.modifiers { + m(selector) + } + for _, p := range rq.predicates { + p(selector) + } + for _, p := range rq.order { + p(selector) + } + if offset := rq.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 := rq.limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// ForUpdate locks the selected rows against concurrent updates, and prevent them from being +// updated, deleted or "selected ... for update" by other sessions, until the transaction is +// either committed or rolled-back. +func (rq *ReviewQuery) ForUpdate(opts ...sql.LockOption) *ReviewQuery { + if rq.driver.Dialect() == dialect.Postgres { + rq.Unique(false) + } + rq.modifiers = append(rq.modifiers, func(s *sql.Selector) { + s.ForUpdate(opts...) + }) + return rq +} + +// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock +// on any rows that are read. Other sessions can read the rows, but cannot modify them +// until your transaction commits. +func (rq *ReviewQuery) ForShare(opts ...sql.LockOption) *ReviewQuery { + if rq.driver.Dialect() == dialect.Postgres { + rq.Unique(false) + } + rq.modifiers = append(rq.modifiers, func(s *sql.Selector) { + s.ForShare(opts...) + }) + return rq +} + +// ReviewGroupBy is the group-by builder for Review entities. +type ReviewGroupBy struct { + config + fields []string + fns []AggregateFunc + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (rgb *ReviewGroupBy) Aggregate(fns ...AggregateFunc) *ReviewGroupBy { + rgb.fns = append(rgb.fns, fns...) + return rgb +} + +// Scan applies the group-by query and scans the result into the given value. +func (rgb *ReviewGroupBy) Scan(ctx context.Context, v interface{}) error { + query, err := rgb.path(ctx) + if err != nil { + return err + } + rgb.sql = query + return rgb.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (rgb *ReviewGroupBy) ScanX(ctx context.Context, v interface{}) { + if err := rgb.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from group-by. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Strings(ctx context.Context) ([]string, error) { + if len(rgb.fields) > 1 { + return nil, errors.New("ent: ReviewGroupBy.Strings is not achievable when grouping more than 1 field") + } + var v []string + if err := rgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (rgb *ReviewGroupBy) StringsX(ctx context.Context) []string { + v, err := rgb.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// String returns a single string from a group-by query. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) String(ctx context.Context) (_ string, err error) { + var v []string + if v, err = rgb.Strings(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewGroupBy.Strings returned %d results when one was expected", len(v)) + } + return +} + +// StringX is like String, but panics if an error occurs. +func (rgb *ReviewGroupBy) StringX(ctx context.Context) string { + v, err := rgb.String(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from group-by. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Ints(ctx context.Context) ([]int, error) { + if len(rgb.fields) > 1 { + return nil, errors.New("ent: ReviewGroupBy.Ints is not achievable when grouping more than 1 field") + } + var v []int + if err := rgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (rgb *ReviewGroupBy) IntsX(ctx context.Context) []int { + v, err := rgb.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Int returns a single int from a group-by query. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Int(ctx context.Context) (_ int, err error) { + var v []int + if v, err = rgb.Ints(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewGroupBy.Ints returned %d results when one was expected", len(v)) + } + return +} + +// IntX is like Int, but panics if an error occurs. +func (rgb *ReviewGroupBy) IntX(ctx context.Context) int { + v, err := rgb.Int(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from group-by. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Float64s(ctx context.Context) ([]float64, error) { + if len(rgb.fields) > 1 { + return nil, errors.New("ent: ReviewGroupBy.Float64s is not achievable when grouping more than 1 field") + } + var v []float64 + if err := rgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (rgb *ReviewGroupBy) Float64sX(ctx context.Context) []float64 { + v, err := rgb.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64 returns a single float64 from a group-by query. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Float64(ctx context.Context) (_ float64, err error) { + var v []float64 + if v, err = rgb.Float64s(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewGroupBy.Float64s returned %d results when one was expected", len(v)) + } + return +} + +// Float64X is like Float64, but panics if an error occurs. +func (rgb *ReviewGroupBy) Float64X(ctx context.Context) float64 { + v, err := rgb.Float64(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from group-by. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Bools(ctx context.Context) ([]bool, error) { + if len(rgb.fields) > 1 { + return nil, errors.New("ent: ReviewGroupBy.Bools is not achievable when grouping more than 1 field") + } + var v []bool + if err := rgb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (rgb *ReviewGroupBy) BoolsX(ctx context.Context) []bool { + v, err := rgb.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bool returns a single bool from a group-by query. +// It is only allowed when executing a group-by query with one field. +func (rgb *ReviewGroupBy) Bool(ctx context.Context) (_ bool, err error) { + var v []bool + if v, err = rgb.Bools(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewGroupBy.Bools returned %d results when one was expected", len(v)) + } + return +} + +// BoolX is like Bool, but panics if an error occurs. +func (rgb *ReviewGroupBy) BoolX(ctx context.Context) bool { + v, err := rgb.Bool(ctx) + if err != nil { + panic(err) + } + return v +} + +func (rgb *ReviewGroupBy) sqlScan(ctx context.Context, v interface{}) error { + for _, f := range rgb.fields { + if !review.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} + } + } + selector := rgb.sqlQuery() + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := rgb.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (rgb *ReviewGroupBy) sqlQuery() *sql.Selector { + selector := rgb.sql.Select() + aggregation := make([]string, 0, len(rgb.fns)) + for _, fn := range rgb.fns { + aggregation = append(aggregation, fn(selector)) + } + // If no columns were selected in a custom aggregation function, the default + // selection is the fields used for "group-by", and the aggregation functions. + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(rgb.fields)+len(rgb.fns)) + for _, f := range rgb.fields { + columns = append(columns, selector.C(f)) + } + for _, c := range aggregation { + columns = append(columns, c) + } + selector.Select(columns...) + } + return selector.GroupBy(selector.Columns(rgb.fields...)...) +} + +// ReviewSelect is the builder for selecting fields of Review entities. +type ReviewSelect struct { + *ReviewQuery + // intermediate query (i.e. traversal path). + sql *sql.Selector +} + +// Scan applies the selector query and scans the result into the given value. +func (rs *ReviewSelect) Scan(ctx context.Context, v interface{}) error { + if err := rs.prepareQuery(ctx); err != nil { + return err + } + rs.sql = rs.ReviewQuery.sqlQuery(ctx) + return rs.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (rs *ReviewSelect) ScanX(ctx context.Context, v interface{}) { + if err := rs.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Strings(ctx context.Context) ([]string, error) { + if len(rs.fields) > 1 { + return nil, errors.New("ent: ReviewSelect.Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := rs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (rs *ReviewSelect) StringsX(ctx context.Context) []string { + v, err := rs.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// String returns a single string from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) String(ctx context.Context) (_ string, err error) { + var v []string + if v, err = rs.Strings(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewSelect.Strings returned %d results when one was expected", len(v)) + } + return +} + +// StringX is like String, but panics if an error occurs. +func (rs *ReviewSelect) StringX(ctx context.Context) string { + v, err := rs.String(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Ints(ctx context.Context) ([]int, error) { + if len(rs.fields) > 1 { + return nil, errors.New("ent: ReviewSelect.Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := rs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (rs *ReviewSelect) IntsX(ctx context.Context) []int { + v, err := rs.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Int returns a single int from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Int(ctx context.Context) (_ int, err error) { + var v []int + if v, err = rs.Ints(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewSelect.Ints returned %d results when one was expected", len(v)) + } + return +} + +// IntX is like Int, but panics if an error occurs. +func (rs *ReviewSelect) IntX(ctx context.Context) int { + v, err := rs.Int(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Float64s(ctx context.Context) ([]float64, error) { + if len(rs.fields) > 1 { + return nil, errors.New("ent: ReviewSelect.Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := rs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (rs *ReviewSelect) Float64sX(ctx context.Context) []float64 { + v, err := rs.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64 returns a single float64 from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Float64(ctx context.Context) (_ float64, err error) { + var v []float64 + if v, err = rs.Float64s(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewSelect.Float64s returned %d results when one was expected", len(v)) + } + return +} + +// Float64X is like Float64, but panics if an error occurs. +func (rs *ReviewSelect) Float64X(ctx context.Context) float64 { + v, err := rs.Float64(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Bools(ctx context.Context) ([]bool, error) { + if len(rs.fields) > 1 { + return nil, errors.New("ent: ReviewSelect.Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := rs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (rs *ReviewSelect) BoolsX(ctx context.Context) []bool { + v, err := rs.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bool returns a single bool from a selector. It is only allowed when selecting one field. +func (rs *ReviewSelect) Bool(ctx context.Context) (_ bool, err error) { + var v []bool + if v, err = rs.Bools(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{review.Label} + default: + err = fmt.Errorf("ent: ReviewSelect.Bools returned %d results when one was expected", len(v)) + } + return +} + +// BoolX is like Bool, but panics if an error occurs. +func (rs *ReviewSelect) BoolX(ctx context.Context) bool { + v, err := rs.Bool(ctx) + if err != nil { + panic(err) + } + return v +} + +func (rs *ReviewSelect) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := rs.sql.Query() + if err := rs.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/ent/review_update.go b/ent/review_update.go new file mode 100644 index 00000000..aa728633 --- /dev/null +++ b/ent/review_update.go @@ -0,0 +1,803 @@ +// Code generated by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/schema/field" + "github.com/gitploy-io/gitploy/ent/deployment" + "github.com/gitploy-io/gitploy/ent/event" + "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" + "github.com/gitploy-io/gitploy/ent/user" +) + +// ReviewUpdate is the builder for updating Review entities. +type ReviewUpdate struct { + config + hooks []Hook + mutation *ReviewMutation +} + +// Where appends a list predicates to the ReviewUpdate builder. +func (ru *ReviewUpdate) Where(ps ...predicate.Review) *ReviewUpdate { + ru.mutation.Where(ps...) + return ru +} + +// SetStatus sets the "status" field. +func (ru *ReviewUpdate) SetStatus(r review.Status) *ReviewUpdate { + ru.mutation.SetStatus(r) + return ru +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (ru *ReviewUpdate) SetNillableStatus(r *review.Status) *ReviewUpdate { + if r != nil { + ru.SetStatus(*r) + } + return ru +} + +// SetCreatedAt sets the "created_at" field. +func (ru *ReviewUpdate) SetCreatedAt(t time.Time) *ReviewUpdate { + ru.mutation.SetCreatedAt(t) + return ru +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (ru *ReviewUpdate) SetNillableCreatedAt(t *time.Time) *ReviewUpdate { + if t != nil { + ru.SetCreatedAt(*t) + } + return ru +} + +// SetUpdatedAt sets the "updated_at" field. +func (ru *ReviewUpdate) SetUpdatedAt(t time.Time) *ReviewUpdate { + ru.mutation.SetUpdatedAt(t) + return ru +} + +// SetUserID sets the "user_id" field. +func (ru *ReviewUpdate) SetUserID(i int64) *ReviewUpdate { + ru.mutation.SetUserID(i) + return ru +} + +// SetDeploymentID sets the "deployment_id" field. +func (ru *ReviewUpdate) SetDeploymentID(i int) *ReviewUpdate { + ru.mutation.SetDeploymentID(i) + return ru +} + +// SetUser sets the "user" edge to the User entity. +func (ru *ReviewUpdate) SetUser(u *User) *ReviewUpdate { + return ru.SetUserID(u.ID) +} + +// SetDeployment sets the "deployment" edge to the Deployment entity. +func (ru *ReviewUpdate) SetDeployment(d *Deployment) *ReviewUpdate { + return ru.SetDeploymentID(d.ID) +} + +// AddEventIDs adds the "event" edge to the Event entity by IDs. +func (ru *ReviewUpdate) AddEventIDs(ids ...int) *ReviewUpdate { + ru.mutation.AddEventIDs(ids...) + return ru +} + +// AddEvent adds the "event" edges to the Event entity. +func (ru *ReviewUpdate) AddEvent(e ...*Event) *ReviewUpdate { + ids := make([]int, len(e)) + for i := range e { + ids[i] = e[i].ID + } + return ru.AddEventIDs(ids...) +} + +// Mutation returns the ReviewMutation object of the builder. +func (ru *ReviewUpdate) Mutation() *ReviewMutation { + return ru.mutation +} + +// ClearUser clears the "user" edge to the User entity. +func (ru *ReviewUpdate) ClearUser() *ReviewUpdate { + ru.mutation.ClearUser() + return ru +} + +// ClearDeployment clears the "deployment" edge to the Deployment entity. +func (ru *ReviewUpdate) ClearDeployment() *ReviewUpdate { + ru.mutation.ClearDeployment() + return ru +} + +// ClearEvent clears all "event" edges to the Event entity. +func (ru *ReviewUpdate) ClearEvent() *ReviewUpdate { + ru.mutation.ClearEvent() + return ru +} + +// RemoveEventIDs removes the "event" edge to Event entities by IDs. +func (ru *ReviewUpdate) RemoveEventIDs(ids ...int) *ReviewUpdate { + ru.mutation.RemoveEventIDs(ids...) + return ru +} + +// RemoveEvent removes "event" edges to Event entities. +func (ru *ReviewUpdate) RemoveEvent(e ...*Event) *ReviewUpdate { + ids := make([]int, len(e)) + for i := range e { + ids[i] = e[i].ID + } + return ru.RemoveEventIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (ru *ReviewUpdate) Save(ctx context.Context) (int, error) { + var ( + err error + affected int + ) + ru.defaults() + if len(ru.hooks) == 0 { + if err = ru.check(); err != nil { + return 0, err + } + affected, err = ru.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ReviewMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err = ru.check(); err != nil { + return 0, err + } + ru.mutation = mutation + affected, err = ru.sqlSave(ctx) + mutation.done = true + return affected, err + }) + for i := len(ru.hooks) - 1; i >= 0; i-- { + if ru.hooks[i] == nil { + return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = ru.hooks[i](mut) + } + if _, err := mut.Mutate(ctx, ru.mutation); err != nil { + return 0, err + } + } + return affected, err +} + +// SaveX is like Save, but panics if an error occurs. +func (ru *ReviewUpdate) SaveX(ctx context.Context) int { + affected, err := ru.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (ru *ReviewUpdate) Exec(ctx context.Context) error { + _, err := ru.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (ru *ReviewUpdate) ExecX(ctx context.Context) { + if err := ru.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (ru *ReviewUpdate) defaults() { + if _, ok := ru.mutation.UpdatedAt(); !ok { + v := review.UpdateDefaultUpdatedAt() + ru.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (ru *ReviewUpdate) check() error { + if v, ok := ru.mutation.Status(); ok { + if err := review.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf("ent: validator failed for field \"status\": %w", err)} + } + } + if _, ok := ru.mutation.UserID(); ru.mutation.UserCleared() && !ok { + return errors.New("ent: clearing a required unique edge \"user\"") + } + if _, ok := ru.mutation.DeploymentID(); ru.mutation.DeploymentCleared() && !ok { + return errors.New("ent: clearing a required unique edge \"deployment\"") + } + return nil +} + +func (ru *ReviewUpdate) sqlSave(ctx context.Context) (n int, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: review.Table, + Columns: review.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + if ps := ru.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := ru.mutation.Status(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Value: value, + Column: review.FieldStatus, + }) + } + if value, ok := ru.mutation.CreatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: review.FieldCreatedAt, + }) + } + if value, ok := ru.mutation.UpdatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: review.FieldUpdatedAt, + }) + } + if ru.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.UserTable, + Columns: []string{review.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt64, + Column: user.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ru.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.UserTable, + Columns: []string{review.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt64, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if ru.mutation.DeploymentCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.DeploymentTable, + Columns: []string{review.DeploymentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ru.mutation.DeploymentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.DeploymentTable, + Columns: []string{review.DeploymentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if ru.mutation.EventCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ru.mutation.RemovedEventIDs(); len(nodes) > 0 && !ru.mutation.EventCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ru.mutation.EventIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + 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, ru.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{review.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{err.Error(), err} + } + return 0, err + } + return n, nil +} + +// ReviewUpdateOne is the builder for updating a single Review entity. +type ReviewUpdateOne struct { + config + fields []string + hooks []Hook + mutation *ReviewMutation +} + +// SetStatus sets the "status" field. +func (ruo *ReviewUpdateOne) SetStatus(r review.Status) *ReviewUpdateOne { + ruo.mutation.SetStatus(r) + return ruo +} + +// SetNillableStatus sets the "status" field if the given value is not nil. +func (ruo *ReviewUpdateOne) SetNillableStatus(r *review.Status) *ReviewUpdateOne { + if r != nil { + ruo.SetStatus(*r) + } + return ruo +} + +// SetCreatedAt sets the "created_at" field. +func (ruo *ReviewUpdateOne) SetCreatedAt(t time.Time) *ReviewUpdateOne { + ruo.mutation.SetCreatedAt(t) + return ruo +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (ruo *ReviewUpdateOne) SetNillableCreatedAt(t *time.Time) *ReviewUpdateOne { + if t != nil { + ruo.SetCreatedAt(*t) + } + return ruo +} + +// SetUpdatedAt sets the "updated_at" field. +func (ruo *ReviewUpdateOne) SetUpdatedAt(t time.Time) *ReviewUpdateOne { + ruo.mutation.SetUpdatedAt(t) + return ruo +} + +// SetUserID sets the "user_id" field. +func (ruo *ReviewUpdateOne) SetUserID(i int64) *ReviewUpdateOne { + ruo.mutation.SetUserID(i) + return ruo +} + +// SetDeploymentID sets the "deployment_id" field. +func (ruo *ReviewUpdateOne) SetDeploymentID(i int) *ReviewUpdateOne { + ruo.mutation.SetDeploymentID(i) + return ruo +} + +// SetUser sets the "user" edge to the User entity. +func (ruo *ReviewUpdateOne) SetUser(u *User) *ReviewUpdateOne { + return ruo.SetUserID(u.ID) +} + +// SetDeployment sets the "deployment" edge to the Deployment entity. +func (ruo *ReviewUpdateOne) SetDeployment(d *Deployment) *ReviewUpdateOne { + return ruo.SetDeploymentID(d.ID) +} + +// AddEventIDs adds the "event" edge to the Event entity by IDs. +func (ruo *ReviewUpdateOne) AddEventIDs(ids ...int) *ReviewUpdateOne { + ruo.mutation.AddEventIDs(ids...) + return ruo +} + +// AddEvent adds the "event" edges to the Event entity. +func (ruo *ReviewUpdateOne) AddEvent(e ...*Event) *ReviewUpdateOne { + ids := make([]int, len(e)) + for i := range e { + ids[i] = e[i].ID + } + return ruo.AddEventIDs(ids...) +} + +// Mutation returns the ReviewMutation object of the builder. +func (ruo *ReviewUpdateOne) Mutation() *ReviewMutation { + return ruo.mutation +} + +// ClearUser clears the "user" edge to the User entity. +func (ruo *ReviewUpdateOne) ClearUser() *ReviewUpdateOne { + ruo.mutation.ClearUser() + return ruo +} + +// ClearDeployment clears the "deployment" edge to the Deployment entity. +func (ruo *ReviewUpdateOne) ClearDeployment() *ReviewUpdateOne { + ruo.mutation.ClearDeployment() + return ruo +} + +// ClearEvent clears all "event" edges to the Event entity. +func (ruo *ReviewUpdateOne) ClearEvent() *ReviewUpdateOne { + ruo.mutation.ClearEvent() + return ruo +} + +// RemoveEventIDs removes the "event" edge to Event entities by IDs. +func (ruo *ReviewUpdateOne) RemoveEventIDs(ids ...int) *ReviewUpdateOne { + ruo.mutation.RemoveEventIDs(ids...) + return ruo +} + +// RemoveEvent removes "event" edges to Event entities. +func (ruo *ReviewUpdateOne) RemoveEvent(e ...*Event) *ReviewUpdateOne { + ids := make([]int, len(e)) + for i := range e { + ids[i] = e[i].ID + } + return ruo.RemoveEventIDs(ids...) +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (ruo *ReviewUpdateOne) Select(field string, fields ...string) *ReviewUpdateOne { + ruo.fields = append([]string{field}, fields...) + return ruo +} + +// Save executes the query and returns the updated Review entity. +func (ruo *ReviewUpdateOne) Save(ctx context.Context) (*Review, error) { + var ( + err error + node *Review + ) + ruo.defaults() + if len(ruo.hooks) == 0 { + if err = ruo.check(); err != nil { + return nil, err + } + node, err = ruo.sqlSave(ctx) + } else { + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*ReviewMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err = ruo.check(); err != nil { + return nil, err + } + ruo.mutation = mutation + node, err = ruo.sqlSave(ctx) + mutation.done = true + return node, err + }) + for i := len(ruo.hooks) - 1; i >= 0; i-- { + if ruo.hooks[i] == nil { + return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = ruo.hooks[i](mut) + } + if _, err := mut.Mutate(ctx, ruo.mutation); err != nil { + return nil, err + } + } + return node, err +} + +// SaveX is like Save, but panics if an error occurs. +func (ruo *ReviewUpdateOne) SaveX(ctx context.Context) *Review { + node, err := ruo.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (ruo *ReviewUpdateOne) Exec(ctx context.Context) error { + _, err := ruo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (ruo *ReviewUpdateOne) ExecX(ctx context.Context) { + if err := ruo.Exec(ctx); err != nil { + panic(err) + } +} + +// defaults sets the default values of the builder before save. +func (ruo *ReviewUpdateOne) defaults() { + if _, ok := ruo.mutation.UpdatedAt(); !ok { + v := review.UpdateDefaultUpdatedAt() + ruo.mutation.SetUpdatedAt(v) + } +} + +// check runs all checks and user-defined validators on the builder. +func (ruo *ReviewUpdateOne) check() error { + if v, ok := ruo.mutation.Status(); ok { + if err := review.StatusValidator(v); err != nil { + return &ValidationError{Name: "status", err: fmt.Errorf("ent: validator failed for field \"status\": %w", err)} + } + } + if _, ok := ruo.mutation.UserID(); ruo.mutation.UserCleared() && !ok { + return errors.New("ent: clearing a required unique edge \"user\"") + } + if _, ok := ruo.mutation.DeploymentID(); ruo.mutation.DeploymentCleared() && !ok { + return errors.New("ent: clearing a required unique edge \"deployment\"") + } + return nil +} + +func (ruo *ReviewUpdateOne) sqlSave(ctx context.Context) (_node *Review, err error) { + _spec := &sqlgraph.UpdateSpec{ + Node: &sqlgraph.NodeSpec{ + Table: review.Table, + Columns: review.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + id, ok := ruo.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Review.ID for update")} + } + _spec.Node.ID.Value = id + if fields := ruo.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, review.FieldID) + for _, f := range fields { + if !review.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != review.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := ruo.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := ruo.mutation.Status(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeEnum, + Value: value, + Column: review.FieldStatus, + }) + } + if value, ok := ruo.mutation.CreatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: review.FieldCreatedAt, + }) + } + if value, ok := ruo.mutation.UpdatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: review.FieldUpdatedAt, + }) + } + if ruo.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.UserTable, + Columns: []string{review.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt64, + Column: user.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ruo.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.UserTable, + Columns: []string{review.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt64, + Column: user.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if ruo.mutation.DeploymentCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.DeploymentTable, + Columns: []string{review.DeploymentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ruo.mutation.DeploymentIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: review.DeploymentTable, + Columns: []string{review.DeploymentColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if ruo.mutation.EventCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ruo.mutation.RemovedEventIDs(); len(nodes) > 0 && !ruo.mutation.EventCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := ruo.mutation.EventIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: review.EventTable, + Columns: []string{review.EventColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: event.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _node = &Review{config: ruo.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, ruo.driver, _spec); err != nil { + if _, ok := err.(*sqlgraph.NotFoundError); ok { + err = &NotFoundError{review.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{err.Error(), err} + } + return nil, err + } + return _node, nil +} diff --git a/ent/runtime.go b/ent/runtime.go index da22dd25..916186a6 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -15,6 +15,7 @@ import ( "github.com/gitploy-io/gitploy/ent/lock" "github.com/gitploy-io/gitploy/ent/perm" "github.com/gitploy-io/gitploy/ent/repo" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/schema" "github.com/gitploy-io/gitploy/ent/user" ) @@ -191,6 +192,18 @@ func init() { repo.DefaultUpdatedAt = repoDescUpdatedAt.Default.(func() time.Time) // repo.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. repo.UpdateDefaultUpdatedAt = repoDescUpdatedAt.UpdateDefault.(func() time.Time) + reviewFields := schema.Review{}.Fields() + _ = reviewFields + // reviewDescCreatedAt is the schema descriptor for created_at field. + reviewDescCreatedAt := reviewFields[1].Descriptor() + // review.DefaultCreatedAt holds the default value on creation for the created_at field. + review.DefaultCreatedAt = reviewDescCreatedAt.Default.(func() time.Time) + // reviewDescUpdatedAt is the schema descriptor for updated_at field. + reviewDescUpdatedAt := reviewFields[2].Descriptor() + // review.DefaultUpdatedAt holds the default value on creation for the updated_at field. + review.DefaultUpdatedAt = reviewDescUpdatedAt.Default.(func() time.Time) + // review.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. + review.UpdateDefaultUpdatedAt = reviewDescUpdatedAt.UpdateDefault.(func() time.Time) userFields := schema.User{}.Fields() _ = userFields // userDescAdmin is the schema descriptor for admin field. diff --git a/ent/schema/deployment.go b/ent/schema/deployment.go index 54f4c020..18be0ecb 100644 --- a/ent/schema/deployment.go +++ b/ent/schema/deployment.go @@ -81,6 +81,10 @@ func (Deployment) Edges() []ent.Edge { Annotations(entsql.Annotation{ OnDelete: entsql.Cascade, }), + edge.To("reviews", Review.Type). + Annotations(entsql.Annotation{ + OnDelete: entsql.Cascade, + }), edge.To("deployment_statuses", DeploymentStatus.Type). Annotations(entsql.Annotation{ OnDelete: entsql.Cascade, diff --git a/ent/schema/event.go b/ent/schema/event.go index 2f9f7fec..a44c94df 100644 --- a/ent/schema/event.go +++ b/ent/schema/event.go @@ -19,6 +19,7 @@ func (Event) Fields() []ent.Field { Values( "deployment", "approval", + "review", ), field.Enum("type"). Values( @@ -32,6 +33,8 @@ func (Event) Fields() []ent.Field { Optional(), field.Int("approval_id"). Optional(), + field.Int("review_id"). + Optional(), // This field is filled when the type is 'deleted'. field.Int("deleted_id"). Optional(), @@ -49,6 +52,10 @@ func (Event) Edges() []ent.Edge { Ref("event"). Field("approval_id"). Unique(), + edge.From("review", Review.Type). + Ref("event"). + Field("review_id"). + Unique(), edge.To("notification_record", NotificationRecord.Type). Unique(), } diff --git a/ent/schema/review.go b/ent/schema/review.go new file mode 100644 index 00000000..ae16cd84 --- /dev/null +++ b/ent/schema/review.go @@ -0,0 +1,54 @@ +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" +) + +// Review holds the schema definition for the Review entity. +type Review struct { + ent.Schema +} + +// Fields of the Review. +func (Review) Fields() []ent.Field { + return []ent.Field{ + field.Enum("status"). + Values( + "pending", + "rejected", + "approved", + ). + Default("pending"), + field.Time("created_at"). + Default(nowUTC), + field.Time("updated_at"). + Default(nowUTC). + UpdateDefault(nowUTC), + // Edges + field.Int64("user_id"), + field.Int("deployment_id"), + } +} + +// Edges of the Review. +func (Review) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("user", User.Type). + Ref("reviews"). + Field("user_id"). + Unique(). + Required(), + edge.From("deployment", Deployment.Type). + Ref("reviews"). + Field("deployment_id"). + Unique(). + Required(), + edge.To("event", Event.Type). + Annotations(entsql.Annotation{ + OnDelete: entsql.Cascade, + }), + } +} diff --git a/ent/schema/user.go b/ent/schema/user.go index 0b15689d..3bb2b7c9 100644 --- a/ent/schema/user.go +++ b/ent/schema/user.go @@ -53,6 +53,7 @@ func (User) Edges() []ent.Edge { }), edge.To("deployments", Deployment.Type), edge.To("approvals", Approval.Type), + edge.To("reviews", Review.Type), edge.To("locks", Lock.Type), } } diff --git a/ent/tx.go b/ent/tx.go index ee298594..9be2b5b8 100644 --- a/ent/tx.go +++ b/ent/tx.go @@ -34,6 +34,8 @@ type Tx struct { Perm *PermClient // Repo is the client for interacting with the Repo builders. Repo *RepoClient + // Review is the client for interacting with the Review builders. + Review *ReviewClient // User is the client for interacting with the User builders. User *UserClient @@ -182,6 +184,7 @@ func (tx *Tx) init() { tx.NotificationRecord = NewNotificationRecordClient(tx.config) tx.Perm = NewPermClient(tx.config) tx.Repo = NewRepoClient(tx.config) + tx.Review = NewReviewClient(tx.config) tx.User = NewUserClient(tx.config) } diff --git a/ent/user.go b/ent/user.go index 64e13632..50a179c4 100644 --- a/ent/user.go +++ b/ent/user.go @@ -50,11 +50,13 @@ type UserEdges struct { Deployments []*Deployment `json:"deployments,omitempty"` // Approvals holds the value of the approvals edge. Approvals []*Approval `json:"approvals,omitempty"` + // Reviews holds the value of the reviews edge. + Reviews []*Review `json:"reviews,omitempty"` // Locks holds the value of the locks edge. Locks []*Lock `json:"locks,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [5]bool + loadedTypes [6]bool } // ChatUserOrErr returns the ChatUser value or an error if the edge @@ -98,10 +100,19 @@ func (e UserEdges) ApprovalsOrErr() ([]*Approval, error) { return nil, &NotLoadedError{edge: "approvals"} } +// ReviewsOrErr returns the Reviews value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) ReviewsOrErr() ([]*Review, error) { + if e.loadedTypes[4] { + return e.Reviews, nil + } + return nil, &NotLoadedError{edge: "reviews"} +} + // LocksOrErr returns the Locks value or an error if the edge // was not loaded in eager-loading. func (e UserEdges) LocksOrErr() ([]*Lock, error) { - if e.loadedTypes[4] { + if e.loadedTypes[5] { return e.Locks, nil } return nil, &NotLoadedError{edge: "locks"} @@ -220,6 +231,11 @@ func (u *User) QueryApprovals() *ApprovalQuery { return (&UserClient{config: u.config}).QueryApprovals(u) } +// QueryReviews queries the "reviews" edge of the User entity. +func (u *User) QueryReviews() *ReviewQuery { + return (&UserClient{config: u.config}).QueryReviews(u) +} + // QueryLocks queries the "locks" edge of the User entity. func (u *User) QueryLocks() *LockQuery { return (&UserClient{config: u.config}).QueryLocks(u) diff --git a/ent/user/user.go b/ent/user/user.go index 4848ee67..04472fad 100644 --- a/ent/user/user.go +++ b/ent/user/user.go @@ -37,6 +37,8 @@ const ( EdgeDeployments = "deployments" // EdgeApprovals holds the string denoting the approvals edge name in mutations. EdgeApprovals = "approvals" + // EdgeReviews holds the string denoting the reviews edge name in mutations. + EdgeReviews = "reviews" // EdgeLocks holds the string denoting the locks edge name in mutations. EdgeLocks = "locks" // Table holds the table name of the user in the database. @@ -69,6 +71,13 @@ const ( ApprovalsInverseTable = "approvals" // ApprovalsColumn is the table column denoting the approvals relation/edge. ApprovalsColumn = "user_id" + // ReviewsTable is the table that holds the reviews relation/edge. + ReviewsTable = "reviews" + // ReviewsInverseTable is the table name for the Review entity. + // It exists in this package in order to avoid circular dependency with the "review" package. + ReviewsInverseTable = "reviews" + // ReviewsColumn is the table column denoting the reviews relation/edge. + ReviewsColumn = "user_id" // LocksTable is the table that holds the locks relation/edge. LocksTable = "locks" // LocksInverseTable is the table name for the Lock entity. diff --git a/ent/user/where.go b/ent/user/where.go index 633314ee..a41be7a5 100644 --- a/ent/user/where.go +++ b/ent/user/where.go @@ -1065,6 +1065,34 @@ func HasApprovalsWith(preds ...predicate.Approval) predicate.User { }) } +// HasReviews applies the HasEdge predicate on the "reviews" edge. +func HasReviews() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ReviewsTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, ReviewsTable, ReviewsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasReviewsWith applies the HasEdge predicate on the "reviews" edge with a given conditions (other predicates). +func HasReviewsWith(preds ...predicate.Review) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ReviewsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, ReviewsTable, ReviewsColumn), + ) + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + // HasLocks applies the HasEdge predicate on the "locks" edge. func HasLocks() predicate.User { return predicate.User(func(s *sql.Selector) { diff --git a/ent/user_create.go b/ent/user_create.go index d0177f13..e70429be 100644 --- a/ent/user_create.go +++ b/ent/user_create.go @@ -15,6 +15,7 @@ import ( "github.com/gitploy-io/gitploy/ent/deployment" "github.com/gitploy-io/gitploy/ent/lock" "github.com/gitploy-io/gitploy/ent/perm" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -181,6 +182,21 @@ func (uc *UserCreate) AddApprovals(a ...*Approval) *UserCreate { return uc.AddApprovalIDs(ids...) } +// AddReviewIDs adds the "reviews" edge to the Review entity by IDs. +func (uc *UserCreate) AddReviewIDs(ids ...int) *UserCreate { + uc.mutation.AddReviewIDs(ids...) + return uc +} + +// AddReviews adds the "reviews" edges to the Review entity. +func (uc *UserCreate) AddReviews(r ...*Review) *UserCreate { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return uc.AddReviewIDs(ids...) +} + // AddLockIDs adds the "locks" edge to the Lock entity by IDs. func (uc *UserCreate) AddLockIDs(ids ...int) *UserCreate { uc.mutation.AddLockIDs(ids...) @@ -495,6 +511,25 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := uc.mutation.ReviewsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } if nodes := uc.mutation.LocksIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, diff --git a/ent/user_query.go b/ent/user_query.go index 55231f89..f2826a85 100644 --- a/ent/user_query.go +++ b/ent/user_query.go @@ -19,6 +19,7 @@ import ( "github.com/gitploy-io/gitploy/ent/lock" "github.com/gitploy-io/gitploy/ent/perm" "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -36,6 +37,7 @@ type UserQuery struct { withPerms *PermQuery withDeployments *DeploymentQuery withApprovals *ApprovalQuery + withReviews *ReviewQuery withLocks *LockQuery modifiers []func(s *sql.Selector) // intermediate query (i.e. traversal path). @@ -162,6 +164,28 @@ func (uq *UserQuery) QueryApprovals() *ApprovalQuery { return query } +// QueryReviews chains the current query on the "reviews" edge. +func (uq *UserQuery) QueryReviews() *ReviewQuery { + query := &ReviewQuery{config: uq.config} + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := uq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := uq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, selector), + sqlgraph.To(review.Table, review.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, user.ReviewsTable, user.ReviewsColumn), + ) + fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // QueryLocks chains the current query on the "locks" edge. func (uq *UserQuery) QueryLocks() *LockQuery { query := &LockQuery{config: uq.config} @@ -369,6 +393,7 @@ func (uq *UserQuery) Clone() *UserQuery { withPerms: uq.withPerms.Clone(), withDeployments: uq.withDeployments.Clone(), withApprovals: uq.withApprovals.Clone(), + withReviews: uq.withReviews.Clone(), withLocks: uq.withLocks.Clone(), // clone intermediate query. sql: uq.sql.Clone(), @@ -420,6 +445,17 @@ func (uq *UserQuery) WithApprovals(opts ...func(*ApprovalQuery)) *UserQuery { return uq } +// WithReviews tells the query-builder to eager-load the nodes that are connected to +// the "reviews" edge. The optional arguments are used to configure the query builder of the edge. +func (uq *UserQuery) WithReviews(opts ...func(*ReviewQuery)) *UserQuery { + query := &ReviewQuery{config: uq.config} + for _, opt := range opts { + opt(query) + } + uq.withReviews = query + return uq +} + // WithLocks tells the query-builder to eager-load the nodes that are connected to // the "locks" edge. The optional arguments are used to configure the query builder of the edge. func (uq *UserQuery) WithLocks(opts ...func(*LockQuery)) *UserQuery { @@ -496,11 +532,12 @@ func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) { var ( nodes = []*User{} _spec = uq.querySpec() - loadedTypes = [5]bool{ + loadedTypes = [6]bool{ uq.withChatUser != nil, uq.withPerms != nil, uq.withDeployments != nil, uq.withApprovals != nil, + uq.withReviews != nil, uq.withLocks != nil, } ) @@ -626,6 +663,31 @@ func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) { } } + if query := uq.withReviews; query != nil { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int64]*User) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + nodes[i].Edges.Reviews = []*Review{} + } + query.Where(predicate.Review(func(s *sql.Selector) { + s.Where(sql.InValues(user.ReviewsColumn, fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return nil, err + } + for _, n := range neighbors { + fk := n.UserID + node, ok := nodeids[fk] + if !ok { + return nil, fmt.Errorf(`unexpected foreign-key "user_id" returned %v for node %v`, fk, n.ID) + } + node.Edges.Reviews = append(node.Edges.Reviews, n) + } + } + if query := uq.withLocks; query != nil { fks := make([]driver.Value, 0, len(nodes)) nodeids := make(map[int64]*User) diff --git a/ent/user_update.go b/ent/user_update.go index 351b885c..008c2883 100644 --- a/ent/user_update.go +++ b/ent/user_update.go @@ -16,6 +16,7 @@ import ( "github.com/gitploy-io/gitploy/ent/lock" "github.com/gitploy-io/gitploy/ent/perm" "github.com/gitploy-io/gitploy/ent/predicate" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/ent/user" ) @@ -160,6 +161,21 @@ func (uu *UserUpdate) AddApprovals(a ...*Approval) *UserUpdate { return uu.AddApprovalIDs(ids...) } +// AddReviewIDs adds the "reviews" edge to the Review entity by IDs. +func (uu *UserUpdate) AddReviewIDs(ids ...int) *UserUpdate { + uu.mutation.AddReviewIDs(ids...) + return uu +} + +// AddReviews adds the "reviews" edges to the Review entity. +func (uu *UserUpdate) AddReviews(r ...*Review) *UserUpdate { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return uu.AddReviewIDs(ids...) +} + // AddLockIDs adds the "locks" edge to the Lock entity by IDs. func (uu *UserUpdate) AddLockIDs(ids ...int) *UserUpdate { uu.mutation.AddLockIDs(ids...) @@ -249,6 +265,27 @@ func (uu *UserUpdate) RemoveApprovals(a ...*Approval) *UserUpdate { return uu.RemoveApprovalIDs(ids...) } +// ClearReviews clears all "reviews" edges to the Review entity. +func (uu *UserUpdate) ClearReviews() *UserUpdate { + uu.mutation.ClearReviews() + return uu +} + +// RemoveReviewIDs removes the "reviews" edge to Review entities by IDs. +func (uu *UserUpdate) RemoveReviewIDs(ids ...int) *UserUpdate { + uu.mutation.RemoveReviewIDs(ids...) + return uu +} + +// RemoveReviews removes "reviews" edges to Review entities. +func (uu *UserUpdate) RemoveReviews(r ...*Review) *UserUpdate { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return uu.RemoveReviewIDs(ids...) +} + // ClearLocks clears all "locks" edges to the Lock entity. func (uu *UserUpdate) ClearLocks() *UserUpdate { uu.mutation.ClearLocks() @@ -604,6 +641,60 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if uu.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.RemovedReviewsIDs(); len(nodes) > 0 && !uu.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.ReviewsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if uu.mutation.LocksCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, @@ -805,6 +896,21 @@ func (uuo *UserUpdateOne) AddApprovals(a ...*Approval) *UserUpdateOne { return uuo.AddApprovalIDs(ids...) } +// AddReviewIDs adds the "reviews" edge to the Review entity by IDs. +func (uuo *UserUpdateOne) AddReviewIDs(ids ...int) *UserUpdateOne { + uuo.mutation.AddReviewIDs(ids...) + return uuo +} + +// AddReviews adds the "reviews" edges to the Review entity. +func (uuo *UserUpdateOne) AddReviews(r ...*Review) *UserUpdateOne { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return uuo.AddReviewIDs(ids...) +} + // AddLockIDs adds the "locks" edge to the Lock entity by IDs. func (uuo *UserUpdateOne) AddLockIDs(ids ...int) *UserUpdateOne { uuo.mutation.AddLockIDs(ids...) @@ -894,6 +1000,27 @@ func (uuo *UserUpdateOne) RemoveApprovals(a ...*Approval) *UserUpdateOne { return uuo.RemoveApprovalIDs(ids...) } +// ClearReviews clears all "reviews" edges to the Review entity. +func (uuo *UserUpdateOne) ClearReviews() *UserUpdateOne { + uuo.mutation.ClearReviews() + return uuo +} + +// RemoveReviewIDs removes the "reviews" edge to Review entities by IDs. +func (uuo *UserUpdateOne) RemoveReviewIDs(ids ...int) *UserUpdateOne { + uuo.mutation.RemoveReviewIDs(ids...) + return uuo +} + +// RemoveReviews removes "reviews" edges to Review entities. +func (uuo *UserUpdateOne) RemoveReviews(r ...*Review) *UserUpdateOne { + ids := make([]int, len(r)) + for i := range r { + ids[i] = r[i].ID + } + return uuo.RemoveReviewIDs(ids...) +} + // ClearLocks clears all "locks" edges to the Lock entity. func (uuo *UserUpdateOne) ClearLocks() *UserUpdateOne { uuo.mutation.ClearLocks() @@ -1273,6 +1400,60 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if uuo.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.RemovedReviewsIDs(); len(nodes) > 0 && !uuo.mutation.ReviewsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.ReviewsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: user.ReviewsTable, + Columns: []string{user.ReviewsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: review.FieldID, + }, + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if uuo.mutation.LocksCleared() { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.O2M, From 7b346e9ef9f9bbc713cada30b2ac801bc4fe1e98 Mon Sep 17 00:00:00 2001 From: noah Date: Mon, 1 Nov 2021 20:44:35 +0900 Subject: [PATCH 02/13] Add APIs for review --- internal/interactor/interface.go | 4 + internal/interactor/mock/pkg.go | 45 +++++ internal/pkg/store/review.go | 81 +++++++++ internal/server/api/v1/repos/interface.go | 4 + .../server/api/v1/repos/mock/interactor.go | 45 +++++ internal/server/api/v1/repos/review.go | 172 ++++++++++++++++++ .../repos/{comment_oss.go => review_oss.go} | 8 +- internal/server/router.go | 3 + openapi/v1.yaml | 147 +++++++++++++++ 9 files changed, 505 insertions(+), 4 deletions(-) create mode 100644 internal/pkg/store/review.go create mode 100644 internal/server/api/v1/repos/review.go rename internal/server/api/v1/repos/{comment_oss.go => review_oss.go} (63%) diff --git a/internal/interactor/interface.go b/internal/interactor/interface.go index 44cb915a..9c4d6eab 100644 --- a/internal/interactor/interface.go +++ b/internal/interactor/interface.go @@ -78,6 +78,10 @@ type ( UpdateApproval(ctx context.Context, a *ent.Approval) (*ent.Approval, error) DeleteApproval(ctx context.Context, a *ent.Approval) error + ListReviews(ctx context.Context, d *ent.Deployment) ([]*ent.Review, error) + FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deployment) (*ent.Review, error) + UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) + ListExpiredLocksLessThanTime(ctx context.Context, t time.Time) ([]*ent.Lock, error) ListLocksOfRepo(ctx context.Context, r *ent.Repo) ([]*ent.Lock, error) FindLockOfRepoByEnv(ctx context.Context, r *ent.Repo, env string) (*ent.Lock, error) diff --git a/internal/interactor/mock/pkg.go b/internal/interactor/mock/pkg.go index 940bb143..6c6b896b 100644 --- a/internal/interactor/mock/pkg.go +++ b/internal/interactor/mock/pkg.go @@ -589,6 +589,21 @@ func (mr *MockStoreMockRecorder) FindRepoOfUserByNamespaceName(ctx, u, namespace return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindRepoOfUserByNamespaceName", reflect.TypeOf((*MockStore)(nil).FindRepoOfUserByNamespaceName), ctx, u, namespace, name) } +// FindReviewOfUser mocks base method. +func (m *MockStore) FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deployment) (*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindReviewOfUser", ctx, u, d) + ret0, _ := ret[0].(*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindReviewOfUser indicates an expected call of FindReviewOfUser. +func (mr *MockStoreMockRecorder) FindReviewOfUser(ctx, u, d interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindReviewOfUser", reflect.TypeOf((*MockStore)(nil).FindReviewOfUser), ctx, u, d) +} + // FindUserByHash mocks base method. func (m *MockStore) FindUserByHash(ctx context.Context, hash string) (*ent.User, error) { m.ctrl.T.Helper() @@ -814,6 +829,21 @@ func (mr *MockStoreMockRecorder) ListReposOfUser(ctx, u, q, namespace, name, sor return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListReposOfUser", reflect.TypeOf((*MockStore)(nil).ListReposOfUser), ctx, u, q, namespace, name, sorted, page, perPage) } +// ListReviews mocks base method. +func (m *MockStore) ListReviews(ctx context.Context, d *ent.Deployment) ([]*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListReviews", ctx, d) + ret0, _ := ret[0].([]*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListReviews indicates an expected call of ListReviews. +func (mr *MockStoreMockRecorder) ListReviews(ctx, d interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListReviews", reflect.TypeOf((*MockStore)(nil).ListReviews), ctx, d) +} + // ListUsers mocks base method. func (m *MockStore) ListUsers(ctx context.Context, login string, page, perPage int) ([]*ent.User, error) { m.ctrl.T.Helper() @@ -994,6 +1024,21 @@ func (mr *MockStoreMockRecorder) UpdateRepo(ctx, r interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRepo", reflect.TypeOf((*MockStore)(nil).UpdateRepo), ctx, r) } +// UpdateReview mocks base method. +func (m *MockStore) UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateReview", ctx, rv) + ret0, _ := ret[0].(*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateReview indicates an expected call of UpdateReview. +func (mr *MockStoreMockRecorder) UpdateReview(ctx, rv interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateReview", reflect.TypeOf((*MockStore)(nil).UpdateReview), ctx, rv) +} + // UpdateUser mocks base method. func (m *MockStore) UpdateUser(ctx context.Context, u *ent.User) (*ent.User, error) { m.ctrl.T.Helper() diff --git a/internal/pkg/store/review.go b/internal/pkg/store/review.go new file mode 100644 index 00000000..3027b5c5 --- /dev/null +++ b/internal/pkg/store/review.go @@ -0,0 +1,81 @@ +package store + +import ( + "context" + "fmt" + + "github.com/gitploy-io/gitploy/ent" + "github.com/gitploy-io/gitploy/ent/review" + "github.com/gitploy-io/gitploy/pkg/e" +) + +func (s *Store) ListReviews(ctx context.Context, d *ent.Deployment) ([]*ent.Review, error) { + rvs, err := s.c.Review. + Query(). + Where( + review.DeploymentIDEQ(d.ID), + ). + WithUser(). + WithDeployment(). + All(ctx) + if err != nil { + return nil, e.NewError(e.ErrorCodeInternalError, err) + } + + return rvs, nil +} + +func (s *Store) FindReviewByID(ctx context.Context, id int) (*ent.Review, error) { + rv, err := s.c.Review. + Query(). + Where( + review.IDEQ(id), + ). + WithUser(). + WithDeployment(). + Only(ctx) + if ent.IsNotFound(err) { + return nil, e.NewErrorWithMessage(e.ErrorCodeNotFound, "The review is not found.", err) + } else if err != nil { + return nil, e.NewError(e.ErrorCodeInternalError, err) + } + + return rv, nil +} + +func (s *Store) FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deployment) (*ent.Review, error) { + rv, err := s.c.Review. + Query(). + Where( + review.DeploymentIDEQ(d.ID), + review.UserIDEQ(u.ID), + ). + WithUser(). + WithDeployment(). + Only(ctx) + if ent.IsNotFound(err) { + return nil, e.NewErrorWithMessage(e.ErrorCodeNotFound, "The review is not found.", err) + } else if err != nil { + return nil, e.NewError(e.ErrorCodeInternalError, err) + } + + return rv, nil +} + +func (s *Store) UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) { + rv, err := s.c.Review. + UpdateOne(rv). + SetStatus(rv.Status). + Save(ctx) + if ent.IsValidationError(err) { + return nil, e.NewErrorWithMessage( + e.ErrorCodeUnprocessableEntity, + fmt.Sprintf("Failed to update the review. The value of \"%s\" field is invalid.", err.(*ent.ValidationError).Name), + err, + ) + } else if err != nil { + return nil, e.NewError(e.ErrorCodeInternalError, err) + } + + return s.FindReviewByID(ctx, rv.ID) +} diff --git a/internal/server/api/v1/repos/interface.go b/internal/server/api/v1/repos/interface.go index 22bbe48c..8883af83 100644 --- a/internal/server/api/v1/repos/interface.go +++ b/internal/server/api/v1/repos/interface.go @@ -39,6 +39,10 @@ type ( UpdateApproval(ctx context.Context, a *ent.Approval) (*ent.Approval, error) DeleteApproval(ctx context.Context, a *ent.Approval) error + ListReviews(ctx context.Context, d *ent.Deployment) ([]*ent.Review, error) + FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deployment) (*ent.Review, error) + UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) + ListLocksOfRepo(ctx context.Context, r *ent.Repo) ([]*ent.Lock, error) HasLockOfRepoForEnv(ctx context.Context, r *ent.Repo, env string) (bool, error) FindLockByID(ctx context.Context, id int) (*ent.Lock, error) diff --git a/internal/server/api/v1/repos/mock/interactor.go b/internal/server/api/v1/repos/mock/interactor.go index 3778dd9a..c2873215 100644 --- a/internal/server/api/v1/repos/mock/interactor.go +++ b/internal/server/api/v1/repos/mock/interactor.go @@ -320,6 +320,21 @@ func (mr *MockInteractorMockRecorder) FindRepoOfUserByNamespaceName(ctx, u, name return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindRepoOfUserByNamespaceName", reflect.TypeOf((*MockInteractor)(nil).FindRepoOfUserByNamespaceName), ctx, u, namespace, name) } +// FindReviewOfUser mocks base method. +func (m *MockInteractor) FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deployment) (*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindReviewOfUser", ctx, u, d) + ret0, _ := ret[0].(*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FindReviewOfUser indicates an expected call of FindReviewOfUser. +func (mr *MockInteractorMockRecorder) FindReviewOfUser(ctx, u, d interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindReviewOfUser", reflect.TypeOf((*MockInteractor)(nil).FindReviewOfUser), ctx, u, d) +} + // FindUserByID mocks base method. func (m *MockInteractor) FindUserByID(ctx context.Context, id int64) (*ent.User, error) { m.ctrl.T.Helper() @@ -544,6 +559,21 @@ func (mr *MockInteractorMockRecorder) ListReposOfUser(ctx, u, q, namespace, name return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListReposOfUser", reflect.TypeOf((*MockInteractor)(nil).ListReposOfUser), ctx, u, q, namespace, name, sorted, page, perPage) } +// ListReviews mocks base method. +func (m *MockInteractor) ListReviews(ctx context.Context, d *ent.Deployment) ([]*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListReviews", ctx, d) + ret0, _ := ret[0].([]*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListReviews indicates an expected call of ListReviews. +func (mr *MockInteractorMockRecorder) ListReviews(ctx, d interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListReviews", reflect.TypeOf((*MockInteractor)(nil).ListReviews), ctx, d) +} + // ListTags mocks base method. func (m *MockInteractor) ListTags(ctx context.Context, u *ent.User, r *ent.Repo, page, perPage int) ([]*vo.Tag, error) { m.ctrl.T.Helper() @@ -603,3 +633,18 @@ func (mr *MockInteractorMockRecorder) UpdateRepo(ctx, r interface{}) *gomock.Cal mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRepo", reflect.TypeOf((*MockInteractor)(nil).UpdateRepo), ctx, r) } + +// UpdateReview mocks base method. +func (m *MockInteractor) UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateReview", ctx, rv) + ret0, _ := ret[0].(*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateReview indicates an expected call of UpdateReview. +func (mr *MockInteractorMockRecorder) UpdateReview(ctx, rv interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateReview", reflect.TypeOf((*MockInteractor)(nil).UpdateReview), ctx, rv) +} diff --git a/internal/server/api/v1/repos/review.go b/internal/server/api/v1/repos/review.go new file mode 100644 index 00000000..fe4a844f --- /dev/null +++ b/internal/server/api/v1/repos/review.go @@ -0,0 +1,172 @@ +// Copyright 2021 Gitploy.IO Inc. All rights reserved. +// Use of this source code is governed by the Gitploy Non-Commercial License +// that can be found in the LICENSE file. + +// +build !oss + +package repos + +import ( + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" + "go.uber.org/zap" + + "github.com/gitploy-io/gitploy/ent" + "github.com/gitploy-io/gitploy/ent/event" + "github.com/gitploy-io/gitploy/ent/review" + gb "github.com/gitploy-io/gitploy/internal/server/global" + "github.com/gitploy-io/gitploy/pkg/e" +) + +type ( + reviewPatchPayload struct { + Status string `json:"status"` + } +) + +func (r *Repo) ListReviews(c *gin.Context) { + ctx := c.Request.Context() + + var ( + number int + err error + ) + + if number, err = strconv.Atoi(c.Param("number")); err != nil { + r.log.Warn("The number of deployment must be number.") + gb.ResponseWithError( + c, + e.NewErrorWithMessage(e.ErrorCodeInvalidRequest, "The number of deployment must be number.", err), + ) + return + } + + vr, _ := c.Get(KeyRepo) + re := vr.(*ent.Repo) + + d, err := r.i.FindDeploymentOfRepoByNumber(ctx, re, number) + if err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to find the deployment.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + rvs, err := r.i.ListReviews(ctx, d) + if err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to list reviews.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + gb.Response(c, http.StatusOK, rvs) +} + +func (r *Repo) GetUserReview(c *gin.Context) { + ctx := c.Request.Context() + + var ( + number int + err error + ) + + if number, err = strconv.Atoi(c.Param("number")); err != nil { + r.log.Warn("The number of deployment must be number.") + gb.ResponseWithError( + c, + e.NewErrorWithMessage(e.ErrorCodeInvalidRequest, "The number of deployemnt must be number.", err), + ) + return + } + + vu, _ := c.Get(gb.KeyUser) + u := vu.(*ent.User) + + vr, _ := c.Get(KeyRepo) + re := vr.(*ent.Repo) + + d, err := r.i.FindDeploymentOfRepoByNumber(ctx, re, number) + if err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to find the deployment.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + rv, err := r.i.FindReviewOfUser(ctx, u, d) + if err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to find the user's review.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + gb.Response(c, http.StatusOK, rv) +} + +func (r *Repo) UpdateUserReview(c *gin.Context) { + ctx := c.Request.Context() + + var ( + number int + err error + ) + + if number, err = strconv.Atoi(c.Param("number")); err != nil { + r.log.Warn("The number of deployment must be number.") + gb.ResponseWithError( + c, + e.NewErrorWithMessage(e.ErrorCodeInvalidRequest, "The number of deployment must be number.", err), + ) + return + } + + p := &reviewPatchPayload{} + if err := c.ShouldBindBodyWith(p, binding.JSON); err != nil { + r.log.Warn("Failed to bind the payload.", zap.Error(err)) + gb.ResponseWithError( + c, + e.NewErrorWithMessage(e.ErrorCodeInvalidRequest, "It has failed to bind the payload.", nil), + ) + return + } + + vu, _ := c.Get(gb.KeyUser) + u := vu.(*ent.User) + + vr, _ := c.Get(KeyRepo) + re := vr.(*ent.Repo) + + d, err := r.i.FindDeploymentOfRepoByNumber(ctx, re, number) + if err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to find the deployment.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + rv, err := r.i.FindReviewOfUser(ctx, u, d) + if err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to find the user's review.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + if p.Status != string(rv.Status) { + rv.Status = review.Status(p.Status) + if rv, err = r.i.UpdateReview(ctx, rv); err != nil { + r.log.Check(gb.GetZapLogLevel(err), "Failed to update the review.").Write(zap.Error(err)) + gb.ResponseWithError(c, err) + return + } + + if _, err := r.i.CreateEvent(ctx, &ent.Event{ + Kind: event.KindReview, + Type: event.TypeUpdated, + ReviewID: rv.ID, + }); err != nil { + r.log.Error("Failed to create the event.", zap.Error(err)) + } + } + + gb.Response(c, http.StatusOK, rv) +} diff --git a/internal/server/api/v1/repos/comment_oss.go b/internal/server/api/v1/repos/review_oss.go similarity index 63% rename from internal/server/api/v1/repos/comment_oss.go rename to internal/server/api/v1/repos/review_oss.go index b7ae275c..3f889275 100644 --- a/internal/server/api/v1/repos/comment_oss.go +++ b/internal/server/api/v1/repos/review_oss.go @@ -12,15 +12,15 @@ import ( "github.com/gitploy-io/gitploy/pkg/e" ) -func (r *Repo) ListComments(c *gin.Context) { - gb.Response(c, http.StatusOK, make([]*ent.Comment, 0)) +func (r *Repo) ListReviews(c *gin.Context) { + gb.Response(c, http.StatusOK, make([]*ent.Review, 0)) } -func (r *Repo) GetComment(c *gin.Context) { +func (r *Repo) GetUserApproval(c *gin.Context) { gb.Response(c, http.StatusNotFound, nil) } -func (r *Repo) CreateComment(c *gin.Context) { +func (r *Repo) UpdateUserReview(c *gin.Context) { gb.ResponseWithError( c, e.NewError(e.ErrorCodeLicenseRequired, nil), diff --git a/internal/server/router.go b/internal/server/router.go index 1c86321a..78e87102 100644 --- a/internal/server/router.go +++ b/internal/server/router.go @@ -153,6 +153,9 @@ func NewRouter(c *RouterConfig) *gin.Engine { repov1.PATCH("/:namespace/:name/deployments/:number/approval", rm.RepoReadPerm(), r.UpdateMyApproval) repov1.GET("/:namespace/:name/approvals/:aid", rm.RepoReadPerm(), r.GetApproval) repov1.DELETE("/:namespace/:name/approvals/:aid", rm.RepoReadPerm(), r.DeleteApproval) + repov1.GET("/:namespace/:name/deployments/:number/reviews", rm.RepoReadPerm(), r.ListReviews) + repov1.GET("/:namespace/:name/deployments/:number/review", rm.RepoReadPerm(), r.GetUserReview) + repov1.PATCH("/:namespace/:name/deployments/:number/review", rm.RepoReadPerm(), r.UpdateUserReview) repov1.GET("/:namespace/:name/locks", rm.RepoReadPerm(), r.ListLocks) repov1.POST("/:namespace/:name/locks", rm.RepoWritePerm(), r.CreateLock) repov1.PATCH("/:namespace/:name/locks/:lockID", rm.RepoWritePerm(), r.UpdateLock) diff --git a/openapi/v1.yaml b/openapi/v1.yaml index 88dfc822..bc03957f 100644 --- a/openapi/v1.yaml +++ b/openapi/v1.yaml @@ -993,6 +993,122 @@ paths: $ref: '#/components/responses/404NotFound' '500': $ref: '#/components/responses/500InternalError' + /repos/{namespace}/{name}/deployments/{number}/reviews: + get: + tags: + - Repo + summary: List reviews of the deployment. + parameters: + - in: path + name: namespace + required: true + schema: + type: string + - in: path + name: name + required: true + schema: + type: string + - in: path + name: number + required: true + schema: + type: integer + description: The deployment number. + responses: + '200': + description: List of reviews. + content: + application/json: + schema: + $ref: '#/components/schemas/Reviews' + '401': + $ref: '#/components/responses/401Unauthorized' + '402': + $ref: '#/components/responses/402PaymentRequired' + '403': + $ref: '#/components/responses/403Forbidden' + '500': + $ref: '#/components/responses/500InternalError' + /repos/{namespace}/{name}/deployments/{number}/review: + get: + tags: + - Repo + summary: Get the review of the user. + parameters: + - in: path + name: namespace + required: true + schema: + type: string + - in: path + name: name + required: true + schema: + type: string + - in: path + name: number + required: true + schema: + type: integer + description: The deployment number. + responses: + '200': + description: Return the review. + content: + application/json: + schema: + $ref: '#/components/schemas/Review' + '401': + $ref: '#/components/responses/401Unauthorized' + '402': + $ref: '#/components/responses/402PaymentRequired' + '403': + $ref: '#/components/responses/403Forbidden' + '404': + $ref: '#/components/responses/404NotFound' + '500': + $ref: '#/components/responses/500InternalError' + patch: + tags: + - Repo + summary: Update the review of the user if it exist. + parameters: + - in: path + name: namespace + required: true + schema: + type: string + - in: path + name: name + required: true + schema: + type: string + - in: path + name: number + required: true + schema: + type: integer + description: The deployment number. + responses: + '200': + description: Return the review. + content: + application/json: + schema: + $ref: '#/components/schemas/Review' + '401': + $ref: '#/components/responses/401Unauthorized' + '402': + $ref: '#/components/responses/402PaymentRequired' + '403': + $ref: '#/components/responses/403Forbidden' + '404': + $ref: '#/components/responses/404NotFound' + '422': + $ref: '#/components/responses/422UnprocessableEntity' + '500': + $ref: '#/components/responses/500InternalError' /repos/{namespace}/{name}/locks: get: tags: @@ -1951,6 +2067,37 @@ components: - status - created_at - updated_at + Reviews: + type: array + items: + $ref: '#/components/schemas/Review' + Review: + type: object + properties: + id: + type: integer + status: + type: string + enum: + - pending + - rejected + - approved + created_at: + type: string + updated_at: + type: string + edges: + type: object + properties: + user: + $ref: '#/components/schemas/User' + deployment: + $ref: '#/components/schemas/Deployment' + required: + - id + - status + - created_at + - updated_at RateLimit: type: object properties: From d38b7632136836faf30d335ab4ccde12aa9bd905 Mon Sep 17 00:00:00 2001 From: noah Date: Mon, 1 Nov 2021 21:48:18 +0900 Subject: [PATCH 03/13] Deprecate field for approval --- ent/deployment.go | 48 +++--- ent/deployment/deployment.go | 16 +- ent/deployment/where.go | 236 ++++++++++++++++------------ ent/deployment_create.go | 102 ++++++------ ent/deployment_update.go | 212 +++++++++++++++---------- ent/migrate/schema.go | 12 +- ent/mutation.go | 295 ++++++++++++++++++++--------------- ent/runtime.go | 12 +- ent/schema/deployment.go | 12 +- 9 files changed, 522 insertions(+), 423 deletions(-) diff --git a/ent/deployment.go b/ent/deployment.go index 190dca9e..fdaad44d 100644 --- a/ent/deployment.go +++ b/ent/deployment.go @@ -38,10 +38,6 @@ type Deployment struct { ProductionEnvironment bool `json:"production_environment"` // IsRollback holds the value of the "is_rollback" field. IsRollback bool `json:"is_rollback"` - // IsApprovalEnabled holds the value of the "is_approval_enabled" field. - IsApprovalEnabled bool `json:"is_approval_enabled"` - // RequiredApprovalCount holds the value of the "required_approval_count" field. - RequiredApprovalCount int `json:"required_approval_count"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at"` // UpdatedAt holds the value of the "updated_at" field. @@ -50,6 +46,10 @@ type Deployment struct { UserID int64 `json:"user_id"` // RepoID holds the value of the "repo_id" field. RepoID int64 `json:"repo_id"` + // IsApprovalEnabled holds the value of the "is_approval_enabled" field. + IsApprovalEnabled *bool `json:"is_approval_enabled,omitemtpy"` + // RequiredApprovalCount holds the value of the "required_approval_count" field. + RequiredApprovalCount *int `json:"required_approval_count,omitemtpy"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the DeploymentQuery when eager-loading is set. Edges DeploymentEdges `json:"edges"` @@ -145,7 +145,7 @@ func (*Deployment) scanValues(columns []string) ([]interface{}, error) { switch columns[i] { case deployment.FieldProductionEnvironment, deployment.FieldIsRollback, deployment.FieldIsApprovalEnabled: values[i] = new(sql.NullBool) - case deployment.FieldID, deployment.FieldNumber, deployment.FieldUID, deployment.FieldRequiredApprovalCount, deployment.FieldUserID, deployment.FieldRepoID: + case deployment.FieldID, deployment.FieldNumber, deployment.FieldUID, deployment.FieldUserID, deployment.FieldRepoID, deployment.FieldRequiredApprovalCount: values[i] = new(sql.NullInt64) case deployment.FieldType, deployment.FieldEnv, deployment.FieldRef, deployment.FieldStatus, deployment.FieldSha, deployment.FieldHTMLURL: values[i] = new(sql.NullString) @@ -232,18 +232,6 @@ func (d *Deployment) assignValues(columns []string, values []interface{}) error } else if value.Valid { d.IsRollback = value.Bool } - case deployment.FieldIsApprovalEnabled: - if value, ok := values[i].(*sql.NullBool); !ok { - return fmt.Errorf("unexpected type %T for field is_approval_enabled", values[i]) - } else if value.Valid { - d.IsApprovalEnabled = value.Bool - } - case deployment.FieldRequiredApprovalCount: - if value, ok := values[i].(*sql.NullInt64); !ok { - return fmt.Errorf("unexpected type %T for field required_approval_count", values[i]) - } else if value.Valid { - d.RequiredApprovalCount = int(value.Int64) - } case deployment.FieldCreatedAt: if value, ok := values[i].(*sql.NullTime); !ok { return fmt.Errorf("unexpected type %T for field created_at", values[i]) @@ -268,6 +256,20 @@ func (d *Deployment) assignValues(columns []string, values []interface{}) error } else if value.Valid { d.RepoID = value.Int64 } + case deployment.FieldIsApprovalEnabled: + if value, ok := values[i].(*sql.NullBool); !ok { + return fmt.Errorf("unexpected type %T for field is_approval_enabled", values[i]) + } else if value.Valid { + d.IsApprovalEnabled = new(bool) + *d.IsApprovalEnabled = value.Bool + } + case deployment.FieldRequiredApprovalCount: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field required_approval_count", values[i]) + } else if value.Valid { + d.RequiredApprovalCount = new(int) + *d.RequiredApprovalCount = int(value.Int64) + } } } return nil @@ -346,10 +348,6 @@ func (d *Deployment) String() string { builder.WriteString(fmt.Sprintf("%v", d.ProductionEnvironment)) builder.WriteString(", is_rollback=") builder.WriteString(fmt.Sprintf("%v", d.IsRollback)) - builder.WriteString(", is_approval_enabled=") - builder.WriteString(fmt.Sprintf("%v", d.IsApprovalEnabled)) - builder.WriteString(", required_approval_count=") - builder.WriteString(fmt.Sprintf("%v", d.RequiredApprovalCount)) builder.WriteString(", created_at=") builder.WriteString(d.CreatedAt.Format(time.ANSIC)) builder.WriteString(", updated_at=") @@ -358,6 +356,14 @@ func (d *Deployment) String() string { builder.WriteString(fmt.Sprintf("%v", d.UserID)) builder.WriteString(", repo_id=") builder.WriteString(fmt.Sprintf("%v", d.RepoID)) + if v := d.IsApprovalEnabled; v != nil { + builder.WriteString(", is_approval_enabled=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } + if v := d.RequiredApprovalCount; v != nil { + builder.WriteString(", required_approval_count=") + builder.WriteString(fmt.Sprintf("%v", *v)) + } builder.WriteByte(')') return builder.String() } diff --git a/ent/deployment/deployment.go b/ent/deployment/deployment.go index bd1b1ad0..57bd5097 100644 --- a/ent/deployment/deployment.go +++ b/ent/deployment/deployment.go @@ -32,10 +32,6 @@ const ( FieldProductionEnvironment = "production_environment" // FieldIsRollback holds the string denoting the is_rollback field in the database. FieldIsRollback = "is_rollback" - // FieldIsApprovalEnabled holds the string denoting the is_approval_enabled field in the database. - FieldIsApprovalEnabled = "is_approval_enabled" - // FieldRequiredApprovalCount holds the string denoting the required_approval_count field in the database. - FieldRequiredApprovalCount = "required_approval_count" // FieldCreatedAt holds the string denoting the created_at field in the database. FieldCreatedAt = "created_at" // FieldUpdatedAt holds the string denoting the updated_at field in the database. @@ -44,6 +40,10 @@ const ( FieldUserID = "user_id" // FieldRepoID holds the string denoting the repo_id field in the database. FieldRepoID = "repo_id" + // FieldIsApprovalEnabled holds the string denoting the is_approval_enabled field in the database. + FieldIsApprovalEnabled = "is_approval_enabled" + // FieldRequiredApprovalCount holds the string denoting the required_approval_count field in the database. + FieldRequiredApprovalCount = "required_approval_count" // EdgeUser holds the string denoting the user edge name in mutations. EdgeUser = "user" // EdgeRepo holds the string denoting the repo edge name in mutations. @@ -115,12 +115,12 @@ var Columns = []string{ FieldHTMLURL, FieldProductionEnvironment, FieldIsRollback, - FieldIsApprovalEnabled, - FieldRequiredApprovalCount, FieldCreatedAt, FieldUpdatedAt, FieldUserID, FieldRepoID, + FieldIsApprovalEnabled, + FieldRequiredApprovalCount, } // ValidColumn reports if the column name is valid (part of the table columns). @@ -140,10 +140,6 @@ var ( DefaultProductionEnvironment bool // DefaultIsRollback holds the default value on creation for the "is_rollback" field. DefaultIsRollback bool - // DefaultIsApprovalEnabled holds the default value on creation for the "is_approval_enabled" field. - DefaultIsApprovalEnabled bool - // DefaultRequiredApprovalCount holds the default value on creation for the "required_approval_count" field. - DefaultRequiredApprovalCount int // DefaultCreatedAt holds the default value on creation for the "created_at" field. DefaultCreatedAt func() time.Time // DefaultUpdatedAt holds the default value on creation for the "updated_at" field. diff --git a/ent/deployment/where.go b/ent/deployment/where.go index 0422f39a..65e9dcd1 100644 --- a/ent/deployment/where.go +++ b/ent/deployment/where.go @@ -149,20 +149,6 @@ func IsRollback(v bool) predicate.Deployment { }) } -// IsApprovalEnabled applies equality check predicate on the "is_approval_enabled" field. It's identical to IsApprovalEnabledEQ. -func IsApprovalEnabled(v bool) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldIsApprovalEnabled), v)) - }) -} - -// RequiredApprovalCount applies equality check predicate on the "required_approval_count" field. It's identical to RequiredApprovalCountEQ. -func RequiredApprovalCount(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRequiredApprovalCount), v)) - }) -} - // CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. func CreatedAt(v time.Time) predicate.Deployment { return predicate.Deployment(func(s *sql.Selector) { @@ -191,6 +177,20 @@ func RepoID(v int64) predicate.Deployment { }) } +// IsApprovalEnabled applies equality check predicate on the "is_approval_enabled" field. It's identical to IsApprovalEnabledEQ. +func IsApprovalEnabled(v bool) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldIsApprovalEnabled), v)) + }) +} + +// RequiredApprovalCount applies equality check predicate on the "required_approval_count" field. It's identical to RequiredApprovalCountEQ. +func RequiredApprovalCount(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldRequiredApprovalCount), v)) + }) +} + // NumberEQ applies the EQ predicate on the "number" field. func NumberEQ(v int) predicate.Deployment { return predicate.Deployment(func(s *sql.Selector) { @@ -953,96 +953,6 @@ func IsRollbackNEQ(v bool) predicate.Deployment { }) } -// IsApprovalEnabledEQ applies the EQ predicate on the "is_approval_enabled" field. -func IsApprovalEnabledEQ(v bool) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldIsApprovalEnabled), v)) - }) -} - -// IsApprovalEnabledNEQ applies the NEQ predicate on the "is_approval_enabled" field. -func IsApprovalEnabledNEQ(v bool) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldIsApprovalEnabled), v)) - }) -} - -// RequiredApprovalCountEQ applies the EQ predicate on the "required_approval_count" field. -func RequiredApprovalCountEQ(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.EQ(s.C(FieldRequiredApprovalCount), v)) - }) -} - -// RequiredApprovalCountNEQ applies the NEQ predicate on the "required_approval_count" field. -func RequiredApprovalCountNEQ(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.NEQ(s.C(FieldRequiredApprovalCount), v)) - }) -} - -// RequiredApprovalCountIn applies the In predicate on the "required_approval_count" field. -func RequiredApprovalCountIn(vs ...int) predicate.Deployment { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Deployment(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.In(s.C(FieldRequiredApprovalCount), v...)) - }) -} - -// RequiredApprovalCountNotIn applies the NotIn predicate on the "required_approval_count" field. -func RequiredApprovalCountNotIn(vs ...int) predicate.Deployment { - v := make([]interface{}, len(vs)) - for i := range v { - v[i] = vs[i] - } - return predicate.Deployment(func(s *sql.Selector) { - // if not arguments were provided, append the FALSE constants, - // since we can't apply "IN ()". This will make this predicate falsy. - if len(v) == 0 { - s.Where(sql.False()) - return - } - s.Where(sql.NotIn(s.C(FieldRequiredApprovalCount), v...)) - }) -} - -// RequiredApprovalCountGT applies the GT predicate on the "required_approval_count" field. -func RequiredApprovalCountGT(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.GT(s.C(FieldRequiredApprovalCount), v)) - }) -} - -// RequiredApprovalCountGTE applies the GTE predicate on the "required_approval_count" field. -func RequiredApprovalCountGTE(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.GTE(s.C(FieldRequiredApprovalCount), v)) - }) -} - -// RequiredApprovalCountLT applies the LT predicate on the "required_approval_count" field. -func RequiredApprovalCountLT(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.LT(s.C(FieldRequiredApprovalCount), v)) - }) -} - -// RequiredApprovalCountLTE applies the LTE predicate on the "required_approval_count" field. -func RequiredApprovalCountLTE(v int) predicate.Deployment { - return predicate.Deployment(func(s *sql.Selector) { - s.Where(sql.LTE(s.C(FieldRequiredApprovalCount), v)) - }) -} - // CreatedAtEQ applies the EQ predicate on the "created_at" field. func CreatedAtEQ(v time.Time) predicate.Deployment { return predicate.Deployment(func(s *sql.Selector) { @@ -1291,6 +1201,124 @@ func RepoIDNotIn(vs ...int64) predicate.Deployment { }) } +// IsApprovalEnabledEQ applies the EQ predicate on the "is_approval_enabled" field. +func IsApprovalEnabledEQ(v bool) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldIsApprovalEnabled), v)) + }) +} + +// IsApprovalEnabledNEQ applies the NEQ predicate on the "is_approval_enabled" field. +func IsApprovalEnabledNEQ(v bool) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldIsApprovalEnabled), v)) + }) +} + +// IsApprovalEnabledIsNil applies the IsNil predicate on the "is_approval_enabled" field. +func IsApprovalEnabledIsNil() predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldIsApprovalEnabled))) + }) +} + +// IsApprovalEnabledNotNil applies the NotNil predicate on the "is_approval_enabled" field. +func IsApprovalEnabledNotNil() predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldIsApprovalEnabled))) + }) +} + +// RequiredApprovalCountEQ applies the EQ predicate on the "required_approval_count" field. +func RequiredApprovalCountEQ(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldRequiredApprovalCount), v)) + }) +} + +// RequiredApprovalCountNEQ applies the NEQ predicate on the "required_approval_count" field. +func RequiredApprovalCountNEQ(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldRequiredApprovalCount), v)) + }) +} + +// RequiredApprovalCountIn applies the In predicate on the "required_approval_count" field. +func RequiredApprovalCountIn(vs ...int) predicate.Deployment { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Deployment(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.In(s.C(FieldRequiredApprovalCount), v...)) + }) +} + +// RequiredApprovalCountNotIn applies the NotIn predicate on the "required_approval_count" field. +func RequiredApprovalCountNotIn(vs ...int) predicate.Deployment { + v := make([]interface{}, len(vs)) + for i := range v { + v[i] = vs[i] + } + return predicate.Deployment(func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(v) == 0 { + s.Where(sql.False()) + return + } + s.Where(sql.NotIn(s.C(FieldRequiredApprovalCount), v...)) + }) +} + +// RequiredApprovalCountGT applies the GT predicate on the "required_approval_count" field. +func RequiredApprovalCountGT(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldRequiredApprovalCount), v)) + }) +} + +// RequiredApprovalCountGTE applies the GTE predicate on the "required_approval_count" field. +func RequiredApprovalCountGTE(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldRequiredApprovalCount), v)) + }) +} + +// RequiredApprovalCountLT applies the LT predicate on the "required_approval_count" field. +func RequiredApprovalCountLT(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldRequiredApprovalCount), v)) + }) +} + +// RequiredApprovalCountLTE applies the LTE predicate on the "required_approval_count" field. +func RequiredApprovalCountLTE(v int) predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldRequiredApprovalCount), v)) + }) +} + +// RequiredApprovalCountIsNil applies the IsNil predicate on the "required_approval_count" field. +func RequiredApprovalCountIsNil() predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.IsNull(s.C(FieldRequiredApprovalCount))) + }) +} + +// RequiredApprovalCountNotNil applies the NotNil predicate on the "required_approval_count" field. +func RequiredApprovalCountNotNil() predicate.Deployment { + return predicate.Deployment(func(s *sql.Selector) { + s.Where(sql.NotNull(s.C(FieldRequiredApprovalCount))) + }) +} + // HasUser applies the HasEdge predicate on the "user" edge. func HasUser() predicate.Deployment { return predicate.Deployment(func(s *sql.Selector) { diff --git a/ent/deployment_create.go b/ent/deployment_create.go index a24e157c..61e39ac2 100644 --- a/ent/deployment_create.go +++ b/ent/deployment_create.go @@ -142,34 +142,6 @@ func (dc *DeploymentCreate) SetNillableIsRollback(b *bool) *DeploymentCreate { return dc } -// SetIsApprovalEnabled sets the "is_approval_enabled" field. -func (dc *DeploymentCreate) SetIsApprovalEnabled(b bool) *DeploymentCreate { - dc.mutation.SetIsApprovalEnabled(b) - return dc -} - -// SetNillableIsApprovalEnabled sets the "is_approval_enabled" field if the given value is not nil. -func (dc *DeploymentCreate) SetNillableIsApprovalEnabled(b *bool) *DeploymentCreate { - if b != nil { - dc.SetIsApprovalEnabled(*b) - } - return dc -} - -// SetRequiredApprovalCount sets the "required_approval_count" field. -func (dc *DeploymentCreate) SetRequiredApprovalCount(i int) *DeploymentCreate { - dc.mutation.SetRequiredApprovalCount(i) - return dc -} - -// SetNillableRequiredApprovalCount sets the "required_approval_count" field if the given value is not nil. -func (dc *DeploymentCreate) SetNillableRequiredApprovalCount(i *int) *DeploymentCreate { - if i != nil { - dc.SetRequiredApprovalCount(*i) - } - return dc -} - // SetCreatedAt sets the "created_at" field. func (dc *DeploymentCreate) SetCreatedAt(t time.Time) *DeploymentCreate { dc.mutation.SetCreatedAt(t) @@ -210,6 +182,34 @@ func (dc *DeploymentCreate) SetRepoID(i int64) *DeploymentCreate { return dc } +// SetIsApprovalEnabled sets the "is_approval_enabled" field. +func (dc *DeploymentCreate) SetIsApprovalEnabled(b bool) *DeploymentCreate { + dc.mutation.SetIsApprovalEnabled(b) + return dc +} + +// SetNillableIsApprovalEnabled sets the "is_approval_enabled" field if the given value is not nil. +func (dc *DeploymentCreate) SetNillableIsApprovalEnabled(b *bool) *DeploymentCreate { + if b != nil { + dc.SetIsApprovalEnabled(*b) + } + return dc +} + +// SetRequiredApprovalCount sets the "required_approval_count" field. +func (dc *DeploymentCreate) SetRequiredApprovalCount(i int) *DeploymentCreate { + dc.mutation.SetRequiredApprovalCount(i) + return dc +} + +// SetNillableRequiredApprovalCount sets the "required_approval_count" field if the given value is not nil. +func (dc *DeploymentCreate) SetNillableRequiredApprovalCount(i *int) *DeploymentCreate { + if i != nil { + dc.SetRequiredApprovalCount(*i) + } + return dc +} + // SetUser sets the "user" edge to the User entity. func (dc *DeploymentCreate) SetUser(u *User) *DeploymentCreate { return dc.SetUserID(u.ID) @@ -367,14 +367,6 @@ func (dc *DeploymentCreate) defaults() { v := deployment.DefaultIsRollback dc.mutation.SetIsRollback(v) } - if _, ok := dc.mutation.IsApprovalEnabled(); !ok { - v := deployment.DefaultIsApprovalEnabled - dc.mutation.SetIsApprovalEnabled(v) - } - if _, ok := dc.mutation.RequiredApprovalCount(); !ok { - v := deployment.DefaultRequiredApprovalCount - dc.mutation.SetRequiredApprovalCount(v) - } if _, ok := dc.mutation.CreatedAt(); !ok { v := deployment.DefaultCreatedAt() dc.mutation.SetCreatedAt(v) @@ -423,12 +415,6 @@ func (dc *DeploymentCreate) check() error { if _, ok := dc.mutation.IsRollback(); !ok { return &ValidationError{Name: "is_rollback", err: errors.New(`ent: missing required field "is_rollback"`)} } - if _, ok := dc.mutation.IsApprovalEnabled(); !ok { - return &ValidationError{Name: "is_approval_enabled", err: errors.New(`ent: missing required field "is_approval_enabled"`)} - } - if _, ok := dc.mutation.RequiredApprovalCount(); !ok { - return &ValidationError{Name: "required_approval_count", err: errors.New(`ent: missing required field "required_approval_count"`)} - } if _, ok := dc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "created_at"`)} } @@ -554,22 +540,6 @@ func (dc *DeploymentCreate) createSpec() (*Deployment, *sqlgraph.CreateSpec) { }) _node.IsRollback = value } - if value, ok := dc.mutation.IsApprovalEnabled(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeBool, - Value: value, - Column: deployment.FieldIsApprovalEnabled, - }) - _node.IsApprovalEnabled = value - } - if value, ok := dc.mutation.RequiredApprovalCount(); ok { - _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ - Type: field.TypeInt, - Value: value, - Column: deployment.FieldRequiredApprovalCount, - }) - _node.RequiredApprovalCount = value - } if value, ok := dc.mutation.CreatedAt(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeTime, @@ -586,6 +556,22 @@ func (dc *DeploymentCreate) createSpec() (*Deployment, *sqlgraph.CreateSpec) { }) _node.UpdatedAt = value } + if value, ok := dc.mutation.IsApprovalEnabled(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeBool, + Value: value, + Column: deployment.FieldIsApprovalEnabled, + }) + _node.IsApprovalEnabled = &value + } + if value, ok := dc.mutation.RequiredApprovalCount(); ok { + _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Value: value, + Column: deployment.FieldRequiredApprovalCount, + }) + _node.RequiredApprovalCount = &value + } if nodes := dc.mutation.UserIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ Rel: sqlgraph.M2O, diff --git a/ent/deployment_update.go b/ent/deployment_update.go index ef1dd72b..5bab24a8 100644 --- a/ent/deployment_update.go +++ b/ent/deployment_update.go @@ -182,6 +182,38 @@ func (du *DeploymentUpdate) SetNillableIsRollback(b *bool) *DeploymentUpdate { return du } +// SetCreatedAt sets the "created_at" field. +func (du *DeploymentUpdate) SetCreatedAt(t time.Time) *DeploymentUpdate { + du.mutation.SetCreatedAt(t) + return du +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (du *DeploymentUpdate) SetNillableCreatedAt(t *time.Time) *DeploymentUpdate { + if t != nil { + du.SetCreatedAt(*t) + } + return du +} + +// SetUpdatedAt sets the "updated_at" field. +func (du *DeploymentUpdate) SetUpdatedAt(t time.Time) *DeploymentUpdate { + du.mutation.SetUpdatedAt(t) + return du +} + +// SetUserID sets the "user_id" field. +func (du *DeploymentUpdate) SetUserID(i int64) *DeploymentUpdate { + du.mutation.SetUserID(i) + return du +} + +// SetRepoID sets the "repo_id" field. +func (du *DeploymentUpdate) SetRepoID(i int64) *DeploymentUpdate { + du.mutation.SetRepoID(i) + return du +} + // SetIsApprovalEnabled sets the "is_approval_enabled" field. func (du *DeploymentUpdate) SetIsApprovalEnabled(b bool) *DeploymentUpdate { du.mutation.SetIsApprovalEnabled(b) @@ -196,6 +228,12 @@ func (du *DeploymentUpdate) SetNillableIsApprovalEnabled(b *bool) *DeploymentUpd return du } +// ClearIsApprovalEnabled clears the value of the "is_approval_enabled" field. +func (du *DeploymentUpdate) ClearIsApprovalEnabled() *DeploymentUpdate { + du.mutation.ClearIsApprovalEnabled() + return du +} + // SetRequiredApprovalCount sets the "required_approval_count" field. func (du *DeploymentUpdate) SetRequiredApprovalCount(i int) *DeploymentUpdate { du.mutation.ResetRequiredApprovalCount() @@ -217,35 +255,9 @@ func (du *DeploymentUpdate) AddRequiredApprovalCount(i int) *DeploymentUpdate { return du } -// SetCreatedAt sets the "created_at" field. -func (du *DeploymentUpdate) SetCreatedAt(t time.Time) *DeploymentUpdate { - du.mutation.SetCreatedAt(t) - return du -} - -// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (du *DeploymentUpdate) SetNillableCreatedAt(t *time.Time) *DeploymentUpdate { - if t != nil { - du.SetCreatedAt(*t) - } - return du -} - -// SetUpdatedAt sets the "updated_at" field. -func (du *DeploymentUpdate) SetUpdatedAt(t time.Time) *DeploymentUpdate { - du.mutation.SetUpdatedAt(t) - return du -} - -// SetUserID sets the "user_id" field. -func (du *DeploymentUpdate) SetUserID(i int64) *DeploymentUpdate { - du.mutation.SetUserID(i) - return du -} - -// SetRepoID sets the "repo_id" field. -func (du *DeploymentUpdate) SetRepoID(i int64) *DeploymentUpdate { - du.mutation.SetRepoID(i) +// ClearRequiredApprovalCount clears the value of the "required_approval_count" field. +func (du *DeploymentUpdate) ClearRequiredApprovalCount() *DeploymentUpdate { + du.mutation.ClearRequiredApprovalCount() return du } @@ -635,6 +647,20 @@ func (du *DeploymentUpdate) sqlSave(ctx context.Context) (n int, err error) { Column: deployment.FieldIsRollback, }) } + if value, ok := du.mutation.CreatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: deployment.FieldCreatedAt, + }) + } + if value, ok := du.mutation.UpdatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: deployment.FieldUpdatedAt, + }) + } if value, ok := du.mutation.IsApprovalEnabled(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBool, @@ -642,6 +668,12 @@ func (du *DeploymentUpdate) sqlSave(ctx context.Context) (n int, err error) { Column: deployment.FieldIsApprovalEnabled, }) } + if du.mutation.IsApprovalEnabledCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeBool, + Column: deployment.FieldIsApprovalEnabled, + }) + } if value, ok := du.mutation.RequiredApprovalCount(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, @@ -656,18 +688,10 @@ func (du *DeploymentUpdate) sqlSave(ctx context.Context) (n int, err error) { Column: deployment.FieldRequiredApprovalCount, }) } - if value, ok := du.mutation.CreatedAt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: deployment.FieldCreatedAt, - }) - } - if value, ok := du.mutation.UpdatedAt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: deployment.FieldUpdatedAt, + if du.mutation.RequiredApprovalCountCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldRequiredApprovalCount, }) } if du.mutation.UserCleared() { @@ -1123,6 +1147,38 @@ func (duo *DeploymentUpdateOne) SetNillableIsRollback(b *bool) *DeploymentUpdate return duo } +// SetCreatedAt sets the "created_at" field. +func (duo *DeploymentUpdateOne) SetCreatedAt(t time.Time) *DeploymentUpdateOne { + duo.mutation.SetCreatedAt(t) + return duo +} + +// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. +func (duo *DeploymentUpdateOne) SetNillableCreatedAt(t *time.Time) *DeploymentUpdateOne { + if t != nil { + duo.SetCreatedAt(*t) + } + return duo +} + +// SetUpdatedAt sets the "updated_at" field. +func (duo *DeploymentUpdateOne) SetUpdatedAt(t time.Time) *DeploymentUpdateOne { + duo.mutation.SetUpdatedAt(t) + return duo +} + +// SetUserID sets the "user_id" field. +func (duo *DeploymentUpdateOne) SetUserID(i int64) *DeploymentUpdateOne { + duo.mutation.SetUserID(i) + return duo +} + +// SetRepoID sets the "repo_id" field. +func (duo *DeploymentUpdateOne) SetRepoID(i int64) *DeploymentUpdateOne { + duo.mutation.SetRepoID(i) + return duo +} + // SetIsApprovalEnabled sets the "is_approval_enabled" field. func (duo *DeploymentUpdateOne) SetIsApprovalEnabled(b bool) *DeploymentUpdateOne { duo.mutation.SetIsApprovalEnabled(b) @@ -1137,6 +1193,12 @@ func (duo *DeploymentUpdateOne) SetNillableIsApprovalEnabled(b *bool) *Deploymen return duo } +// ClearIsApprovalEnabled clears the value of the "is_approval_enabled" field. +func (duo *DeploymentUpdateOne) ClearIsApprovalEnabled() *DeploymentUpdateOne { + duo.mutation.ClearIsApprovalEnabled() + return duo +} + // SetRequiredApprovalCount sets the "required_approval_count" field. func (duo *DeploymentUpdateOne) SetRequiredApprovalCount(i int) *DeploymentUpdateOne { duo.mutation.ResetRequiredApprovalCount() @@ -1158,35 +1220,9 @@ func (duo *DeploymentUpdateOne) AddRequiredApprovalCount(i int) *DeploymentUpdat return duo } -// SetCreatedAt sets the "created_at" field. -func (duo *DeploymentUpdateOne) SetCreatedAt(t time.Time) *DeploymentUpdateOne { - duo.mutation.SetCreatedAt(t) - return duo -} - -// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (duo *DeploymentUpdateOne) SetNillableCreatedAt(t *time.Time) *DeploymentUpdateOne { - if t != nil { - duo.SetCreatedAt(*t) - } - return duo -} - -// SetUpdatedAt sets the "updated_at" field. -func (duo *DeploymentUpdateOne) SetUpdatedAt(t time.Time) *DeploymentUpdateOne { - duo.mutation.SetUpdatedAt(t) - return duo -} - -// SetUserID sets the "user_id" field. -func (duo *DeploymentUpdateOne) SetUserID(i int64) *DeploymentUpdateOne { - duo.mutation.SetUserID(i) - return duo -} - -// SetRepoID sets the "repo_id" field. -func (duo *DeploymentUpdateOne) SetRepoID(i int64) *DeploymentUpdateOne { - duo.mutation.SetRepoID(i) +// ClearRequiredApprovalCount clears the value of the "required_approval_count" field. +func (duo *DeploymentUpdateOne) ClearRequiredApprovalCount() *DeploymentUpdateOne { + duo.mutation.ClearRequiredApprovalCount() return duo } @@ -1600,6 +1636,20 @@ func (duo *DeploymentUpdateOne) sqlSave(ctx context.Context) (_node *Deployment, Column: deployment.FieldIsRollback, }) } + if value, ok := duo.mutation.CreatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: deployment.FieldCreatedAt, + }) + } + if value, ok := duo.mutation.UpdatedAt(); ok { + _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ + Type: field.TypeTime, + Value: value, + Column: deployment.FieldUpdatedAt, + }) + } if value, ok := duo.mutation.IsApprovalEnabled(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeBool, @@ -1607,6 +1657,12 @@ func (duo *DeploymentUpdateOne) sqlSave(ctx context.Context) (_node *Deployment, Column: deployment.FieldIsApprovalEnabled, }) } + if duo.mutation.IsApprovalEnabledCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeBool, + Column: deployment.FieldIsApprovalEnabled, + }) + } if value, ok := duo.mutation.RequiredApprovalCount(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeInt, @@ -1621,18 +1677,10 @@ func (duo *DeploymentUpdateOne) sqlSave(ctx context.Context) (_node *Deployment, Column: deployment.FieldRequiredApprovalCount, }) } - if value, ok := duo.mutation.CreatedAt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: deployment.FieldCreatedAt, - }) - } - if value, ok := duo.mutation.UpdatedAt(); ok { - _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ - Type: field.TypeTime, - Value: value, - Column: deployment.FieldUpdatedAt, + if duo.mutation.RequiredApprovalCountCleared() { + _spec.Fields.Clear = append(_spec.Fields.Clear, &sqlgraph.FieldSpec{ + Type: field.TypeInt, + Column: deployment.FieldRequiredApprovalCount, }) } if duo.mutation.UserCleared() { diff --git a/ent/migrate/schema.go b/ent/migrate/schema.go index 9f4a7784..611d7890 100644 --- a/ent/migrate/schema.go +++ b/ent/migrate/schema.go @@ -98,10 +98,10 @@ var ( {Name: "html_url", Type: field.TypeString, Nullable: true, Size: 2000}, {Name: "production_environment", Type: field.TypeBool, Default: false}, {Name: "is_rollback", Type: field.TypeBool, Default: false}, - {Name: "is_approval_enabled", Type: field.TypeBool, Default: false}, - {Name: "required_approval_count", Type: field.TypeInt, Default: 0}, {Name: "created_at", Type: field.TypeTime}, {Name: "updated_at", Type: field.TypeTime}, + {Name: "is_approval_enabled", Type: field.TypeBool, Nullable: true}, + {Name: "required_approval_count", Type: field.TypeInt, Nullable: true}, {Name: "repo_id", Type: field.TypeInt64, Nullable: true}, {Name: "user_id", Type: field.TypeInt64, Nullable: true}, } @@ -128,17 +128,17 @@ var ( { Name: "deployment_repo_id_env_status_updated_at", Unique: false, - Columns: []*schema.Column{DeploymentsColumns[15], DeploymentsColumns[3], DeploymentsColumns[5], DeploymentsColumns[14]}, + Columns: []*schema.Column{DeploymentsColumns[15], DeploymentsColumns[3], DeploymentsColumns[5], DeploymentsColumns[12]}, }, { Name: "deployment_repo_id_env_created_at", Unique: false, - Columns: []*schema.Column{DeploymentsColumns[15], DeploymentsColumns[3], DeploymentsColumns[13]}, + Columns: []*schema.Column{DeploymentsColumns[15], DeploymentsColumns[3], DeploymentsColumns[11]}, }, { Name: "deployment_repo_id_created_at", Unique: false, - Columns: []*schema.Column{DeploymentsColumns[15], DeploymentsColumns[13]}, + Columns: []*schema.Column{DeploymentsColumns[15], DeploymentsColumns[11]}, }, { Name: "deployment_number_repo_id", @@ -153,7 +153,7 @@ var ( { Name: "deployment_status_created_at", Unique: false, - Columns: []*schema.Column{DeploymentsColumns[5], DeploymentsColumns[13]}, + Columns: []*schema.Column{DeploymentsColumns[5], DeploymentsColumns[11]}, }, }, } diff --git a/ent/mutation.go b/ent/mutation.go index de2dc1eb..3e483d9c 100644 --- a/ent/mutation.go +++ b/ent/mutation.go @@ -2008,11 +2008,11 @@ type DeploymentMutation struct { html_url *string production_environment *bool is_rollback *bool + created_at *time.Time + updated_at *time.Time is_approval_enabled *bool required_approval_count *int addrequired_approval_count *int - created_at *time.Time - updated_at *time.Time clearedFields map[string]struct{} user *int64 cleareduser bool @@ -2554,98 +2554,6 @@ func (m *DeploymentMutation) ResetIsRollback() { m.is_rollback = nil } -// SetIsApprovalEnabled sets the "is_approval_enabled" field. -func (m *DeploymentMutation) SetIsApprovalEnabled(b bool) { - m.is_approval_enabled = &b -} - -// IsApprovalEnabled returns the value of the "is_approval_enabled" field in the mutation. -func (m *DeploymentMutation) IsApprovalEnabled() (r bool, exists bool) { - v := m.is_approval_enabled - if v == nil { - return - } - return *v, true -} - -// OldIsApprovalEnabled returns the old "is_approval_enabled" field's value of the Deployment entity. -// If the Deployment 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 *DeploymentMutation) OldIsApprovalEnabled(ctx context.Context) (v bool, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldIsApprovalEnabled is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldIsApprovalEnabled requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldIsApprovalEnabled: %w", err) - } - return oldValue.IsApprovalEnabled, nil -} - -// ResetIsApprovalEnabled resets all changes to the "is_approval_enabled" field. -func (m *DeploymentMutation) ResetIsApprovalEnabled() { - m.is_approval_enabled = nil -} - -// SetRequiredApprovalCount sets the "required_approval_count" field. -func (m *DeploymentMutation) SetRequiredApprovalCount(i int) { - m.required_approval_count = &i - m.addrequired_approval_count = nil -} - -// RequiredApprovalCount returns the value of the "required_approval_count" field in the mutation. -func (m *DeploymentMutation) RequiredApprovalCount() (r int, exists bool) { - v := m.required_approval_count - if v == nil { - return - } - return *v, true -} - -// OldRequiredApprovalCount returns the old "required_approval_count" field's value of the Deployment entity. -// If the Deployment 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 *DeploymentMutation) OldRequiredApprovalCount(ctx context.Context) (v int, err error) { - if !m.op.Is(OpUpdateOne) { - return v, fmt.Errorf("OldRequiredApprovalCount is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, fmt.Errorf("OldRequiredApprovalCount requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldRequiredApprovalCount: %w", err) - } - return oldValue.RequiredApprovalCount, nil -} - -// AddRequiredApprovalCount adds i to the "required_approval_count" field. -func (m *DeploymentMutation) AddRequiredApprovalCount(i int) { - if m.addrequired_approval_count != nil { - *m.addrequired_approval_count += i - } else { - m.addrequired_approval_count = &i - } -} - -// AddedRequiredApprovalCount returns the value that was added to the "required_approval_count" field in this mutation. -func (m *DeploymentMutation) AddedRequiredApprovalCount() (r int, exists bool) { - v := m.addrequired_approval_count - if v == nil { - return - } - return *v, true -} - -// ResetRequiredApprovalCount resets all changes to the "required_approval_count" field. -func (m *DeploymentMutation) ResetRequiredApprovalCount() { - m.required_approval_count = nil - m.addrequired_approval_count = nil -} - // SetCreatedAt sets the "created_at" field. func (m *DeploymentMutation) SetCreatedAt(t time.Time) { m.created_at = &t @@ -2790,6 +2698,125 @@ func (m *DeploymentMutation) ResetRepoID() { m.repo = nil } +// SetIsApprovalEnabled sets the "is_approval_enabled" field. +func (m *DeploymentMutation) SetIsApprovalEnabled(b bool) { + m.is_approval_enabled = &b +} + +// IsApprovalEnabled returns the value of the "is_approval_enabled" field in the mutation. +func (m *DeploymentMutation) IsApprovalEnabled() (r bool, exists bool) { + v := m.is_approval_enabled + if v == nil { + return + } + return *v, true +} + +// OldIsApprovalEnabled returns the old "is_approval_enabled" field's value of the Deployment entity. +// If the Deployment 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 *DeploymentMutation) OldIsApprovalEnabled(ctx context.Context) (v *bool, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldIsApprovalEnabled is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldIsApprovalEnabled requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldIsApprovalEnabled: %w", err) + } + return oldValue.IsApprovalEnabled, nil +} + +// ClearIsApprovalEnabled clears the value of the "is_approval_enabled" field. +func (m *DeploymentMutation) ClearIsApprovalEnabled() { + m.is_approval_enabled = nil + m.clearedFields[deployment.FieldIsApprovalEnabled] = struct{}{} +} + +// IsApprovalEnabledCleared returns if the "is_approval_enabled" field was cleared in this mutation. +func (m *DeploymentMutation) IsApprovalEnabledCleared() bool { + _, ok := m.clearedFields[deployment.FieldIsApprovalEnabled] + return ok +} + +// ResetIsApprovalEnabled resets all changes to the "is_approval_enabled" field. +func (m *DeploymentMutation) ResetIsApprovalEnabled() { + m.is_approval_enabled = nil + delete(m.clearedFields, deployment.FieldIsApprovalEnabled) +} + +// SetRequiredApprovalCount sets the "required_approval_count" field. +func (m *DeploymentMutation) SetRequiredApprovalCount(i int) { + m.required_approval_count = &i + m.addrequired_approval_count = nil +} + +// RequiredApprovalCount returns the value of the "required_approval_count" field in the mutation. +func (m *DeploymentMutation) RequiredApprovalCount() (r int, exists bool) { + v := m.required_approval_count + if v == nil { + return + } + return *v, true +} + +// OldRequiredApprovalCount returns the old "required_approval_count" field's value of the Deployment entity. +// If the Deployment 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 *DeploymentMutation) OldRequiredApprovalCount(ctx context.Context) (v *int, err error) { + if !m.op.Is(OpUpdateOne) { + return v, fmt.Errorf("OldRequiredApprovalCount is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, fmt.Errorf("OldRequiredApprovalCount requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldRequiredApprovalCount: %w", err) + } + return oldValue.RequiredApprovalCount, nil +} + +// AddRequiredApprovalCount adds i to the "required_approval_count" field. +func (m *DeploymentMutation) AddRequiredApprovalCount(i int) { + if m.addrequired_approval_count != nil { + *m.addrequired_approval_count += i + } else { + m.addrequired_approval_count = &i + } +} + +// AddedRequiredApprovalCount returns the value that was added to the "required_approval_count" field in this mutation. +func (m *DeploymentMutation) AddedRequiredApprovalCount() (r int, exists bool) { + v := m.addrequired_approval_count + if v == nil { + return + } + return *v, true +} + +// ClearRequiredApprovalCount clears the value of the "required_approval_count" field. +func (m *DeploymentMutation) ClearRequiredApprovalCount() { + m.required_approval_count = nil + m.addrequired_approval_count = nil + m.clearedFields[deployment.FieldRequiredApprovalCount] = struct{}{} +} + +// RequiredApprovalCountCleared returns if the "required_approval_count" field was cleared in this mutation. +func (m *DeploymentMutation) RequiredApprovalCountCleared() bool { + _, ok := m.clearedFields[deployment.FieldRequiredApprovalCount] + return ok +} + +// ResetRequiredApprovalCount resets all changes to the "required_approval_count" field. +func (m *DeploymentMutation) ResetRequiredApprovalCount() { + m.required_approval_count = nil + m.addrequired_approval_count = nil + delete(m.clearedFields, deployment.FieldRequiredApprovalCount) +} + // ClearUser clears the "user" edge to the User entity. func (m *DeploymentMutation) ClearUser() { m.cleareduser = true @@ -3108,12 +3135,6 @@ func (m *DeploymentMutation) Fields() []string { if m.is_rollback != nil { fields = append(fields, deployment.FieldIsRollback) } - if m.is_approval_enabled != nil { - fields = append(fields, deployment.FieldIsApprovalEnabled) - } - if m.required_approval_count != nil { - fields = append(fields, deployment.FieldRequiredApprovalCount) - } if m.created_at != nil { fields = append(fields, deployment.FieldCreatedAt) } @@ -3126,6 +3147,12 @@ func (m *DeploymentMutation) Fields() []string { if m.repo != nil { fields = append(fields, deployment.FieldRepoID) } + if m.is_approval_enabled != nil { + fields = append(fields, deployment.FieldIsApprovalEnabled) + } + if m.required_approval_count != nil { + fields = append(fields, deployment.FieldRequiredApprovalCount) + } return fields } @@ -3154,10 +3181,6 @@ func (m *DeploymentMutation) Field(name string) (ent.Value, bool) { return m.ProductionEnvironment() case deployment.FieldIsRollback: return m.IsRollback() - case deployment.FieldIsApprovalEnabled: - return m.IsApprovalEnabled() - case deployment.FieldRequiredApprovalCount: - return m.RequiredApprovalCount() case deployment.FieldCreatedAt: return m.CreatedAt() case deployment.FieldUpdatedAt: @@ -3166,6 +3189,10 @@ func (m *DeploymentMutation) Field(name string) (ent.Value, bool) { return m.UserID() case deployment.FieldRepoID: return m.RepoID() + case deployment.FieldIsApprovalEnabled: + return m.IsApprovalEnabled() + case deployment.FieldRequiredApprovalCount: + return m.RequiredApprovalCount() } return nil, false } @@ -3195,10 +3222,6 @@ func (m *DeploymentMutation) OldField(ctx context.Context, name string) (ent.Val return m.OldProductionEnvironment(ctx) case deployment.FieldIsRollback: return m.OldIsRollback(ctx) - case deployment.FieldIsApprovalEnabled: - return m.OldIsApprovalEnabled(ctx) - case deployment.FieldRequiredApprovalCount: - return m.OldRequiredApprovalCount(ctx) case deployment.FieldCreatedAt: return m.OldCreatedAt(ctx) case deployment.FieldUpdatedAt: @@ -3207,6 +3230,10 @@ func (m *DeploymentMutation) OldField(ctx context.Context, name string) (ent.Val return m.OldUserID(ctx) case deployment.FieldRepoID: return m.OldRepoID(ctx) + case deployment.FieldIsApprovalEnabled: + return m.OldIsApprovalEnabled(ctx) + case deployment.FieldRequiredApprovalCount: + return m.OldRequiredApprovalCount(ctx) } return nil, fmt.Errorf("unknown Deployment field %s", name) } @@ -3286,20 +3313,6 @@ func (m *DeploymentMutation) SetField(name string, value ent.Value) error { } m.SetIsRollback(v) return nil - case deployment.FieldIsApprovalEnabled: - v, ok := value.(bool) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetIsApprovalEnabled(v) - return nil - case deployment.FieldRequiredApprovalCount: - v, ok := value.(int) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetRequiredApprovalCount(v) - return nil case deployment.FieldCreatedAt: v, ok := value.(time.Time) if !ok { @@ -3328,6 +3341,20 @@ func (m *DeploymentMutation) SetField(name string, value ent.Value) error { } m.SetRepoID(v) return nil + case deployment.FieldIsApprovalEnabled: + v, ok := value.(bool) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetIsApprovalEnabled(v) + return nil + case deployment.FieldRequiredApprovalCount: + v, ok := value.(int) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetRequiredApprovalCount(v) + return nil } return fmt.Errorf("unknown Deployment field %s", name) } @@ -3406,6 +3433,12 @@ func (m *DeploymentMutation) ClearedFields() []string { if m.FieldCleared(deployment.FieldHTMLURL) { fields = append(fields, deployment.FieldHTMLURL) } + if m.FieldCleared(deployment.FieldIsApprovalEnabled) { + fields = append(fields, deployment.FieldIsApprovalEnabled) + } + if m.FieldCleared(deployment.FieldRequiredApprovalCount) { + fields = append(fields, deployment.FieldRequiredApprovalCount) + } return fields } @@ -3429,6 +3462,12 @@ func (m *DeploymentMutation) ClearField(name string) error { case deployment.FieldHTMLURL: m.ClearHTMLURL() return nil + case deployment.FieldIsApprovalEnabled: + m.ClearIsApprovalEnabled() + return nil + case deployment.FieldRequiredApprovalCount: + m.ClearRequiredApprovalCount() + return nil } return fmt.Errorf("unknown Deployment nullable field %s", name) } @@ -3467,12 +3506,6 @@ func (m *DeploymentMutation) ResetField(name string) error { case deployment.FieldIsRollback: m.ResetIsRollback() return nil - case deployment.FieldIsApprovalEnabled: - m.ResetIsApprovalEnabled() - return nil - case deployment.FieldRequiredApprovalCount: - m.ResetRequiredApprovalCount() - return nil case deployment.FieldCreatedAt: m.ResetCreatedAt() return nil @@ -3485,6 +3518,12 @@ func (m *DeploymentMutation) ResetField(name string) error { case deployment.FieldRepoID: m.ResetRepoID() return nil + case deployment.FieldIsApprovalEnabled: + m.ResetIsApprovalEnabled() + return nil + case deployment.FieldRequiredApprovalCount: + m.ResetRequiredApprovalCount() + return nil } return fmt.Errorf("unknown Deployment field %s", name) } diff --git a/ent/runtime.go b/ent/runtime.go index 916186a6..be36c3af 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -78,20 +78,12 @@ func init() { deploymentDescIsRollback := deploymentFields[9].Descriptor() // deployment.DefaultIsRollback holds the default value on creation for the is_rollback field. deployment.DefaultIsRollback = deploymentDescIsRollback.Default.(bool) - // deploymentDescIsApprovalEnabled is the schema descriptor for is_approval_enabled field. - deploymentDescIsApprovalEnabled := deploymentFields[10].Descriptor() - // deployment.DefaultIsApprovalEnabled holds the default value on creation for the is_approval_enabled field. - deployment.DefaultIsApprovalEnabled = deploymentDescIsApprovalEnabled.Default.(bool) - // deploymentDescRequiredApprovalCount is the schema descriptor for required_approval_count field. - deploymentDescRequiredApprovalCount := deploymentFields[11].Descriptor() - // deployment.DefaultRequiredApprovalCount holds the default value on creation for the required_approval_count field. - deployment.DefaultRequiredApprovalCount = deploymentDescRequiredApprovalCount.Default.(int) // deploymentDescCreatedAt is the schema descriptor for created_at field. - deploymentDescCreatedAt := deploymentFields[12].Descriptor() + deploymentDescCreatedAt := deploymentFields[10].Descriptor() // deployment.DefaultCreatedAt holds the default value on creation for the created_at field. deployment.DefaultCreatedAt = deploymentDescCreatedAt.Default.(func() time.Time) // deploymentDescUpdatedAt is the schema descriptor for updated_at field. - deploymentDescUpdatedAt := deploymentFields[13].Descriptor() + deploymentDescUpdatedAt := deploymentFields[11].Descriptor() // deployment.DefaultUpdatedAt holds the default value on creation for the updated_at field. deployment.DefaultUpdatedAt = deploymentDescUpdatedAt.Default.(func() time.Time) // deployment.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. diff --git a/ent/schema/deployment.go b/ent/schema/deployment.go index 18be0ecb..2b035cce 100644 --- a/ent/schema/deployment.go +++ b/ent/schema/deployment.go @@ -49,10 +49,6 @@ func (Deployment) Fields() []ent.Field { Default(false), field.Bool("is_rollback"). Default(false), - field.Bool("is_approval_enabled"). - Default(false), - field.Int("required_approval_count"). - Default(0), field.Time("created_at"). Default(nowUTC), field.Time("updated_at"). @@ -61,6 +57,14 @@ func (Deployment) Fields() []ent.Field { // Edges field.Int64("user_id"), field.Int64("repo_id"), + + // Deprecated fields. + field.Bool("is_approval_enabled"). + Optional(). + Nillable(), + field.Int("required_approval_count"). + Optional(). + Nillable(), } } From df18de79602acd0ab02000e6b7c9b3ce77758e51 Mon Sep 17 00:00:00 2001 From: noah Date: Mon, 1 Nov 2021 22:12:55 +0900 Subject: [PATCH 04/13] Fix to request reviews when it deploys --- internal/interactor/deployment.go | 45 ++++--- internal/interactor/deployment_test.go | 150 +++++++++------------ internal/interactor/interface.go | 1 + internal/interactor/mock/pkg.go | 15 +++ internal/interactor/review.go | 34 +++++ internal/pkg/store/deployment.go | 4 - internal/pkg/store/review.go | 19 +++ internal/server/api/v1/repos/deployment.go | 1 + pkg/e/code.go | 2 +- pkg/e/trans.go | 4 +- vo/config.go | 13 ++ 11 files changed, 181 insertions(+), 107 deletions(-) create mode 100644 internal/interactor/review.go diff --git a/internal/interactor/deployment.go b/internal/interactor/deployment.go index 56a6207b..c79a2e43 100644 --- a/internal/interactor/deployment.go +++ b/internal/interactor/deployment.go @@ -7,8 +7,8 @@ import ( "github.com/AlekSi/pointer" "github.com/gitploy-io/gitploy/ent" - "github.com/gitploy-io/gitploy/ent/approval" "github.com/gitploy-io/gitploy/ent/deployment" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/pkg/e" "github.com/gitploy-io/gitploy/vo" "go.uber.org/zap" @@ -34,7 +34,7 @@ func (i *Interactor) Deploy(ctx context.Context, u *ent.User, r *ent.Repo, d *en ) } - if env.IsApprovalEabled() { + if env.HasReview() { d := &ent.Deployment{ Number: number, Type: d.Type, @@ -43,14 +43,24 @@ func (i *Interactor) Deploy(ctx context.Context, u *ent.User, r *ent.Repo, d *en Status: deployment.StatusWaiting, ProductionEnvironment: env.IsProductionEnvironment(), IsRollback: d.IsRollback, - IsApprovalEnabled: true, - RequiredApprovalCount: env.Approval.RequiredCount, UserID: u.ID, RepoID: r.ID, } - i.log.Debug("Save a new deployment to wait approvals.", zap.Any("deployment", d)) - return i.Store.CreateDeployment(ctx, d) + i.log.Debug("Save the deployment to wait reviews.") + d, err = i.Store.CreateDeployment(ctx, d) + if err != nil { + return nil, err + } + + for _, rvr := range env.Review.Reviewers { + i.log.Debug(fmt.Sprintf("Request a review to %s.", rvr)) + if _, err := i.requestReviewByLogin(ctx, d, rvr); err != nil { + i.log.Error("Failed to request the review.", zap.Error(err)) + } + } + + return d, nil } i.log.Debug("Create a new remote deployment.") @@ -70,8 +80,6 @@ func (i *Interactor) Deploy(ctx context.Context, u *ent.User, r *ent.Repo, d *en HTMLURL: rd.HTLMURL, ProductionEnvironment: env.IsProductionEnvironment(), IsRollback: d.IsRollback, - IsApprovalEnabled: false, - RequiredApprovalCount: 0, UserID: u.ID, RepoID: r.ID, } @@ -92,16 +100,21 @@ func (i *Interactor) Deploy(ctx context.Context, u *ent.User, r *ent.Repo, d *en } func (i *Interactor) IsApproved(ctx context.Context, d *ent.Deployment) bool { - as, _ := i.ListApprovals(ctx, d) + rvs, _ := i.ListReviews(ctx, d) + + for _, r := range rvs { + if r.Status == review.StatusRejected { + return false + } + } - approved := 0 - for _, a := range as { - if a.Status == approval.StatusApproved { - approved = approved + 1 + for _, r := range rvs { + if r.Status == review.StatusApproved { + return true } } - return approved >= d.RequiredApprovalCount + return false } // DeployToRemote create a new remote deployment after the deployment was approved. @@ -115,9 +128,9 @@ func (i *Interactor) DeployToRemote(ctx context.Context, u *ent.User, r *ent.Rep return nil, err } - if d.IsApprovalEnabled && !i.IsApproved(ctx, d) { + if !i.IsApproved(ctx, d) { return nil, e.NewError( - e.ErrorCodeDeploymentUnapproved, + e.ErrorCodeDeploymentNotApproved, nil, ) } diff --git a/internal/interactor/deployment_test.go b/internal/interactor/deployment_test.go index e3e139d1..d194fbcd 100644 --- a/internal/interactor/deployment_test.go +++ b/internal/interactor/deployment_test.go @@ -7,6 +7,7 @@ import ( "github.com/gitploy-io/gitploy/ent" "github.com/gitploy-io/gitploy/ent/deployment" + "github.com/gitploy-io/gitploy/ent/review" "github.com/gitploy-io/gitploy/internal/interactor/mock" "github.com/gitploy-io/gitploy/vo" "github.com/golang/mock/gomock" @@ -24,23 +25,15 @@ func newMockInteractor(store Store, scm SCM) *Interactor { func TestInteractor_Deploy(t *testing.T) { ctx := gomock.Any() - t.Run("create a new deployment.", func(t *testing.T) { + t.Run("Return a new deployment.", func(t *testing.T) { input := struct { - u *ent.User - r *ent.Repo d *ent.Deployment e *vo.Env }{ - u: &ent.User{ - ID: 1, - }, - r: &ent.Repo{ - ID: 1, - }, d: &ent.Deployment{ - Type: deployment.TypeCommit, - Ref: "3ee3221", - Env: "local", + Type: deployment.TypeBranch, + Ref: "main", + Env: "production", }, e: &vo.Env{}, } @@ -50,45 +43,39 @@ func TestInteractor_Deploy(t *testing.T) { scm := mock.NewMockSCM(ctrl) const ( - ID = 1 UID = 1000 ) - t.Log("MOCK - Check the environment is locked.") store. EXPECT(). - HasLockOfRepoForEnv(ctx, gomock.Eq(input.r), gomock.Eq(input.d.Env)). + HasLockOfRepoForEnv(ctx, gomock.AssignableToTypeOf(&ent.Repo{}), gomock.AssignableToTypeOf("")). Return(false, nil) - t.Log("MOCK - Get the next deployment number.") store. EXPECT(). - GetNextDeploymentNumberOfRepo(ctx, gomock.Eq(input.r)). + GetNextDeploymentNumberOfRepo(ctx, gomock.AssignableToTypeOf(&ent.Repo{})). Return(1, nil) - t.Logf("Returns a new remote deployment with UID = %d", UID) scm. EXPECT(). - CreateRemoteDeployment(ctx, gomock.Eq(input.u), gomock.Eq(input.r), gomock.Eq(input.d), gomock.Eq(input.e)). + CreateRemoteDeployment(ctx, gomock.Eq(&ent.User{}), gomock.Eq(&ent.Repo{}), gomock.AssignableToTypeOf(&ent.Deployment{}), gomock.Eq(&vo.Env{})). Return(&vo.RemoteDeployment{ UID: UID, }, nil) - t.Logf("Check the deployment input has UID") + t.Logf("MOCK - compare the deployment parameter.") store. EXPECT(). CreateDeployment(ctx, gomock.Eq(&ent.Deployment{ - Number: 1, + Number: 1, // The next deployment number. Type: input.d.Type, Ref: input.d.Ref, Env: input.d.Env, UID: UID, Status: deployment.StatusCreated, - UserID: input.u.ID, - RepoID: input.r.ID, })). DoAndReturn(func(ctx context.Context, d *ent.Deployment) (interface{}, interface{}) { - d.ID = ID + d.ID = 1 return d, nil }) @@ -98,52 +85,46 @@ func TestInteractor_Deploy(t *testing.T) { i := newMockInteractor(store, scm) - d, err := i.Deploy(context.Background(), input.u, input.r, input.d, input.e) + d, err := i.Deploy(context.Background(), &ent.User{}, &ent.Repo{}, input.d, input.e) if err != nil { t.Errorf("Deploy returns a error: %s", err) t.FailNow() } expected := &ent.Deployment{ - ID: ID, + ID: 1, Number: 1, Type: input.d.Type, Ref: input.d.Ref, Env: input.d.Env, UID: UID, Status: deployment.StatusCreated, - UserID: input.u.ID, - RepoID: input.r.ID, } if !reflect.DeepEqual(d, expected) { t.Errorf("Deploy = %v, wanted %v", d, expected) } }) - t.Run("create a new deployment with the approval configuration.", func(t *testing.T) { + t.Run("Return the waiting deployment and reviews.", func(t *testing.T) { input := struct { - u *ent.User - r *ent.Repo d *ent.Deployment e *vo.Env }{ - u: &ent.User{ - ID: 1, - }, - r: &ent.Repo{ - ID: 1, - }, d: &ent.Deployment{ Number: 3, - Type: deployment.TypeCommit, - Ref: "3ee3221", - Env: "local", + Type: deployment.TypeBranch, + Ref: "main", + Env: "production", }, e: &vo.Env{ Approval: &vo.Approval{ Enabled: true, RequiredCount: 1, }, + Review: &vo.Review{ + Enabled: true, + Reviewers: []string{"octocat"}, + }, }, } @@ -151,60 +132,61 @@ func TestInteractor_Deploy(t *testing.T) { store := mock.NewMockStore(ctrl) scm := mock.NewMockSCM(ctrl) - const ( - ID = 1 - ) - - t.Log("MOCK - Check the environment is locked.") store. EXPECT(). - HasLockOfRepoForEnv(ctx, gomock.Eq(input.r), gomock.Eq(input.d.Env)). + HasLockOfRepoForEnv(ctx, gomock.AssignableToTypeOf(&ent.Repo{}), gomock.AssignableToTypeOf("")). Return(false, nil) - t.Log("MOCK - Get the next deployment number.") store. EXPECT(). - GetNextDeploymentNumberOfRepo(ctx, gomock.Eq(input.r)). + GetNextDeploymentNumberOfRepo(ctx, gomock.AssignableToTypeOf(&ent.Repo{})). Return(1, nil) - t.Logf("Check the deployment has configurations of approval.") + t.Logf("MOCK - compare the deployment parameter.") store. EXPECT(). CreateDeployment(ctx, gomock.Eq(&ent.Deployment{ - Number: 1, - Type: input.d.Type, - Ref: input.d.Ref, - Env: input.d.Env, - IsApprovalEnabled: true, - RequiredApprovalCount: input.e.Approval.RequiredCount, - Status: deployment.StatusWaiting, - UserID: input.u.ID, - RepoID: input.r.ID, + Number: 1, + Type: input.d.Type, + Ref: input.d.Ref, + Env: input.d.Env, + Status: deployment.StatusWaiting, })). DoAndReturn(func(ctx context.Context, d *ent.Deployment) (interface{}, interface{}) { - d.ID = ID + d.ID = 1 return d, nil }) + store. + EXPECT(). + FindUserByLogin(ctx, gomock.AssignableToTypeOf("")). + Return(&ent.User{}, nil) + + store. + EXPECT(). + CreateReview(ctx, gomock.AssignableToTypeOf(&ent.Review{})). + Return(&ent.Review{}, nil) + + store. + EXPECT(). + CreateEvent(ctx, gomock.AssignableToTypeOf(&ent.Event{})). + Return(&ent.Event{}, nil) + i := newMockInteractor(store, scm) - d, err := i.Deploy(context.Background(), input.u, input.r, input.d, input.e) + d, err := i.Deploy(context.Background(), &ent.User{}, &ent.Repo{}, input.d, input.e) if err != nil { t.Errorf("Deploy returns a error: %s", err) t.FailNow() } expected := &ent.Deployment{ - ID: ID, - Number: 1, - Type: input.d.Type, - Ref: input.d.Ref, - Env: input.d.Env, - IsApprovalEnabled: true, - RequiredApprovalCount: input.e.Approval.RequiredCount, - Status: deployment.StatusWaiting, - UserID: input.u.ID, - RepoID: input.r.ID, + ID: 1, + Number: 1, + Type: input.d.Type, + Ref: input.d.Ref, + Env: input.d.Env, + Status: deployment.StatusWaiting, } if !reflect.DeepEqual(d, expected) { t.Errorf("Deploy = %v, wanted %v", d, expected) @@ -217,16 +199,10 @@ func TestInteractor_DeployToRemote(t *testing.T) { t.Run("create a new remote deployment and update the deployment.", func(t *testing.T) { input := struct { - u *ent.User - r *ent.Repo d *ent.Deployment e *vo.Env }{ - u: &ent.User{}, - r: &ent.Repo{}, - d: &ent.Deployment{ - ID: 1, - }, + d: &ent.Deployment{}, e: &vo.Env{}, } @@ -238,26 +214,32 @@ func TestInteractor_DeployToRemote(t *testing.T) { UID = 1000 ) - t.Log("MOCK - Check the environment is locked.") store. EXPECT(). HasLockOfRepoForEnv(ctx, gomock.AssignableToTypeOf(&ent.Repo{}), gomock.AssignableToTypeOf("")). Return(false, nil) - t.Logf("MOCK - Returns a new remote deployment with UID = %d", UID) + // Return a approved review. + store. + EXPECT(). + ListReviews(ctx, gomock.AssignableToTypeOf(&ent.Deployment{})). + Return([]*ent.Review{ + { + Status: review.StatusApproved, + }, + }, nil) + scm. EXPECT(). - CreateRemoteDeployment(ctx, gomock.Eq(input.u), gomock.Eq(input.r), gomock.Eq(input.d), gomock.Eq(input.e)). + CreateRemoteDeployment(ctx, gomock.AssignableToTypeOf(&ent.User{}), gomock.AssignableToTypeOf(&ent.Repo{}), gomock.AssignableToTypeOf(&ent.Deployment{}), gomock.AssignableToTypeOf(&vo.Env{})). Return(&vo.RemoteDeployment{ UID: UID, }, nil) - t.Logf("MOCK - Check the deployment input has UID") + t.Log("MOCK - Compare the deployment parameter.") store. EXPECT(). UpdateDeployment(ctx, gomock.Eq(&ent.Deployment{ - ID: input.d.ID, - Env: input.d.Env, UID: UID, Status: deployment.StatusCreated, })). @@ -271,7 +253,7 @@ func TestInteractor_DeployToRemote(t *testing.T) { i := newMockInteractor(store, scm) - d, err := i.DeployToRemote(context.Background(), input.u, input.r, input.d, input.e) + d, err := i.DeployToRemote(context.Background(), &ent.User{}, &ent.Repo{}, input.d, input.e) if err != nil { t.Errorf("CreateRemoteDeployment returns a error: %s", err) t.FailNow() diff --git a/internal/interactor/interface.go b/internal/interactor/interface.go index 9c4d6eab..ae9d7da7 100644 --- a/internal/interactor/interface.go +++ b/internal/interactor/interface.go @@ -80,6 +80,7 @@ type ( ListReviews(ctx context.Context, d *ent.Deployment) ([]*ent.Review, error) FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deployment) (*ent.Review, error) + CreateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) ListExpiredLocksLessThanTime(ctx context.Context, t time.Time) ([]*ent.Lock, error) diff --git a/internal/interactor/mock/pkg.go b/internal/interactor/mock/pkg.go index 6c6b896b..59bbcec9 100644 --- a/internal/interactor/mock/pkg.go +++ b/internal/interactor/mock/pkg.go @@ -263,6 +263,21 @@ func (mr *MockStoreMockRecorder) CreatePerm(ctx, p interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatePerm", reflect.TypeOf((*MockStore)(nil).CreatePerm), ctx, p) } +// CreateReview mocks base method. +func (m *MockStore) CreateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateReview", ctx, rv) + ret0, _ := ret[0].(*ent.Review) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateReview indicates an expected call of CreateReview. +func (mr *MockStoreMockRecorder) CreateReview(ctx, rv interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateReview", reflect.TypeOf((*MockStore)(nil).CreateReview), ctx, rv) +} + // CreateUser mocks base method. func (m *MockStore) CreateUser(ctx context.Context, u *ent.User) (*ent.User, error) { m.ctrl.T.Helper() diff --git a/internal/interactor/review.go b/internal/interactor/review.go new file mode 100644 index 00000000..2a85f644 --- /dev/null +++ b/internal/interactor/review.go @@ -0,0 +1,34 @@ +package interactor + +import ( + "context" + + "github.com/gitploy-io/gitploy/ent" + "github.com/gitploy-io/gitploy/ent/event" + "go.uber.org/zap" +) + +func (i *Interactor) requestReviewByLogin(ctx context.Context, d *ent.Deployment, login string) (*ent.Review, error) { + u, err := i.Store.FindUserByLogin(ctx, login) + if err != nil { + return nil, err + } + + rv, err := i.Store.CreateReview(ctx, &ent.Review{ + DeploymentID: d.ID, + UserID: u.ID, + }) + if err != nil { + return nil, err + } + + if _, err := i.Store.CreateEvent(ctx, &ent.Event{ + Kind: event.KindReview, + Type: event.TypeCreated, + ReviewID: rv.ID, + }); err != nil { + i.log.Error("Failed to create the event.", zap.Error(err)) + } + + return rv, nil +} diff --git a/internal/pkg/store/deployment.go b/internal/pkg/store/deployment.go index 20244dec..4c03ed08 100644 --- a/internal/pkg/store/deployment.go +++ b/internal/pkg/store/deployment.go @@ -244,8 +244,6 @@ func (s *Store) CreateDeployment(ctx context.Context, d *ent.Deployment) (*ent.D SetHTMLURL(d.HTMLURL). SetProductionEnvironment(d.ProductionEnvironment). SetIsRollback(d.IsRollback). - SetIsApprovalEnabled(d.IsApprovalEnabled). - SetRequiredApprovalCount(d.RequiredApprovalCount). SetStatus(d.Status). SetUserID(d.UserID). SetRepoID(d.RepoID). @@ -279,8 +277,6 @@ func (s *Store) UpdateDeployment(ctx context.Context, d *ent.Deployment) (*ent.D SetSha(d.Sha). SetHTMLURL(d.HTMLURL). SetIsRollback(d.IsRollback). - SetIsApprovalEnabled(d.IsApprovalEnabled). - SetRequiredApprovalCount(d.RequiredApprovalCount). SetStatus(d.Status). Save(ctx) if ent.IsValidationError(err) { diff --git a/internal/pkg/store/review.go b/internal/pkg/store/review.go index 3027b5c5..3335b55f 100644 --- a/internal/pkg/store/review.go +++ b/internal/pkg/store/review.go @@ -62,6 +62,25 @@ func (s *Store) FindReviewOfUser(ctx context.Context, u *ent.User, d *ent.Deploy return rv, nil } +func (s *Store) CreateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) { + rv, err := s.c.Review. + Create(). + SetDeploymentID(rv.DeploymentID). + SetUserID(rv.UserID). + Save(ctx) + if ent.IsValidationError(err) { + return nil, e.NewErrorWithMessage( + e.ErrorCodeUnprocessableEntity, + fmt.Sprintf("Failed to create a review. The value of \"%s\" field is invalid.", err.(*ent.ValidationError).Name), + err, + ) + } else if err != nil { + return nil, e.NewError(e.ErrorCodeInternalError, err) + } + + return s.FindReviewByID(ctx, rv.ID) +} + func (s *Store) UpdateReview(ctx context.Context, rv *ent.Review) (*ent.Review, error) { rv, err := s.c.Review. UpdateOne(rv). diff --git a/internal/server/api/v1/repos/deployment.go b/internal/server/api/v1/repos/deployment.go index 9696fc29..901634e9 100644 --- a/internal/server/api/v1/repos/deployment.go +++ b/internal/server/api/v1/repos/deployment.go @@ -131,6 +131,7 @@ func (r *Repo) CreateDeployment(c *gin.Context) { return } + // TODO: Migrate the event logic into the interactor. if _, err := r.i.CreateEvent(ctx, &ent.Event{ Kind: event.KindDeployment, Type: event.TypeCreated, diff --git a/pkg/e/code.go b/pkg/e/code.go index f96a4795..419b9217 100644 --- a/pkg/e/code.go +++ b/pkg/e/code.go @@ -16,7 +16,7 @@ const ( // ErrorCodeDeploymentLocked is when the environment is locked. ErrorCodeDeploymentLocked ErrorCode = "deployment_locked" // ErrorCodeDeploymentUnapproved is when the deployment is not approved. - ErrorCodeDeploymentUnapproved ErrorCode = "deployment_unapproved" + ErrorCodeDeploymentNotApproved ErrorCode = "deployment_not_approved" // ErrorCodeDeploymentUndeployable is that the merge conflict occurs or a commit status has failed. ErrorCodeDeploymentUndeployable ErrorCode = "deployment_undeployable" diff --git a/pkg/e/trans.go b/pkg/e/trans.go index d1b42a85..411f6f47 100644 --- a/pkg/e/trans.go +++ b/pkg/e/trans.go @@ -7,7 +7,7 @@ var messages = map[ErrorCode]string{ ErrorCodeDeploymentConflict: "The conflict occurs, please retry.", ErrorCodeDeploymentInvalid: "The validation has failed.", ErrorCodeDeploymentLocked: "The environment is locked.", - ErrorCodeDeploymentUnapproved: "The deployment is not approved", + ErrorCodeDeploymentNotApproved: "The deployment is not approved", ErrorCodeDeploymentUndeployable: "There is merge conflict or a commit status check failed.", ErrorCodeLicenseDecode: "Decoding the license is failed.", ErrorCodeLicenseRequired: "The license is required.", @@ -32,7 +32,7 @@ var httpCodes = map[ErrorCode]int{ ErrorCodeDeploymentConflict: http.StatusUnprocessableEntity, ErrorCodeDeploymentInvalid: http.StatusUnprocessableEntity, ErrorCodeDeploymentLocked: http.StatusUnprocessableEntity, - ErrorCodeDeploymentUnapproved: http.StatusUnprocessableEntity, + ErrorCodeDeploymentNotApproved: http.StatusUnprocessableEntity, ErrorCodeDeploymentUndeployable: http.StatusUnprocessableEntity, ErrorCodeLicenseDecode: http.StatusUnprocessableEntity, ErrorCodeLicenseRequired: http.StatusPaymentRequired, diff --git a/vo/config.go b/vo/config.go index 7784b982..cdcae239 100644 --- a/vo/config.go +++ b/vo/config.go @@ -29,6 +29,10 @@ type ( // Approval is the configuration of Approval, // It is disabled when it is empty. Approval *Approval `json:"approval,omitempty" yaml:"approval"` + + // Review is the configuration of Review, + // It is disabled when it is empty. + Review *Review `json:"review,omitempty" yaml:"review"` } Approval struct { @@ -36,6 +40,11 @@ type ( RequiredCount int `json:"required_count" yaml:"required_count"` } + Review struct { + Enabled bool `json:"enabled" yaml:"enabled"` + Reviewers []string `json:"reviewers" yaml:"reviewers"` + } + EvalValues struct { IsRollback bool } @@ -92,6 +101,10 @@ func (e *Env) IsApprovalEabled() bool { return e.Approval.Enabled } +func (e *Env) HasReview() bool { + return e.Review != nil && e.Review.Enabled +} + func (e *Env) Eval(v *EvalValues) error { byts, err := json.Marshal(e) if err != nil { From e17c1fe32f0b35cb5c3164c694172bc2160008f1 Mon Sep 17 00:00:00 2001 From: noah Date: Mon, 1 Nov 2021 22:23:02 +0900 Subject: [PATCH 05/13] Fix OpenAPI --- openapi/v1.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openapi/v1.yaml b/openapi/v1.yaml index bc03957f..3fd9995a 100644 --- a/openapi/v1.yaml +++ b/openapi/v1.yaml @@ -1090,6 +1090,19 @@ paths: schema: type: integer description: The deployment number. + requestBody: + content: + application/json: + schema: + type: object + properties: + status: + type: string + enum: + - approved + - rejected + required: + - status responses: '200': description: Return the review. From a20c524596a8e3c6a20c95b8acf3fa60756342b2 Mon Sep 17 00:00:00 2001 From: noah Date: Tue, 2 Nov 2021 22:38:31 +0900 Subject: [PATCH 06/13] Add review APIs in UI --- ui/src/apis/config.ts | 15 ++--- ui/src/apis/deployment.ts | 4 -- ui/src/apis/index.ts | 8 +++ ui/src/apis/review.ts | 130 ++++++++++++++++++++++++++++++++++++++ ui/src/models/Config.ts | 10 ++- ui/src/models/Review.ts | 17 +++++ ui/src/models/index.ts | 3 + 7 files changed, 168 insertions(+), 19 deletions(-) create mode 100644 ui/src/apis/review.ts create mode 100644 ui/src/models/Review.ts diff --git a/ui/src/apis/config.ts b/ui/src/apis/config.ts index 2eb431f7..a5be0f2e 100644 --- a/ui/src/apis/config.ts +++ b/ui/src/apis/config.ts @@ -15,23 +15,20 @@ interface EnvData { enabled: boolean required_count: number } + review?: { + enabled: boolean + reviewers: string[] + } } const mapDataToConfig = (data: ConfigData): Config => { const envs: Env[] = data.envs.map((e: EnvData) => { - let approval: EnvApproval | undefined - - if (e.approval) { - approval = { - enabled: e.approval.enabled, - required_count: e.approval.required_count, - } - } + const { review } = e return { name: e.name, requiredContexts: e.required_contexts, - approval + review, } }) diff --git a/ui/src/apis/deployment.ts b/ui/src/apis/deployment.ts index c95e1f41..0216da42 100644 --- a/ui/src/apis/deployment.ts +++ b/ui/src/apis/deployment.ts @@ -28,8 +28,6 @@ export interface DeploymentData { status: string uid: number is_rollback: boolean - is_approval_enabled: boolean - required_approval_count: number auto_deploy: boolean created_at: string updated_at: string @@ -77,8 +75,6 @@ export const mapDataToDeployment = (data: DeploymentData): Deployment => { status: mapDeploymentStatusEnum(data.status), uid: data.uid, isRollback: data.is_rollback, - isApprovalEanbled: data.is_approval_enabled, - requiredApprovalCount: data.required_approval_count, createdAt: new Date(data.created_at), updatedAt: new Date(data.updated_at), deployer, diff --git a/ui/src/apis/index.ts b/ui/src/apis/index.ts index b961c367..95963e19 100644 --- a/ui/src/apis/index.ts +++ b/ui/src/apis/index.ts @@ -33,6 +33,11 @@ import { setApprovalApproved, setApprovalDeclined } from "./approval" +import { + listReviews, + approveReview, + rejectReview, +} from "./review" import { listLocks, lock, @@ -80,6 +85,9 @@ export { getMyApproval, setApprovalApproved, setApprovalDeclined, + listReviews, + approveReview, + rejectReview, listLocks, lock, unlock, diff --git a/ui/src/apis/review.ts b/ui/src/apis/review.ts new file mode 100644 index 00000000..e64ae53f --- /dev/null +++ b/ui/src/apis/review.ts @@ -0,0 +1,130 @@ +import { StatusCodes } from 'http-status-codes' + +import { instance, headers } from './setting' +import { _fetch } from "./_base" +import { UserData, mapDataToUser } from "./user" +import { DeploymentData, mapDataToDeployment } from "./deployment" +import { + User, + Deployment, + Review, + ReviewStatusEnum, + HttpNotFoundError, + } from '../models' + +export interface ReviewData { + id: number, + status: string + created_at: string + updated_at: string + edges: { + user: UserData, + deployment: DeploymentData + } +} + +// eslint-disable-next-line +export const mapDataToReview = (data: ReviewData): Review => { + let user: User | null = null + let deployment: Deployment | null = null + + if ("user" in data.edges) { + user = mapDataToUser(data.edges.user) + } + + if ("deployment" in data.edges) { + deployment = mapDataToDeployment(data.edges.deployment) + } + + return { + id: data.id, + status: mapDataToApprovalStatus(data.status), + createdAt: new Date(data.created_at), + updatedAt: new Date(data.updated_at), + user, + deployment + } +} + +const mapDataToApprovalStatus = (status: string): ReviewStatusEnum => { + switch (status) { + case "pending": + return ReviewStatusEnum.Pending + case "approved": + return ReviewStatusEnum.Approved + case "declined": + return ReviewStatusEnum.Rejected + default: + return ReviewStatusEnum.Pending + } +} + +export const listReviews = async (namespace: string, name: string, number: number): Promise => { + const res = await _fetch(`${instance}/api/v1/repos/${namespace}/${name}/deployments/${number}/reviews`, { + credentials: "same-origin", + headers, + }) + + const reviews: Review[] = await res.json() + .then(data => data.map((d:any): Review => mapDataToReview(d))) + + return reviews +} + +export const getUserReview = async (namespace: string, name: string, number: number): Promise => { + const res = await _fetch(`${instance}/api/v1/repos/${namespace}/${name}/deployments/${number}/review`, { + credentials: "same-origin", + headers, + }) + + if (res.status === StatusCodes.NOT_FOUND) { + const { message } = await res.json() + throw new HttpNotFoundError(message) + } + + const review = await res.json() + .then(data => mapDataToReview(data)) + return review +} + +export const approveReview = async (namespace: string, name: string, number: number): Promise => { + const body = { + status: "approved", + } + const res = await _fetch(`${instance}/api/v1/repos/${namespace}/${name}/deployments/${number}/review`, { + credentials: "same-origin", + headers, + method: "PATCH", + body: JSON.stringify(body), + }) + + if (res.status === StatusCodes.NOT_FOUND) { + const { message } = await res.json() + throw new HttpNotFoundError(message) + } + + const review = await res.json() + .then(data => mapDataToReview(data)) + return review +} + +export const rejectReview = async (namespace: string, name: string, number: number): Promise => { + const body = { + status: "rejected", + } + const res = await _fetch(`${instance}/api/v1/repos/${namespace}/${name}/deployments/${number}/review`, { + credentials: "same-origin", + headers, + method: "PATCH", + body: JSON.stringify(body), + }) + + if (res.status === StatusCodes.NOT_FOUND) { + const { message } = await res.json() + throw new HttpNotFoundError(message) + } + + const review = await res.json() + .then(data => mapDataToReview(data)) + return review +} \ No newline at end of file diff --git a/ui/src/models/Config.ts b/ui/src/models/Config.ts index 88373950..5744d132 100644 --- a/ui/src/models/Config.ts +++ b/ui/src/models/Config.ts @@ -5,10 +5,8 @@ export default interface Config { export interface Env { name: string requiredContexts?: string[] - approval?: EnvApproval + review?: { + enabled: boolean + reviewers: string[] + } } - -export interface EnvApproval { - enabled: boolean - required_count: number -} \ No newline at end of file diff --git a/ui/src/models/Review.ts b/ui/src/models/Review.ts new file mode 100644 index 00000000..eec9484c --- /dev/null +++ b/ui/src/models/Review.ts @@ -0,0 +1,17 @@ +import User from "./User" +import Deployment from "./Deployment" + +export interface Review { + id: number + status: ReviewStatusEnum + createdAt: Date + updatedAt: Date + user: User | null + deployment: Deployment | null +} + +export enum ReviewStatusEnum { + Pending = "pending", + Approved = "approved", + Rejected = "rejected" +} \ No newline at end of file diff --git a/ui/src/models/index.ts b/ui/src/models/index.ts index d34ca362..d21da027 100644 --- a/ui/src/models/index.ts +++ b/ui/src/models/index.ts @@ -11,6 +11,7 @@ import Branch from "./Branch" import Tag from "./Tag" import User, { ChatUser, RateLimit } from "./User" import Approval, { ApprovalStatus } from "./Approval" +import { Review, ReviewStatusEnum } from "./Review" import Lock from "./Lock" import License from "./License" import Event, {EventKindEnum, EventTypeEnum} from "./Event" @@ -42,6 +43,7 @@ export type { ChatUser, RateLimit, Approval, + Review, Lock, License, Event @@ -60,6 +62,7 @@ export { StatusState, RequestStatus, ApprovalStatus, + ReviewStatusEnum, EventKindEnum, EventTypeEnum } \ No newline at end of file From 3f2682fc195fb155c39a31738eff1497603a247b Mon Sep 17 00:00:00 2001 From: noah Date: Tue, 2 Nov 2021 23:47:37 +0900 Subject: [PATCH 07/13] Replace into review UI --- ui/src/apis/config.ts | 2 +- ui/src/apis/deployment.ts | 2 + ui/src/apis/index.ts | 2 + ui/src/apis/review.ts | 6 +- .../ApproversSelector/ApprovalList.tsx | 41 ----- .../ApproversSelector/ApproversSearch.tsx | 64 ------- ui/src/components/ApproversSelector/index.tsx | 33 ---- ui/src/components/DeployForm.tsx | 20 +-- ...pprovalDropdown.tsx => ReviewDropdown.tsx} | 13 +- ui/src/components/ReviewList.tsx | 48 ++++++ ui/src/components/RollbackForm.tsx | 19 +-- ui/src/models/Review.ts | 4 +- ui/src/models/index.ts | 3 +- ui/src/redux/deployment.tsx | 156 +++++------------- ui/src/redux/repoDeploy.tsx | 49 +----- ui/src/redux/repoRollback.tsx | 49 +----- ui/src/views/Deployment.tsx | 109 +++++------- ui/src/views/RepoDeploy.tsx | 21 +-- ui/src/views/RepoRollback.tsx | 22 +-- 19 files changed, 158 insertions(+), 505 deletions(-) delete mode 100644 ui/src/components/ApproversSelector/ApprovalList.tsx delete mode 100644 ui/src/components/ApproversSelector/ApproversSearch.tsx delete mode 100644 ui/src/components/ApproversSelector/index.tsx rename ui/src/components/{ApprovalDropdown.tsx => ReviewDropdown.tsx} (54%) create mode 100644 ui/src/components/ReviewList.tsx diff --git a/ui/src/apis/config.ts b/ui/src/apis/config.ts index a5be0f2e..25ce82b6 100644 --- a/ui/src/apis/config.ts +++ b/ui/src/apis/config.ts @@ -2,7 +2,7 @@ import { StatusCodes } from 'http-status-codes' import { instance, headers } from './setting' import { _fetch } from "./_base" -import { Config, Env, EnvApproval, HttpNotFoundError } from '../models' +import { Config, Env, HttpNotFoundError } from '../models' interface ConfigData { envs: EnvData[] diff --git a/ui/src/apis/deployment.ts b/ui/src/apis/deployment.ts index 0216da42..1df9be5e 100644 --- a/ui/src/apis/deployment.ts +++ b/ui/src/apis/deployment.ts @@ -75,6 +75,8 @@ export const mapDataToDeployment = (data: DeploymentData): Deployment => { status: mapDeploymentStatusEnum(data.status), uid: data.uid, isRollback: data.is_rollback, + isApprovalEanbled: true, + requiredApprovalCount: 0, createdAt: new Date(data.created_at), updatedAt: new Date(data.updated_at), deployer, diff --git a/ui/src/apis/index.ts b/ui/src/apis/index.ts index 95963e19..2249484c 100644 --- a/ui/src/apis/index.ts +++ b/ui/src/apis/index.ts @@ -35,6 +35,7 @@ import { } from "./approval" import { listReviews, + getUserReview, approveReview, rejectReview, } from "./review" @@ -86,6 +87,7 @@ export { setApprovalApproved, setApprovalDeclined, listReviews, + getUserReview, approveReview, rejectReview, listLocks, diff --git a/ui/src/apis/review.ts b/ui/src/apis/review.ts index e64ae53f..70e0b18b 100644 --- a/ui/src/apis/review.ts +++ b/ui/src/apis/review.ts @@ -25,8 +25,8 @@ export interface ReviewData { // eslint-disable-next-line export const mapDataToReview = (data: ReviewData): Review => { - let user: User | null = null - let deployment: Deployment | null = null + let user: User | undefined + let deployment: Deployment | undefined if ("user" in data.edges) { user = mapDataToUser(data.edges.user) @@ -52,7 +52,7 @@ const mapDataToApprovalStatus = (status: string): ReviewStatusEnum => { return ReviewStatusEnum.Pending case "approved": return ReviewStatusEnum.Approved - case "declined": + case "rejected": return ReviewStatusEnum.Rejected default: return ReviewStatusEnum.Pending diff --git a/ui/src/components/ApproversSelector/ApprovalList.tsx b/ui/src/components/ApproversSelector/ApprovalList.tsx deleted file mode 100644 index cb799ec8..00000000 --- a/ui/src/components/ApproversSelector/ApprovalList.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Avatar } from "antd" -import { CheckOutlined, CloseOutlined } from "@ant-design/icons" - -import { Approval, ApprovalStatus } from "../../models" - -export interface ApprovalListProps { - approvals: Approval[] -} - -export default function ApprovalList(props: ApprovalListProps): JSX.Element { - return ( -
- {props.approvals.map((a, idx) => { - const user = a.user - const avatar = (user !== null)? - {user.login} : - U - const icon = mapApprovalStatusToIcon(a.status) - - return ( -
- {icon}  - {avatar} -
) - })} -
- ) -} - -function mapApprovalStatusToIcon(status: ApprovalStatus): JSX.Element { - switch (status) { - case ApprovalStatus.Pending: - return - case ApprovalStatus.Approved: - return - case ApprovalStatus.Declined: - return - default: - return - } -} \ No newline at end of file diff --git a/ui/src/components/ApproversSelector/ApproversSearch.tsx b/ui/src/components/ApproversSelector/ApproversSearch.tsx deleted file mode 100644 index b355bc34..00000000 --- a/ui/src/components/ApproversSelector/ApproversSearch.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from "react" -import { Select, SelectProps, Avatar, Spin } from "antd" -import { CheckOutlined } from "@ant-design/icons" -import debounce from "lodash.debounce" - -import { User } from "../../models" - -export interface ApproversSelectProps extends SelectProps{ - approvers: User[] - candidates: User[] - // The type of parameter have to be string - // because candidates could be dynamically changed with search. - onSelectCandidate(id: string): void - onSearchCandidates(login: string): void -} - -export default function ApproversSelect(props: ApproversSelectProps): JSX.Element { - const [ searching, setSearching ] = React.useState(false) - - // Clone Select props only - // https://stackoverflow.com/questions/34698905/how-can-i-clone-a-javascript-object-except-for-one-key - const {candidates, onSelectCandidate, onSearchCandidates, ...selectProps} = props // eslint-disable-line - - // debounce search action. - const onSearch = debounce((login: string) => { - setSearching(true) - setTimeout(() => { - setSearching(false) - }, 500); - - props.onSearchCandidates(login) - }, 800) - - - return ( - - ) -} \ No newline at end of file diff --git a/ui/src/components/ApproversSelector/index.tsx b/ui/src/components/ApproversSelector/index.tsx deleted file mode 100644 index 616c0c23..00000000 --- a/ui/src/components/ApproversSelector/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Typography } from "antd" - -import ApproversSearch, { ApproversSelectProps } from "./ApproversSearch" -import ApprovalList, { ApprovalListProps } from "./ApprovalList" - -const { Text } = Typography - -interface ApproversSelectorProps extends ApproversSelectProps, ApprovalListProps { -} - -export default function ApproversSelector(props: ApproversSelectorProps): JSX.Element { - return ( -
-
- Approvers -
-
- -
-
- {(props.approvals.length !== 0) ? - : - No approvers } -
-
- ) -} \ No newline at end of file diff --git a/ui/src/components/DeployForm.tsx b/ui/src/components/DeployForm.tsx index c4a78ff5..c8650454 100644 --- a/ui/src/components/DeployForm.tsx +++ b/ui/src/components/DeployForm.tsx @@ -1,11 +1,10 @@ import { useState } from "react" import { Form, Select, Radio, Button, Typography, Avatar, Tag as AntdTag } from "antd" -import { Branch, Commit, Tag, Deployment, DeploymentType, Status, User, Env } from "../models" +import { Branch, Commit, Tag, Deployment, DeploymentType, Status, Env } from "../models" import CreatableSelect, {Option as Op} from "./CreatableSelect" import StatusStateIcon from "./StatusStateIcon" -import ApproversSelect from "./ApproversSelect" import moment from "moment" export type Option = Op @@ -31,12 +30,6 @@ interface DeployFormProps { tagStatuses: Status[] deploying: boolean onClickDeploy(): void - // properties for approvers. - approvalEnabled: boolean - candidates: User[] - onSelectCandidate(candidate: User): void - onDeselectCandidate(candidate: User): void - onSearchCandidates(login: string): void } export default function DeployForm(props: DeployFormProps): JSX.Element { @@ -273,17 +266,6 @@ export default function DeployForm(props: DeployFormProps): JSX.Element {   - - - - + }> - + ) diff --git a/ui/src/components/ReviewList.tsx b/ui/src/components/ReviewList.tsx new file mode 100644 index 00000000..aa63ec73 --- /dev/null +++ b/ui/src/components/ReviewList.tsx @@ -0,0 +1,48 @@ +import { Typography } from "antd" +import { CheckOutlined, CloseOutlined } from "@ant-design/icons" + +import { Review, ReviewStatusEnum } from "../models" +import UserAvatar from "./UserAvatar" + +const { Text } = Typography + + +export interface ReviewListProps { + reviews: Review[] +} + +export default function ReviewList(props: ReviewListProps): JSX.Element { + return ( +
+
+ Reviewers +
+
+ {(props.reviews.length !== 0) ? +
+ {props.reviews.map((r, idx) => { + return ( +
+ {mapApprovalStatusToIcon(r.status)}  +
+ ) + })} +
: + No approvers } +
+
+ ) +} + +function mapApprovalStatusToIcon(status: ReviewStatusEnum): JSX.Element { + switch (status) { + case ReviewStatusEnum.Pending: + return + case ReviewStatusEnum.Approved: + return + case ReviewStatusEnum.Rejected: + return + default: + return + } +} \ No newline at end of file diff --git a/ui/src/components/RollbackForm.tsx b/ui/src/components/RollbackForm.tsx index e827a1a0..a92834fa 100644 --- a/ui/src/components/RollbackForm.tsx +++ b/ui/src/components/RollbackForm.tsx @@ -1,8 +1,7 @@ import { Form, Select, Button, Avatar } from 'antd' import moment from 'moment' -import { User, Deployment, Env } from "../models" -import ApproversSelect from "./ApproversSelect" +import { Deployment, Env } from "../models" import DeploymentRefCode from './DeploymentRefCode' interface RollbackFormProps { @@ -12,11 +11,6 @@ interface RollbackFormProps { onSelectDeployment(deployment: Deployment): void onClickRollback(): void deploying: boolean - approvalEnabled: boolean - candidates: User[] - onSelectCandidate(candidate: User): void - onDeselectCandidate(candidate: User): void - onSearchCandidates(login: string): void } export default function RollbackForm(props: RollbackFormProps): JSX.Element { @@ -93,17 +87,6 @@ export default function RollbackForm(props: RollbackFormProps): JSX.Element { })}
- - -