diff --git a/db/ent/client.go b/db/ent/client.go index c07eee4..77d4ace 100644 --- a/db/ent/client.go +++ b/db/ent/client.go @@ -327,6 +327,22 @@ func (c *TextureClient) QueryCreatedUser(t *Texture) *UserQuery { return query } +// QueryUser queries the user edge of a Texture. +func (c *TextureClient) QueryUser(t *Texture) *UserProfileQuery { + query := (&UserProfileClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := t.ID + step := sqlgraph.NewStep( + sqlgraph.From(texture.Table, texture.FieldID, id), + sqlgraph.To(userprofile.Table, userprofile.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, texture.UserTable, texture.UserColumn), + ) + fromV = sqlgraph.Neighbors(t.driver.Dialect(), step) + return fromV, nil + } + return query +} + // Hooks returns the client hooks. func (c *TextureClient) Hooks() []Hook { return c.hooks.Texture @@ -485,7 +501,7 @@ func (c *UserClient) QueryToken(u *User) *UserTokenQuery { step := sqlgraph.NewStep( sqlgraph.From(user.Table, user.FieldID, id), sqlgraph.To(usertoken.Table, usertoken.FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, user.TokenTable, user.TokenColumn), + sqlgraph.Edge(sqlgraph.O2O, false, user.TokenTable, user.TokenColumn), ) fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) return fromV, nil @@ -761,6 +777,22 @@ func (c *UserTokenClient) GetX(ctx context.Context, id int) *UserToken { return obj } +// QueryUser queries the user edge of a UserToken. +func (c *UserTokenClient) QueryUser(ut *UserToken) *UserQuery { + query := (&UserClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := ut.ID + step := sqlgraph.NewStep( + sqlgraph.From(usertoken.Table, usertoken.FieldID, id), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, usertoken.UserTable, usertoken.UserColumn), + ) + fromV = sqlgraph.Neighbors(ut.driver.Dialect(), step) + return fromV, nil + } + return query +} + // Hooks returns the client hooks. func (c *UserTokenClient) Hooks() []Hook { return c.hooks.UserToken diff --git a/db/ent/migrate/schema.go b/db/ent/migrate/schema.go index 6bc241f..09950da 100644 --- a/db/ent/migrate/schema.go +++ b/db/ent/migrate/schema.go @@ -15,7 +15,7 @@ var ( {Name: "type", Type: field.TypeString, SchemaType: map[string]string{"mysql": "VARCHAR(10)"}}, {Name: "variant", Type: field.TypeString, SchemaType: map[string]string{"mysql": "VARCHAR(10)"}}, {Name: "texture_created_user", Type: field.TypeInt}, - {Name: "user_profile_texture", Type: field.TypeInt, Nullable: true}, + {Name: "user_profile_texture", Type: field.TypeInt}, } // TexturesTable holds the schema information for the "textures" table. TexturesTable = &schema.Table{ @@ -33,14 +33,7 @@ var ( Symbol: "textures_user_profiles_texture", Columns: []*schema.Column{TexturesColumns[5]}, RefColumns: []*schema.Column{UserProfilesColumns[0]}, - OnDelete: schema.SetNull, - }, - }, - Indexes: []*schema.Index{ - { - Name: "texture_texture_hash", - Unique: false, - Columns: []*schema.Column{TexturesColumns[1]}, + OnDelete: schema.NoAction, }, }, } @@ -53,21 +46,12 @@ var ( {Name: "reg_ip", Type: field.TypeString, SchemaType: map[string]string{"mysql": "VARCHAR(32)"}}, {Name: "state", Type: field.TypeInt}, {Name: "reg_time", Type: field.TypeInt64}, - {Name: "user_token", Type: field.TypeInt, Nullable: true}, } // UsersTable holds the schema information for the "users" table. UsersTable = &schema.Table{ Name: "users", Columns: UsersColumns, PrimaryKey: []*schema.Column{UsersColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "users_user_tokens_token", - Columns: []*schema.Column{UsersColumns[7]}, - RefColumns: []*schema.Column{UserTokensColumns[0]}, - OnDelete: schema.Cascade, - }, - }, Indexes: []*schema.Index{ { Name: "user_email", @@ -98,14 +82,14 @@ var ( Symbol: "user_profiles_users_profile", Columns: []*schema.Column{UserProfilesColumns[3]}, RefColumns: []*schema.Column{UsersColumns[0]}, - OnDelete: schema.Cascade, + OnDelete: schema.NoAction, }, }, Indexes: []*schema.Index{ { - Name: "userprofile_uuid", + Name: "userprofile_user_profile", Unique: false, - Columns: []*schema.Column{UserProfilesColumns[2]}, + Columns: []*schema.Column{UserProfilesColumns[3]}, }, }, } @@ -113,16 +97,24 @@ var ( UserTokensColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "token_id", Type: field.TypeUint64}, - {Name: "uuid", Type: field.TypeString, SchemaType: map[string]string{"mysql": "VARCHAR(32)"}}, + {Name: "user_token", Type: field.TypeInt, Unique: true, Nullable: true}, } // UserTokensTable holds the schema information for the "user_tokens" table. UserTokensTable = &schema.Table{ Name: "user_tokens", Columns: UserTokensColumns, PrimaryKey: []*schema.Column{UserTokensColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "user_tokens_users_token", + Columns: []*schema.Column{UserTokensColumns[2]}, + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.SetNull, + }, + }, Indexes: []*schema.Index{ { - Name: "usertoken_uuid", + Name: "usertoken_user_token", Unique: false, Columns: []*schema.Column{UserTokensColumns[2]}, }, @@ -140,6 +132,6 @@ var ( func init() { TexturesTable.ForeignKeys[0].RefTable = UsersTable TexturesTable.ForeignKeys[1].RefTable = UserProfilesTable - UsersTable.ForeignKeys[0].RefTable = UserTokensTable UserProfilesTable.ForeignKeys[0].RefTable = UsersTable + UserTokensTable.ForeignKeys[0].RefTable = UsersTable } diff --git a/db/ent/mutation.go b/db/ent/mutation.go index 1e9df54..17fcbde 100644 --- a/db/ent/mutation.go +++ b/db/ent/mutation.go @@ -44,6 +44,8 @@ type TextureMutation struct { clearedFields map[string]struct{} created_user *int clearedcreated_user bool + user *int + cleareduser bool done bool oldValue func(context.Context) (*Texture, error) predicates []predicate.Texture @@ -294,6 +296,45 @@ func (m *TextureMutation) ResetCreatedUser() { m.clearedcreated_user = false } +// SetUserID sets the "user" edge to the UserProfile entity by id. +func (m *TextureMutation) SetUserID(id int) { + m.user = &id +} + +// ClearUser clears the "user" edge to the UserProfile entity. +func (m *TextureMutation) ClearUser() { + m.cleareduser = true +} + +// UserCleared reports if the "user" edge to the UserProfile entity was cleared. +func (m *TextureMutation) UserCleared() bool { + return m.cleareduser +} + +// UserID returns the "user" edge ID in the mutation. +func (m *TextureMutation) UserID() (id int, exists bool) { + if m.user != nil { + return *m.user, true + } + return +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *TextureMutation) UserIDs() (ids []int) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *TextureMutation) ResetUser() { + m.user = nil + m.cleareduser = false +} + // Where appends a list predicates to the TextureMutation builder. func (m *TextureMutation) Where(ps ...predicate.Texture) { m.predicates = append(m.predicates, ps...) @@ -461,10 +502,13 @@ func (m *TextureMutation) ResetField(name string) error { // AddedEdges returns all edge names that were set/added in this mutation. func (m *TextureMutation) AddedEdges() []string { - edges := make([]string, 0, 1) + edges := make([]string, 0, 2) if m.created_user != nil { edges = append(edges, texture.EdgeCreatedUser) } + if m.user != nil { + edges = append(edges, texture.EdgeUser) + } return edges } @@ -476,13 +520,17 @@ func (m *TextureMutation) AddedIDs(name string) []ent.Value { if id := m.created_user; id != nil { return []ent.Value{*id} } + case texture.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *TextureMutation) RemovedEdges() []string { - edges := make([]string, 0, 1) + edges := make([]string, 0, 2) return edges } @@ -494,10 +542,13 @@ func (m *TextureMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *TextureMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) + edges := make([]string, 0, 2) if m.clearedcreated_user { edges = append(edges, texture.EdgeCreatedUser) } + if m.cleareduser { + edges = append(edges, texture.EdgeUser) + } return edges } @@ -507,6 +558,8 @@ func (m *TextureMutation) EdgeCleared(name string) bool { switch name { case texture.EdgeCreatedUser: return m.clearedcreated_user + case texture.EdgeUser: + return m.cleareduser } return false } @@ -518,6 +571,9 @@ func (m *TextureMutation) ClearEdge(name string) error { case texture.EdgeCreatedUser: m.ClearCreatedUser() return nil + case texture.EdgeUser: + m.ClearUser() + return nil } return fmt.Errorf("unknown Texture unique edge %s", name) } @@ -529,6 +585,9 @@ func (m *TextureMutation) ResetEdge(name string) error { case texture.EdgeCreatedUser: m.ResetCreatedUser() return nil + case texture.EdgeUser: + m.ResetUser() + return nil } return fmt.Errorf("unknown Texture edge %s", name) } @@ -1949,8 +2008,9 @@ type UserTokenMutation struct { id *int token_id *uint64 addtoken_id *int64 - uuid *string clearedFields map[string]struct{} + user *int + cleareduser bool done bool oldValue func(context.Context) (*UserToken, error) predicates []predicate.UserToken @@ -2110,40 +2170,43 @@ func (m *UserTokenMutation) ResetTokenID() { m.addtoken_id = nil } -// SetUUID sets the "uuid" field. -func (m *UserTokenMutation) SetUUID(s string) { - m.uuid = &s +// SetUserID sets the "user" edge to the User entity by id. +func (m *UserTokenMutation) SetUserID(id int) { + m.user = &id } -// UUID returns the value of the "uuid" field in the mutation. -func (m *UserTokenMutation) UUID() (r string, exists bool) { - v := m.uuid - if v == nil { - return - } - return *v, true +// ClearUser clears the "user" edge to the User entity. +func (m *UserTokenMutation) ClearUser() { + m.cleareduser = true } -// OldUUID returns the old "uuid" field's value of the UserToken entity. -// If the UserToken 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 *UserTokenMutation) OldUUID(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldUUID is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldUUID requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldUUID: %w", err) - } - return oldValue.UUID, nil +// UserCleared reports if the "user" edge to the User entity was cleared. +func (m *UserTokenMutation) UserCleared() bool { + return m.cleareduser } -// ResetUUID resets all changes to the "uuid" field. -func (m *UserTokenMutation) ResetUUID() { - m.uuid = nil +// UserID returns the "user" edge ID in the mutation. +func (m *UserTokenMutation) UserID() (id int, exists bool) { + if m.user != nil { + return *m.user, true + } + return +} + +// UserIDs returns the "user" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// UserID instead. It exists only for internal usage by the builders. +func (m *UserTokenMutation) UserIDs() (ids []int) { + if id := m.user; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetUser resets all changes to the "user" edge. +func (m *UserTokenMutation) ResetUser() { + m.user = nil + m.cleareduser = false } // Where appends a list predicates to the UserTokenMutation builder. @@ -2180,13 +2243,10 @@ func (m *UserTokenMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *UserTokenMutation) Fields() []string { - fields := make([]string, 0, 2) + fields := make([]string, 0, 1) if m.token_id != nil { fields = append(fields, usertoken.FieldTokenID) } - if m.uuid != nil { - fields = append(fields, usertoken.FieldUUID) - } return fields } @@ -2197,8 +2257,6 @@ func (m *UserTokenMutation) Field(name string) (ent.Value, bool) { switch name { case usertoken.FieldTokenID: return m.TokenID() - case usertoken.FieldUUID: - return m.UUID() } return nil, false } @@ -2210,8 +2268,6 @@ func (m *UserTokenMutation) OldField(ctx context.Context, name string) (ent.Valu switch name { case usertoken.FieldTokenID: return m.OldTokenID(ctx) - case usertoken.FieldUUID: - return m.OldUUID(ctx) } return nil, fmt.Errorf("unknown UserToken field %s", name) } @@ -2228,13 +2284,6 @@ func (m *UserTokenMutation) SetField(name string, value ent.Value) error { } m.SetTokenID(v) return nil - case usertoken.FieldUUID: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetUUID(v) - return nil } return fmt.Errorf("unknown UserToken field %s", name) } @@ -2302,28 +2351,34 @@ func (m *UserTokenMutation) ResetField(name string) error { case usertoken.FieldTokenID: m.ResetTokenID() return nil - case usertoken.FieldUUID: - m.ResetUUID() - return nil } return fmt.Errorf("unknown UserToken field %s", name) } // AddedEdges returns all edge names that were set/added in this mutation. func (m *UserTokenMutation) AddedEdges() []string { - edges := make([]string, 0, 0) + edges := make([]string, 0, 1) + if m.user != nil { + edges = append(edges, usertoken.EdgeUser) + } return edges } // AddedIDs returns all IDs (to other nodes) that were added for the given edge // name in this mutation. func (m *UserTokenMutation) AddedIDs(name string) []ent.Value { + switch name { + case usertoken.EdgeUser: + if id := m.user; id != nil { + return []ent.Value{*id} + } + } return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserTokenMutation) RemovedEdges() []string { - edges := make([]string, 0, 0) + edges := make([]string, 0, 1) return edges } @@ -2335,24 +2390,41 @@ func (m *UserTokenMutation) RemovedIDs(name string) []ent.Value { // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserTokenMutation) ClearedEdges() []string { - edges := make([]string, 0, 0) + edges := make([]string, 0, 1) + if m.cleareduser { + edges = append(edges, usertoken.EdgeUser) + } return edges } // EdgeCleared returns a boolean which indicates if the edge with the given name // was cleared in this mutation. func (m *UserTokenMutation) EdgeCleared(name string) bool { + switch name { + case usertoken.EdgeUser: + return m.cleareduser + } return false } // ClearEdge clears the value of the edge with the given name. It returns an error // if that edge is not defined in the schema. func (m *UserTokenMutation) ClearEdge(name string) error { + switch name { + case usertoken.EdgeUser: + m.ClearUser() + return nil + } return fmt.Errorf("unknown UserToken unique edge %s", name) } // ResetEdge resets all changes to the edge with the given name in this mutation. // It returns an error if the edge is not defined in the schema. func (m *UserTokenMutation) ResetEdge(name string) error { + switch name { + case usertoken.EdgeUser: + m.ResetUser() + return nil + } return fmt.Errorf("unknown UserToken edge %s", name) } diff --git a/db/ent/schema/texture.go b/db/ent/schema/texture.go index afb3448..7736166 100644 --- a/db/ent/schema/texture.go +++ b/db/ent/schema/texture.go @@ -5,7 +5,6 @@ import ( "entgo.io/ent/dialect" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" - "entgo.io/ent/schema/index" ) // Texture holds the schema definition for the Texture entity. @@ -34,11 +33,10 @@ func (Texture) Fields() []ent.Field { func (Texture) Edges() []ent.Edge { return []ent.Edge{ edge.To("created_user", User.Type).Unique().Required(), + edge.From("user", UserProfile.Type).Ref("texture").Required().Unique(), } } func (Texture) Indexes() []ent.Index { - return []ent.Index{ - index.Fields("texture_hash"), - } + return nil } diff --git a/db/ent/schema/user.go b/db/ent/schema/user.go index 7dd7ee7..7582c96 100644 --- a/db/ent/schema/user.go +++ b/db/ent/schema/user.go @@ -3,7 +3,6 @@ package schema import ( "entgo.io/ent" "entgo.io/ent/dialect" - "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" @@ -39,8 +38,8 @@ func (User) Fields() []ent.Field { func (User) Edges() []ent.Edge { return []ent.Edge{ edge.From("created_texture", Texture.Type).Ref("created_user"), - edge.To("profile", UserProfile.Type).Unique().Annotations(entsql.OnDelete(entsql.Cascade)), - edge.To("token", UserToken.Type).Unique().Annotations(entsql.OnDelete(entsql.Cascade)), + edge.To("profile", UserProfile.Type).Unique(), + edge.To("token", UserToken.Type).Unique(), } } diff --git a/db/ent/schema/userprofile.go b/db/ent/schema/userprofile.go index d332d07..69b4088 100644 --- a/db/ent/schema/userprofile.go +++ b/db/ent/schema/userprofile.go @@ -35,6 +35,6 @@ func (UserProfile) Edges() []ent.Edge { func (UserProfile) Indexes() []ent.Index { return []ent.Index{ - index.Fields("uuid"), + index.Edges("user"), } } diff --git a/db/ent/schema/usertoken.go b/db/ent/schema/usertoken.go index c417e52..637df5f 100644 --- a/db/ent/schema/usertoken.go +++ b/db/ent/schema/usertoken.go @@ -2,7 +2,7 @@ package schema import ( "entgo.io/ent" - "entgo.io/ent/dialect" + "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "entgo.io/ent/schema/index" ) @@ -17,19 +17,18 @@ func (UserToken) Fields() []ent.Field { return []ent.Field{ // 用于验证 jwt token 是否被注销,若相同则有效 field.Uint64("token_id"), - field.String("uuid").SchemaType(map[string]string{ - dialect.MySQL: "VARCHAR(32)", - }), } } // Edges of the UserToken. func (UserToken) Edges() []ent.Edge { - return nil + return []ent.Edge{ + edge.From("user", User.Type).Ref("token").Unique(), + } } func (UserToken) Indexes() []ent.Index { return []ent.Index{ - index.Fields("uuid"), + index.Edges("user"), } } diff --git a/db/ent/texture.go b/db/ent/texture.go index fd588ea..8f0276d 100644 --- a/db/ent/texture.go +++ b/db/ent/texture.go @@ -10,6 +10,7 @@ import ( "entgo.io/ent/dialect/sql" "github.com/xmdhs/authlib-skin/db/ent/texture" "github.com/xmdhs/authlib-skin/db/ent/user" + "github.com/xmdhs/authlib-skin/db/ent/userprofile" ) // Texture is the model entity for the Texture schema. @@ -35,9 +36,11 @@ type Texture struct { type TextureEdges struct { // CreatedUser holds the value of the created_user edge. CreatedUser *User `json:"created_user,omitempty"` + // User holds the value of the user edge. + User *UserProfile `json:"user,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 } // CreatedUserOrErr returns the CreatedUser value or an error if the edge @@ -53,6 +56,19 @@ func (e TextureEdges) CreatedUserOrErr() (*User, error) { return nil, &NotLoadedError{edge: "created_user"} } +// UserOrErr returns the User value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e TextureEdges) UserOrErr() (*UserProfile, error) { + if e.loadedTypes[1] { + if e.User == nil { + // Edge was loaded but was not found. + return nil, &NotFoundError{label: userprofile.Label} + } + return e.User, nil + } + return nil, &NotLoadedError{edge: "user"} +} + // scanValues returns the types for scanning values from sql.Rows. func (*Texture) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) @@ -137,6 +153,11 @@ func (t *Texture) QueryCreatedUser() *UserQuery { return NewTextureClient(t.config).QueryCreatedUser(t) } +// QueryUser queries the "user" edge of the Texture entity. +func (t *Texture) QueryUser() *UserProfileQuery { + return NewTextureClient(t.config).QueryUser(t) +} + // Update returns a builder for updating this Texture. // Note that you need to call Texture.Unwrap() before calling this method if this Texture // was returned from a transaction, and the transaction was committed or rolled back. diff --git a/db/ent/texture/texture.go b/db/ent/texture/texture.go index e3223d5..44a1040 100644 --- a/db/ent/texture/texture.go +++ b/db/ent/texture/texture.go @@ -20,6 +20,8 @@ const ( FieldVariant = "variant" // EdgeCreatedUser holds the string denoting the created_user edge name in mutations. EdgeCreatedUser = "created_user" + // EdgeUser holds the string denoting the user edge name in mutations. + EdgeUser = "user" // Table holds the table name of the texture in the database. Table = "textures" // CreatedUserTable is the table that holds the created_user relation/edge. @@ -29,6 +31,13 @@ const ( CreatedUserInverseTable = "users" // CreatedUserColumn is the table column denoting the created_user relation/edge. CreatedUserColumn = "texture_created_user" + // UserTable is the table that holds the user relation/edge. + UserTable = "textures" + // UserInverseTable is the table name for the UserProfile entity. + // It exists in this package in order to avoid circular dependency with the "userprofile" package. + UserInverseTable = "user_profiles" + // UserColumn is the table column denoting the user relation/edge. + UserColumn = "user_profile_texture" ) // Columns holds all SQL columns for texture fields. @@ -90,6 +99,13 @@ func ByCreatedUserField(field string, opts ...sql.OrderTermOption) OrderOption { sqlgraph.OrderByNeighborTerms(s, newCreatedUserStep(), sql.OrderByField(field, opts...)) } } + +// ByUserField orders the results by user field. +func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...)) + } +} func newCreatedUserStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), @@ -97,3 +113,10 @@ func newCreatedUserStep() *sqlgraph.Step { sqlgraph.Edge(sqlgraph.M2O, false, CreatedUserTable, CreatedUserColumn), ) } +func newUserStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) +} diff --git a/db/ent/texture/where.go b/db/ent/texture/where.go index 5c7bf5a..2d9af22 100644 --- a/db/ent/texture/where.go +++ b/db/ent/texture/where.go @@ -286,6 +286,29 @@ func HasCreatedUserWith(preds ...predicate.User) predicate.Texture { }) } +// HasUser applies the HasEdge predicate on the "user" edge. +func HasUser() predicate.Texture { + return predicate.Texture(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). +func HasUserWith(preds ...predicate.UserProfile) predicate.Texture { + return predicate.Texture(func(s *sql.Selector) { + step := newUserStep() + 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.Texture) predicate.Texture { return predicate.Texture(func(s *sql.Selector) { diff --git a/db/ent/texture_create.go b/db/ent/texture_create.go index 0e3ad09..a1219dd 100644 --- a/db/ent/texture_create.go +++ b/db/ent/texture_create.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent/schema/field" "github.com/xmdhs/authlib-skin/db/ent/texture" "github.com/xmdhs/authlib-skin/db/ent/user" + "github.com/xmdhs/authlib-skin/db/ent/userprofile" ) // TextureCreate is the builder for creating a Texture entity. @@ -49,6 +50,17 @@ func (tc *TextureCreate) SetCreatedUser(u *User) *TextureCreate { return tc.SetCreatedUserID(u.ID) } +// SetUserID sets the "user" edge to the UserProfile entity by ID. +func (tc *TextureCreate) SetUserID(id int) *TextureCreate { + tc.mutation.SetUserID(id) + return tc +} + +// SetUser sets the "user" edge to the UserProfile entity. +func (tc *TextureCreate) SetUser(u *UserProfile) *TextureCreate { + return tc.SetUserID(u.ID) +} + // Mutation returns the TextureMutation object of the builder. func (tc *TextureCreate) Mutation() *TextureMutation { return tc.mutation @@ -95,6 +107,9 @@ func (tc *TextureCreate) check() error { if _, ok := tc.mutation.CreatedUserID(); !ok { return &ValidationError{Name: "created_user", err: errors.New(`ent: missing required edge "Texture.created_user"`)} } + if _, ok := tc.mutation.UserID(); !ok { + return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "Texture.user"`)} + } return nil } @@ -150,6 +165,23 @@ func (tc *TextureCreate) createSpec() (*Texture, *sqlgraph.CreateSpec) { _node.texture_created_user = &nodes[0] _spec.Edges = append(_spec.Edges, edge) } + if nodes := tc.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: texture.UserTable, + Columns: []string{texture.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userprofile.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.user_profile_texture = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } return _node, _spec } diff --git a/db/ent/texture_query.go b/db/ent/texture_query.go index 2f79fb4..da1aa1f 100644 --- a/db/ent/texture_query.go +++ b/db/ent/texture_query.go @@ -14,6 +14,7 @@ import ( "github.com/xmdhs/authlib-skin/db/ent/predicate" "github.com/xmdhs/authlib-skin/db/ent/texture" "github.com/xmdhs/authlib-skin/db/ent/user" + "github.com/xmdhs/authlib-skin/db/ent/userprofile" ) // TextureQuery is the builder for querying Texture entities. @@ -24,6 +25,7 @@ type TextureQuery struct { inters []Interceptor predicates []predicate.Texture withCreatedUser *UserQuery + withUser *UserProfileQuery withFKs bool modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). @@ -84,6 +86,28 @@ func (tq *TextureQuery) QueryCreatedUser() *UserQuery { return query } +// QueryUser chains the current query on the "user" edge. +func (tq *TextureQuery) QueryUser() *UserProfileQuery { + query := (&UserProfileClient{config: tq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := tq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := tq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(texture.Table, texture.FieldID, selector), + sqlgraph.To(userprofile.Table, userprofile.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, texture.UserTable, texture.UserColumn), + ) + fromU = sqlgraph.SetNeighbors(tq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // First returns the first Texture entity from the query. // Returns a *NotFoundError when no Texture was found. func (tq *TextureQuery) First(ctx context.Context) (*Texture, error) { @@ -277,6 +301,7 @@ func (tq *TextureQuery) Clone() *TextureQuery { inters: append([]Interceptor{}, tq.inters...), predicates: append([]predicate.Texture{}, tq.predicates...), withCreatedUser: tq.withCreatedUser.Clone(), + withUser: tq.withUser.Clone(), // clone intermediate query. sql: tq.sql.Clone(), path: tq.path, @@ -294,6 +319,17 @@ func (tq *TextureQuery) WithCreatedUser(opts ...func(*UserQuery)) *TextureQuery return tq } +// WithUser tells the query-builder to eager-load the nodes that are connected to +// the "user" edge. The optional arguments are used to configure the query builder of the edge. +func (tq *TextureQuery) WithUser(opts ...func(*UserProfileQuery)) *TextureQuery { + query := (&UserProfileClient{config: tq.config}).Query() + for _, opt := range opts { + opt(query) + } + tq.withUser = query + return tq +} + // 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. // @@ -373,11 +409,12 @@ func (tq *TextureQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Text nodes = []*Texture{} withFKs = tq.withFKs _spec = tq.querySpec() - loadedTypes = [1]bool{ + loadedTypes = [2]bool{ tq.withCreatedUser != nil, + tq.withUser != nil, } ) - if tq.withCreatedUser != nil { + if tq.withCreatedUser != nil || tq.withUser != nil { withFKs = true } if withFKs { @@ -410,6 +447,12 @@ func (tq *TextureQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Text return nil, err } } + if query := tq.withUser; query != nil { + if err := tq.loadUser(ctx, query, nodes, nil, + func(n *Texture, e *UserProfile) { n.Edges.User = e }); err != nil { + return nil, err + } + } return nodes, nil } @@ -445,6 +488,38 @@ func (tq *TextureQuery) loadCreatedUser(ctx context.Context, query *UserQuery, n } return nil } +func (tq *TextureQuery) loadUser(ctx context.Context, query *UserProfileQuery, nodes []*Texture, init func(*Texture), assign func(*Texture, *UserProfile)) error { + ids := make([]int, 0, len(nodes)) + nodeids := make(map[int][]*Texture) + for i := range nodes { + if nodes[i].user_profile_texture == nil { + continue + } + fk := *nodes[i].user_profile_texture + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(userprofile.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_profile_texture" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} func (tq *TextureQuery) sqlCount(ctx context.Context) (int, error) { _spec := tq.querySpec() diff --git a/db/ent/texture_update.go b/db/ent/texture_update.go index e6076ea..978027f 100644 --- a/db/ent/texture_update.go +++ b/db/ent/texture_update.go @@ -13,6 +13,7 @@ import ( "github.com/xmdhs/authlib-skin/db/ent/predicate" "github.com/xmdhs/authlib-skin/db/ent/texture" "github.com/xmdhs/authlib-skin/db/ent/user" + "github.com/xmdhs/authlib-skin/db/ent/userprofile" ) // TextureUpdate is the builder for updating Texture entities. @@ -57,6 +58,17 @@ func (tu *TextureUpdate) SetCreatedUser(u *User) *TextureUpdate { return tu.SetCreatedUserID(u.ID) } +// SetUserID sets the "user" edge to the UserProfile entity by ID. +func (tu *TextureUpdate) SetUserID(id int) *TextureUpdate { + tu.mutation.SetUserID(id) + return tu +} + +// SetUser sets the "user" edge to the UserProfile entity. +func (tu *TextureUpdate) SetUser(u *UserProfile) *TextureUpdate { + return tu.SetUserID(u.ID) +} + // Mutation returns the TextureMutation object of the builder. func (tu *TextureUpdate) Mutation() *TextureMutation { return tu.mutation @@ -68,6 +80,12 @@ func (tu *TextureUpdate) ClearCreatedUser() *TextureUpdate { return tu } +// ClearUser clears the "user" edge to the UserProfile entity. +func (tu *TextureUpdate) ClearUser() *TextureUpdate { + tu.mutation.ClearUser() + return tu +} + // Save executes the query and returns the number of nodes affected by the update operation. func (tu *TextureUpdate) Save(ctx context.Context) (int, error) { return withHooks(ctx, tu.sqlSave, tu.mutation, tu.hooks) @@ -100,6 +118,9 @@ func (tu *TextureUpdate) check() error { if _, ok := tu.mutation.CreatedUserID(); tu.mutation.CreatedUserCleared() && !ok { return errors.New(`ent: clearing a required unique edge "Texture.created_user"`) } + if _, ok := tu.mutation.UserID(); tu.mutation.UserCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Texture.user"`) + } return nil } @@ -153,6 +174,35 @@ func (tu *TextureUpdate) sqlSave(ctx context.Context) (n int, err error) { } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if tu.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: texture.UserTable, + Columns: []string{texture.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userprofile.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := tu.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: texture.UserTable, + Columns: []string{texture.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userprofile.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, tu.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{texture.Label} @@ -202,6 +252,17 @@ func (tuo *TextureUpdateOne) SetCreatedUser(u *User) *TextureUpdateOne { return tuo.SetCreatedUserID(u.ID) } +// SetUserID sets the "user" edge to the UserProfile entity by ID. +func (tuo *TextureUpdateOne) SetUserID(id int) *TextureUpdateOne { + tuo.mutation.SetUserID(id) + return tuo +} + +// SetUser sets the "user" edge to the UserProfile entity. +func (tuo *TextureUpdateOne) SetUser(u *UserProfile) *TextureUpdateOne { + return tuo.SetUserID(u.ID) +} + // Mutation returns the TextureMutation object of the builder. func (tuo *TextureUpdateOne) Mutation() *TextureMutation { return tuo.mutation @@ -213,6 +274,12 @@ func (tuo *TextureUpdateOne) ClearCreatedUser() *TextureUpdateOne { return tuo } +// ClearUser clears the "user" edge to the UserProfile entity. +func (tuo *TextureUpdateOne) ClearUser() *TextureUpdateOne { + tuo.mutation.ClearUser() + return tuo +} + // Where appends a list predicates to the TextureUpdate builder. func (tuo *TextureUpdateOne) Where(ps ...predicate.Texture) *TextureUpdateOne { tuo.mutation.Where(ps...) @@ -258,6 +325,9 @@ func (tuo *TextureUpdateOne) check() error { if _, ok := tuo.mutation.CreatedUserID(); tuo.mutation.CreatedUserCleared() && !ok { return errors.New(`ent: clearing a required unique edge "Texture.created_user"`) } + if _, ok := tuo.mutation.UserID(); tuo.mutation.UserCleared() && !ok { + return errors.New(`ent: clearing a required unique edge "Texture.user"`) + } return nil } @@ -328,6 +398,35 @@ func (tuo *TextureUpdateOne) sqlSave(ctx context.Context) (_node *Texture, err e } _spec.Edges.Add = append(_spec.Edges.Add, edge) } + if tuo.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: texture.UserTable, + Columns: []string{texture.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userprofile.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := tuo.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: texture.UserTable, + Columns: []string{texture.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(userprofile.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } _node = &Texture{config: tuo.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues diff --git a/db/ent/user.go b/db/ent/user.go index 6f98415..21ff390 100644 --- a/db/ent/user.go +++ b/db/ent/user.go @@ -33,7 +33,6 @@ type User struct { // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the UserQuery when eager-loading is set. Edges UserEdges `json:"edges"` - user_token *int selectValues sql.SelectValues } @@ -94,8 +93,6 @@ func (*User) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullInt64) case user.FieldEmail, user.FieldPassword, user.FieldSalt, user.FieldRegIP: values[i] = new(sql.NullString) - case user.ForeignKeys[0]: // user_token - values[i] = new(sql.NullInt64) default: values[i] = new(sql.UnknownType) } @@ -153,13 +150,6 @@ func (u *User) assignValues(columns []string, values []any) error { } else if value.Valid { u.RegTime = value.Int64 } - case user.ForeignKeys[0]: - if value, ok := values[i].(*sql.NullInt64); !ok { - return fmt.Errorf("unexpected type %T for edge-field user_token", value) - } else if value.Valid { - u.user_token = new(int) - *u.user_token = int(value.Int64) - } default: u.selectValues.Set(columns[i], values[i]) } diff --git a/db/ent/user/user.go b/db/ent/user/user.go index 230dc27..0604af8 100644 --- a/db/ent/user/user.go +++ b/db/ent/user/user.go @@ -47,7 +47,7 @@ const ( // ProfileColumn is the table column denoting the profile relation/edge. ProfileColumn = "user_profile" // TokenTable is the table that holds the token relation/edge. - TokenTable = "users" + TokenTable = "user_tokens" // TokenInverseTable is the table name for the UserToken entity. // It exists in this package in order to avoid circular dependency with the "usertoken" package. TokenInverseTable = "user_tokens" @@ -66,12 +66,6 @@ var Columns = []string{ FieldRegTime, } -// ForeignKeys holds the SQL foreign-keys that are owned by the "users" -// table and are not defined as standalone fields in the schema. -var ForeignKeys = []string{ - "user_token", -} - // ValidColumn reports if the column name is valid (part of the table columns). func ValidColumn(column string) bool { for i := range Columns { @@ -79,11 +73,6 @@ func ValidColumn(column string) bool { return true } } - for i := range ForeignKeys { - if column == ForeignKeys[i] { - return true - } - } return false } @@ -170,6 +159,6 @@ func newTokenStep() *sqlgraph.Step { return sqlgraph.NewStep( sqlgraph.From(Table, FieldID), sqlgraph.To(TokenInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, TokenTable, TokenColumn), + sqlgraph.Edge(sqlgraph.O2O, false, TokenTable, TokenColumn), ) } diff --git a/db/ent/user/where.go b/db/ent/user/where.go index b6f4982..f19d46e 100644 --- a/db/ent/user/where.go +++ b/db/ent/user/where.go @@ -474,7 +474,7 @@ func HasToken() predicate.User { return predicate.User(func(s *sql.Selector) { step := sqlgraph.NewStep( sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, TokenTable, TokenColumn), + sqlgraph.Edge(sqlgraph.O2O, false, TokenTable, TokenColumn), ) sqlgraph.HasNeighbors(s, step) }) diff --git a/db/ent/user_create.go b/db/ent/user_create.go index 28306dc..8aa35c2 100644 --- a/db/ent/user_create.go +++ b/db/ent/user_create.go @@ -247,7 +247,7 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { } if nodes := uc.mutation.TokenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.O2O, Inverse: false, Table: user.TokenTable, Columns: []string{user.TokenColumn}, @@ -259,7 +259,6 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } - _node.user_token = &nodes[0] _spec.Edges = append(_spec.Edges, edge) } return _node, _spec diff --git a/db/ent/user_query.go b/db/ent/user_query.go index e8c5d6f..6b2a663 100644 --- a/db/ent/user_query.go +++ b/db/ent/user_query.go @@ -29,7 +29,6 @@ type UserQuery struct { withCreatedTexture *TextureQuery withProfile *UserProfileQuery withToken *UserTokenQuery - withFKs bool modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). sql *sql.Selector @@ -125,7 +124,7 @@ func (uq *UserQuery) QueryToken() *UserTokenQuery { step := sqlgraph.NewStep( sqlgraph.From(user.Table, user.FieldID, selector), sqlgraph.To(usertoken.Table, usertoken.FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, user.TokenTable, user.TokenColumn), + sqlgraph.Edge(sqlgraph.O2O, false, user.TokenTable, user.TokenColumn), ) fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) return fromU, nil @@ -444,7 +443,6 @@ func (uq *UserQuery) prepareQuery(ctx context.Context) error { func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, error) { var ( nodes = []*User{} - withFKs = uq.withFKs _spec = uq.querySpec() loadedTypes = [3]bool{ uq.withCreatedTexture != nil, @@ -452,12 +450,6 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e uq.withToken != nil, } ) - if uq.withToken != nil { - withFKs = true - } - if withFKs { - _spec.Node.Columns = append(_spec.Node.Columns, user.ForeignKeys...) - } _spec.ScanValues = func(columns []string) ([]any, error) { return (*User).scanValues(nil, columns) } @@ -561,34 +553,30 @@ func (uq *UserQuery) loadProfile(ctx context.Context, query *UserProfileQuery, n return nil } func (uq *UserQuery) loadToken(ctx context.Context, query *UserTokenQuery, nodes []*User, init func(*User), assign func(*User, *UserToken)) error { - ids := make([]int, 0, len(nodes)) - nodeids := make(map[int][]*User) + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int]*User) for i := range nodes { - if nodes[i].user_token == nil { - continue - } - fk := *nodes[i].user_token - if _, ok := nodeids[fk]; !ok { - ids = append(ids, fk) - } - nodeids[fk] = append(nodeids[fk], nodes[i]) + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] } - if len(ids) == 0 { - return nil - } - query.Where(usertoken.IDIn(ids...)) + query.withFKs = true + query.Where(predicate.UserToken(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(user.TokenColumn), fks...)) + })) neighbors, err := query.All(ctx) if err != nil { return err } for _, n := range neighbors { - nodes, ok := nodeids[n.ID] + fk := n.user_token + if fk == nil { + return fmt.Errorf(`foreign-key "user_token" is nil for node %v`, n.ID) + } + node, ok := nodeids[*fk] if !ok { - return fmt.Errorf(`unexpected foreign-key "user_token" returned %v`, n.ID) - } - for i := range nodes { - assign(nodes[i], n) + return fmt.Errorf(`unexpected referenced foreign-key "user_token" returned %v for node %v`, *fk, n.ID) } + assign(node, n) } return nil } diff --git a/db/ent/user_update.go b/db/ent/user_update.go index 1339e2e..9a9141f 100644 --- a/db/ent/user_update.go +++ b/db/ent/user_update.go @@ -307,7 +307,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } if uu.mutation.TokenCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.O2O, Inverse: false, Table: user.TokenTable, Columns: []string{user.TokenColumn}, @@ -320,7 +320,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { } if nodes := uu.mutation.TokenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.O2O, Inverse: false, Table: user.TokenTable, Columns: []string{user.TokenColumn}, @@ -661,7 +661,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) } if uuo.mutation.TokenCleared() { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.O2O, Inverse: false, Table: user.TokenTable, Columns: []string{user.TokenColumn}, @@ -674,7 +674,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) } if nodes := uuo.mutation.TokenIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, + Rel: sqlgraph.O2O, Inverse: false, Table: user.TokenTable, Columns: []string{user.TokenColumn}, diff --git a/db/ent/usertoken.go b/db/ent/usertoken.go index 41da04b..c944538 100644 --- a/db/ent/usertoken.go +++ b/db/ent/usertoken.go @@ -8,6 +8,7 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" + "github.com/xmdhs/authlib-skin/db/ent/user" "github.com/xmdhs/authlib-skin/db/ent/usertoken" ) @@ -18,11 +19,35 @@ type UserToken struct { ID int `json:"id,omitempty"` // TokenID holds the value of the "token_id" field. TokenID uint64 `json:"token_id,omitempty"` - // UUID holds the value of the "uuid" field. - UUID string `json:"uuid,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the UserTokenQuery when eager-loading is set. + Edges UserTokenEdges `json:"edges"` + user_token *int selectValues sql.SelectValues } +// UserTokenEdges holds the relations/edges for other nodes in the graph. +type UserTokenEdges struct { + // User holds the value of the user edge. + User *User `json:"user,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// UserOrErr returns the User value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e UserTokenEdges) UserOrErr() (*User, error) { + if e.loadedTypes[0] { + if e.User == nil { + // Edge was loaded but was not found. + return nil, &NotFoundError{label: user.Label} + } + return e.User, nil + } + return nil, &NotLoadedError{edge: "user"} +} + // scanValues returns the types for scanning values from sql.Rows. func (*UserToken) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) @@ -30,8 +55,8 @@ func (*UserToken) scanValues(columns []string) ([]any, error) { switch columns[i] { case usertoken.FieldID, usertoken.FieldTokenID: values[i] = new(sql.NullInt64) - case usertoken.FieldUUID: - values[i] = new(sql.NullString) + case usertoken.ForeignKeys[0]: // user_token + values[i] = new(sql.NullInt64) default: values[i] = new(sql.UnknownType) } @@ -59,11 +84,12 @@ func (ut *UserToken) assignValues(columns []string, values []any) error { } else if value.Valid { ut.TokenID = uint64(value.Int64) } - case usertoken.FieldUUID: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field uuid", values[i]) + case usertoken.ForeignKeys[0]: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for edge-field user_token", value) } else if value.Valid { - ut.UUID = value.String + ut.user_token = new(int) + *ut.user_token = int(value.Int64) } default: ut.selectValues.Set(columns[i], values[i]) @@ -78,6 +104,11 @@ func (ut *UserToken) Value(name string) (ent.Value, error) { return ut.selectValues.Get(name) } +// QueryUser queries the "user" edge of the UserToken entity. +func (ut *UserToken) QueryUser() *UserQuery { + return NewUserTokenClient(ut.config).QueryUser(ut) +} + // Update returns a builder for updating this UserToken. // Note that you need to call UserToken.Unwrap() before calling this method if this UserToken // was returned from a transaction, and the transaction was committed or rolled back. @@ -103,9 +134,6 @@ func (ut *UserToken) String() string { builder.WriteString(fmt.Sprintf("id=%v, ", ut.ID)) builder.WriteString("token_id=") builder.WriteString(fmt.Sprintf("%v", ut.TokenID)) - builder.WriteString(", ") - builder.WriteString("uuid=") - builder.WriteString(ut.UUID) builder.WriteByte(')') return builder.String() } diff --git a/db/ent/usertoken/usertoken.go b/db/ent/usertoken/usertoken.go index 2e001d7..a9d8958 100644 --- a/db/ent/usertoken/usertoken.go +++ b/db/ent/usertoken/usertoken.go @@ -4,6 +4,7 @@ package usertoken import ( "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" ) const ( @@ -13,17 +14,29 @@ const ( FieldID = "id" // FieldTokenID holds the string denoting the token_id field in the database. FieldTokenID = "token_id" - // FieldUUID holds the string denoting the uuid field in the database. - FieldUUID = "uuid" + // EdgeUser holds the string denoting the user edge name in mutations. + EdgeUser = "user" // Table holds the table name of the usertoken in the database. Table = "user_tokens" + // UserTable is the table that holds the user relation/edge. + UserTable = "user_tokens" + // UserInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UserInverseTable = "users" + // UserColumn is the table column denoting the user relation/edge. + UserColumn = "user_token" ) // Columns holds all SQL columns for usertoken fields. var Columns = []string{ FieldID, FieldTokenID, - FieldUUID, +} + +// ForeignKeys holds the SQL foreign-keys that are owned by the "user_tokens" +// table and are not defined as standalone fields in the schema. +var ForeignKeys = []string{ + "user_token", } // ValidColumn reports if the column name is valid (part of the table columns). @@ -33,6 +46,11 @@ func ValidColumn(column string) bool { return true } } + for i := range ForeignKeys { + if column == ForeignKeys[i] { + return true + } + } return false } @@ -49,7 +67,16 @@ func ByTokenID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldTokenID, opts...).ToFunc() } -// ByUUID orders the results by the uuid field. -func ByUUID(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldUUID, opts...).ToFunc() +// ByUserField orders the results by user field. +func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...)) + } +} +func newUserStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(UserInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, UserTable, UserColumn), + ) } diff --git a/db/ent/usertoken/where.go b/db/ent/usertoken/where.go index 491cd20..fb39a0f 100644 --- a/db/ent/usertoken/where.go +++ b/db/ent/usertoken/where.go @@ -4,6 +4,7 @@ package usertoken import ( "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" "github.com/xmdhs/authlib-skin/db/ent/predicate" ) @@ -57,11 +58,6 @@ func TokenID(v uint64) predicate.UserToken { return predicate.UserToken(sql.FieldEQ(FieldTokenID, v)) } -// UUID applies equality check predicate on the "uuid" field. It's identical to UUIDEQ. -func UUID(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldEQ(FieldUUID, v)) -} - // TokenIDEQ applies the EQ predicate on the "token_id" field. func TokenIDEQ(v uint64) predicate.UserToken { return predicate.UserToken(sql.FieldEQ(FieldTokenID, v)) @@ -102,69 +98,27 @@ func TokenIDLTE(v uint64) predicate.UserToken { return predicate.UserToken(sql.FieldLTE(FieldTokenID, v)) } -// UUIDEQ applies the EQ predicate on the "uuid" field. -func UUIDEQ(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldEQ(FieldUUID, v)) +// HasUser applies the HasEdge predicate on the "user" edge. +func HasUser() predicate.UserToken { + return predicate.UserToken(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, UserTable, UserColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) } -// UUIDNEQ applies the NEQ predicate on the "uuid" field. -func UUIDNEQ(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldNEQ(FieldUUID, v)) -} - -// UUIDIn applies the In predicate on the "uuid" field. -func UUIDIn(vs ...string) predicate.UserToken { - return predicate.UserToken(sql.FieldIn(FieldUUID, vs...)) -} - -// UUIDNotIn applies the NotIn predicate on the "uuid" field. -func UUIDNotIn(vs ...string) predicate.UserToken { - return predicate.UserToken(sql.FieldNotIn(FieldUUID, vs...)) -} - -// UUIDGT applies the GT predicate on the "uuid" field. -func UUIDGT(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldGT(FieldUUID, v)) -} - -// UUIDGTE applies the GTE predicate on the "uuid" field. -func UUIDGTE(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldGTE(FieldUUID, v)) -} - -// UUIDLT applies the LT predicate on the "uuid" field. -func UUIDLT(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldLT(FieldUUID, v)) -} - -// UUIDLTE applies the LTE predicate on the "uuid" field. -func UUIDLTE(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldLTE(FieldUUID, v)) -} - -// UUIDContains applies the Contains predicate on the "uuid" field. -func UUIDContains(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldContains(FieldUUID, v)) -} - -// UUIDHasPrefix applies the HasPrefix predicate on the "uuid" field. -func UUIDHasPrefix(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldHasPrefix(FieldUUID, v)) -} - -// UUIDHasSuffix applies the HasSuffix predicate on the "uuid" field. -func UUIDHasSuffix(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldHasSuffix(FieldUUID, v)) -} - -// UUIDEqualFold applies the EqualFold predicate on the "uuid" field. -func UUIDEqualFold(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldEqualFold(FieldUUID, v)) -} - -// UUIDContainsFold applies the ContainsFold predicate on the "uuid" field. -func UUIDContainsFold(v string) predicate.UserToken { - return predicate.UserToken(sql.FieldContainsFold(FieldUUID, v)) +// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). +func HasUserWith(preds ...predicate.User) predicate.UserToken { + return predicate.UserToken(func(s *sql.Selector) { + step := newUserStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) } // And groups predicates with the AND operator between them. diff --git a/db/ent/usertoken_create.go b/db/ent/usertoken_create.go index fb296b0..3bf2219 100644 --- a/db/ent/usertoken_create.go +++ b/db/ent/usertoken_create.go @@ -9,6 +9,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" + "github.com/xmdhs/authlib-skin/db/ent/user" "github.com/xmdhs/authlib-skin/db/ent/usertoken" ) @@ -25,12 +26,25 @@ func (utc *UserTokenCreate) SetTokenID(u uint64) *UserTokenCreate { return utc } -// SetUUID sets the "uuid" field. -func (utc *UserTokenCreate) SetUUID(s string) *UserTokenCreate { - utc.mutation.SetUUID(s) +// SetUserID sets the "user" edge to the User entity by ID. +func (utc *UserTokenCreate) SetUserID(id int) *UserTokenCreate { + utc.mutation.SetUserID(id) return utc } +// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil. +func (utc *UserTokenCreate) SetNillableUserID(id *int) *UserTokenCreate { + if id != nil { + utc = utc.SetUserID(*id) + } + return utc +} + +// SetUser sets the "user" edge to the User entity. +func (utc *UserTokenCreate) SetUser(u *User) *UserTokenCreate { + return utc.SetUserID(u.ID) +} + // Mutation returns the UserTokenMutation object of the builder. func (utc *UserTokenCreate) Mutation() *UserTokenMutation { return utc.mutation @@ -68,9 +82,6 @@ func (utc *UserTokenCreate) check() error { if _, ok := utc.mutation.TokenID(); !ok { return &ValidationError{Name: "token_id", err: errors.New(`ent: missing required field "UserToken.token_id"`)} } - if _, ok := utc.mutation.UUID(); !ok { - return &ValidationError{Name: "uuid", err: errors.New(`ent: missing required field "UserToken.uuid"`)} - } return nil } @@ -101,9 +112,22 @@ func (utc *UserTokenCreate) createSpec() (*UserToken, *sqlgraph.CreateSpec) { _spec.SetField(usertoken.FieldTokenID, field.TypeUint64, value) _node.TokenID = value } - if value, ok := utc.mutation.UUID(); ok { - _spec.SetField(usertoken.FieldUUID, field.TypeString, value) - _node.UUID = value + if nodes := utc.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: true, + Table: usertoken.UserTable, + Columns: []string{usertoken.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.user_token = &nodes[0] + _spec.Edges = append(_spec.Edges, edge) } return _node, _spec } diff --git a/db/ent/usertoken_query.go b/db/ent/usertoken_query.go index f9432f5..3421b65 100644 --- a/db/ent/usertoken_query.go +++ b/db/ent/usertoken_query.go @@ -12,6 +12,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/xmdhs/authlib-skin/db/ent/predicate" + "github.com/xmdhs/authlib-skin/db/ent/user" "github.com/xmdhs/authlib-skin/db/ent/usertoken" ) @@ -22,6 +23,8 @@ type UserTokenQuery struct { order []usertoken.OrderOption inters []Interceptor predicates []predicate.UserToken + withUser *UserQuery + withFKs bool modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). sql *sql.Selector @@ -59,6 +62,28 @@ func (utq *UserTokenQuery) Order(o ...usertoken.OrderOption) *UserTokenQuery { return utq } +// QueryUser chains the current query on the "user" edge. +func (utq *UserTokenQuery) QueryUser() *UserQuery { + query := (&UserClient{config: utq.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := utq.prepareQuery(ctx); err != nil { + return nil, err + } + selector := utq.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(usertoken.Table, usertoken.FieldID, selector), + sqlgraph.To(user.Table, user.FieldID), + sqlgraph.Edge(sqlgraph.O2O, true, usertoken.UserTable, usertoken.UserColumn), + ) + fromU = sqlgraph.SetNeighbors(utq.driver.Dialect(), step) + return fromU, nil + } + return query +} + // First returns the first UserToken entity from the query. // Returns a *NotFoundError when no UserToken was found. func (utq *UserTokenQuery) First(ctx context.Context) (*UserToken, error) { @@ -251,12 +276,24 @@ func (utq *UserTokenQuery) Clone() *UserTokenQuery { order: append([]usertoken.OrderOption{}, utq.order...), inters: append([]Interceptor{}, utq.inters...), predicates: append([]predicate.UserToken{}, utq.predicates...), + withUser: utq.withUser.Clone(), // clone intermediate query. sql: utq.sql.Clone(), path: utq.path, } } +// WithUser tells the query-builder to eager-load the nodes that are connected to +// the "user" edge. The optional arguments are used to configure the query builder of the edge. +func (utq *UserTokenQuery) WithUser(opts ...func(*UserQuery)) *UserTokenQuery { + query := (&UserClient{config: utq.config}).Query() + for _, opt := range opts { + opt(query) + } + utq.withUser = query + return utq +} + // 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. // @@ -333,15 +370,26 @@ func (utq *UserTokenQuery) prepareQuery(ctx context.Context) error { func (utq *UserTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UserToken, error) { var ( - nodes = []*UserToken{} - _spec = utq.querySpec() + nodes = []*UserToken{} + withFKs = utq.withFKs + _spec = utq.querySpec() + loadedTypes = [1]bool{ + utq.withUser != nil, + } ) + if utq.withUser != nil { + withFKs = true + } + if withFKs { + _spec.Node.Columns = append(_spec.Node.Columns, usertoken.ForeignKeys...) + } _spec.ScanValues = func(columns []string) ([]any, error) { return (*UserToken).scanValues(nil, columns) } _spec.Assign = func(columns []string, values []any) error { node := &UserToken{config: utq.config} nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes return node.assignValues(columns, values) } if len(utq.modifiers) > 0 { @@ -356,9 +404,48 @@ func (utq *UserTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*U if len(nodes) == 0 { return nodes, nil } + if query := utq.withUser; query != nil { + if err := utq.loadUser(ctx, query, nodes, nil, + func(n *UserToken, e *User) { n.Edges.User = e }); err != nil { + return nil, err + } + } return nodes, nil } +func (utq *UserTokenQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*UserToken, init func(*UserToken), assign func(*UserToken, *User)) error { + ids := make([]int, 0, len(nodes)) + nodeids := make(map[int][]*UserToken) + for i := range nodes { + if nodes[i].user_token == nil { + continue + } + fk := *nodes[i].user_token + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(user.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "user_token" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + func (utq *UserTokenQuery) sqlCount(ctx context.Context) (int, error) { _spec := utq.querySpec() if len(utq.modifiers) > 0 { diff --git a/db/ent/usertoken_update.go b/db/ent/usertoken_update.go index 6653b54..457eeeb 100644 --- a/db/ent/usertoken_update.go +++ b/db/ent/usertoken_update.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" "github.com/xmdhs/authlib-skin/db/ent/predicate" + "github.com/xmdhs/authlib-skin/db/ent/user" "github.com/xmdhs/authlib-skin/db/ent/usertoken" ) @@ -40,17 +41,36 @@ func (utu *UserTokenUpdate) AddTokenID(u int64) *UserTokenUpdate { return utu } -// SetUUID sets the "uuid" field. -func (utu *UserTokenUpdate) SetUUID(s string) *UserTokenUpdate { - utu.mutation.SetUUID(s) +// SetUserID sets the "user" edge to the User entity by ID. +func (utu *UserTokenUpdate) SetUserID(id int) *UserTokenUpdate { + utu.mutation.SetUserID(id) return utu } +// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil. +func (utu *UserTokenUpdate) SetNillableUserID(id *int) *UserTokenUpdate { + if id != nil { + utu = utu.SetUserID(*id) + } + return utu +} + +// SetUser sets the "user" edge to the User entity. +func (utu *UserTokenUpdate) SetUser(u *User) *UserTokenUpdate { + return utu.SetUserID(u.ID) +} + // Mutation returns the UserTokenMutation object of the builder. func (utu *UserTokenUpdate) Mutation() *UserTokenMutation { return utu.mutation } +// ClearUser clears the "user" edge to the User entity. +func (utu *UserTokenUpdate) ClearUser() *UserTokenUpdate { + utu.mutation.ClearUser() + return utu +} + // Save executes the query and returns the number of nodes affected by the update operation. func (utu *UserTokenUpdate) Save(ctx context.Context) (int, error) { return withHooks(ctx, utu.sqlSave, utu.mutation, utu.hooks) @@ -93,8 +113,34 @@ func (utu *UserTokenUpdate) sqlSave(ctx context.Context) (n int, err error) { if value, ok := utu.mutation.AddedTokenID(); ok { _spec.AddField(usertoken.FieldTokenID, field.TypeUint64, value) } - if value, ok := utu.mutation.UUID(); ok { - _spec.SetField(usertoken.FieldUUID, field.TypeString, value) + if utu.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: true, + Table: usertoken.UserTable, + Columns: []string{usertoken.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := utu.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: true, + Table: usertoken.UserTable, + Columns: []string{usertoken.UserColumn}, + 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 n, err = sqlgraph.UpdateNodes(ctx, utu.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { @@ -129,17 +175,36 @@ func (utuo *UserTokenUpdateOne) AddTokenID(u int64) *UserTokenUpdateOne { return utuo } -// SetUUID sets the "uuid" field. -func (utuo *UserTokenUpdateOne) SetUUID(s string) *UserTokenUpdateOne { - utuo.mutation.SetUUID(s) +// SetUserID sets the "user" edge to the User entity by ID. +func (utuo *UserTokenUpdateOne) SetUserID(id int) *UserTokenUpdateOne { + utuo.mutation.SetUserID(id) return utuo } +// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil. +func (utuo *UserTokenUpdateOne) SetNillableUserID(id *int) *UserTokenUpdateOne { + if id != nil { + utuo = utuo.SetUserID(*id) + } + return utuo +} + +// SetUser sets the "user" edge to the User entity. +func (utuo *UserTokenUpdateOne) SetUser(u *User) *UserTokenUpdateOne { + return utuo.SetUserID(u.ID) +} + // Mutation returns the UserTokenMutation object of the builder. func (utuo *UserTokenUpdateOne) Mutation() *UserTokenMutation { return utuo.mutation } +// ClearUser clears the "user" edge to the User entity. +func (utuo *UserTokenUpdateOne) ClearUser() *UserTokenUpdateOne { + utuo.mutation.ClearUser() + return utuo +} + // Where appends a list predicates to the UserTokenUpdate builder. func (utuo *UserTokenUpdateOne) Where(ps ...predicate.UserToken) *UserTokenUpdateOne { utuo.mutation.Where(ps...) @@ -212,8 +277,34 @@ func (utuo *UserTokenUpdateOne) sqlSave(ctx context.Context) (_node *UserToken, if value, ok := utuo.mutation.AddedTokenID(); ok { _spec.AddField(usertoken.FieldTokenID, field.TypeUint64, value) } - if value, ok := utuo.mutation.UUID(); ok { - _spec.SetField(usertoken.FieldUUID, field.TypeString, value) + if utuo.mutation.UserCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: true, + Table: usertoken.UserTable, + Columns: []string{usertoken.UserColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := utuo.mutation.UserIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2O, + Inverse: true, + Table: usertoken.UserTable, + Columns: []string{usertoken.UserColumn}, + 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) } _node = &UserToken{config: utuo.config} _spec.Assign = _node.assignValues diff --git a/model/model.go b/model/model.go index dd156f5..a8fbd55 100644 --- a/model/model.go +++ b/model/model.go @@ -19,5 +19,7 @@ type TokenClaims struct { Tid string `json:"tid"` // ClientToken Yggdrasil 协议中使用 CID string `json:"cid"` + // 用户 id + UID int `json:"uid"` jwt.RegisteredClaims } diff --git a/server/server.go b/server/server.go index 80ed667..728a2dd 100644 --- a/server/server.go +++ b/server/server.go @@ -30,7 +30,7 @@ func NewServer(c config.Config, sl *slog.Logger, route *httprouter.Router) (*htt }) r = r.WithContext(ctx) } - if sl.Enabled(ctx, slog.LevelDebug) { + if c.Debug && sl.Enabled(ctx, slog.LevelDebug) { sl.DebugContext(ctx, r.Method) } route.ServeHTTP(w, r) diff --git a/service/utils/auth.go b/service/utils/auth.go index 1f38236..29cbb3b 100644 --- a/service/utils/auth.go +++ b/service/utils/auth.go @@ -10,6 +10,7 @@ import ( "github.com/golang-jwt/jwt/v5" "github.com/xmdhs/authlib-skin/db/ent" + "github.com/xmdhs/authlib-skin/db/ent/user" "github.com/xmdhs/authlib-skin/db/ent/usertoken" "github.com/xmdhs/authlib-skin/model" "github.com/xmdhs/authlib-skin/model/yggdrasil" @@ -50,7 +51,7 @@ func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, pu } } - ut, err := client.UserToken.Query().Where(usertoken.UUIDEQ(claims.Subject)).First(ctx) + ut, err := client.UserToken.Query().Where(usertoken.HasUserWith(user.ID(claims.UID))).First(ctx) if err != nil { return nil, fmt.Errorf("Auth: %w", err) } diff --git a/service/yggdrasil/user.go b/service/yggdrasil/user.go index 6578520..53b7faa 100644 --- a/service/yggdrasil/user.go +++ b/service/yggdrasil/user.go @@ -63,7 +63,7 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat } } if utoken == nil { - ut, err := tx.UserToken.Create().SetTokenID(1).SetUUID(u.Edges.Profile.UUID).Save(cxt) + ut, err := tx.UserToken.Create().SetTokenID(1).SetUser(u).Save(cxt) if err != nil { return err } @@ -79,7 +79,7 @@ func (y *Yggdrasil) Authenticate(cxt context.Context, auth yggdrasil.Authenticat return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err) } - jwts, err := newJwtToken(y.prikey, strconv.FormatUint(utoken.TokenID, 10), clientToken, u.Edges.Profile.UUID) + jwts, err := newJwtToken(y.prikey, strconv.FormatUint(utoken.TokenID, 10), clientToken, u.Edges.Profile.UUID, u.ID) if err != nil { return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err) } @@ -113,7 +113,7 @@ func (y *Yggdrasil) SignOut(ctx context.Context, t yggdrasil.Pass) error { if err != nil { return fmt.Errorf("SignOut: %w", err) } - ut, err := y.client.UserToken.Query().Where(usertoken.UUIDEQ(u.Edges.Profile.UUID)).First(ctx) + ut, err := y.client.UserToken.Query().Where(usertoken.HasUserWith(user.IDEQ(u.ID))).First(ctx) if err != nil { var nf *ent.NotFoundError if !errors.As(err, &nf) { @@ -133,7 +133,7 @@ func (y *Yggdrasil) Invalidate(ctx context.Context, accessToken string) error { if err != nil { return fmt.Errorf("Invalidate: %w", err) } - err = y.client.UserToken.Update().Where(usertoken.UUIDEQ(t.Subject)).AddTokenID(1).Exec(ctx) + err = y.client.UserToken.Update().Where(usertoken.HasUserWith(user.ID(t.UID))).AddTokenID(1).Exec(ctx) if err != nil { return fmt.Errorf("Invalidate: %w", err) } @@ -145,12 +145,12 @@ func (y *Yggdrasil) Refresh(ctx context.Context, token yggdrasil.RefreshToken) ( if err != nil { return yggdrasil.Token{}, fmt.Errorf("Refresh: %w", err) } - jwts, err := newJwtToken(y.prikey, t.Tid, t.CID, t.Subject) + jwts, err := newJwtToken(y.prikey, t.Tid, t.CID, t.Subject, t.UID) if err != nil { return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err) } - up, err := y.client.UserProfile.Query().Where(userprofile.UUIDEQ(t.Subject)).First(ctx) + up, err := y.client.UserProfile.Query().Where(userprofile.HasUserWith(user.ID(t.UID))).First(ctx) if err != nil { return yggdrasil.Token{}, fmt.Errorf("Authenticate: %w", err) } diff --git a/service/yggdrasil/yggdrasil.go b/service/yggdrasil/yggdrasil.go index 6c3aa4c..00d6635 100644 --- a/service/yggdrasil/yggdrasil.go +++ b/service/yggdrasil/yggdrasil.go @@ -64,10 +64,11 @@ func putUint(n uint64, c cache.Cache, key []byte, d time.Duration) error { return nil } -func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string) (string, error) { +func newJwtToken(jwtKey *rsa.PrivateKey, tokenID, clientToken, UUID string, userID int) (string, error) { claims := model.TokenClaims{ Tid: tokenID, CID: clientToken, + UID: userID, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * 24 * time.Hour)), Issuer: "authlib-skin",