fix: 复合主键表改为单字段 id 以支持 ent 完整生成

This commit is contained in:
zetaloop
2026-04-24 07:32:52 +08:00
parent c62d743320
commit 5ad579f03c
19 changed files with 324 additions and 82 deletions
@@ -6,6 +6,7 @@ import (
"juwan-backend/app/shop/rpc/internal/svc"
"juwan-backend/app/shop/rpc/pb"
"juwan-backend/app/snowflake/rpc/snowflake"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -26,14 +27,21 @@ func NewAddShopPlayersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ad
// -----------------------shopPlayers-----------------------
func (l *AddShopPlayersLogic) AddShopPlayers(in *pb.AddShopPlayersReq) (*pb.AddShopPlayersResp, error) {
_, err := l.svcCtx.ShopModelRW.ShopPlayers.Create().
idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{})
if err != nil {
logx.Errorf("addShopPlayers snowflake err:%v", err)
return nil, errors.New("create shop player id failed")
}
_, err = l.svcCtx.ShopModelRW.ShopPlayers.Create().
SetID(idResp.Id).
SetShopID(in.ShopId).
SetPlayerID(in.PlayerId).
SetIsPrimary(in.IsPrimary).
Save(l.ctx)
if err != nil {
logx.Errorf("addPlayerServices err:%v", err)
return nil, errors.New("add player service failed")
logx.Errorf("addShopPlayers err:%v", err)
return nil, errors.New("add shop player failed")
}
return &pb.AddShopPlayersResp{}, nil
@@ -3,6 +3,7 @@ package logic
import (
"context"
"errors"
"juwan-backend/app/shop/rpc/internal/models/shopplayers"
"time"
"juwan-backend/app/shop/rpc/internal/svc"
@@ -30,28 +31,23 @@ func (l *UpdateShopPlayersLogic) UpdateShopPlayers(in *pb.UpdateShopPlayersReq)
return nil, errors.New("invalid shop_id or player_id")
}
// ent 的 Update().Where() 不支持复合主键表(shop_players 的主键是 (shop_id, player_id)),
// 会报 "sql/sqlgraph: invalid composite id for update table"。
// Create/Delete/Query 不受影响,仅 Update 需要走原生 SQL。
query := `UPDATE shop_players SET is_primary = $1, left_at = $2 WHERE shop_id = $3 AND player_id = $4`
updater := l.svcCtx.ShopModelRW.ShopPlayers.Update().
Where(
shopplayers.ShopIDEQ(in.ShopId),
shopplayers.PlayerIDEQ(in.PlayerId),
).
SetIsPrimary(in.IsPrimary)
var leftAt *time.Time
if in.LeftAt > 0 {
t := time.Unix(in.LeftAt, 0)
leftAt = &t
updater = updater.SetLeftAt(t)
}
result, err := l.svcCtx.DBRW.ExecContext(l.ctx, query, in.IsPrimary, leftAt, in.ShopId, in.PlayerId)
affected, err := updater.Save(l.ctx)
if err != nil {
logx.Errorf("update shop players failed, %s", err.Error())
return nil, errors.New("update shop players failed")
}
affected, err := result.RowsAffected()
if err != nil {
logx.Errorf("get rows affected failed, %s", err.Error())
return nil, errors.New("update shop players failed")
}
if affected == 0 {
return nil, errors.New("shop player not found")
}
+27 -4
View File
@@ -410,6 +410,12 @@ func (c *ShopPlayersClient) UpdateOne(_m *ShopPlayers) *ShopPlayersUpdateOne {
return &ShopPlayersUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// UpdateOneID returns an update builder for the given id.
func (c *ShopPlayersClient) UpdateOneID(id int64) *ShopPlayersUpdateOne {
mutation := newShopPlayersMutation(c.config, OpUpdateOne, withShopPlayersID(id))
return &ShopPlayersUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}
// Delete returns a delete builder for ShopPlayers.
func (c *ShopPlayersClient) Delete() *ShopPlayersDelete {
mutation := newShopPlayersMutation(c.config, OpDelete)
@@ -418,10 +424,13 @@ func (c *ShopPlayersClient) Delete() *ShopPlayersDelete {
// DeleteOne returns a builder for deleting the given entity.
func (c *ShopPlayersClient) DeleteOne(_m *ShopPlayers) *ShopPlayersDeleteOne {
builder := c.Delete().Where(
shopplayers.ShopIDEQ(_m.ShopID),
shopplayers.PlayerIDEQ(_m.PlayerID),
)
return c.DeleteOneID(_m.ID)
}
// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *ShopPlayersClient) DeleteOneID(id int64) *ShopPlayersDeleteOne {
builder := c.Delete().Where(shopplayers.ID(id))
builder.mutation.id = &id
builder.mutation.op = OpDeleteOne
return &ShopPlayersDeleteOne{builder}
}
@@ -435,6 +444,20 @@ func (c *ShopPlayersClient) Query() *ShopPlayersQuery {
}
}
// Get returns a ShopPlayers entity by its id.
func (c *ShopPlayersClient) Get(ctx context.Context, id int64) (*ShopPlayers, error) {
return c.Query().Where(shopplayers.ID(id)).Only(ctx)
}
// GetX is like Get, but panics if an error occurs.
func (c *ShopPlayersClient) GetX(ctx context.Context, id int64) *ShopPlayers {
obj, err := c.Get(ctx, id)
if err != nil {
panic(err)
}
return obj
}
// Hooks returns the client hooks.
func (c *ShopPlayersClient) Hooks() []Hook {
return c.hooks.ShopPlayers
@@ -49,6 +49,7 @@ var (
}
// ShopPlayersColumns holds the columns for the "shop_players" table.
ShopPlayersColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt64, Increment: true},
{Name: "shop_id", Type: field.TypeInt64},
{Name: "player_id", Type: field.TypeInt64},
{Name: "is_primary", Type: field.TypeBool, Nullable: true, Default: false},
@@ -59,17 +60,22 @@ var (
ShopPlayersTable = &schema.Table{
Name: "shop_players",
Columns: ShopPlayersColumns,
PrimaryKey: []*schema.Column{ShopPlayersColumns[0], ShopPlayersColumns[1]},
PrimaryKey: []*schema.Column{ShopPlayersColumns[0]},
Indexes: []*schema.Index{
{
Name: "shopplayers_shop_id_player_id",
Unique: true,
Columns: []*schema.Column{ShopPlayersColumns[1], ShopPlayersColumns[2]},
},
{
Name: "shopplayers_player_id",
Unique: false,
Columns: []*schema.Column{ShopPlayersColumns[1]},
Columns: []*schema.Column{ShopPlayersColumns[2]},
},
{
Name: "shopplayers_shop_id_joined_at",
Unique: false,
Columns: []*schema.Column{ShopPlayersColumns[0], ShopPlayersColumns[3]},
Columns: []*schema.Column{ShopPlayersColumns[1], ShopPlayersColumns[4]},
},
},
}
+61 -15
View File
@@ -764,6 +764,7 @@ type ShopPlayersMutation struct {
config
op Op
typ string
id *int64
shop_id *int64
addshop_id *int64
player_id *int64
@@ -796,16 +797,35 @@ func newShopPlayersMutation(c config, op Op, opts ...shopplayersOption) *ShopPla
return m
}
// withShopPlayersID sets the ID field of the mutation.
func withShopPlayersID(id int64) shopplayersOption {
return func(m *ShopPlayersMutation) {
var (
err error
once sync.Once
value *ShopPlayers
)
m.oldValue = func(ctx context.Context) (*ShopPlayers, error) {
once.Do(func() {
if m.done {
err = errors.New("querying old values post mutation is not allowed")
} else {
value, err = m.Client().ShopPlayers.Get(ctx, id)
}
})
return value, err
}
m.id = &id
}
}
// withShopPlayers sets the old ShopPlayers of the mutation.
func withShopPlayers(node *ShopPlayers) shopplayersOption {
return func(m *ShopPlayersMutation) {
m.oldValue = func(context.Context) (*ShopPlayers, error) {
return node, nil
}
m.predicates = append(m.predicates,
shopplayers.ShopIDEQ(node.ShopID),
shopplayers.PlayerIDEQ(node.PlayerID),
)
m.id = &node.ID
}
}
@@ -828,12 +848,38 @@ func (m ShopPlayersMutation) Tx() (*Tx, error) {
return tx, nil
}
// SetID sets the value of the id field. Note that this
// operation is only accepted on creation of ShopPlayers entities.
func (m *ShopPlayersMutation) SetID(id int64) {
m.id = &id
}
// ID returns the ID value in the mutation. Note that the ID is only available
// if it was provided to the builder or after it was returned from the database.
func (m *ShopPlayersMutation) ID() (id int64, exists bool) {
if m.id == nil {
return
}
return *m.id, true
}
// IDs queries the database and returns the entity ids that match the mutation's predicate.
// That means, if the mutation is applied within a transaction with an isolation level such
// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated
// or updated by the mutation.
func (m *ShopPlayersMutation) IDs(ctx context.Context) ([]int64, error) {
return nil, fmt.Errorf("IDs is not supported on %s operations for ShopPlayers", m.op)
switch {
case m.op.Is(OpUpdateOne | OpDeleteOne):
id, exists := m.ID()
if exists {
return []int64{id}, nil
}
fallthrough
case m.op.Is(OpUpdate | OpDelete):
return m.Client().ShopPlayers.Query().Where(m.predicates...).IDs(ctx)
default:
return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
}
}
// SetShopID sets the "shop_id" field.
@@ -858,8 +904,8 @@ func (m *ShopPlayersMutation) OldShopID(ctx context.Context) (v int64, err error
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldShopID is only allowed on UpdateOne operations")
}
if m.oldValue == nil {
return v, errors.New("OldShopID requires the old ShopPlayers value in the mutation")
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldShopID requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
@@ -914,8 +960,8 @@ func (m *ShopPlayersMutation) OldPlayerID(ctx context.Context) (v int64, err err
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldPlayerID is only allowed on UpdateOne operations")
}
if m.oldValue == nil {
return v, errors.New("OldPlayerID requires the old ShopPlayers value in the mutation")
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldPlayerID requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
@@ -969,8 +1015,8 @@ func (m *ShopPlayersMutation) OldIsPrimary(ctx context.Context) (v bool, err err
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldIsPrimary is only allowed on UpdateOne operations")
}
if m.oldValue == nil {
return v, errors.New("OldIsPrimary requires the old ShopPlayers value in the mutation")
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldIsPrimary requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
@@ -1018,8 +1064,8 @@ func (m *ShopPlayersMutation) OldJoinedAt(ctx context.Context) (v time.Time, err
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldJoinedAt is only allowed on UpdateOne operations")
}
if m.oldValue == nil {
return v, errors.New("OldJoinedAt requires the old ShopPlayers value in the mutation")
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldJoinedAt requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
@@ -1054,8 +1100,8 @@ func (m *ShopPlayersMutation) OldLeftAt(ctx context.Context) (v *time.Time, err
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldLeftAt is only allowed on UpdateOne operations")
}
if m.oldValue == nil {
return v, errors.New("OldLeftAt requires the old ShopPlayers value in the mutation")
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldLeftAt requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
+2 -2
View File
@@ -31,11 +31,11 @@ func init() {
shopplayersFields := schema.ShopPlayers{}.Fields()
_ = shopplayersFields
// shopplayersDescIsPrimary is the schema descriptor for is_primary field.
shopplayersDescIsPrimary := shopplayersFields[2].Descriptor()
shopplayersDescIsPrimary := shopplayersFields[3].Descriptor()
// shopplayers.DefaultIsPrimary holds the default value on creation for the is_primary field.
shopplayers.DefaultIsPrimary = shopplayersDescIsPrimary.Default.(bool)
// shopplayersDescJoinedAt is the schema descriptor for joined_at field.
shopplayersDescJoinedAt := shopplayersFields[3].Descriptor()
shopplayersDescJoinedAt := shopplayersFields[4].Descriptor()
// shopplayers.DefaultJoinedAt holds the default value on creation for the joined_at field.
shopplayers.DefaultJoinedAt = shopplayersDescJoinedAt.Default.(func() time.Time)
shopsFields := schema.Shops{}.Fields()
@@ -4,7 +4,6 @@ import (
"time"
"entgo.io/ent"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
@@ -14,15 +13,10 @@ type ShopPlayers struct {
ent.Schema
}
func (ShopPlayers) Annotations() []schema.Annotation {
return []schema.Annotation{
field.ID("shop_id", "player_id"),
}
}
// Fields of the ShopPlayers.
func (ShopPlayers) Fields() []ent.Field {
return []ent.Field{
field.Int64("id").Immutable().Unique(),
field.Int64("shop_id"),
field.Int64("player_id"),
field.Bool("is_primary").Optional().Default(false),
@@ -34,6 +28,7 @@ func (ShopPlayers) Fields() []ent.Field {
// Indexes of the ShopPlayers.
func (ShopPlayers) Indexes() []ent.Index {
return []ent.Index{
index.Fields("shop_id", "player_id").Unique(),
index.Fields("player_id"),
index.Fields("shop_id", "joined_at"),
}
+10 -1
View File
@@ -15,6 +15,8 @@ import (
// ShopPlayers is the model entity for the ShopPlayers schema.
type ShopPlayers struct {
config `json:"-"`
// ID of the ent.
ID int64 `json:"id,omitempty"`
// ShopID holds the value of the "shop_id" field.
ShopID int64 `json:"shop_id,omitempty"`
// PlayerID holds the value of the "player_id" field.
@@ -35,7 +37,7 @@ func (*ShopPlayers) scanValues(columns []string) ([]any, error) {
switch columns[i] {
case shopplayers.FieldIsPrimary:
values[i] = new(sql.NullBool)
case shopplayers.FieldShopID, shopplayers.FieldPlayerID:
case shopplayers.FieldID, shopplayers.FieldShopID, shopplayers.FieldPlayerID:
values[i] = new(sql.NullInt64)
case shopplayers.FieldJoinedAt, shopplayers.FieldLeftAt:
values[i] = new(sql.NullTime)
@@ -54,6 +56,12 @@ func (_m *ShopPlayers) assignValues(columns []string, values []any) error {
}
for i := range columns {
switch columns[i] {
case shopplayers.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
_m.ID = int64(value.Int64)
case shopplayers.FieldShopID:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for field shop_id", values[i])
@@ -120,6 +128,7 @@ func (_m *ShopPlayers) Unwrap() *ShopPlayers {
func (_m *ShopPlayers) String() string {
var builder strings.Builder
builder.WriteString("ShopPlayers(")
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
builder.WriteString("shop_id=")
builder.WriteString(fmt.Sprintf("%v", _m.ShopID))
builder.WriteString(", ")
@@ -11,6 +11,8 @@ import (
const (
// Label holds the string label denoting the shopplayers type in the database.
Label = "shop_players"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldShopID holds the string denoting the shop_id field in the database.
FieldShopID = "shop_id"
// FieldPlayerID holds the string denoting the player_id field in the database.
@@ -27,6 +29,7 @@ const (
// Columns holds all SQL columns for shopplayers fields.
var Columns = []string{
FieldID,
FieldShopID,
FieldPlayerID,
FieldIsPrimary,
@@ -54,6 +57,11 @@ var (
// OrderOption defines the ordering options for the ShopPlayers queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByShopID orders the results by the shop_id field.
func ByShopID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldShopID, opts...).ToFunc()
@@ -9,6 +9,51 @@ import (
"entgo.io/ent/dialect/sql"
)
// ID filters vertices based on their ID field.
func ID(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldLTE(FieldID, id))
}
// ShopID applies equality check predicate on the "shop_id" field. It's identical to ShopIDEQ.
func ShopID(v int64) predicate.ShopPlayers {
return predicate.ShopPlayers(sql.FieldEQ(FieldShopID, v))
@@ -74,6 +74,12 @@ func (_c *ShopPlayersCreate) SetNillableLeftAt(v *time.Time) *ShopPlayersCreate
return _c
}
// SetID sets the "id" field.
func (_c *ShopPlayersCreate) SetID(v int64) *ShopPlayersCreate {
_c.mutation.SetID(v)
return _c
}
// Mutation returns the ShopPlayersMutation object of the builder.
func (_c *ShopPlayersCreate) Mutation() *ShopPlayersMutation {
return _c.mutation
@@ -144,6 +150,11 @@ func (_c *ShopPlayersCreate) sqlSave(ctx context.Context) (*ShopPlayers, error)
}
return nil, err
}
if _spec.ID.Value != _node.ID {
id := _spec.ID.Value.(int64)
_node.ID = int64(id)
}
_c.mutation.id = &_node.ID
_c.mutation.done = true
return _node, nil
}
@@ -151,8 +162,12 @@ func (_c *ShopPlayersCreate) sqlSave(ctx context.Context) (*ShopPlayers, error)
func (_c *ShopPlayersCreate) createSpec() (*ShopPlayers, *sqlgraph.CreateSpec) {
var (
_node = &ShopPlayers{config: _c.config}
_spec = sqlgraph.NewCreateSpec(shopplayers.Table, nil)
_spec = sqlgraph.NewCreateSpec(shopplayers.Table, sqlgraph.NewFieldSpec(shopplayers.FieldID, field.TypeInt64))
)
if id, ok := _c.mutation.ID(); ok {
_node.ID = id
_spec.ID.Value = id
}
if value, ok := _c.mutation.ShopID(); ok {
_spec.SetField(shopplayers.FieldShopID, field.TypeInt64, value)
_node.ShopID = value
@@ -220,6 +235,11 @@ func (_c *ShopPlayersCreateBulk) Save(ctx context.Context) ([]*ShopPlayers, erro
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil && nodes[i].ID == 0 {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int64(id)
}
mutation.done = true
return nodes[i], nil
})
@@ -9,6 +9,7 @@ import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ShopPlayersDelete is the builder for deleting a ShopPlayers entity.
@@ -39,7 +40,7 @@ func (_d *ShopPlayersDelete) ExecX(ctx context.Context) int {
}
func (_d *ShopPlayersDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(shopplayers.Table, nil)
_spec := sqlgraph.NewDeleteSpec(shopplayers.Table, sqlgraph.NewFieldSpec(shopplayers.FieldID, field.TypeInt64))
if ps := _d.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
@@ -12,6 +12,7 @@ import (
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
)
// ShopPlayersQuery is the builder for querying ShopPlayers entities.
@@ -79,6 +80,29 @@ func (_q *ShopPlayersQuery) FirstX(ctx context.Context) *ShopPlayers {
return node
}
// FirstID returns the first ShopPlayers ID from the query.
// Returns a *NotFoundError when no ShopPlayers ID was found.
func (_q *ShopPlayersQuery) FirstID(ctx context.Context) (id int64, err error) {
var ids []int64
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{shopplayers.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (_q *ShopPlayersQuery) FirstIDX(ctx context.Context) int64 {
id, err := _q.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single ShopPlayers entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one ShopPlayers entity is found.
// Returns a *NotFoundError when no ShopPlayers entities are found.
@@ -106,6 +130,34 @@ func (_q *ShopPlayersQuery) OnlyX(ctx context.Context) *ShopPlayers {
return node
}
// OnlyID is like Only, but returns the only ShopPlayers ID in the query.
// Returns a *NotSingularError when more than one ShopPlayers ID is found.
// Returns a *NotFoundError when no entities are found.
func (_q *ShopPlayersQuery) OnlyID(ctx context.Context) (id int64, err error) {
var ids []int64
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{shopplayers.Label}
default:
err = &NotSingularError{shopplayers.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (_q *ShopPlayersQuery) OnlyIDX(ctx context.Context) int64 {
id, err := _q.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of ShopPlayersSlice.
func (_q *ShopPlayersQuery) All(ctx context.Context) ([]*ShopPlayers, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
@@ -125,6 +177,27 @@ func (_q *ShopPlayersQuery) AllX(ctx context.Context) []*ShopPlayers {
return nodes
}
// IDs executes the query and returns a list of ShopPlayers IDs.
func (_q *ShopPlayersQuery) IDs(ctx context.Context) (ids []int64, err error) {
if _q.ctx.Unique == nil && _q.path != nil {
_q.Unique(true)
}
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
if err = _q.Select(shopplayers.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (_q *ShopPlayersQuery) IDsX(ctx context.Context) []int64 {
ids, err := _q.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (_q *ShopPlayersQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
@@ -146,7 +219,7 @@ func (_q *ShopPlayersQuery) CountX(ctx context.Context) int {
// Exist returns true if the query has elements in the graph.
func (_q *ShopPlayersQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
switch _, err := _q.First(ctx); {
switch _, err := _q.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
@@ -292,7 +365,7 @@ func (_q *ShopPlayersQuery) sqlCount(ctx context.Context) (int, error) {
}
func (_q *ShopPlayersQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(shopplayers.Table, shopplayers.Columns, nil)
_spec := sqlgraph.NewQuerySpec(shopplayers.Table, shopplayers.Columns, sqlgraph.NewFieldSpec(shopplayers.FieldID, field.TypeInt64))
_spec.From = _q.sql
if unique := _q.ctx.Unique; unique != nil {
_spec.Unique = *unique
@@ -301,10 +374,13 @@ func (_q *ShopPlayersQuery) querySpec() *sqlgraph.QuerySpec {
}
if fields := _q.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, shopplayers.FieldID)
for i := range fields {
if fields[i] != shopplayers.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := _q.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
@@ -4,6 +4,7 @@ package models
import (
"context"
"errors"
"fmt"
"juwan-backend/app/shop/rpc/internal/models/predicate"
"juwan-backend/app/shop/rpc/internal/models/shopplayers"
@@ -142,7 +143,7 @@ func (_u *ShopPlayersUpdate) ExecX(ctx context.Context) {
}
func (_u *ShopPlayersUpdate) sqlSave(ctx context.Context) (_node int, err error) {
_spec := sqlgraph.NewUpdateSpec(shopplayers.Table, shopplayers.Columns)
_spec := sqlgraph.NewUpdateSpec(shopplayers.Table, shopplayers.Columns, sqlgraph.NewFieldSpec(shopplayers.FieldID, field.TypeInt64))
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
@@ -322,16 +323,24 @@ func (_u *ShopPlayersUpdateOne) ExecX(ctx context.Context) {
}
func (_u *ShopPlayersUpdateOne) sqlSave(ctx context.Context) (_node *ShopPlayers, err error) {
_spec := sqlgraph.NewUpdateSpec(shopplayers.Table, shopplayers.Columns)
_spec := sqlgraph.NewUpdateSpec(shopplayers.Table, shopplayers.Columns, sqlgraph.NewFieldSpec(shopplayers.FieldID, field.TypeInt64))
id, ok := _u.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`models: missing "ShopPlayers.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := _u.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, shopplayers.FieldID)
for _, f := range fields {
if !shopplayers.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("models: invalid field %q for query", f)}
}
if f != shopplayers.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := _u.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
@@ -27,7 +27,6 @@ type ServiceContext struct {
UsersRpc usercenter.Usercenter
ShopModelRW *models.Client
ShopModelRO *models.Client
DBRW *stdsql.DB
}
func NewServiceContext(c config.Config) *ServiceContext {
@@ -69,6 +68,5 @@ func NewServiceContext(c config.Config) *ServiceContext {
UsersRpc: usercenter.NewUsercenter(zrpc.MustNewClient(c.UsersRpcConf)),
ShopModelRO: models.NewClient(roModelOpts...),
ShopModelRW: models.NewClient(rwModelOpts...),
DBRW: rawRW,
}
}
+20 -20
View File
@@ -46,14 +46,14 @@ def reset():
psql("""
DELETE FROM wallet_transactions WHERE user_id BETWEEN 100001 AND 109999;
DELETE FROM wallets WHERE user_id BETWEEN 100001 AND 109999;
DELETE FROM comment_likes WHERE user_id BETWEEN 100001 AND 109999;
DELETE FROM post_likes WHERE user_id BETWEEN 100001 AND 109999;
DELETE FROM comment_likes WHERE id BETWEEN 100001 AND 109999;
DELETE FROM post_likes WHERE id BETWEEN 100001 AND 109999;
DELETE FROM comments WHERE id BETWEEN 100001 AND 109999;
DELETE FROM posts WHERE id BETWEEN 100001 AND 109999;
DELETE FROM order_state_logs WHERE id BETWEEN 100001 AND 109999;
DELETE FROM orders WHERE id BETWEEN 100001 AND 109999;
DELETE FROM shop_invitations WHERE id BETWEEN 100001 AND 109999;
DELETE FROM shop_players WHERE shop_id BETWEEN 100001 AND 109999;
DELETE FROM shop_players WHERE id BETWEEN 100001 AND 109999;
DELETE FROM player_services WHERE id BETWEEN 100001 AND 109999;
DELETE FROM shops WHERE id BETWEEN 100001 AND 109999;
DELETE FROM players WHERE id BETWEEN 100001 AND 109999;
@@ -175,11 +175,11 @@ INSERT INTO shops (id, owner_id, name, description, rating, total_orders, player
# ── Shop players ───────────────────────────────────────────────
psql("""
INSERT INTO shop_players (shop_id, player_id, is_primary) VALUES
(100001, 100001, true),
(100001, 100002, false),
(100002, 100003, true),
(100003, 100004, true);
INSERT INTO shop_players (id, shop_id, player_id, is_primary) VALUES
(109001, 100001, 100001, true),
(109002, 100001, 100002, false),
(109003, 100002, 100003, true),
(109004, 100003, 100004, true);
""")
# Update players.shop_id cache
@@ -310,22 +310,22 @@ INSERT INTO comments (id, post_id, author_id, content, like_count) VALUES
# ── Post likes ─────────────────────────────────────────────────
psql("""
INSERT INTO post_likes (post_id, user_id) VALUES
(100001, 100002),(100001, 100003),(100001, 100006),(100001, 100007),
(100002, 100001),(100002, 100006),
(100003, 100001),(100003, 100002),
(100004, 100001),(100004, 100004),
(100005, 100001),(100005, 100003),(100005, 100006),(100005, 100007);
INSERT INTO post_likes (id, post_id, user_id) VALUES
(109101, 100001, 100002),(109102, 100001, 100003),(109103, 100001, 100006),(109104, 100001, 100007),
(109105, 100002, 100001),(109106, 100002, 100006),
(109107, 100003, 100001),(109108, 100003, 100002),
(109109, 100004, 100001),(109110, 100004, 100004),
(109111, 100005, 100001),(109112, 100005, 100003),(109113, 100005, 100006),(109114, 100005, 100007);
""")
# ── Comment likes ──────────────────────────────────────────────
psql("""
INSERT INTO comment_likes (comment_id, user_id) VALUES
(100001, 100001),(100001, 100006),(100001, 100007),
(100003, 100001),(100003, 100006),
(100006, 100001),(100006, 100004),
(100009, 100001),(100009, 100007),
(100011, 100002),(100011, 100006),(100011, 100007);
INSERT INTO comment_likes (id, comment_id, user_id) VALUES
(109201, 100001, 100001),(109202, 100001, 100006),(109203, 100001, 100007),
(109204, 100003, 100001),(109205, 100003, 100006),
(109206, 100006, 100001),(109207, 100006, 100004),
(109208, 100009, 100001),(109209, 100009, 100007),
(109210, 100011, 100002),(109211, 100011, 100006),(109212, 100011, 100007);
""")
# ── User follows ───────────────────────────────────────────────
+2 -1
View File
@@ -1,10 +1,11 @@
CREATE TABLE comment_likes
(
id BIGINT PRIMARY KEY,
comment_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (comment_id, user_id)
UNIQUE (comment_id, user_id)
);
CREATE INDEX idx_comment_likes_lookup ON comment_likes (user_id, comment_id);
+2 -2
View File
@@ -1,11 +1,11 @@
CREATE TABLE post_likes
(
id BIGINT PRIMARY KEY,
post_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- 复合主键,防止重复点赞
PRIMARY KEY (post_id, user_id)
UNIQUE (post_id, user_id)
);
-- [核心索引] 优化 "feed流中判断我是否已赞" (user_id = ? AND post_id IN (...))
+2 -1
View File
@@ -1,5 +1,6 @@
CREATE TABLE shop_players
(
id BIGINT PRIMARY KEY,
shop_id BIGINT NOT NULL REFERENCES shops (id),
player_id BIGINT NOT NULL,
@@ -8,7 +9,7 @@ CREATE TABLE shop_players
joined_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
left_at TIMESTAMPTZ, -- 软删除,表示已离职
PRIMARY KEY (shop_id, player_id)
UNIQUE (shop_id, player_id)
);
-- 索引