From b772443b72ebf5389a7b51f39309ac57c51058ff Mon Sep 17 00:00:00 2001 From: darius Date: Sun, 19 May 2024 17:04:15 +0200 Subject: [PATCH] database update --- database/ent/client.go | 44 +- database/ent/migrate/schema.go | 71 +++- database/ent/mutation.go | 694 ++++++++++++++++++++++++++------ database/ent/project.go | 95 +++-- database/ent/project/project.go | 111 +++-- database/ent/project/where.go | 315 ++++++++++++++- database/ent/project_create.go | 109 ++++- database/ent/project_query.go | 210 ++++++++-- database/ent/project_update.go | 437 ++++++++++++++++++-- database/ent/schema/project.go | 11 +- database/ent/schema/team.go | 2 +- database/ent/schema/user.go | 2 + database/ent/team.go | 18 +- database/ent/team/team.go | 35 +- database/ent/team/where.go | 12 +- database/ent/team_create.go | 14 +- database/ent/team_query.go | 118 ++++-- database/ent/team_update.go | 84 ++-- database/ent/user.go | 31 +- database/ent/user/user.go | 39 ++ database/ent/user/where.go | 93 +++++ database/ent/user_create.go | 45 +++ database/ent/user_query.go | 129 +++++- database/ent/user_update.go | 197 +++++++++ 24 files changed, 2489 insertions(+), 427 deletions(-) diff --git a/database/ent/client.go b/database/ent/client.go index 92fd80f..dc37603 100644 --- a/database/ent/client.go +++ b/database/ent/client.go @@ -326,15 +326,31 @@ func (c *ProjectClient) GetX(ctx context.Context, id int) *Project { return obj } -// QueryTeam queries the team edge of a Project. -func (c *ProjectClient) QueryTeam(pr *Project) *TeamQuery { +// QueryUsers queries the users edge of a Project. +func (c *ProjectClient) QueryUsers(pr *Project) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := pr.ID + step := sqlgraph.NewStep( + sqlgraph.From(project.Table, project.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, project.UsersTable, project.UsersPrimaryKey...), + ) + fromV = sqlgraph.Neighbors(pr.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryTeams queries the teams edge of a Project. +func (c *ProjectClient) QueryTeams(pr *Project) *TeamQuery { query := (&TeamClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := pr.ID step := sqlgraph.NewStep( sqlgraph.From(project.Table, project.FieldID, id), sqlgraph.To(team.Table, team.FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, project.TeamTable, project.TeamColumn), + sqlgraph.Edge(sqlgraph.M2M, true, project.TeamsTable, project.TeamsPrimaryKey...), ) fromV = sqlgraph.Neighbors(pr.driver.Dialect(), step) return fromV, nil @@ -475,15 +491,15 @@ func (c *TeamClient) GetX(ctx context.Context, id int) *Team { return obj } -// QueryProject queries the project edge of a Team. -func (c *TeamClient) QueryProject(t *Team) *ProjectQuery { +// QueryProjects queries the projects edge of a Team. +func (c *TeamClient) QueryProjects(t *Team) *ProjectQuery { query := (&ProjectClient{config: c.config}).Query() query.path = func(context.Context) (fromV *sql.Selector, _ error) { id := t.ID step := sqlgraph.NewStep( sqlgraph.From(team.Table, team.FieldID, id), sqlgraph.To(project.Table, project.FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, team.ProjectTable, team.ProjectColumn), + sqlgraph.Edge(sqlgraph.M2M, false, team.ProjectsTable, team.ProjectsPrimaryKey...), ) fromV = sqlgraph.Neighbors(t.driver.Dialect(), step) return fromV, nil @@ -656,6 +672,22 @@ func (c *UserClient) QueryTeams(u *User) *TeamQuery { return query } +// QueryProjects queries the projects edge of a User. +func (c *UserClient) QueryProjects(u *User) *ProjectQuery { + query := (&ProjectClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := u.ID + step := sqlgraph.NewStep( + sqlgraph.From(user.Table, user.FieldID, id), + sqlgraph.To(project.Table, project.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, user.ProjectsTable, user.ProjectsPrimaryKey...), + ) + fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) + return fromV, nil + } + return query +} + // Hooks returns the client hooks. func (c *UserClient) Hooks() []Hook { return c.hooks.User diff --git a/database/ent/migrate/schema.go b/database/ent/migrate/schema.go index 8f9d96f..d9bc151 100644 --- a/database/ent/migrate/schema.go +++ b/database/ent/migrate/schema.go @@ -12,21 +12,16 @@ var ( ProjectsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "name", Type: field.TypeString, Unique: true}, - {Name: "team_project", Type: field.TypeInt, Nullable: true}, + {Name: "description", Type: field.TypeString}, + {Name: "url", Type: field.TypeString}, + {Name: "image_url", Type: field.TypeString}, + {Name: "doc_url", Type: field.TypeString}, } // ProjectsTable holds the schema information for the "projects" table. ProjectsTable = &schema.Table{ Name: "projects", Columns: ProjectsColumns, PrimaryKey: []*schema.Column{ProjectsColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "projects_teams_project", - Columns: []*schema.Column{ProjectsColumns[2]}, - RefColumns: []*schema.Column{TeamsColumns[0]}, - OnDelete: schema.SetNull, - }, - }, } // TeamsColumns holds the columns for the "teams" table. TeamsColumns = []*schema.Column{ @@ -43,6 +38,7 @@ var ( UsersColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "name", Type: field.TypeString, Unique: true}, + {Name: "email", Type: field.TypeString}, {Name: "password", Type: field.TypeString}, {Name: "role", Type: field.TypeEnum, Enums: []string{"admin", "user", "visitor"}}, } @@ -52,6 +48,31 @@ var ( Columns: UsersColumns, PrimaryKey: []*schema.Column{UsersColumns[0]}, } + // TeamProjectsColumns holds the columns for the "team_projects" table. + TeamProjectsColumns = []*schema.Column{ + {Name: "team_id", Type: field.TypeInt}, + {Name: "project_id", Type: field.TypeInt}, + } + // TeamProjectsTable holds the schema information for the "team_projects" table. + TeamProjectsTable = &schema.Table{ + Name: "team_projects", + Columns: TeamProjectsColumns, + PrimaryKey: []*schema.Column{TeamProjectsColumns[0], TeamProjectsColumns[1]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "team_projects_team_id", + Columns: []*schema.Column{TeamProjectsColumns[0]}, + RefColumns: []*schema.Column{TeamsColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "team_projects_project_id", + Columns: []*schema.Column{TeamProjectsColumns[1]}, + RefColumns: []*schema.Column{ProjectsColumns[0]}, + OnDelete: schema.Cascade, + }, + }, + } // UserTeamsColumns holds the columns for the "user_teams" table. UserTeamsColumns = []*schema.Column{ {Name: "user_id", Type: field.TypeInt}, @@ -77,17 +98,47 @@ var ( }, }, } + // UserProjectsColumns holds the columns for the "user_projects" table. + UserProjectsColumns = []*schema.Column{ + {Name: "user_id", Type: field.TypeInt}, + {Name: "project_id", Type: field.TypeInt}, + } + // UserProjectsTable holds the schema information for the "user_projects" table. + UserProjectsTable = &schema.Table{ + Name: "user_projects", + Columns: UserProjectsColumns, + PrimaryKey: []*schema.Column{UserProjectsColumns[0], UserProjectsColumns[1]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "user_projects_user_id", + Columns: []*schema.Column{UserProjectsColumns[0]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "user_projects_project_id", + Columns: []*schema.Column{UserProjectsColumns[1]}, + RefColumns: []*schema.Column{ProjectsColumns[0]}, + OnDelete: schema.Cascade, + }, + }, + } // Tables holds all the tables in the schema. Tables = []*schema.Table{ ProjectsTable, TeamsTable, UsersTable, + TeamProjectsTable, UserTeamsTable, + UserProjectsTable, } ) func init() { - ProjectsTable.ForeignKeys[0].RefTable = TeamsTable + TeamProjectsTable.ForeignKeys[0].RefTable = TeamsTable + TeamProjectsTable.ForeignKeys[1].RefTable = ProjectsTable UserTeamsTable.ForeignKeys[0].RefTable = UsersTable UserTeamsTable.ForeignKeys[1].RefTable = TeamsTable + UserProjectsTable.ForeignKeys[0].RefTable = UsersTable + UserProjectsTable.ForeignKeys[1].RefTable = ProjectsTable } diff --git a/database/ent/mutation.go b/database/ent/mutation.go index 52457af..e24de90 100644 --- a/database/ent/mutation.go +++ b/database/ent/mutation.go @@ -37,9 +37,17 @@ type ProjectMutation struct { typ string id *int name *string + description *string + url *string + image_url *string + doc_url *string clearedFields map[string]struct{} - team *int - clearedteam bool + users map[int]struct{} + removedusers map[int]struct{} + clearedusers bool + teams map[int]struct{} + removedteams map[int]struct{} + clearedteams bool done bool oldValue func(context.Context) (*Project, error) predicates []predicate.Project @@ -179,43 +187,256 @@ func (m *ProjectMutation) ResetName() { m.name = nil } -// SetTeamID sets the "team" edge to the Team entity by id. -func (m *ProjectMutation) SetTeamID(id int) { - m.team = &id +// SetDescription sets the "description" field. +func (m *ProjectMutation) SetDescription(s string) { + m.description = &s } -// ClearTeam clears the "team" edge to the Team entity. -func (m *ProjectMutation) ClearTeam() { - m.clearedteam = true +// Description returns the value of the "description" field in the mutation. +func (m *ProjectMutation) Description() (r string, exists bool) { + v := m.description + if v == nil { + return + } + return *v, true } -// TeamCleared reports if the "team" edge to the Team entity was cleared. -func (m *ProjectMutation) TeamCleared() bool { - return m.clearedteam +// OldDescription returns the old "description" field's value of the Project entity. +// If the Project 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 *ProjectMutation) OldDescription(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDescription is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDescription requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDescription: %w", err) + } + return oldValue.Description, nil } -// TeamID returns the "team" edge ID in the mutation. -func (m *ProjectMutation) TeamID() (id int, exists bool) { - if m.team != nil { - return *m.team, true +// ResetDescription resets all changes to the "description" field. +func (m *ProjectMutation) ResetDescription() { + m.description = nil +} + +// SetURL sets the "url" field. +func (m *ProjectMutation) SetURL(s string) { + m.url = &s +} + +// URL returns the value of the "url" field in the mutation. +func (m *ProjectMutation) URL() (r string, exists bool) { + v := m.url + if v == nil { + return + } + return *v, true +} + +// OldURL returns the old "url" field's value of the Project entity. +// If the Project 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 *ProjectMutation) OldURL(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldURL is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldURL requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldURL: %w", err) + } + return oldValue.URL, nil +} + +// ResetURL resets all changes to the "url" field. +func (m *ProjectMutation) ResetURL() { + m.url = nil +} + +// SetImageURL sets the "image_url" field. +func (m *ProjectMutation) SetImageURL(s string) { + m.image_url = &s +} + +// ImageURL returns the value of the "image_url" field in the mutation. +func (m *ProjectMutation) ImageURL() (r string, exists bool) { + v := m.image_url + if v == nil { + return + } + return *v, true +} + +// OldImageURL returns the old "image_url" field's value of the Project entity. +// If the Project 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 *ProjectMutation) OldImageURL(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldImageURL is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldImageURL requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldImageURL: %w", err) + } + return oldValue.ImageURL, nil +} + +// ResetImageURL resets all changes to the "image_url" field. +func (m *ProjectMutation) ResetImageURL() { + m.image_url = nil +} + +// SetDocURL sets the "doc_url" field. +func (m *ProjectMutation) SetDocURL(s string) { + m.doc_url = &s +} + +// DocURL returns the value of the "doc_url" field in the mutation. +func (m *ProjectMutation) DocURL() (r string, exists bool) { + v := m.doc_url + if v == nil { + return + } + return *v, true +} + +// OldDocURL returns the old "doc_url" field's value of the Project entity. +// If the Project 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 *ProjectMutation) OldDocURL(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldDocURL is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldDocURL requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldDocURL: %w", err) + } + return oldValue.DocURL, nil +} + +// ResetDocURL resets all changes to the "doc_url" field. +func (m *ProjectMutation) ResetDocURL() { + m.doc_url = nil +} + +// AddUserIDs adds the "users" edge to the User entity by ids. +func (m *ProjectMutation) AddUserIDs(ids ...int) { + if m.users == nil { + m.users = make(map[int]struct{}) + } + for i := range ids { + m.users[ids[i]] = struct{}{} + } +} + +// ClearUsers clears the "users" edge to the User entity. +func (m *ProjectMutation) ClearUsers() { + m.clearedusers = true +} + +// UsersCleared reports if the "users" edge to the User entity was cleared. +func (m *ProjectMutation) UsersCleared() bool { + return m.clearedusers +} + +// RemoveUserIDs removes the "users" edge to the User entity by IDs. +func (m *ProjectMutation) RemoveUserIDs(ids ...int) { + if m.removedusers == nil { + m.removedusers = make(map[int]struct{}) + } + for i := range ids { + delete(m.users, ids[i]) + m.removedusers[ids[i]] = struct{}{} + } +} + +// RemovedUsers returns the removed IDs of the "users" edge to the User entity. +func (m *ProjectMutation) RemovedUsersIDs() (ids []int) { + for id := range m.removedusers { + ids = append(ids, id) } return } -// TeamIDs returns the "team" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// TeamID instead. It exists only for internal usage by the builders. -func (m *ProjectMutation) TeamIDs() (ids []int) { - if id := m.team; id != nil { - ids = append(ids, *id) +// UsersIDs returns the "users" edge IDs in the mutation. +func (m *ProjectMutation) UsersIDs() (ids []int) { + for id := range m.users { + ids = append(ids, id) } return } -// ResetTeam resets all changes to the "team" edge. -func (m *ProjectMutation) ResetTeam() { - m.team = nil - m.clearedteam = false +// ResetUsers resets all changes to the "users" edge. +func (m *ProjectMutation) ResetUsers() { + m.users = nil + m.clearedusers = false + m.removedusers = nil +} + +// AddTeamIDs adds the "teams" edge to the Team entity by ids. +func (m *ProjectMutation) AddTeamIDs(ids ...int) { + if m.teams == nil { + m.teams = make(map[int]struct{}) + } + for i := range ids { + m.teams[ids[i]] = struct{}{} + } +} + +// ClearTeams clears the "teams" edge to the Team entity. +func (m *ProjectMutation) ClearTeams() { + m.clearedteams = true +} + +// TeamsCleared reports if the "teams" edge to the Team entity was cleared. +func (m *ProjectMutation) TeamsCleared() bool { + return m.clearedteams +} + +// RemoveTeamIDs removes the "teams" edge to the Team entity by IDs. +func (m *ProjectMutation) RemoveTeamIDs(ids ...int) { + if m.removedteams == nil { + m.removedteams = make(map[int]struct{}) + } + for i := range ids { + delete(m.teams, ids[i]) + m.removedteams[ids[i]] = struct{}{} + } +} + +// RemovedTeams returns the removed IDs of the "teams" edge to the Team entity. +func (m *ProjectMutation) RemovedTeamsIDs() (ids []int) { + for id := range m.removedteams { + ids = append(ids, id) + } + return +} + +// TeamsIDs returns the "teams" edge IDs in the mutation. +func (m *ProjectMutation) TeamsIDs() (ids []int) { + for id := range m.teams { + ids = append(ids, id) + } + return +} + +// ResetTeams resets all changes to the "teams" edge. +func (m *ProjectMutation) ResetTeams() { + m.teams = nil + m.clearedteams = false + m.removedteams = nil } // Where appends a list predicates to the ProjectMutation builder. @@ -252,10 +473,22 @@ func (m *ProjectMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *ProjectMutation) Fields() []string { - fields := make([]string, 0, 1) + fields := make([]string, 0, 5) if m.name != nil { fields = append(fields, project.FieldName) } + if m.description != nil { + fields = append(fields, project.FieldDescription) + } + if m.url != nil { + fields = append(fields, project.FieldURL) + } + if m.image_url != nil { + fields = append(fields, project.FieldImageURL) + } + if m.doc_url != nil { + fields = append(fields, project.FieldDocURL) + } return fields } @@ -266,6 +499,14 @@ func (m *ProjectMutation) Field(name string) (ent.Value, bool) { switch name { case project.FieldName: return m.Name() + case project.FieldDescription: + return m.Description() + case project.FieldURL: + return m.URL() + case project.FieldImageURL: + return m.ImageURL() + case project.FieldDocURL: + return m.DocURL() } return nil, false } @@ -277,6 +518,14 @@ func (m *ProjectMutation) OldField(ctx context.Context, name string) (ent.Value, switch name { case project.FieldName: return m.OldName(ctx) + case project.FieldDescription: + return m.OldDescription(ctx) + case project.FieldURL: + return m.OldURL(ctx) + case project.FieldImageURL: + return m.OldImageURL(ctx) + case project.FieldDocURL: + return m.OldDocURL(ctx) } return nil, fmt.Errorf("unknown Project field %s", name) } @@ -293,6 +542,34 @@ func (m *ProjectMutation) SetField(name string, value ent.Value) error { } m.SetName(v) return nil + case project.FieldDescription: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDescription(v) + return nil + case project.FieldURL: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetURL(v) + return nil + case project.FieldImageURL: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetImageURL(v) + return nil + case project.FieldDocURL: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetDocURL(v) + return nil } return fmt.Errorf("unknown Project field %s", name) } @@ -345,15 +622,30 @@ func (m *ProjectMutation) ResetField(name string) error { case project.FieldName: m.ResetName() return nil + case project.FieldDescription: + m.ResetDescription() + return nil + case project.FieldURL: + m.ResetURL() + return nil + case project.FieldImageURL: + m.ResetImageURL() + return nil + case project.FieldDocURL: + m.ResetDocURL() + return nil } return fmt.Errorf("unknown Project field %s", name) } // AddedEdges returns all edge names that were set/added in this mutation. func (m *ProjectMutation) AddedEdges() []string { - edges := make([]string, 0, 1) - if m.team != nil { - edges = append(edges, project.EdgeTeam) + edges := make([]string, 0, 2) + if m.users != nil { + edges = append(edges, project.EdgeUsers) + } + if m.teams != nil { + edges = append(edges, project.EdgeTeams) } return edges } @@ -362,31 +654,62 @@ func (m *ProjectMutation) AddedEdges() []string { // name in this mutation. func (m *ProjectMutation) AddedIDs(name string) []ent.Value { switch name { - case project.EdgeTeam: - if id := m.team; id != nil { - return []ent.Value{*id} + case project.EdgeUsers: + ids := make([]ent.Value, 0, len(m.users)) + for id := range m.users { + ids = append(ids, id) } + return ids + case project.EdgeTeams: + ids := make([]ent.Value, 0, len(m.teams)) + for id := range m.teams { + ids = append(ids, id) + } + return ids } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *ProjectMutation) RemovedEdges() []string { - edges := make([]string, 0, 1) + edges := make([]string, 0, 2) + if m.removedusers != nil { + edges = append(edges, project.EdgeUsers) + } + if m.removedteams != nil { + edges = append(edges, project.EdgeTeams) + } return edges } // RemovedIDs returns all IDs (to other nodes) that were removed for the edge with // the given name in this mutation. func (m *ProjectMutation) RemovedIDs(name string) []ent.Value { + switch name { + case project.EdgeUsers: + ids := make([]ent.Value, 0, len(m.removedusers)) + for id := range m.removedusers { + ids = append(ids, id) + } + return ids + case project.EdgeTeams: + ids := make([]ent.Value, 0, len(m.removedteams)) + for id := range m.removedteams { + ids = append(ids, id) + } + return ids + } return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *ProjectMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) - if m.clearedteam { - edges = append(edges, project.EdgeTeam) + edges := make([]string, 0, 2) + if m.clearedusers { + edges = append(edges, project.EdgeUsers) + } + if m.clearedteams { + edges = append(edges, project.EdgeTeams) } return edges } @@ -395,8 +718,10 @@ func (m *ProjectMutation) ClearedEdges() []string { // was cleared in this mutation. func (m *ProjectMutation) EdgeCleared(name string) bool { switch name { - case project.EdgeTeam: - return m.clearedteam + case project.EdgeUsers: + return m.clearedusers + case project.EdgeTeams: + return m.clearedteams } return false } @@ -405,9 +730,6 @@ func (m *ProjectMutation) EdgeCleared(name string) bool { // if that edge is not defined in the schema. func (m *ProjectMutation) ClearEdge(name string) error { switch name { - case project.EdgeTeam: - m.ClearTeam() - return nil } return fmt.Errorf("unknown Project unique edge %s", name) } @@ -416,8 +738,11 @@ func (m *ProjectMutation) ClearEdge(name string) error { // It returns an error if the edge is not defined in the schema. func (m *ProjectMutation) ResetEdge(name string) error { switch name { - case project.EdgeTeam: - m.ResetTeam() + case project.EdgeUsers: + m.ResetUsers() + return nil + case project.EdgeTeams: + m.ResetTeams() return nil } return fmt.Errorf("unknown Project edge %s", name) @@ -426,20 +751,20 @@ func (m *ProjectMutation) ResetEdge(name string) error { // TeamMutation represents an operation that mutates the Team nodes in the graph. type TeamMutation struct { config - op Op - typ string - id *int - name *string - clearedFields map[string]struct{} - project map[int]struct{} - removedproject map[int]struct{} - clearedproject bool - users map[int]struct{} - removedusers map[int]struct{} - clearedusers bool - done bool - oldValue func(context.Context) (*Team, error) - predicates []predicate.Team + op Op + typ string + id *int + name *string + clearedFields map[string]struct{} + projects map[int]struct{} + removedprojects map[int]struct{} + clearedprojects bool + users map[int]struct{} + removedusers map[int]struct{} + clearedusers bool + done bool + oldValue func(context.Context) (*Team, error) + predicates []predicate.Team } var _ ent.Mutation = (*TeamMutation)(nil) @@ -576,58 +901,58 @@ func (m *TeamMutation) ResetName() { m.name = nil } -// AddProjectIDs adds the "project" edge to the Project entity by ids. +// AddProjectIDs adds the "projects" edge to the Project entity by ids. func (m *TeamMutation) AddProjectIDs(ids ...int) { - if m.project == nil { - m.project = make(map[int]struct{}) + if m.projects == nil { + m.projects = make(map[int]struct{}) } for i := range ids { - m.project[ids[i]] = struct{}{} + m.projects[ids[i]] = struct{}{} } } -// ClearProject clears the "project" edge to the Project entity. -func (m *TeamMutation) ClearProject() { - m.clearedproject = true +// ClearProjects clears the "projects" edge to the Project entity. +func (m *TeamMutation) ClearProjects() { + m.clearedprojects = true } -// ProjectCleared reports if the "project" edge to the Project entity was cleared. -func (m *TeamMutation) ProjectCleared() bool { - return m.clearedproject +// ProjectsCleared reports if the "projects" edge to the Project entity was cleared. +func (m *TeamMutation) ProjectsCleared() bool { + return m.clearedprojects } -// RemoveProjectIDs removes the "project" edge to the Project entity by IDs. +// RemoveProjectIDs removes the "projects" edge to the Project entity by IDs. func (m *TeamMutation) RemoveProjectIDs(ids ...int) { - if m.removedproject == nil { - m.removedproject = make(map[int]struct{}) + if m.removedprojects == nil { + m.removedprojects = make(map[int]struct{}) } for i := range ids { - delete(m.project, ids[i]) - m.removedproject[ids[i]] = struct{}{} + delete(m.projects, ids[i]) + m.removedprojects[ids[i]] = struct{}{} } } -// RemovedProject returns the removed IDs of the "project" edge to the Project entity. -func (m *TeamMutation) RemovedProjectIDs() (ids []int) { - for id := range m.removedproject { +// RemovedProjects returns the removed IDs of the "projects" edge to the Project entity. +func (m *TeamMutation) RemovedProjectsIDs() (ids []int) { + for id := range m.removedprojects { ids = append(ids, id) } return } -// ProjectIDs returns the "project" edge IDs in the mutation. -func (m *TeamMutation) ProjectIDs() (ids []int) { - for id := range m.project { +// ProjectsIDs returns the "projects" edge IDs in the mutation. +func (m *TeamMutation) ProjectsIDs() (ids []int) { + for id := range m.projects { ids = append(ids, id) } return } -// ResetProject resets all changes to the "project" edge. -func (m *TeamMutation) ResetProject() { - m.project = nil - m.clearedproject = false - m.removedproject = nil +// ResetProjects resets all changes to the "projects" edge. +func (m *TeamMutation) ResetProjects() { + m.projects = nil + m.clearedprojects = false + m.removedprojects = nil } // AddUserIDs adds the "users" edge to the User entity by ids. @@ -818,8 +1143,8 @@ func (m *TeamMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *TeamMutation) AddedEdges() []string { edges := make([]string, 0, 2) - if m.project != nil { - edges = append(edges, team.EdgeProject) + if m.projects != nil { + edges = append(edges, team.EdgeProjects) } if m.users != nil { edges = append(edges, team.EdgeUsers) @@ -831,9 +1156,9 @@ func (m *TeamMutation) AddedEdges() []string { // name in this mutation. func (m *TeamMutation) AddedIDs(name string) []ent.Value { switch name { - case team.EdgeProject: - ids := make([]ent.Value, 0, len(m.project)) - for id := range m.project { + case team.EdgeProjects: + ids := make([]ent.Value, 0, len(m.projects)) + for id := range m.projects { ids = append(ids, id) } return ids @@ -850,8 +1175,8 @@ func (m *TeamMutation) AddedIDs(name string) []ent.Value { // RemovedEdges returns all edge names that were removed in this mutation. func (m *TeamMutation) RemovedEdges() []string { edges := make([]string, 0, 2) - if m.removedproject != nil { - edges = append(edges, team.EdgeProject) + if m.removedprojects != nil { + edges = append(edges, team.EdgeProjects) } if m.removedusers != nil { edges = append(edges, team.EdgeUsers) @@ -863,9 +1188,9 @@ func (m *TeamMutation) RemovedEdges() []string { // the given name in this mutation. func (m *TeamMutation) RemovedIDs(name string) []ent.Value { switch name { - case team.EdgeProject: - ids := make([]ent.Value, 0, len(m.removedproject)) - for id := range m.removedproject { + case team.EdgeProjects: + ids := make([]ent.Value, 0, len(m.removedprojects)) + for id := range m.removedprojects { ids = append(ids, id) } return ids @@ -882,8 +1207,8 @@ func (m *TeamMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *TeamMutation) ClearedEdges() []string { edges := make([]string, 0, 2) - if m.clearedproject { - edges = append(edges, team.EdgeProject) + if m.clearedprojects { + edges = append(edges, team.EdgeProjects) } if m.clearedusers { edges = append(edges, team.EdgeUsers) @@ -895,8 +1220,8 @@ func (m *TeamMutation) ClearedEdges() []string { // was cleared in this mutation. func (m *TeamMutation) EdgeCleared(name string) bool { switch name { - case team.EdgeProject: - return m.clearedproject + case team.EdgeProjects: + return m.clearedprojects case team.EdgeUsers: return m.clearedusers } @@ -915,8 +1240,8 @@ func (m *TeamMutation) ClearEdge(name string) error { // It returns an error if the edge is not defined in the schema. func (m *TeamMutation) ResetEdge(name string) error { switch name { - case team.EdgeProject: - m.ResetProject() + case team.EdgeProjects: + m.ResetProjects() return nil case team.EdgeUsers: m.ResetUsers() @@ -928,19 +1253,23 @@ func (m *TeamMutation) ResetEdge(name string) error { // UserMutation represents an operation that mutates the User nodes in the graph. type UserMutation struct { config - op Op - typ string - id *int - name *string - password *string - role *user.Role - clearedFields map[string]struct{} - teams map[int]struct{} - removedteams map[int]struct{} - clearedteams bool - done bool - oldValue func(context.Context) (*User, error) - predicates []predicate.User + op Op + typ string + id *int + name *string + email *string + password *string + role *user.Role + clearedFields map[string]struct{} + teams map[int]struct{} + removedteams map[int]struct{} + clearedteams bool + projects map[int]struct{} + removedprojects map[int]struct{} + clearedprojects bool + done bool + oldValue func(context.Context) (*User, error) + predicates []predicate.User } var _ ent.Mutation = (*UserMutation)(nil) @@ -1077,6 +1406,42 @@ func (m *UserMutation) ResetName() { m.name = nil } +// SetEmail sets the "email" field. +func (m *UserMutation) SetEmail(s string) { + m.email = &s +} + +// Email returns the value of the "email" field in the mutation. +func (m *UserMutation) Email() (r string, exists bool) { + v := m.email + if v == nil { + return + } + return *v, true +} + +// OldEmail returns the old "email" 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) OldEmail(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldEmail is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldEmail requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldEmail: %w", err) + } + return oldValue.Email, nil +} + +// ResetEmail resets all changes to the "email" field. +func (m *UserMutation) ResetEmail() { + m.email = nil +} + // SetPassword sets the "password" field. func (m *UserMutation) SetPassword(s string) { m.password = &s @@ -1203,6 +1568,60 @@ func (m *UserMutation) ResetTeams() { m.removedteams = nil } +// AddProjectIDs adds the "projects" edge to the Project entity by ids. +func (m *UserMutation) AddProjectIDs(ids ...int) { + if m.projects == nil { + m.projects = make(map[int]struct{}) + } + for i := range ids { + m.projects[ids[i]] = struct{}{} + } +} + +// ClearProjects clears the "projects" edge to the Project entity. +func (m *UserMutation) ClearProjects() { + m.clearedprojects = true +} + +// ProjectsCleared reports if the "projects" edge to the Project entity was cleared. +func (m *UserMutation) ProjectsCleared() bool { + return m.clearedprojects +} + +// RemoveProjectIDs removes the "projects" edge to the Project entity by IDs. +func (m *UserMutation) RemoveProjectIDs(ids ...int) { + if m.removedprojects == nil { + m.removedprojects = make(map[int]struct{}) + } + for i := range ids { + delete(m.projects, ids[i]) + m.removedprojects[ids[i]] = struct{}{} + } +} + +// RemovedProjects returns the removed IDs of the "projects" edge to the Project entity. +func (m *UserMutation) RemovedProjectsIDs() (ids []int) { + for id := range m.removedprojects { + ids = append(ids, id) + } + return +} + +// ProjectsIDs returns the "projects" edge IDs in the mutation. +func (m *UserMutation) ProjectsIDs() (ids []int) { + for id := range m.projects { + ids = append(ids, id) + } + return +} + +// ResetProjects resets all changes to the "projects" edge. +func (m *UserMutation) ResetProjects() { + m.projects = nil + m.clearedprojects = false + m.removedprojects = nil +} + // Where appends a list predicates to the UserMutation builder. func (m *UserMutation) Where(ps ...predicate.User) { m.predicates = append(m.predicates, ps...) @@ -1237,10 +1656,13 @@ func (m *UserMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *UserMutation) Fields() []string { - fields := make([]string, 0, 3) + fields := make([]string, 0, 4) if m.name != nil { fields = append(fields, user.FieldName) } + if m.email != nil { + fields = append(fields, user.FieldEmail) + } if m.password != nil { fields = append(fields, user.FieldPassword) } @@ -1257,6 +1679,8 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) { switch name { case user.FieldName: return m.Name() + case user.FieldEmail: + return m.Email() case user.FieldPassword: return m.Password() case user.FieldRole: @@ -1272,6 +1696,8 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er switch name { case user.FieldName: return m.OldName(ctx) + case user.FieldEmail: + return m.OldEmail(ctx) case user.FieldPassword: return m.OldPassword(ctx) case user.FieldRole: @@ -1292,6 +1718,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error { } m.SetName(v) return nil + case user.FieldEmail: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetEmail(v) + return nil case user.FieldPassword: v, ok := value.(string) if !ok { @@ -1358,6 +1791,9 @@ func (m *UserMutation) ResetField(name string) error { case user.FieldName: m.ResetName() return nil + case user.FieldEmail: + m.ResetEmail() + return nil case user.FieldPassword: m.ResetPassword() return nil @@ -1370,10 +1806,13 @@ 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, 1) + edges := make([]string, 0, 2) if m.teams != nil { edges = append(edges, user.EdgeTeams) } + if m.projects != nil { + edges = append(edges, user.EdgeProjects) + } return edges } @@ -1387,16 +1826,25 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgeProjects: + ids := make([]ent.Value, 0, len(m.projects)) + for id := range m.projects { + ids = append(ids, id) + } + return ids } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserMutation) RemovedEdges() []string { - edges := make([]string, 0, 1) + edges := make([]string, 0, 2) if m.removedteams != nil { edges = append(edges, user.EdgeTeams) } + if m.removedprojects != nil { + edges = append(edges, user.EdgeProjects) + } return edges } @@ -1410,16 +1858,25 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value { ids = append(ids, id) } return ids + case user.EdgeProjects: + ids := make([]ent.Value, 0, len(m.removedprojects)) + for id := range m.removedprojects { + ids = append(ids, id) + } + return ids } return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) + edges := make([]string, 0, 2) if m.clearedteams { edges = append(edges, user.EdgeTeams) } + if m.clearedprojects { + edges = append(edges, user.EdgeProjects) + } return edges } @@ -1429,6 +1886,8 @@ func (m *UserMutation) EdgeCleared(name string) bool { switch name { case user.EdgeTeams: return m.clearedteams + case user.EdgeProjects: + return m.clearedprojects } return false } @@ -1448,6 +1907,9 @@ func (m *UserMutation) ResetEdge(name string) error { case user.EdgeTeams: m.ResetTeams() return nil + case user.EdgeProjects: + m.ResetProjects() + return nil } return fmt.Errorf("unknown User edge %s", name) } diff --git a/database/ent/project.go b/database/ent/project.go index 3a61870..d1ec7f1 100644 --- a/database/ent/project.go +++ b/database/ent/project.go @@ -5,7 +5,6 @@ package ent import ( "fmt" "portfolio/database/ent/project" - "portfolio/database/ent/team" "strings" "entgo.io/ent" @@ -19,31 +18,47 @@ type Project struct { ID int `json:"id,omitempty"` // Name holds the value of the "name" field. Name string `json:"name,omitempty"` + // Description holds the value of the "description" field. + Description string `json:"description,omitempty"` + // URL holds the value of the "url" field. + URL string `json:"url,omitempty"` + // ImageURL holds the value of the "image_url" field. + ImageURL string `json:"image_url,omitempty"` + // DocURL holds the value of the "doc_url" field. + DocURL string `json:"doc_url,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the ProjectQuery when eager-loading is set. Edges ProjectEdges `json:"edges"` - team_project *int selectValues sql.SelectValues } // ProjectEdges holds the relations/edges for other nodes in the graph. type ProjectEdges struct { - // Team holds the value of the team edge. - Team *Team `json:"team,omitempty"` + // Users holds the value of the users edge. + Users []*User `json:"users,omitempty"` + // Teams holds the value of the teams edge. + Teams []*Team `json:"teams,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [1]bool + loadedTypes [2]bool } -// TeamOrErr returns the Team value or an error if the edge -// was not loaded in eager-loading, or loaded but was not found. -func (e ProjectEdges) TeamOrErr() (*Team, error) { - if e.Team != nil { - return e.Team, nil - } else if e.loadedTypes[0] { - return nil, &NotFoundError{label: team.Label} +// UsersOrErr returns the Users value or an error if the edge +// was not loaded in eager-loading. +func (e ProjectEdges) UsersOrErr() ([]*User, error) { + if e.loadedTypes[0] { + return e.Users, nil } - return nil, &NotLoadedError{edge: "team"} + return nil, &NotLoadedError{edge: "users"} +} + +// TeamsOrErr returns the Teams value or an error if the edge +// was not loaded in eager-loading. +func (e ProjectEdges) TeamsOrErr() ([]*Team, error) { + if e.loadedTypes[1] { + return e.Teams, nil + } + return nil, &NotLoadedError{edge: "teams"} } // scanValues returns the types for scanning values from sql.Rows. @@ -53,10 +68,8 @@ func (*Project) scanValues(columns []string) ([]any, error) { switch columns[i] { case project.FieldID: values[i] = new(sql.NullInt64) - case project.FieldName: + case project.FieldName, project.FieldDescription, project.FieldURL, project.FieldImageURL, project.FieldDocURL: values[i] = new(sql.NullString) - case project.ForeignKeys[0]: // team_project - values[i] = new(sql.NullInt64) default: values[i] = new(sql.UnknownType) } @@ -84,12 +97,29 @@ func (pr *Project) assignValues(columns []string, values []any) error { } else if value.Valid { pr.Name = value.String } - case project.ForeignKeys[0]: - if value, ok := values[i].(*sql.NullInt64); !ok { - return fmt.Errorf("unexpected type %T for edge-field team_project", value) + case project.FieldDescription: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field description", values[i]) } else if value.Valid { - pr.team_project = new(int) - *pr.team_project = int(value.Int64) + pr.Description = value.String + } + case project.FieldURL: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field url", values[i]) + } else if value.Valid { + pr.URL = value.String + } + case project.FieldImageURL: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field image_url", values[i]) + } else if value.Valid { + pr.ImageURL = value.String + } + case project.FieldDocURL: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field doc_url", values[i]) + } else if value.Valid { + pr.DocURL = value.String } default: pr.selectValues.Set(columns[i], values[i]) @@ -104,9 +134,14 @@ func (pr *Project) Value(name string) (ent.Value, error) { return pr.selectValues.Get(name) } -// QueryTeam queries the "team" edge of the Project entity. -func (pr *Project) QueryTeam() *TeamQuery { - return NewProjectClient(pr.config).QueryTeam(pr) +// QueryUsers queries the "users" edge of the Project entity. +func (pr *Project) QueryUsers() *UserQuery { + return NewProjectClient(pr.config).QueryUsers(pr) +} + +// QueryTeams queries the "teams" edge of the Project entity. +func (pr *Project) QueryTeams() *TeamQuery { + return NewProjectClient(pr.config).QueryTeams(pr) } // Update returns a builder for updating this Project. @@ -134,6 +169,18 @@ func (pr *Project) String() string { builder.WriteString(fmt.Sprintf("id=%v, ", pr.ID)) builder.WriteString("name=") builder.WriteString(pr.Name) + builder.WriteString(", ") + builder.WriteString("description=") + builder.WriteString(pr.Description) + builder.WriteString(", ") + builder.WriteString("url=") + builder.WriteString(pr.URL) + builder.WriteString(", ") + builder.WriteString("image_url=") + builder.WriteString(pr.ImageURL) + builder.WriteString(", ") + builder.WriteString("doc_url=") + builder.WriteString(pr.DocURL) builder.WriteByte(')') return builder.String() } diff --git a/database/ent/project/project.go b/database/ent/project/project.go index 9d18f4f..4fc22ec 100644 --- a/database/ent/project/project.go +++ b/database/ent/project/project.go @@ -14,30 +14,50 @@ const ( FieldID = "id" // FieldName holds the string denoting the name field in the database. FieldName = "name" - // EdgeTeam holds the string denoting the team edge name in mutations. - EdgeTeam = "team" + // FieldDescription holds the string denoting the description field in the database. + FieldDescription = "description" + // FieldURL holds the string denoting the url field in the database. + FieldURL = "url" + // FieldImageURL holds the string denoting the image_url field in the database. + FieldImageURL = "image_url" + // FieldDocURL holds the string denoting the doc_url field in the database. + FieldDocURL = "doc_url" + // EdgeUsers holds the string denoting the users edge name in mutations. + EdgeUsers = "users" + // EdgeTeams holds the string denoting the teams edge name in mutations. + EdgeTeams = "teams" // Table holds the table name of the project in the database. Table = "projects" - // TeamTable is the table that holds the team relation/edge. - TeamTable = "projects" - // TeamInverseTable is the table name for the Team entity. + // UsersTable is the table that holds the users relation/edge. The primary key declared below. + UsersTable = "user_projects" + // UsersInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UsersInverseTable = "users" + // TeamsTable is the table that holds the teams relation/edge. The primary key declared below. + TeamsTable = "team_projects" + // TeamsInverseTable is the table name for the Team entity. // It exists in this package in order to avoid circular dependency with the "team" package. - TeamInverseTable = "teams" - // TeamColumn is the table column denoting the team relation/edge. - TeamColumn = "team_project" + TeamsInverseTable = "teams" ) // Columns holds all SQL columns for project fields. var Columns = []string{ FieldID, FieldName, + FieldDescription, + FieldURL, + FieldImageURL, + FieldDocURL, } -// ForeignKeys holds the SQL foreign-keys that are owned by the "projects" -// table and are not defined as standalone fields in the schema. -var ForeignKeys = []string{ - "team_project", -} +var ( + // UsersPrimaryKey and UsersColumn2 are the table columns denoting the + // primary key for the users relation (M2M). + UsersPrimaryKey = []string{"user_id", "project_id"} + // TeamsPrimaryKey and TeamsColumn2 are the table columns denoting the + // primary key for the teams relation (M2M). + TeamsPrimaryKey = []string{"team_id", "project_id"} +) // ValidColumn reports if the column name is valid (part of the table columns). func ValidColumn(column string) bool { @@ -46,11 +66,6 @@ func ValidColumn(column string) bool { return true } } - for i := range ForeignKeys { - if column == ForeignKeys[i] { - return true - } - } return false } @@ -67,16 +82,64 @@ func ByName(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldName, opts...).ToFunc() } -// ByTeamField orders the results by team field. -func ByTeamField(field string, opts ...sql.OrderTermOption) OrderOption { +// ByDescription orders the results by the description field. +func ByDescription(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDescription, opts...).ToFunc() +} + +// ByURL orders the results by the url field. +func ByURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldURL, opts...).ToFunc() +} + +// ByImageURL orders the results by the image_url field. +func ByImageURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldImageURL, opts...).ToFunc() +} + +// ByDocURL orders the results by the doc_url field. +func ByDocURL(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldDocURL, opts...).ToFunc() +} + +// ByUsersCount orders the results by users count. +func ByUsersCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { - sqlgraph.OrderByNeighborTerms(s, newTeamStep(), sql.OrderByField(field, opts...)) + sqlgraph.OrderByNeighborsCount(s, newUsersStep(), opts...) } } -func newTeamStep() *sqlgraph.Step { + +// ByUsers orders the results by users terms. +func ByUsers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newUsersStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} + +// ByTeamsCount orders the results by teams count. +func ByTeamsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newTeamsStep(), opts...) + } +} + +// ByTeams orders the results by teams terms. +func ByTeams(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newTeamsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newUsersStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.To(TeamInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, TeamTable, TeamColumn), + sqlgraph.To(UsersInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, UsersTable, UsersPrimaryKey...), + ) +} +func newTeamsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(TeamsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, TeamsTable, TeamsPrimaryKey...), ) } diff --git a/database/ent/project/where.go b/database/ent/project/where.go index 5952c71..900077d 100644 --- a/database/ent/project/where.go +++ b/database/ent/project/where.go @@ -59,6 +59,26 @@ func Name(v string) predicate.Project { return predicate.Project(sql.FieldEQ(FieldName, v)) } +// Description applies equality check predicate on the "description" field. It's identical to DescriptionEQ. +func Description(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldDescription, v)) +} + +// URL applies equality check predicate on the "url" field. It's identical to URLEQ. +func URL(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldURL, v)) +} + +// ImageURL applies equality check predicate on the "image_url" field. It's identical to ImageURLEQ. +func ImageURL(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldImageURL, v)) +} + +// DocURL applies equality check predicate on the "doc_url" field. It's identical to DocURLEQ. +func DocURL(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldDocURL, v)) +} + // NameEQ applies the EQ predicate on the "name" field. func NameEQ(v string) predicate.Project { return predicate.Project(sql.FieldEQ(FieldName, v)) @@ -124,21 +144,304 @@ func NameContainsFold(v string) predicate.Project { return predicate.Project(sql.FieldContainsFold(FieldName, v)) } -// HasTeam applies the HasEdge predicate on the "team" edge. -func HasTeam() predicate.Project { +// DescriptionEQ applies the EQ predicate on the "description" field. +func DescriptionEQ(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldDescription, v)) +} + +// DescriptionNEQ applies the NEQ predicate on the "description" field. +func DescriptionNEQ(v string) predicate.Project { + return predicate.Project(sql.FieldNEQ(FieldDescription, v)) +} + +// DescriptionIn applies the In predicate on the "description" field. +func DescriptionIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldIn(FieldDescription, vs...)) +} + +// DescriptionNotIn applies the NotIn predicate on the "description" field. +func DescriptionNotIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldNotIn(FieldDescription, vs...)) +} + +// DescriptionGT applies the GT predicate on the "description" field. +func DescriptionGT(v string) predicate.Project { + return predicate.Project(sql.FieldGT(FieldDescription, v)) +} + +// DescriptionGTE applies the GTE predicate on the "description" field. +func DescriptionGTE(v string) predicate.Project { + return predicate.Project(sql.FieldGTE(FieldDescription, v)) +} + +// DescriptionLT applies the LT predicate on the "description" field. +func DescriptionLT(v string) predicate.Project { + return predicate.Project(sql.FieldLT(FieldDescription, v)) +} + +// DescriptionLTE applies the LTE predicate on the "description" field. +func DescriptionLTE(v string) predicate.Project { + return predicate.Project(sql.FieldLTE(FieldDescription, v)) +} + +// DescriptionContains applies the Contains predicate on the "description" field. +func DescriptionContains(v string) predicate.Project { + return predicate.Project(sql.FieldContains(FieldDescription, v)) +} + +// DescriptionHasPrefix applies the HasPrefix predicate on the "description" field. +func DescriptionHasPrefix(v string) predicate.Project { + return predicate.Project(sql.FieldHasPrefix(FieldDescription, v)) +} + +// DescriptionHasSuffix applies the HasSuffix predicate on the "description" field. +func DescriptionHasSuffix(v string) predicate.Project { + return predicate.Project(sql.FieldHasSuffix(FieldDescription, v)) +} + +// DescriptionEqualFold applies the EqualFold predicate on the "description" field. +func DescriptionEqualFold(v string) predicate.Project { + return predicate.Project(sql.FieldEqualFold(FieldDescription, v)) +} + +// DescriptionContainsFold applies the ContainsFold predicate on the "description" field. +func DescriptionContainsFold(v string) predicate.Project { + return predicate.Project(sql.FieldContainsFold(FieldDescription, v)) +} + +// URLEQ applies the EQ predicate on the "url" field. +func URLEQ(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldURL, v)) +} + +// URLNEQ applies the NEQ predicate on the "url" field. +func URLNEQ(v string) predicate.Project { + return predicate.Project(sql.FieldNEQ(FieldURL, v)) +} + +// URLIn applies the In predicate on the "url" field. +func URLIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldIn(FieldURL, vs...)) +} + +// URLNotIn applies the NotIn predicate on the "url" field. +func URLNotIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldNotIn(FieldURL, vs...)) +} + +// URLGT applies the GT predicate on the "url" field. +func URLGT(v string) predicate.Project { + return predicate.Project(sql.FieldGT(FieldURL, v)) +} + +// URLGTE applies the GTE predicate on the "url" field. +func URLGTE(v string) predicate.Project { + return predicate.Project(sql.FieldGTE(FieldURL, v)) +} + +// URLLT applies the LT predicate on the "url" field. +func URLLT(v string) predicate.Project { + return predicate.Project(sql.FieldLT(FieldURL, v)) +} + +// URLLTE applies the LTE predicate on the "url" field. +func URLLTE(v string) predicate.Project { + return predicate.Project(sql.FieldLTE(FieldURL, v)) +} + +// URLContains applies the Contains predicate on the "url" field. +func URLContains(v string) predicate.Project { + return predicate.Project(sql.FieldContains(FieldURL, v)) +} + +// URLHasPrefix applies the HasPrefix predicate on the "url" field. +func URLHasPrefix(v string) predicate.Project { + return predicate.Project(sql.FieldHasPrefix(FieldURL, v)) +} + +// URLHasSuffix applies the HasSuffix predicate on the "url" field. +func URLHasSuffix(v string) predicate.Project { + return predicate.Project(sql.FieldHasSuffix(FieldURL, v)) +} + +// URLEqualFold applies the EqualFold predicate on the "url" field. +func URLEqualFold(v string) predicate.Project { + return predicate.Project(sql.FieldEqualFold(FieldURL, v)) +} + +// URLContainsFold applies the ContainsFold predicate on the "url" field. +func URLContainsFold(v string) predicate.Project { + return predicate.Project(sql.FieldContainsFold(FieldURL, v)) +} + +// ImageURLEQ applies the EQ predicate on the "image_url" field. +func ImageURLEQ(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldImageURL, v)) +} + +// ImageURLNEQ applies the NEQ predicate on the "image_url" field. +func ImageURLNEQ(v string) predicate.Project { + return predicate.Project(sql.FieldNEQ(FieldImageURL, v)) +} + +// ImageURLIn applies the In predicate on the "image_url" field. +func ImageURLIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldIn(FieldImageURL, vs...)) +} + +// ImageURLNotIn applies the NotIn predicate on the "image_url" field. +func ImageURLNotIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldNotIn(FieldImageURL, vs...)) +} + +// ImageURLGT applies the GT predicate on the "image_url" field. +func ImageURLGT(v string) predicate.Project { + return predicate.Project(sql.FieldGT(FieldImageURL, v)) +} + +// ImageURLGTE applies the GTE predicate on the "image_url" field. +func ImageURLGTE(v string) predicate.Project { + return predicate.Project(sql.FieldGTE(FieldImageURL, v)) +} + +// ImageURLLT applies the LT predicate on the "image_url" field. +func ImageURLLT(v string) predicate.Project { + return predicate.Project(sql.FieldLT(FieldImageURL, v)) +} + +// ImageURLLTE applies the LTE predicate on the "image_url" field. +func ImageURLLTE(v string) predicate.Project { + return predicate.Project(sql.FieldLTE(FieldImageURL, v)) +} + +// ImageURLContains applies the Contains predicate on the "image_url" field. +func ImageURLContains(v string) predicate.Project { + return predicate.Project(sql.FieldContains(FieldImageURL, v)) +} + +// ImageURLHasPrefix applies the HasPrefix predicate on the "image_url" field. +func ImageURLHasPrefix(v string) predicate.Project { + return predicate.Project(sql.FieldHasPrefix(FieldImageURL, v)) +} + +// ImageURLHasSuffix applies the HasSuffix predicate on the "image_url" field. +func ImageURLHasSuffix(v string) predicate.Project { + return predicate.Project(sql.FieldHasSuffix(FieldImageURL, v)) +} + +// ImageURLEqualFold applies the EqualFold predicate on the "image_url" field. +func ImageURLEqualFold(v string) predicate.Project { + return predicate.Project(sql.FieldEqualFold(FieldImageURL, v)) +} + +// ImageURLContainsFold applies the ContainsFold predicate on the "image_url" field. +func ImageURLContainsFold(v string) predicate.Project { + return predicate.Project(sql.FieldContainsFold(FieldImageURL, v)) +} + +// DocURLEQ applies the EQ predicate on the "doc_url" field. +func DocURLEQ(v string) predicate.Project { + return predicate.Project(sql.FieldEQ(FieldDocURL, v)) +} + +// DocURLNEQ applies the NEQ predicate on the "doc_url" field. +func DocURLNEQ(v string) predicate.Project { + return predicate.Project(sql.FieldNEQ(FieldDocURL, v)) +} + +// DocURLIn applies the In predicate on the "doc_url" field. +func DocURLIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldIn(FieldDocURL, vs...)) +} + +// DocURLNotIn applies the NotIn predicate on the "doc_url" field. +func DocURLNotIn(vs ...string) predicate.Project { + return predicate.Project(sql.FieldNotIn(FieldDocURL, vs...)) +} + +// DocURLGT applies the GT predicate on the "doc_url" field. +func DocURLGT(v string) predicate.Project { + return predicate.Project(sql.FieldGT(FieldDocURL, v)) +} + +// DocURLGTE applies the GTE predicate on the "doc_url" field. +func DocURLGTE(v string) predicate.Project { + return predicate.Project(sql.FieldGTE(FieldDocURL, v)) +} + +// DocURLLT applies the LT predicate on the "doc_url" field. +func DocURLLT(v string) predicate.Project { + return predicate.Project(sql.FieldLT(FieldDocURL, v)) +} + +// DocURLLTE applies the LTE predicate on the "doc_url" field. +func DocURLLTE(v string) predicate.Project { + return predicate.Project(sql.FieldLTE(FieldDocURL, v)) +} + +// DocURLContains applies the Contains predicate on the "doc_url" field. +func DocURLContains(v string) predicate.Project { + return predicate.Project(sql.FieldContains(FieldDocURL, v)) +} + +// DocURLHasPrefix applies the HasPrefix predicate on the "doc_url" field. +func DocURLHasPrefix(v string) predicate.Project { + return predicate.Project(sql.FieldHasPrefix(FieldDocURL, v)) +} + +// DocURLHasSuffix applies the HasSuffix predicate on the "doc_url" field. +func DocURLHasSuffix(v string) predicate.Project { + return predicate.Project(sql.FieldHasSuffix(FieldDocURL, v)) +} + +// DocURLEqualFold applies the EqualFold predicate on the "doc_url" field. +func DocURLEqualFold(v string) predicate.Project { + return predicate.Project(sql.FieldEqualFold(FieldDocURL, v)) +} + +// DocURLContainsFold applies the ContainsFold predicate on the "doc_url" field. +func DocURLContainsFold(v string) predicate.Project { + return predicate.Project(sql.FieldContainsFold(FieldDocURL, v)) +} + +// HasUsers applies the HasEdge predicate on the "users" edge. +func HasUsers() predicate.Project { return predicate.Project(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, TeamTable, TeamColumn), + sqlgraph.Edge(sqlgraph.M2M, true, UsersTable, UsersPrimaryKey...), ) sqlgraph.HasNeighbors(s, step) }) } -// HasTeamWith applies the HasEdge predicate on the "team" edge with a given conditions (other predicates). -func HasTeamWith(preds ...predicate.Team) predicate.Project { +// HasUsersWith applies the HasEdge predicate on the "users" edge with a given conditions (other predicates). +func HasUsersWith(preds ...predicate.User) predicate.Project { return predicate.Project(func(s *sql.Selector) { - step := newTeamStep() + step := newUsersStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasTeams applies the HasEdge predicate on the "teams" edge. +func HasTeams() predicate.Project { + return predicate.Project(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, TeamsTable, TeamsPrimaryKey...), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasTeamsWith applies the HasEdge predicate on the "teams" edge with a given conditions (other predicates). +func HasTeamsWith(preds ...predicate.Team) predicate.Project { + return predicate.Project(func(s *sql.Selector) { + step := newTeamsStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { p(s) diff --git a/database/ent/project_create.go b/database/ent/project_create.go index ccfdd5d..5445f60 100644 --- a/database/ent/project_create.go +++ b/database/ent/project_create.go @@ -8,6 +8,7 @@ import ( "fmt" "portfolio/database/ent/project" "portfolio/database/ent/team" + "portfolio/database/ent/user" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" @@ -26,23 +27,58 @@ func (pc *ProjectCreate) SetName(s string) *ProjectCreate { return pc } -// SetTeamID sets the "team" edge to the Team entity by ID. -func (pc *ProjectCreate) SetTeamID(id int) *ProjectCreate { - pc.mutation.SetTeamID(id) +// SetDescription sets the "description" field. +func (pc *ProjectCreate) SetDescription(s string) *ProjectCreate { + pc.mutation.SetDescription(s) return pc } -// SetNillableTeamID sets the "team" edge to the Team entity by ID if the given value is not nil. -func (pc *ProjectCreate) SetNillableTeamID(id *int) *ProjectCreate { - if id != nil { - pc = pc.SetTeamID(*id) +// SetURL sets the "url" field. +func (pc *ProjectCreate) SetURL(s string) *ProjectCreate { + pc.mutation.SetURL(s) + return pc +} + +// SetImageURL sets the "image_url" field. +func (pc *ProjectCreate) SetImageURL(s string) *ProjectCreate { + pc.mutation.SetImageURL(s) + return pc +} + +// SetDocURL sets the "doc_url" field. +func (pc *ProjectCreate) SetDocURL(s string) *ProjectCreate { + pc.mutation.SetDocURL(s) + return pc +} + +// AddUserIDs adds the "users" edge to the User entity by IDs. +func (pc *ProjectCreate) AddUserIDs(ids ...int) *ProjectCreate { + pc.mutation.AddUserIDs(ids...) + return pc +} + +// AddUsers adds the "users" edges to the User entity. +func (pc *ProjectCreate) AddUsers(u ...*User) *ProjectCreate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID } + return pc.AddUserIDs(ids...) +} + +// AddTeamIDs adds the "teams" edge to the Team entity by IDs. +func (pc *ProjectCreate) AddTeamIDs(ids ...int) *ProjectCreate { + pc.mutation.AddTeamIDs(ids...) return pc } -// SetTeam sets the "team" edge to the Team entity. -func (pc *ProjectCreate) SetTeam(t *Team) *ProjectCreate { - return pc.SetTeamID(t.ID) +// AddTeams adds the "teams" edges to the Team entity. +func (pc *ProjectCreate) AddTeams(t ...*Team) *ProjectCreate { + ids := make([]int, len(t)) + for i := range t { + ids[i] = t[i].ID + } + return pc.AddTeamIDs(ids...) } // Mutation returns the ProjectMutation object of the builder. @@ -82,6 +118,18 @@ func (pc *ProjectCreate) check() error { if _, ok := pc.mutation.Name(); !ok { return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "Project.name"`)} } + if _, ok := pc.mutation.Description(); !ok { + return &ValidationError{Name: "description", err: errors.New(`ent: missing required field "Project.description"`)} + } + if _, ok := pc.mutation.URL(); !ok { + return &ValidationError{Name: "url", err: errors.New(`ent: missing required field "Project.url"`)} + } + if _, ok := pc.mutation.ImageURL(); !ok { + return &ValidationError{Name: "image_url", err: errors.New(`ent: missing required field "Project.image_url"`)} + } + if _, ok := pc.mutation.DocURL(); !ok { + return &ValidationError{Name: "doc_url", err: errors.New(`ent: missing required field "Project.doc_url"`)} + } return nil } @@ -112,12 +160,44 @@ func (pc *ProjectCreate) createSpec() (*Project, *sqlgraph.CreateSpec) { _spec.SetField(project.FieldName, field.TypeString, value) _node.Name = value } - if nodes := pc.mutation.TeamIDs(); len(nodes) > 0 { + if value, ok := pc.mutation.Description(); ok { + _spec.SetField(project.FieldDescription, field.TypeString, value) + _node.Description = value + } + if value, ok := pc.mutation.URL(); ok { + _spec.SetField(project.FieldURL, field.TypeString, value) + _node.URL = value + } + if value, ok := pc.mutation.ImageURL(); ok { + _spec.SetField(project.FieldImageURL, field.TypeString, value) + _node.ImageURL = value + } + if value, ok := pc.mutation.DocURL(); ok { + _spec.SetField(project.FieldDocURL, field.TypeString, value) + _node.DocURL = value + } + if nodes := pc.mutation.UsersIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.M2M, Inverse: true, - Table: project.TeamTable, - Columns: []string{project.TeamColumn}, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := pc.mutation.TeamsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), @@ -126,7 +206,6 @@ func (pc *ProjectCreate) createSpec() (*Project, *sqlgraph.CreateSpec) { for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } - _node.team_project = &nodes[0] _spec.Edges = append(_spec.Edges, edge) } return _node, _spec diff --git a/database/ent/project_query.go b/database/ent/project_query.go index 90c3973..5c46a38 100644 --- a/database/ent/project_query.go +++ b/database/ent/project_query.go @@ -4,11 +4,13 @@ package ent import ( "context" + "database/sql/driver" "fmt" "math" "portfolio/database/ent/predicate" "portfolio/database/ent/project" "portfolio/database/ent/team" + "portfolio/database/ent/user" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -22,8 +24,8 @@ type ProjectQuery struct { order []project.OrderOption inters []Interceptor predicates []predicate.Project - withTeam *TeamQuery - withFKs bool + withUsers *UserQuery + withTeams *TeamQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -60,8 +62,30 @@ func (pq *ProjectQuery) Order(o ...project.OrderOption) *ProjectQuery { return pq } -// QueryTeam chains the current query on the "team" edge. -func (pq *ProjectQuery) QueryTeam() *TeamQuery { +// QueryUsers chains the current query on the "users" edge. +func (pq *ProjectQuery) QueryUsers() *UserQuery { + query := (&UserClient{config: pq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := pq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := pq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(project.Table, project.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.M2M, true, project.UsersTable, project.UsersPrimaryKey...), + ) + fromU = sqlgraph.SetNeighbors(pq.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryTeams chains the current query on the "teams" edge. +func (pq *ProjectQuery) QueryTeams() *TeamQuery { query := (&TeamClient{config: pq.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := pq.prepareQuery(ctx); err != nil { @@ -74,7 +98,7 @@ func (pq *ProjectQuery) QueryTeam() *TeamQuery { step := sqlgraph.NewStep( sqlgraph.From(project.Table, project.FieldID, selector), sqlgraph.To(team.Table, team.FieldID), - sqlgraph.Edge(sqlgraph.M2O, true, project.TeamTable, project.TeamColumn), + sqlgraph.Edge(sqlgraph.M2M, true, project.TeamsTable, project.TeamsPrimaryKey...), ) fromU = sqlgraph.SetNeighbors(pq.driver.Dialect(), step) return fromU, nil @@ -274,21 +298,33 @@ func (pq *ProjectQuery) Clone() *ProjectQuery { order: append([]project.OrderOption{}, pq.order...), inters: append([]Interceptor{}, pq.inters...), predicates: append([]predicate.Project{}, pq.predicates...), - withTeam: pq.withTeam.Clone(), + withUsers: pq.withUsers.Clone(), + withTeams: pq.withTeams.Clone(), // clone intermediate query. sql: pq.sql.Clone(), path: pq.path, } } -// WithTeam tells the query-builder to eager-load the nodes that are connected to -// the "team" edge. The optional arguments are used to configure the query builder of the edge. -func (pq *ProjectQuery) WithTeam(opts ...func(*TeamQuery)) *ProjectQuery { +// WithUsers tells the query-builder to eager-load the nodes that are connected to +// the "users" edge. The optional arguments are used to configure the query builder of the edge. +func (pq *ProjectQuery) WithUsers(opts ...func(*UserQuery)) *ProjectQuery { + query := (&UserClient{config: pq.config}).Query() + for _, opt := range opts { + opt(query) + } + pq.withUsers = query + return pq +} + +// WithTeams tells the query-builder to eager-load the nodes that are connected to +// the "teams" edge. The optional arguments are used to configure the query builder of the edge. +func (pq *ProjectQuery) WithTeams(opts ...func(*TeamQuery)) *ProjectQuery { query := (&TeamClient{config: pq.config}).Query() for _, opt := range opts { opt(query) } - pq.withTeam = query + pq.withTeams = query return pq } @@ -369,18 +405,12 @@ func (pq *ProjectQuery) prepareQuery(ctx context.Context) error { func (pq *ProjectQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Project, error) { var ( nodes = []*Project{} - withFKs = pq.withFKs _spec = pq.querySpec() - loadedTypes = [1]bool{ - pq.withTeam != nil, + loadedTypes = [2]bool{ + pq.withUsers != nil, + pq.withTeams != nil, } ) - if pq.withTeam != nil { - withFKs = true - } - if withFKs { - _spec.Node.Columns = append(_spec.Node.Columns, project.ForeignKeys...) - } _spec.ScanValues = func(columns []string) ([]any, error) { return (*Project).scanValues(nil, columns) } @@ -399,43 +429,141 @@ func (pq *ProjectQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Proj if len(nodes) == 0 { return nodes, nil } - if query := pq.withTeam; query != nil { - if err := pq.loadTeam(ctx, query, nodes, nil, - func(n *Project, e *Team) { n.Edges.Team = e }); err != nil { + if query := pq.withUsers; query != nil { + if err := pq.loadUsers(ctx, query, nodes, + func(n *Project) { n.Edges.Users = []*User{} }, + func(n *Project, e *User) { n.Edges.Users = append(n.Edges.Users, e) }); err != nil { + return nil, err + } + } + if query := pq.withTeams; query != nil { + if err := pq.loadTeams(ctx, query, nodes, + func(n *Project) { n.Edges.Teams = []*Team{} }, + func(n *Project, e *Team) { n.Edges.Teams = append(n.Edges.Teams, e) }); err != nil { return nil, err } } return nodes, nil } -func (pq *ProjectQuery) loadTeam(ctx context.Context, query *TeamQuery, nodes []*Project, init func(*Project), assign func(*Project, *Team)) error { - ids := make([]int, 0, len(nodes)) - nodeids := make(map[int][]*Project) - for i := range nodes { - if nodes[i].team_project == nil { - continue +func (pq *ProjectQuery) loadUsers(ctx context.Context, query *UserQuery, nodes []*Project, init func(*Project), assign func(*Project, *User)) error { + edgeIDs := make([]driver.Value, len(nodes)) + byID := make(map[int]*Project) + nids := make(map[int]map[*Project]struct{}) + for i, node := range nodes { + edgeIDs[i] = node.ID + byID[node.ID] = node + if init != nil { + init(node) } - fk := *nodes[i].team_project - if _, ok := nodeids[fk]; !ok { - ids = append(ids, fk) - } - nodeids[fk] = append(nodeids[fk], nodes[i]) } - if len(ids) == 0 { - return nil + query.Where(func(s *sql.Selector) { + joinT := sql.Table(project.UsersTable) + s.Join(joinT).On(s.C(user.FieldID), joinT.C(project.UsersPrimaryKey[0])) + s.Where(sql.InValues(joinT.C(project.UsersPrimaryKey[1]), edgeIDs...)) + columns := s.SelectedColumns() + s.Select(joinT.C(project.UsersPrimaryKey[1])) + s.AppendSelect(columns...) + s.SetDistinct(false) + }) + if err := query.prepareQuery(ctx); err != nil { + return err } - query.Where(team.IDIn(ids...)) - neighbors, err := query.All(ctx) + qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) { + assign := spec.Assign + values := spec.ScanValues + spec.ScanValues = func(columns []string) ([]any, error) { + values, err := values(columns[1:]) + if err != nil { + return nil, err + } + return append([]any{new(sql.NullInt64)}, values...), nil + } + spec.Assign = func(columns []string, values []any) error { + outValue := int(values[0].(*sql.NullInt64).Int64) + inValue := int(values[1].(*sql.NullInt64).Int64) + if nids[inValue] == nil { + nids[inValue] = map[*Project]struct{}{byID[outValue]: {}} + return assign(columns[1:], values[1:]) + } + nids[inValue][byID[outValue]] = struct{}{} + return nil + } + }) + }) + neighbors, err := withInterceptors[[]*User](ctx, query, qr, query.inters) if err != nil { return err } for _, n := range neighbors { - nodes, ok := nodeids[n.ID] + nodes, ok := nids[n.ID] if !ok { - return fmt.Errorf(`unexpected foreign-key "team_project" returned %v`, n.ID) + return fmt.Errorf(`unexpected "users" node returned %v`, n.ID) } - for i := range nodes { - assign(nodes[i], n) + for kn := range nodes { + assign(kn, n) + } + } + return nil +} +func (pq *ProjectQuery) loadTeams(ctx context.Context, query *TeamQuery, nodes []*Project, init func(*Project), assign func(*Project, *Team)) error { + edgeIDs := make([]driver.Value, len(nodes)) + byID := make(map[int]*Project) + nids := make(map[int]map[*Project]struct{}) + for i, node := range nodes { + edgeIDs[i] = node.ID + byID[node.ID] = node + if init != nil { + init(node) + } + } + query.Where(func(s *sql.Selector) { + joinT := sql.Table(project.TeamsTable) + s.Join(joinT).On(s.C(team.FieldID), joinT.C(project.TeamsPrimaryKey[0])) + s.Where(sql.InValues(joinT.C(project.TeamsPrimaryKey[1]), edgeIDs...)) + columns := s.SelectedColumns() + s.Select(joinT.C(project.TeamsPrimaryKey[1])) + s.AppendSelect(columns...) + s.SetDistinct(false) + }) + if err := query.prepareQuery(ctx); err != nil { + return err + } + qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) { + assign := spec.Assign + values := spec.ScanValues + spec.ScanValues = func(columns []string) ([]any, error) { + values, err := values(columns[1:]) + if err != nil { + return nil, err + } + return append([]any{new(sql.NullInt64)}, values...), nil + } + spec.Assign = func(columns []string, values []any) error { + outValue := int(values[0].(*sql.NullInt64).Int64) + inValue := int(values[1].(*sql.NullInt64).Int64) + if nids[inValue] == nil { + nids[inValue] = map[*Project]struct{}{byID[outValue]: {}} + return assign(columns[1:], values[1:]) + } + nids[inValue][byID[outValue]] = struct{}{} + return nil + } + }) + }) + neighbors, err := withInterceptors[[]*Team](ctx, query, qr, query.inters) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nids[n.ID] + if !ok { + return fmt.Errorf(`unexpected "teams" node returned %v`, n.ID) + } + for kn := range nodes { + assign(kn, n) } } return nil diff --git a/database/ent/project_update.go b/database/ent/project_update.go index 8a4d106..9ba13ce 100644 --- a/database/ent/project_update.go +++ b/database/ent/project_update.go @@ -9,6 +9,7 @@ import ( "portfolio/database/ent/predicate" "portfolio/database/ent/project" "portfolio/database/ent/team" + "portfolio/database/ent/user" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" @@ -42,23 +43,90 @@ func (pu *ProjectUpdate) SetNillableName(s *string) *ProjectUpdate { return pu } -// SetTeamID sets the "team" edge to the Team entity by ID. -func (pu *ProjectUpdate) SetTeamID(id int) *ProjectUpdate { - pu.mutation.SetTeamID(id) +// SetDescription sets the "description" field. +func (pu *ProjectUpdate) SetDescription(s string) *ProjectUpdate { + pu.mutation.SetDescription(s) return pu } -// SetNillableTeamID sets the "team" edge to the Team entity by ID if the given value is not nil. -func (pu *ProjectUpdate) SetNillableTeamID(id *int) *ProjectUpdate { - if id != nil { - pu = pu.SetTeamID(*id) +// SetNillableDescription sets the "description" field if the given value is not nil. +func (pu *ProjectUpdate) SetNillableDescription(s *string) *ProjectUpdate { + if s != nil { + pu.SetDescription(*s) } return pu } -// SetTeam sets the "team" edge to the Team entity. -func (pu *ProjectUpdate) SetTeam(t *Team) *ProjectUpdate { - return pu.SetTeamID(t.ID) +// SetURL sets the "url" field. +func (pu *ProjectUpdate) SetURL(s string) *ProjectUpdate { + pu.mutation.SetURL(s) + return pu +} + +// SetNillableURL sets the "url" field if the given value is not nil. +func (pu *ProjectUpdate) SetNillableURL(s *string) *ProjectUpdate { + if s != nil { + pu.SetURL(*s) + } + return pu +} + +// SetImageURL sets the "image_url" field. +func (pu *ProjectUpdate) SetImageURL(s string) *ProjectUpdate { + pu.mutation.SetImageURL(s) + return pu +} + +// SetNillableImageURL sets the "image_url" field if the given value is not nil. +func (pu *ProjectUpdate) SetNillableImageURL(s *string) *ProjectUpdate { + if s != nil { + pu.SetImageURL(*s) + } + return pu +} + +// SetDocURL sets the "doc_url" field. +func (pu *ProjectUpdate) SetDocURL(s string) *ProjectUpdate { + pu.mutation.SetDocURL(s) + return pu +} + +// SetNillableDocURL sets the "doc_url" field if the given value is not nil. +func (pu *ProjectUpdate) SetNillableDocURL(s *string) *ProjectUpdate { + if s != nil { + pu.SetDocURL(*s) + } + return pu +} + +// AddUserIDs adds the "users" edge to the User entity by IDs. +func (pu *ProjectUpdate) AddUserIDs(ids ...int) *ProjectUpdate { + pu.mutation.AddUserIDs(ids...) + return pu +} + +// AddUsers adds the "users" edges to the User entity. +func (pu *ProjectUpdate) AddUsers(u ...*User) *ProjectUpdate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return pu.AddUserIDs(ids...) +} + +// AddTeamIDs adds the "teams" edge to the Team entity by IDs. +func (pu *ProjectUpdate) AddTeamIDs(ids ...int) *ProjectUpdate { + pu.mutation.AddTeamIDs(ids...) + return pu +} + +// AddTeams adds the "teams" edges to the Team entity. +func (pu *ProjectUpdate) AddTeams(t ...*Team) *ProjectUpdate { + ids := make([]int, len(t)) + for i := range t { + ids[i] = t[i].ID + } + return pu.AddTeamIDs(ids...) } // Mutation returns the ProjectMutation object of the builder. @@ -66,12 +134,48 @@ func (pu *ProjectUpdate) Mutation() *ProjectMutation { return pu.mutation } -// ClearTeam clears the "team" edge to the Team entity. -func (pu *ProjectUpdate) ClearTeam() *ProjectUpdate { - pu.mutation.ClearTeam() +// ClearUsers clears all "users" edges to the User entity. +func (pu *ProjectUpdate) ClearUsers() *ProjectUpdate { + pu.mutation.ClearUsers() return pu } +// RemoveUserIDs removes the "users" edge to User entities by IDs. +func (pu *ProjectUpdate) RemoveUserIDs(ids ...int) *ProjectUpdate { + pu.mutation.RemoveUserIDs(ids...) + return pu +} + +// RemoveUsers removes "users" edges to User entities. +func (pu *ProjectUpdate) RemoveUsers(u ...*User) *ProjectUpdate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return pu.RemoveUserIDs(ids...) +} + +// ClearTeams clears all "teams" edges to the Team entity. +func (pu *ProjectUpdate) ClearTeams() *ProjectUpdate { + pu.mutation.ClearTeams() + return pu +} + +// RemoveTeamIDs removes the "teams" edge to Team entities by IDs. +func (pu *ProjectUpdate) RemoveTeamIDs(ids ...int) *ProjectUpdate { + pu.mutation.RemoveTeamIDs(ids...) + return pu +} + +// RemoveTeams removes "teams" edges to Team entities. +func (pu *ProjectUpdate) RemoveTeams(t ...*Team) *ProjectUpdate { + ids := make([]int, len(t)) + for i := range t { + ids[i] = t[i].ID + } + return pu.RemoveTeamIDs(ids...) +} + // Save executes the query and returns the number of nodes affected by the update operation. func (pu *ProjectUpdate) Save(ctx context.Context) (int, error) { return withHooks(ctx, pu.sqlSave, pu.mutation, pu.hooks) @@ -111,12 +215,69 @@ func (pu *ProjectUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := pu.mutation.Name(); ok { _spec.SetField(project.FieldName, field.TypeString, value) } - if pu.mutation.TeamCleared() { + if value, ok := pu.mutation.Description(); ok { + _spec.SetField(project.FieldDescription, field.TypeString, value) + } + if value, ok := pu.mutation.URL(); ok { + _spec.SetField(project.FieldURL, field.TypeString, value) + } + if value, ok := pu.mutation.ImageURL(); ok { + _spec.SetField(project.FieldImageURL, field.TypeString, value) + } + if value, ok := pu.mutation.DocURL(); ok { + _spec.SetField(project.FieldDocURL, field.TypeString, value) + } + if pu.mutation.UsersCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.M2M, Inverse: true, - Table: project.TeamTable, - Columns: []string{project.TeamColumn}, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := pu.mutation.RemovedUsersIDs(); len(nodes) > 0 && !pu.mutation.UsersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := pu.mutation.UsersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if pu.mutation.TeamsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), @@ -124,12 +285,28 @@ func (pu *ProjectUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := pu.mutation.TeamIDs(); len(nodes) > 0 { + if nodes := pu.mutation.RemovedTeamsIDs(); len(nodes) > 0 && !pu.mutation.TeamsCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.M2M, Inverse: true, - Table: project.TeamTable, - Columns: []string{project.TeamColumn}, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := pu.mutation.TeamsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), @@ -174,23 +351,90 @@ func (puo *ProjectUpdateOne) SetNillableName(s *string) *ProjectUpdateOne { return puo } -// SetTeamID sets the "team" edge to the Team entity by ID. -func (puo *ProjectUpdateOne) SetTeamID(id int) *ProjectUpdateOne { - puo.mutation.SetTeamID(id) +// SetDescription sets the "description" field. +func (puo *ProjectUpdateOne) SetDescription(s string) *ProjectUpdateOne { + puo.mutation.SetDescription(s) return puo } -// SetNillableTeamID sets the "team" edge to the Team entity by ID if the given value is not nil. -func (puo *ProjectUpdateOne) SetNillableTeamID(id *int) *ProjectUpdateOne { - if id != nil { - puo = puo.SetTeamID(*id) +// SetNillableDescription sets the "description" field if the given value is not nil. +func (puo *ProjectUpdateOne) SetNillableDescription(s *string) *ProjectUpdateOne { + if s != nil { + puo.SetDescription(*s) } return puo } -// SetTeam sets the "team" edge to the Team entity. -func (puo *ProjectUpdateOne) SetTeam(t *Team) *ProjectUpdateOne { - return puo.SetTeamID(t.ID) +// SetURL sets the "url" field. +func (puo *ProjectUpdateOne) SetURL(s string) *ProjectUpdateOne { + puo.mutation.SetURL(s) + return puo +} + +// SetNillableURL sets the "url" field if the given value is not nil. +func (puo *ProjectUpdateOne) SetNillableURL(s *string) *ProjectUpdateOne { + if s != nil { + puo.SetURL(*s) + } + return puo +} + +// SetImageURL sets the "image_url" field. +func (puo *ProjectUpdateOne) SetImageURL(s string) *ProjectUpdateOne { + puo.mutation.SetImageURL(s) + return puo +} + +// SetNillableImageURL sets the "image_url" field if the given value is not nil. +func (puo *ProjectUpdateOne) SetNillableImageURL(s *string) *ProjectUpdateOne { + if s != nil { + puo.SetImageURL(*s) + } + return puo +} + +// SetDocURL sets the "doc_url" field. +func (puo *ProjectUpdateOne) SetDocURL(s string) *ProjectUpdateOne { + puo.mutation.SetDocURL(s) + return puo +} + +// SetNillableDocURL sets the "doc_url" field if the given value is not nil. +func (puo *ProjectUpdateOne) SetNillableDocURL(s *string) *ProjectUpdateOne { + if s != nil { + puo.SetDocURL(*s) + } + return puo +} + +// AddUserIDs adds the "users" edge to the User entity by IDs. +func (puo *ProjectUpdateOne) AddUserIDs(ids ...int) *ProjectUpdateOne { + puo.mutation.AddUserIDs(ids...) + return puo +} + +// AddUsers adds the "users" edges to the User entity. +func (puo *ProjectUpdateOne) AddUsers(u ...*User) *ProjectUpdateOne { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return puo.AddUserIDs(ids...) +} + +// AddTeamIDs adds the "teams" edge to the Team entity by IDs. +func (puo *ProjectUpdateOne) AddTeamIDs(ids ...int) *ProjectUpdateOne { + puo.mutation.AddTeamIDs(ids...) + return puo +} + +// AddTeams adds the "teams" edges to the Team entity. +func (puo *ProjectUpdateOne) AddTeams(t ...*Team) *ProjectUpdateOne { + ids := make([]int, len(t)) + for i := range t { + ids[i] = t[i].ID + } + return puo.AddTeamIDs(ids...) } // Mutation returns the ProjectMutation object of the builder. @@ -198,12 +442,48 @@ func (puo *ProjectUpdateOne) Mutation() *ProjectMutation { return puo.mutation } -// ClearTeam clears the "team" edge to the Team entity. -func (puo *ProjectUpdateOne) ClearTeam() *ProjectUpdateOne { - puo.mutation.ClearTeam() +// ClearUsers clears all "users" edges to the User entity. +func (puo *ProjectUpdateOne) ClearUsers() *ProjectUpdateOne { + puo.mutation.ClearUsers() return puo } +// RemoveUserIDs removes the "users" edge to User entities by IDs. +func (puo *ProjectUpdateOne) RemoveUserIDs(ids ...int) *ProjectUpdateOne { + puo.mutation.RemoveUserIDs(ids...) + return puo +} + +// RemoveUsers removes "users" edges to User entities. +func (puo *ProjectUpdateOne) RemoveUsers(u ...*User) *ProjectUpdateOne { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return puo.RemoveUserIDs(ids...) +} + +// ClearTeams clears all "teams" edges to the Team entity. +func (puo *ProjectUpdateOne) ClearTeams() *ProjectUpdateOne { + puo.mutation.ClearTeams() + return puo +} + +// RemoveTeamIDs removes the "teams" edge to Team entities by IDs. +func (puo *ProjectUpdateOne) RemoveTeamIDs(ids ...int) *ProjectUpdateOne { + puo.mutation.RemoveTeamIDs(ids...) + return puo +} + +// RemoveTeams removes "teams" edges to Team entities. +func (puo *ProjectUpdateOne) RemoveTeams(t ...*Team) *ProjectUpdateOne { + ids := make([]int, len(t)) + for i := range t { + ids[i] = t[i].ID + } + return puo.RemoveTeamIDs(ids...) +} + // Where appends a list predicates to the ProjectUpdate builder. func (puo *ProjectUpdateOne) Where(ps ...predicate.Project) *ProjectUpdateOne { puo.mutation.Where(ps...) @@ -273,12 +553,69 @@ func (puo *ProjectUpdateOne) sqlSave(ctx context.Context) (_node *Project, err e if value, ok := puo.mutation.Name(); ok { _spec.SetField(project.FieldName, field.TypeString, value) } - if puo.mutation.TeamCleared() { + if value, ok := puo.mutation.Description(); ok { + _spec.SetField(project.FieldDescription, field.TypeString, value) + } + if value, ok := puo.mutation.URL(); ok { + _spec.SetField(project.FieldURL, field.TypeString, value) + } + if value, ok := puo.mutation.ImageURL(); ok { + _spec.SetField(project.FieldImageURL, field.TypeString, value) + } + if value, ok := puo.mutation.DocURL(); ok { + _spec.SetField(project.FieldDocURL, field.TypeString, value) + } + if puo.mutation.UsersCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.M2M, Inverse: true, - Table: project.TeamTable, - Columns: []string{project.TeamColumn}, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := puo.mutation.RemovedUsersIDs(); len(nodes) > 0 && !puo.mutation.UsersCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := puo.mutation.UsersIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.UsersTable, + Columns: project.UsersPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if puo.mutation.TeamsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), @@ -286,12 +623,28 @@ func (puo *ProjectUpdateOne) sqlSave(ctx context.Context) (_node *Project, err e } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := puo.mutation.TeamIDs(); len(nodes) > 0 { + if nodes := puo.mutation.RemovedTeamsIDs(); len(nodes) > 0 && !puo.mutation.TeamsCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.M2M, Inverse: true, - Table: project.TeamTable, - Columns: []string{project.TeamColumn}, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := puo.mutation.TeamsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: true, + Table: project.TeamsTable, + Columns: project.TeamsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(team.FieldID, field.TypeInt), diff --git a/database/ent/schema/project.go b/database/ent/schema/project.go index c85bba2..b93c73b 100644 --- a/database/ent/schema/project.go +++ b/database/ent/schema/project.go @@ -16,14 +16,19 @@ func (Project) Fields() []ent.Field { return []ent.Field{ field.String("name"). Unique(), + field.String("description"), + field.String("url"), + field.String("image_url"), + field.String("doc_url"), } } // Edges of the Project. func (Project) Edges() []ent.Edge { return []ent.Edge{ - edge.From("team", Team.Type). - Ref("project"). - Unique(), + edge.From("users", User.Type). + Ref("projects"), + edge.From("teams", Team.Type). + Ref("projects"), } } diff --git a/database/ent/schema/team.go b/database/ent/schema/team.go index 24fa322..5314a3d 100644 --- a/database/ent/schema/team.go +++ b/database/ent/schema/team.go @@ -21,7 +21,7 @@ func (Team) Fields() []ent.Field { // Edges of the Team. func (Team) Edges() []ent.Edge { return []ent.Edge{ - edge.To("project", Project.Type), + edge.To("projects", Project.Type), edge.From("users", User.Type). Ref("teams"), } diff --git a/database/ent/schema/user.go b/database/ent/schema/user.go index 75f334d..f490834 100644 --- a/database/ent/schema/user.go +++ b/database/ent/schema/user.go @@ -16,6 +16,7 @@ func (User) Fields() []ent.Field { return []ent.Field{ field.String("name"). Unique(), + field.String("email"), field.String("password"), field.Enum("role"). Values("admin", "user", "visitor"), @@ -26,5 +27,6 @@ func (User) Fields() []ent.Field { func (User) Edges() []ent.Edge { return []ent.Edge{ edge.To("teams", Team.Type), + edge.To("projects", Project.Type), } } diff --git a/database/ent/team.go b/database/ent/team.go index 7065b97..1869ce4 100644 --- a/database/ent/team.go +++ b/database/ent/team.go @@ -26,8 +26,8 @@ type Team struct { // TeamEdges holds the relations/edges for other nodes in the graph. type TeamEdges struct { - // Project holds the value of the project edge. - Project []*Project `json:"project,omitempty"` + // Projects holds the value of the projects edge. + Projects []*Project `json:"projects,omitempty"` // Users holds the value of the users edge. Users []*User `json:"users,omitempty"` // loadedTypes holds the information for reporting if a @@ -35,13 +35,13 @@ type TeamEdges struct { loadedTypes [2]bool } -// ProjectOrErr returns the Project value or an error if the edge +// ProjectsOrErr returns the Projects value or an error if the edge // was not loaded in eager-loading. -func (e TeamEdges) ProjectOrErr() ([]*Project, error) { +func (e TeamEdges) ProjectsOrErr() ([]*Project, error) { if e.loadedTypes[0] { - return e.Project, nil + return e.Projects, nil } - return nil, &NotLoadedError{edge: "project"} + return nil, &NotLoadedError{edge: "projects"} } // UsersOrErr returns the Users value or an error if the edge @@ -102,9 +102,9 @@ func (t *Team) Value(name string) (ent.Value, error) { return t.selectValues.Get(name) } -// QueryProject queries the "project" edge of the Team entity. -func (t *Team) QueryProject() *ProjectQuery { - return NewTeamClient(t.config).QueryProject(t) +// QueryProjects queries the "projects" edge of the Team entity. +func (t *Team) QueryProjects() *ProjectQuery { + return NewTeamClient(t.config).QueryProjects(t) } // QueryUsers queries the "users" edge of the Team entity. diff --git a/database/ent/team/team.go b/database/ent/team/team.go index f5b112e..c74cb2c 100644 --- a/database/ent/team/team.go +++ b/database/ent/team/team.go @@ -14,19 +14,17 @@ const ( FieldID = "id" // FieldName holds the string denoting the name field in the database. FieldName = "name" - // EdgeProject holds the string denoting the project edge name in mutations. - EdgeProject = "project" + // EdgeProjects holds the string denoting the projects edge name in mutations. + EdgeProjects = "projects" // EdgeUsers holds the string denoting the users edge name in mutations. EdgeUsers = "users" // Table holds the table name of the team in the database. Table = "teams" - // ProjectTable is the table that holds the project relation/edge. - ProjectTable = "projects" - // ProjectInverseTable is the table name for the Project entity. + // ProjectsTable is the table that holds the projects relation/edge. The primary key declared below. + ProjectsTable = "team_projects" + // ProjectsInverseTable is the table name for the Project entity. // It exists in this package in order to avoid circular dependency with the "project" package. - ProjectInverseTable = "projects" - // ProjectColumn is the table column denoting the project relation/edge. - ProjectColumn = "team_project" + ProjectsInverseTable = "projects" // UsersTable is the table that holds the users relation/edge. The primary key declared below. UsersTable = "user_teams" // UsersInverseTable is the table name for the User entity. @@ -41,6 +39,9 @@ var Columns = []string{ } var ( + // ProjectsPrimaryKey and ProjectsColumn2 are the table columns denoting the + // primary key for the projects relation (M2M). + ProjectsPrimaryKey = []string{"team_id", "project_id"} // UsersPrimaryKey and UsersColumn2 are the table columns denoting the // primary key for the users relation (M2M). UsersPrimaryKey = []string{"user_id", "team_id"} @@ -69,17 +70,17 @@ func ByName(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldName, opts...).ToFunc() } -// ByProjectCount orders the results by project count. -func ByProjectCount(opts ...sql.OrderTermOption) OrderOption { +// ByProjectsCount orders the results by projects count. +func ByProjectsCount(opts ...sql.OrderTermOption) OrderOption { return func(s *sql.Selector) { - sqlgraph.OrderByNeighborsCount(s, newProjectStep(), opts...) + sqlgraph.OrderByNeighborsCount(s, newProjectsStep(), opts...) } } -// ByProject orders the results by project terms. -func ByProject(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { +// ByProjects orders the results by projects terms. +func ByProjects(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { return func(s *sql.Selector) { - sqlgraph.OrderByNeighborTerms(s, newProjectStep(), append([]sql.OrderTerm{term}, terms...)...) + sqlgraph.OrderByNeighborTerms(s, newProjectsStep(), append([]sql.OrderTerm{term}, terms...)...) } } @@ -96,11 +97,11 @@ func ByUsers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { sqlgraph.OrderByNeighborTerms(s, newUsersStep(), append([]sql.OrderTerm{term}, terms...)...) } } -func newProjectStep() *sqlgraph.Step { +func newProjectsStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.To(ProjectInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, ProjectTable, ProjectColumn), + sqlgraph.To(ProjectsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, ProjectsTable, ProjectsPrimaryKey...), ) } func newUsersStep() *sqlgraph.Step { diff --git a/database/ent/team/where.go b/database/ent/team/where.go index 2afd533..7828c62 100644 --- a/database/ent/team/where.go +++ b/database/ent/team/where.go @@ -124,21 +124,21 @@ func NameContainsFold(v string) predicate.Team { return predicate.Team(sql.FieldContainsFold(FieldName, v)) } -// HasProject applies the HasEdge predicate on the "project" edge. -func HasProject() predicate.Team { +// HasProjects applies the HasEdge predicate on the "projects" edge. +func HasProjects() predicate.Team { return predicate.Team(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, ProjectTable, ProjectColumn), + sqlgraph.Edge(sqlgraph.M2M, false, ProjectsTable, ProjectsPrimaryKey...), ) sqlgraph.HasNeighbors(s, step) }) } -// HasProjectWith applies the HasEdge predicate on the "project" edge with a given conditions (other predicates). -func HasProjectWith(preds ...predicate.Project) predicate.Team { +// HasProjectsWith applies the HasEdge predicate on the "projects" edge with a given conditions (other predicates). +func HasProjectsWith(preds ...predicate.Project) predicate.Team { return predicate.Team(func(s *sql.Selector) { - step := newProjectStep() + step := newProjectsStep() sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { for _, p := range preds { p(s) diff --git a/database/ent/team_create.go b/database/ent/team_create.go index aa0215f..445fba6 100644 --- a/database/ent/team_create.go +++ b/database/ent/team_create.go @@ -27,14 +27,14 @@ func (tc *TeamCreate) SetName(s string) *TeamCreate { return tc } -// AddProjectIDs adds the "project" edge to the Project entity by IDs. +// AddProjectIDs adds the "projects" edge to the Project entity by IDs. func (tc *TeamCreate) AddProjectIDs(ids ...int) *TeamCreate { tc.mutation.AddProjectIDs(ids...) return tc } -// AddProject adds the "project" edges to the Project entity. -func (tc *TeamCreate) AddProject(p ...*Project) *TeamCreate { +// AddProjects adds the "projects" edges to the Project entity. +func (tc *TeamCreate) AddProjects(p ...*Project) *TeamCreate { ids := make([]int, len(p)) for i := range p { ids[i] = p[i].ID @@ -124,12 +124,12 @@ func (tc *TeamCreate) createSpec() (*Team, *sqlgraph.CreateSpec) { _spec.SetField(team.FieldName, field.TypeString, value) _node.Name = value } - if nodes := tc.mutation.ProjectIDs(); len(nodes) > 0 { + if nodes := tc.mutation.ProjectsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), diff --git a/database/ent/team_query.go b/database/ent/team_query.go index 6677676..3b08f20 100644 --- a/database/ent/team_query.go +++ b/database/ent/team_query.go @@ -20,12 +20,12 @@ import ( // TeamQuery is the builder for querying Team entities. type TeamQuery struct { config - ctx *QueryContext - order []team.OrderOption - inters []Interceptor - predicates []predicate.Team - withProject *ProjectQuery - withUsers *UserQuery + ctx *QueryContext + order []team.OrderOption + inters []Interceptor + predicates []predicate.Team + withProjects *ProjectQuery + withUsers *UserQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -62,8 +62,8 @@ func (tq *TeamQuery) Order(o ...team.OrderOption) *TeamQuery { return tq } -// QueryProject chains the current query on the "project" edge. -func (tq *TeamQuery) QueryProject() *ProjectQuery { +// QueryProjects chains the current query on the "projects" edge. +func (tq *TeamQuery) QueryProjects() *ProjectQuery { query := (&ProjectClient{config: tq.config}).Query() query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { if err := tq.prepareQuery(ctx); err != nil { @@ -76,7 +76,7 @@ func (tq *TeamQuery) QueryProject() *ProjectQuery { step := sqlgraph.NewStep( sqlgraph.From(team.Table, team.FieldID, selector), sqlgraph.To(project.Table, project.FieldID), - sqlgraph.Edge(sqlgraph.O2M, false, team.ProjectTable, team.ProjectColumn), + sqlgraph.Edge(sqlgraph.M2M, false, team.ProjectsTable, team.ProjectsPrimaryKey...), ) fromU = sqlgraph.SetNeighbors(tq.driver.Dialect(), step) return fromU, nil @@ -293,27 +293,27 @@ func (tq *TeamQuery) Clone() *TeamQuery { return nil } return &TeamQuery{ - config: tq.config, - ctx: tq.ctx.Clone(), - order: append([]team.OrderOption{}, tq.order...), - inters: append([]Interceptor{}, tq.inters...), - predicates: append([]predicate.Team{}, tq.predicates...), - withProject: tq.withProject.Clone(), - withUsers: tq.withUsers.Clone(), + config: tq.config, + ctx: tq.ctx.Clone(), + order: append([]team.OrderOption{}, tq.order...), + inters: append([]Interceptor{}, tq.inters...), + predicates: append([]predicate.Team{}, tq.predicates...), + withProjects: tq.withProjects.Clone(), + withUsers: tq.withUsers.Clone(), // clone intermediate query. sql: tq.sql.Clone(), path: tq.path, } } -// WithProject tells the query-builder to eager-load the nodes that are connected to -// the "project" edge. The optional arguments are used to configure the query builder of the edge. -func (tq *TeamQuery) WithProject(opts ...func(*ProjectQuery)) *TeamQuery { +// WithProjects tells the query-builder to eager-load the nodes that are connected to +// the "projects" edge. The optional arguments are used to configure the query builder of the edge. +func (tq *TeamQuery) WithProjects(opts ...func(*ProjectQuery)) *TeamQuery { query := (&ProjectClient{config: tq.config}).Query() for _, opt := range opts { opt(query) } - tq.withProject = query + tq.withProjects = query return tq } @@ -407,7 +407,7 @@ func (tq *TeamQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Team, e nodes = []*Team{} _spec = tq.querySpec() loadedTypes = [2]bool{ - tq.withProject != nil, + tq.withProjects != nil, tq.withUsers != nil, } ) @@ -429,10 +429,10 @@ func (tq *TeamQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Team, e if len(nodes) == 0 { return nodes, nil } - if query := tq.withProject; query != nil { - if err := tq.loadProject(ctx, query, nodes, - func(n *Team) { n.Edges.Project = []*Project{} }, - func(n *Team, e *Project) { n.Edges.Project = append(n.Edges.Project, e) }); err != nil { + if query := tq.withProjects; query != nil { + if err := tq.loadProjects(ctx, query, nodes, + func(n *Team) { n.Edges.Projects = []*Project{} }, + func(n *Team, e *Project) { n.Edges.Projects = append(n.Edges.Projects, e) }); err != nil { return nil, err } } @@ -446,34 +446,64 @@ func (tq *TeamQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Team, e return nodes, nil } -func (tq *TeamQuery) loadProject(ctx context.Context, query *ProjectQuery, nodes []*Team, init func(*Team), assign func(*Team, *Project)) error { - fks := make([]driver.Value, 0, len(nodes)) - nodeids := make(map[int]*Team) - for i := range nodes { - fks = append(fks, nodes[i].ID) - nodeids[nodes[i].ID] = nodes[i] +func (tq *TeamQuery) loadProjects(ctx context.Context, query *ProjectQuery, nodes []*Team, init func(*Team), assign func(*Team, *Project)) error { + edgeIDs := make([]driver.Value, len(nodes)) + byID := make(map[int]*Team) + nids := make(map[int]map[*Team]struct{}) + for i, node := range nodes { + edgeIDs[i] = node.ID + byID[node.ID] = node if init != nil { - init(nodes[i]) + init(node) } } - query.withFKs = true - query.Where(predicate.Project(func(s *sql.Selector) { - s.Where(sql.InValues(s.C(team.ProjectColumn), fks...)) - })) - neighbors, err := query.All(ctx) + query.Where(func(s *sql.Selector) { + joinT := sql.Table(team.ProjectsTable) + s.Join(joinT).On(s.C(project.FieldID), joinT.C(team.ProjectsPrimaryKey[1])) + s.Where(sql.InValues(joinT.C(team.ProjectsPrimaryKey[0]), edgeIDs...)) + columns := s.SelectedColumns() + s.Select(joinT.C(team.ProjectsPrimaryKey[0])) + s.AppendSelect(columns...) + s.SetDistinct(false) + }) + if err := query.prepareQuery(ctx); err != nil { + return err + } + qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) { + assign := spec.Assign + values := spec.ScanValues + spec.ScanValues = func(columns []string) ([]any, error) { + values, err := values(columns[1:]) + if err != nil { + return nil, err + } + return append([]any{new(sql.NullInt64)}, values...), nil + } + spec.Assign = func(columns []string, values []any) error { + outValue := int(values[0].(*sql.NullInt64).Int64) + inValue := int(values[1].(*sql.NullInt64).Int64) + if nids[inValue] == nil { + nids[inValue] = map[*Team]struct{}{byID[outValue]: {}} + return assign(columns[1:], values[1:]) + } + nids[inValue][byID[outValue]] = struct{}{} + return nil + } + }) + }) + neighbors, err := withInterceptors[[]*Project](ctx, query, qr, query.inters) if err != nil { return err } for _, n := range neighbors { - fk := n.team_project - if fk == nil { - return fmt.Errorf(`foreign-key "team_project" is nil for node %v`, n.ID) - } - node, ok := nodeids[*fk] + nodes, ok := nids[n.ID] if !ok { - return fmt.Errorf(`unexpected referenced foreign-key "team_project" returned %v for node %v`, *fk, n.ID) + return fmt.Errorf(`unexpected "projects" node returned %v`, n.ID) + } + for kn := range nodes { + assign(kn, n) } - assign(node, n) } return nil } diff --git a/database/ent/team_update.go b/database/ent/team_update.go index cc73b63..311ca1d 100644 --- a/database/ent/team_update.go +++ b/database/ent/team_update.go @@ -43,14 +43,14 @@ func (tu *TeamUpdate) SetNillableName(s *string) *TeamUpdate { return tu } -// AddProjectIDs adds the "project" edge to the Project entity by IDs. +// AddProjectIDs adds the "projects" edge to the Project entity by IDs. func (tu *TeamUpdate) AddProjectIDs(ids ...int) *TeamUpdate { tu.mutation.AddProjectIDs(ids...) return tu } -// AddProject adds the "project" edges to the Project entity. -func (tu *TeamUpdate) AddProject(p ...*Project) *TeamUpdate { +// AddProjects adds the "projects" edges to the Project entity. +func (tu *TeamUpdate) AddProjects(p ...*Project) *TeamUpdate { ids := make([]int, len(p)) for i := range p { ids[i] = p[i].ID @@ -78,20 +78,20 @@ func (tu *TeamUpdate) Mutation() *TeamMutation { return tu.mutation } -// ClearProject clears all "project" edges to the Project entity. -func (tu *TeamUpdate) ClearProject() *TeamUpdate { - tu.mutation.ClearProject() +// ClearProjects clears all "projects" edges to the Project entity. +func (tu *TeamUpdate) ClearProjects() *TeamUpdate { + tu.mutation.ClearProjects() return tu } -// RemoveProjectIDs removes the "project" edge to Project entities by IDs. +// RemoveProjectIDs removes the "projects" edge to Project entities by IDs. func (tu *TeamUpdate) RemoveProjectIDs(ids ...int) *TeamUpdate { tu.mutation.RemoveProjectIDs(ids...) return tu } -// RemoveProject removes "project" edges to Project entities. -func (tu *TeamUpdate) RemoveProject(p ...*Project) *TeamUpdate { +// RemoveProjects removes "projects" edges to Project entities. +func (tu *TeamUpdate) RemoveProjects(p ...*Project) *TeamUpdate { ids := make([]int, len(p)) for i := range p { ids[i] = p[i].ID @@ -159,12 +159,12 @@ func (tu *TeamUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := tu.mutation.Name(); ok { _spec.SetField(team.FieldName, field.TypeString, value) } - if tu.mutation.ProjectCleared() { + if tu.mutation.ProjectsCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), @@ -172,12 +172,12 @@ func (tu *TeamUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := tu.mutation.RemovedProjectIDs(); len(nodes) > 0 && !tu.mutation.ProjectCleared() { + if nodes := tu.mutation.RemovedProjectsIDs(); len(nodes) > 0 && !tu.mutation.ProjectsCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), @@ -188,12 +188,12 @@ func (tu *TeamUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := tu.mutation.ProjectIDs(); len(nodes) > 0 { + if nodes := tu.mutation.ProjectsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), @@ -283,14 +283,14 @@ func (tuo *TeamUpdateOne) SetNillableName(s *string) *TeamUpdateOne { return tuo } -// AddProjectIDs adds the "project" edge to the Project entity by IDs. +// AddProjectIDs adds the "projects" edge to the Project entity by IDs. func (tuo *TeamUpdateOne) AddProjectIDs(ids ...int) *TeamUpdateOne { tuo.mutation.AddProjectIDs(ids...) return tuo } -// AddProject adds the "project" edges to the Project entity. -func (tuo *TeamUpdateOne) AddProject(p ...*Project) *TeamUpdateOne { +// AddProjects adds the "projects" edges to the Project entity. +func (tuo *TeamUpdateOne) AddProjects(p ...*Project) *TeamUpdateOne { ids := make([]int, len(p)) for i := range p { ids[i] = p[i].ID @@ -318,20 +318,20 @@ func (tuo *TeamUpdateOne) Mutation() *TeamMutation { return tuo.mutation } -// ClearProject clears all "project" edges to the Project entity. -func (tuo *TeamUpdateOne) ClearProject() *TeamUpdateOne { - tuo.mutation.ClearProject() +// ClearProjects clears all "projects" edges to the Project entity. +func (tuo *TeamUpdateOne) ClearProjects() *TeamUpdateOne { + tuo.mutation.ClearProjects() return tuo } -// RemoveProjectIDs removes the "project" edge to Project entities by IDs. +// RemoveProjectIDs removes the "projects" edge to Project entities by IDs. func (tuo *TeamUpdateOne) RemoveProjectIDs(ids ...int) *TeamUpdateOne { tuo.mutation.RemoveProjectIDs(ids...) return tuo } -// RemoveProject removes "project" edges to Project entities. -func (tuo *TeamUpdateOne) RemoveProject(p ...*Project) *TeamUpdateOne { +// RemoveProjects removes "projects" edges to Project entities. +func (tuo *TeamUpdateOne) RemoveProjects(p ...*Project) *TeamUpdateOne { ids := make([]int, len(p)) for i := range p { ids[i] = p[i].ID @@ -429,12 +429,12 @@ func (tuo *TeamUpdateOne) sqlSave(ctx context.Context) (_node *Team, err error) if value, ok := tuo.mutation.Name(); ok { _spec.SetField(team.FieldName, field.TypeString, value) } - if tuo.mutation.ProjectCleared() { + if tuo.mutation.ProjectsCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), @@ -442,12 +442,12 @@ func (tuo *TeamUpdateOne) sqlSave(ctx context.Context) (_node *Team, err error) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := tuo.mutation.RemovedProjectIDs(); len(nodes) > 0 && !tuo.mutation.ProjectCleared() { + if nodes := tuo.mutation.RemovedProjectsIDs(); len(nodes) > 0 && !tuo.mutation.ProjectsCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), @@ -458,12 +458,12 @@ func (tuo *TeamUpdateOne) sqlSave(ctx context.Context) (_node *Team, err error) } _spec.Edges.Clear = append(_spec.Edges.Clear, edge) } - if nodes := tuo.mutation.ProjectIDs(); len(nodes) > 0 { + if nodes := tuo.mutation.ProjectsIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, + Rel: sqlgraph.M2M, Inverse: false, - Table: team.ProjectTable, - Columns: []string{team.ProjectColumn}, + Table: team.ProjectsTable, + Columns: team.ProjectsPrimaryKey, Bidi: false, Target: &sqlgraph.EdgeTarget{ IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), diff --git a/database/ent/user.go b/database/ent/user.go index 2e21fd0..c57b43b 100644 --- a/database/ent/user.go +++ b/database/ent/user.go @@ -18,6 +18,8 @@ type User struct { ID int `json:"id,omitempty"` // Name holds the value of the "name" field. Name string `json:"name,omitempty"` + // Email holds the value of the "email" field. + Email string `json:"email,omitempty"` // Password holds the value of the "password" field. Password string `json:"password,omitempty"` // Role holds the value of the "role" field. @@ -32,9 +34,11 @@ type User struct { type UserEdges struct { // Teams holds the value of the teams edge. Teams []*Team `json:"teams,omitempty"` + // Projects holds the value of the projects edge. + Projects []*Project `json:"projects,omitempty"` // loadedTypes holds the information for reporting if a // type was loaded (or requested) in eager-loading or not. - loadedTypes [1]bool + loadedTypes [2]bool } // TeamsOrErr returns the Teams value or an error if the edge @@ -46,6 +50,15 @@ func (e UserEdges) TeamsOrErr() ([]*Team, error) { return nil, &NotLoadedError{edge: "teams"} } +// ProjectsOrErr returns the Projects value or an error if the edge +// was not loaded in eager-loading. +func (e UserEdges) ProjectsOrErr() ([]*Project, error) { + if e.loadedTypes[1] { + return e.Projects, nil + } + return nil, &NotLoadedError{edge: "projects"} +} + // scanValues returns the types for scanning values from sql.Rows. func (*User) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) @@ -53,7 +66,7 @@ func (*User) scanValues(columns []string) ([]any, error) { switch columns[i] { case user.FieldID: values[i] = new(sql.NullInt64) - case user.FieldName, user.FieldPassword, user.FieldRole: + case user.FieldName, user.FieldEmail, user.FieldPassword, user.FieldRole: values[i] = new(sql.NullString) default: values[i] = new(sql.UnknownType) @@ -82,6 +95,12 @@ func (u *User) assignValues(columns []string, values []any) error { } else if value.Valid { u.Name = value.String } + case user.FieldEmail: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field email", values[i]) + } else if value.Valid { + u.Email = value.String + } case user.FieldPassword: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field password", values[i]) @@ -112,6 +131,11 @@ func (u *User) QueryTeams() *TeamQuery { return NewUserClient(u.config).QueryTeams(u) } +// QueryProjects queries the "projects" edge of the User entity. +func (u *User) QueryProjects() *ProjectQuery { + return NewUserClient(u.config).QueryProjects(u) +} + // Update returns a builder for updating this User. // Note that you need to call User.Unwrap() before calling this method if this User // was returned from a transaction, and the transaction was committed or rolled back. @@ -138,6 +162,9 @@ func (u *User) String() string { builder.WriteString("name=") builder.WriteString(u.Name) builder.WriteString(", ") + builder.WriteString("email=") + builder.WriteString(u.Email) + builder.WriteString(", ") builder.WriteString("password=") builder.WriteString(u.Password) builder.WriteString(", ") diff --git a/database/ent/user/user.go b/database/ent/user/user.go index 6f03b7f..13149f9 100644 --- a/database/ent/user/user.go +++ b/database/ent/user/user.go @@ -16,12 +16,16 @@ const ( FieldID = "id" // FieldName holds the string denoting the name field in the database. FieldName = "name" + // FieldEmail holds the string denoting the email field in the database. + FieldEmail = "email" // FieldPassword holds the string denoting the password field in the database. FieldPassword = "password" // FieldRole holds the string denoting the role field in the database. FieldRole = "role" // EdgeTeams holds the string denoting the teams edge name in mutations. EdgeTeams = "teams" + // EdgeProjects holds the string denoting the projects edge name in mutations. + EdgeProjects = "projects" // Table holds the table name of the user in the database. Table = "users" // TeamsTable is the table that holds the teams relation/edge. The primary key declared below. @@ -29,12 +33,18 @@ const ( // TeamsInverseTable is the table name for the Team entity. // It exists in this package in order to avoid circular dependency with the "team" package. TeamsInverseTable = "teams" + // ProjectsTable is the table that holds the projects relation/edge. The primary key declared below. + ProjectsTable = "user_projects" + // ProjectsInverseTable is the table name for the Project entity. + // It exists in this package in order to avoid circular dependency with the "project" package. + ProjectsInverseTable = "projects" ) // Columns holds all SQL columns for user fields. var Columns = []string{ FieldID, FieldName, + FieldEmail, FieldPassword, FieldRole, } @@ -43,6 +53,9 @@ var ( // TeamsPrimaryKey and TeamsColumn2 are the table columns denoting the // primary key for the teams relation (M2M). TeamsPrimaryKey = []string{"user_id", "team_id"} + // ProjectsPrimaryKey and ProjectsColumn2 are the table columns denoting the + // primary key for the projects relation (M2M). + ProjectsPrimaryKey = []string{"user_id", "project_id"} ) // ValidColumn reports if the column name is valid (part of the table columns). @@ -92,6 +105,11 @@ func ByName(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldName, opts...).ToFunc() } +// ByEmail orders the results by the email field. +func ByEmail(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldEmail, opts...).ToFunc() +} + // ByPassword orders the results by the password field. func ByPassword(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldPassword, opts...).ToFunc() @@ -115,6 +133,20 @@ func ByTeams(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { sqlgraph.OrderByNeighborTerms(s, newTeamsStep(), append([]sql.OrderTerm{term}, terms...)...) } } + +// ByProjectsCount orders the results by projects count. +func ByProjectsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newProjectsStep(), opts...) + } +} + +// ByProjects orders the results by projects terms. +func ByProjects(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newProjectsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} func newTeamsStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), @@ -122,3 +154,10 @@ func newTeamsStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.M2M, false, TeamsTable, TeamsPrimaryKey...), ) } +func newProjectsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(ProjectsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, ProjectsTable, ProjectsPrimaryKey...), + ) +} diff --git a/database/ent/user/where.go b/database/ent/user/where.go index ce3e0ac..1513c75 100644 --- a/database/ent/user/where.go +++ b/database/ent/user/where.go @@ -59,6 +59,11 @@ func Name(v string) predicate.User { return predicate.User(sql.FieldEQ(FieldName, v)) } +// Email applies equality check predicate on the "email" field. It's identical to EmailEQ. +func Email(v string) predicate.User { + return predicate.User(sql.FieldEQ(FieldEmail, v)) +} + // Password applies equality check predicate on the "password" field. It's identical to PasswordEQ. func Password(v string) predicate.User { return predicate.User(sql.FieldEQ(FieldPassword, v)) @@ -129,6 +134,71 @@ func NameContainsFold(v string) predicate.User { return predicate.User(sql.FieldContainsFold(FieldName, v)) } +// EmailEQ applies the EQ predicate on the "email" field. +func EmailEQ(v string) predicate.User { + return predicate.User(sql.FieldEQ(FieldEmail, v)) +} + +// EmailNEQ applies the NEQ predicate on the "email" field. +func EmailNEQ(v string) predicate.User { + return predicate.User(sql.FieldNEQ(FieldEmail, v)) +} + +// EmailIn applies the In predicate on the "email" field. +func EmailIn(vs ...string) predicate.User { + return predicate.User(sql.FieldIn(FieldEmail, vs...)) +} + +// EmailNotIn applies the NotIn predicate on the "email" field. +func EmailNotIn(vs ...string) predicate.User { + return predicate.User(sql.FieldNotIn(FieldEmail, vs...)) +} + +// EmailGT applies the GT predicate on the "email" field. +func EmailGT(v string) predicate.User { + return predicate.User(sql.FieldGT(FieldEmail, v)) +} + +// EmailGTE applies the GTE predicate on the "email" field. +func EmailGTE(v string) predicate.User { + return predicate.User(sql.FieldGTE(FieldEmail, v)) +} + +// EmailLT applies the LT predicate on the "email" field. +func EmailLT(v string) predicate.User { + return predicate.User(sql.FieldLT(FieldEmail, v)) +} + +// EmailLTE applies the LTE predicate on the "email" field. +func EmailLTE(v string) predicate.User { + return predicate.User(sql.FieldLTE(FieldEmail, v)) +} + +// EmailContains applies the Contains predicate on the "email" field. +func EmailContains(v string) predicate.User { + return predicate.User(sql.FieldContains(FieldEmail, v)) +} + +// EmailHasPrefix applies the HasPrefix predicate on the "email" field. +func EmailHasPrefix(v string) predicate.User { + return predicate.User(sql.FieldHasPrefix(FieldEmail, v)) +} + +// EmailHasSuffix applies the HasSuffix predicate on the "email" field. +func EmailHasSuffix(v string) predicate.User { + return predicate.User(sql.FieldHasSuffix(FieldEmail, v)) +} + +// EmailEqualFold applies the EqualFold predicate on the "email" field. +func EmailEqualFold(v string) predicate.User { + return predicate.User(sql.FieldEqualFold(FieldEmail, v)) +} + +// EmailContainsFold applies the ContainsFold predicate on the "email" field. +func EmailContainsFold(v string) predicate.User { + return predicate.User(sql.FieldContainsFold(FieldEmail, v)) +} + // PasswordEQ applies the EQ predicate on the "password" field. func PasswordEQ(v string) predicate.User { return predicate.User(sql.FieldEQ(FieldPassword, v)) @@ -237,6 +307,29 @@ func HasTeamsWith(preds ...predicate.Team) predicate.User { }) } +// HasProjects applies the HasEdge predicate on the "projects" edge. +func HasProjects() predicate.User { + return predicate.User(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, ProjectsTable, ProjectsPrimaryKey...), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasProjectsWith applies the HasEdge predicate on the "projects" edge with a given conditions (other predicates). +func HasProjectsWith(preds ...predicate.Project) predicate.User { + return predicate.User(func(s *sql.Selector) { + step := newProjectsStep() + 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.User) predicate.User { return predicate.User(sql.AndPredicates(predicates...)) diff --git a/database/ent/user_create.go b/database/ent/user_create.go index 9fd5373..69a945b 100644 --- a/database/ent/user_create.go +++ b/database/ent/user_create.go @@ -6,6 +6,7 @@ import ( "context" "errors" "fmt" + "portfolio/database/ent/project" "portfolio/database/ent/team" "portfolio/database/ent/user" @@ -26,6 +27,12 @@ func (uc *UserCreate) SetName(s string) *UserCreate { return uc } +// SetEmail sets the "email" field. +func (uc *UserCreate) SetEmail(s string) *UserCreate { + uc.mutation.SetEmail(s) + return uc +} + // SetPassword sets the "password" field. func (uc *UserCreate) SetPassword(s string) *UserCreate { uc.mutation.SetPassword(s) @@ -53,6 +60,21 @@ func (uc *UserCreate) AddTeams(t ...*Team) *UserCreate { return uc.AddTeamIDs(ids...) } +// AddProjectIDs adds the "projects" edge to the Project entity by IDs. +func (uc *UserCreate) AddProjectIDs(ids ...int) *UserCreate { + uc.mutation.AddProjectIDs(ids...) + return uc +} + +// AddProjects adds the "projects" edges to the Project entity. +func (uc *UserCreate) AddProjects(p ...*Project) *UserCreate { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return uc.AddProjectIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (uc *UserCreate) Mutation() *UserMutation { return uc.mutation @@ -90,6 +112,9 @@ func (uc *UserCreate) check() error { if _, ok := uc.mutation.Name(); !ok { return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "User.name"`)} } + if _, ok := uc.mutation.Email(); !ok { + return &ValidationError{Name: "email", err: errors.New(`ent: missing required field "User.email"`)} + } if _, ok := uc.mutation.Password(); !ok { return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "User.password"`)} } @@ -131,6 +156,10 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { _spec.SetField(user.FieldName, field.TypeString, value) _node.Name = value } + if value, ok := uc.mutation.Email(); ok { + _spec.SetField(user.FieldEmail, field.TypeString, value) + _node.Email = value + } if value, ok := uc.mutation.Password(); ok { _spec.SetField(user.FieldPassword, field.TypeString, value) _node.Password = value @@ -155,6 +184,22 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { } _spec.Edges = append(_spec.Edges, edge) } + if nodes := uc.mutation.ProjectsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } return _node, _spec } diff --git a/database/ent/user_query.go b/database/ent/user_query.go index 3c72800..ae52689 100644 --- a/database/ent/user_query.go +++ b/database/ent/user_query.go @@ -8,6 +8,7 @@ import ( "fmt" "math" "portfolio/database/ent/predicate" + "portfolio/database/ent/project" "portfolio/database/ent/team" "portfolio/database/ent/user" @@ -19,11 +20,12 @@ import ( // UserQuery is the builder for querying User entities. type UserQuery struct { config - ctx *QueryContext - order []user.OrderOption - inters []Interceptor - predicates []predicate.User - withTeams *TeamQuery + ctx *QueryContext + order []user.OrderOption + inters []Interceptor + predicates []predicate.User + withTeams *TeamQuery + withProjects *ProjectQuery // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -82,6 +84,28 @@ func (uq *UserQuery) QueryTeams() *TeamQuery { return query } +// QueryProjects chains the current query on the "projects" edge. +func (uq *UserQuery) QueryProjects() *ProjectQuery { + query := (&ProjectClient{config: uq.config}).Query() + 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(project.Table, project.FieldID), + sqlgraph.Edge(sqlgraph.M2M, false, user.ProjectsTable, user.ProjectsPrimaryKey...), + ) + fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // First returns the first User entity from the query. // Returns a *NotFoundError when no User was found. func (uq *UserQuery) First(ctx context.Context) (*User, error) { @@ -269,12 +293,13 @@ func (uq *UserQuery) Clone() *UserQuery { return nil } return &UserQuery{ - config: uq.config, - ctx: uq.ctx.Clone(), - order: append([]user.OrderOption{}, uq.order...), - inters: append([]Interceptor{}, uq.inters...), - predicates: append([]predicate.User{}, uq.predicates...), - withTeams: uq.withTeams.Clone(), + config: uq.config, + ctx: uq.ctx.Clone(), + order: append([]user.OrderOption{}, uq.order...), + inters: append([]Interceptor{}, uq.inters...), + predicates: append([]predicate.User{}, uq.predicates...), + withTeams: uq.withTeams.Clone(), + withProjects: uq.withProjects.Clone(), // clone intermediate query. sql: uq.sql.Clone(), path: uq.path, @@ -292,6 +317,17 @@ func (uq *UserQuery) WithTeams(opts ...func(*TeamQuery)) *UserQuery { return uq } +// WithProjects tells the query-builder to eager-load the nodes that are connected to +// the "projects" edge. The optional arguments are used to configure the query builder of the edge. +func (uq *UserQuery) WithProjects(opts ...func(*ProjectQuery)) *UserQuery { + query := (&ProjectClient{config: uq.config}).Query() + for _, opt := range opts { + opt(query) + } + uq.withProjects = query + return uq +} + // 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. // @@ -370,8 +406,9 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e var ( nodes = []*User{} _spec = uq.querySpec() - loadedTypes = [1]bool{ + loadedTypes = [2]bool{ uq.withTeams != nil, + uq.withProjects != nil, } ) _spec.ScanValues = func(columns []string) ([]any, error) { @@ -399,6 +436,13 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e return nil, err } } + if query := uq.withProjects; query != nil { + if err := uq.loadProjects(ctx, query, nodes, + func(n *User) { n.Edges.Projects = []*Project{} }, + func(n *User, e *Project) { n.Edges.Projects = append(n.Edges.Projects, e) }); err != nil { + return nil, err + } + } return nodes, nil } @@ -463,6 +507,67 @@ func (uq *UserQuery) loadTeams(ctx context.Context, query *TeamQuery, nodes []*U } return nil } +func (uq *UserQuery) loadProjects(ctx context.Context, query *ProjectQuery, nodes []*User, init func(*User), assign func(*User, *Project)) error { + edgeIDs := make([]driver.Value, len(nodes)) + byID := make(map[int]*User) + nids := make(map[int]map[*User]struct{}) + for i, node := range nodes { + edgeIDs[i] = node.ID + byID[node.ID] = node + if init != nil { + init(node) + } + } + query.Where(func(s *sql.Selector) { + joinT := sql.Table(user.ProjectsTable) + s.Join(joinT).On(s.C(project.FieldID), joinT.C(user.ProjectsPrimaryKey[1])) + s.Where(sql.InValues(joinT.C(user.ProjectsPrimaryKey[0]), edgeIDs...)) + columns := s.SelectedColumns() + s.Select(joinT.C(user.ProjectsPrimaryKey[0])) + s.AppendSelect(columns...) + s.SetDistinct(false) + }) + if err := query.prepareQuery(ctx); err != nil { + return err + } + qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) { + assign := spec.Assign + values := spec.ScanValues + spec.ScanValues = func(columns []string) ([]any, error) { + values, err := values(columns[1:]) + if err != nil { + return nil, err + } + return append([]any{new(sql.NullInt64)}, values...), nil + } + spec.Assign = func(columns []string, values []any) error { + outValue := int(values[0].(*sql.NullInt64).Int64) + inValue := int(values[1].(*sql.NullInt64).Int64) + if nids[inValue] == nil { + nids[inValue] = map[*User]struct{}{byID[outValue]: {}} + return assign(columns[1:], values[1:]) + } + nids[inValue][byID[outValue]] = struct{}{} + return nil + } + }) + }) + neighbors, err := withInterceptors[[]*Project](ctx, query, qr, query.inters) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nids[n.ID] + if !ok { + return fmt.Errorf(`unexpected "projects" node returned %v`, n.ID) + } + for kn := range nodes { + assign(kn, n) + } + } + return nil +} func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) { _spec := uq.querySpec() diff --git a/database/ent/user_update.go b/database/ent/user_update.go index 102082f..7e5ffb0 100644 --- a/database/ent/user_update.go +++ b/database/ent/user_update.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "portfolio/database/ent/predicate" + "portfolio/database/ent/project" "portfolio/database/ent/team" "portfolio/database/ent/user" @@ -42,6 +43,20 @@ func (uu *UserUpdate) SetNillableName(s *string) *UserUpdate { return uu } +// SetEmail sets the "email" field. +func (uu *UserUpdate) SetEmail(s string) *UserUpdate { + uu.mutation.SetEmail(s) + return uu +} + +// SetNillableEmail sets the "email" field if the given value is not nil. +func (uu *UserUpdate) SetNillableEmail(s *string) *UserUpdate { + if s != nil { + uu.SetEmail(*s) + } + return uu +} + // SetPassword sets the "password" field. func (uu *UserUpdate) SetPassword(s string) *UserUpdate { uu.mutation.SetPassword(s) @@ -85,6 +100,21 @@ func (uu *UserUpdate) AddTeams(t ...*Team) *UserUpdate { return uu.AddTeamIDs(ids...) } +// AddProjectIDs adds the "projects" edge to the Project entity by IDs. +func (uu *UserUpdate) AddProjectIDs(ids ...int) *UserUpdate { + uu.mutation.AddProjectIDs(ids...) + return uu +} + +// AddProjects adds the "projects" edges to the Project entity. +func (uu *UserUpdate) AddProjects(p ...*Project) *UserUpdate { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return uu.AddProjectIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (uu *UserUpdate) Mutation() *UserMutation { return uu.mutation @@ -111,6 +141,27 @@ func (uu *UserUpdate) RemoveTeams(t ...*Team) *UserUpdate { return uu.RemoveTeamIDs(ids...) } +// ClearProjects clears all "projects" edges to the Project entity. +func (uu *UserUpdate) ClearProjects() *UserUpdate { + uu.mutation.ClearProjects() + return uu +} + +// RemoveProjectIDs removes the "projects" edge to Project entities by IDs. +func (uu *UserUpdate) RemoveProjectIDs(ids ...int) *UserUpdate { + uu.mutation.RemoveProjectIDs(ids...) + return uu +} + +// RemoveProjects removes "projects" edges to Project entities. +func (uu *UserUpdate) RemoveProjects(p ...*Project) *UserUpdate { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return uu.RemoveProjectIDs(ids...) +} + // Save executes the query and returns the number of nodes affected by the update operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { return withHooks(ctx, uu.sqlSave, uu.mutation, uu.hooks) @@ -163,6 +214,9 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := uu.mutation.Name(); ok { _spec.SetField(user.FieldName, field.TypeString, value) } + if value, ok := uu.mutation.Email(); ok { + _spec.SetField(user.FieldEmail, field.TypeString, value) + } if value, ok := uu.mutation.Password(); ok { _spec.SetField(user.FieldPassword, field.TypeString, value) } @@ -214,6 +268,51 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if uu.mutation.ProjectsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.RemovedProjectsIDs(); len(nodes) > 0 && !uu.mutation.ProjectsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uu.mutation.ProjectsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{user.Label} @@ -248,6 +347,20 @@ func (uuo *UserUpdateOne) SetNillableName(s *string) *UserUpdateOne { return uuo } +// SetEmail sets the "email" field. +func (uuo *UserUpdateOne) SetEmail(s string) *UserUpdateOne { + uuo.mutation.SetEmail(s) + return uuo +} + +// SetNillableEmail sets the "email" field if the given value is not nil. +func (uuo *UserUpdateOne) SetNillableEmail(s *string) *UserUpdateOne { + if s != nil { + uuo.SetEmail(*s) + } + return uuo +} + // SetPassword sets the "password" field. func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne { uuo.mutation.SetPassword(s) @@ -291,6 +404,21 @@ func (uuo *UserUpdateOne) AddTeams(t ...*Team) *UserUpdateOne { return uuo.AddTeamIDs(ids...) } +// AddProjectIDs adds the "projects" edge to the Project entity by IDs. +func (uuo *UserUpdateOne) AddProjectIDs(ids ...int) *UserUpdateOne { + uuo.mutation.AddProjectIDs(ids...) + return uuo +} + +// AddProjects adds the "projects" edges to the Project entity. +func (uuo *UserUpdateOne) AddProjects(p ...*Project) *UserUpdateOne { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return uuo.AddProjectIDs(ids...) +} + // Mutation returns the UserMutation object of the builder. func (uuo *UserUpdateOne) Mutation() *UserMutation { return uuo.mutation @@ -317,6 +445,27 @@ func (uuo *UserUpdateOne) RemoveTeams(t ...*Team) *UserUpdateOne { return uuo.RemoveTeamIDs(ids...) } +// ClearProjects clears all "projects" edges to the Project entity. +func (uuo *UserUpdateOne) ClearProjects() *UserUpdateOne { + uuo.mutation.ClearProjects() + return uuo +} + +// RemoveProjectIDs removes the "projects" edge to Project entities by IDs. +func (uuo *UserUpdateOne) RemoveProjectIDs(ids ...int) *UserUpdateOne { + uuo.mutation.RemoveProjectIDs(ids...) + return uuo +} + +// RemoveProjects removes "projects" edges to Project entities. +func (uuo *UserUpdateOne) RemoveProjects(p ...*Project) *UserUpdateOne { + ids := make([]int, len(p)) + for i := range p { + ids[i] = p[i].ID + } + return uuo.RemoveProjectIDs(ids...) +} + // Where appends a list predicates to the UserUpdate builder. func (uuo *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne { uuo.mutation.Where(ps...) @@ -399,6 +548,9 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) if value, ok := uuo.mutation.Name(); ok { _spec.SetField(user.FieldName, field.TypeString, value) } + if value, ok := uuo.mutation.Email(); ok { + _spec.SetField(user.FieldEmail, field.TypeString, value) + } if value, ok := uuo.mutation.Password(); ok { _spec.SetField(user.FieldPassword, field.TypeString, value) } @@ -450,6 +602,51 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if uuo.mutation.ProjectsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.RemovedProjectsIDs(); len(nodes) > 0 && !uuo.mutation.ProjectsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := uuo.mutation.ProjectsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2M, + Inverse: false, + Table: user.ProjectsTable, + Columns: user.ProjectsPrimaryKey, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(project.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &User{config: uuo.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues