package repository import ( "context" "database/sql" "encoding/json" "fmt" "strings" "github.com/topfans/backend/services/statisticService/model" ) // EventRepository events 表操作 type EventRepository struct { db *sql.DB schema string } // NewEventRepository 构造 EventRepository func NewEventRepository(db *sql.DB, schema string) *EventRepository { return &EventRepository{db: db, schema: schema} } // InsertBatch 批量插入事件,event_id 重复时 ON CONFLICT DO NOTHING // 返回实际插入的行数 func (r *EventRepository) InsertBatch(ctx context.Context, events []*model.Event) (int, error) { if len(events) == 0 { return 0, nil } placeholders := make([]string, 0, len(events)) args := make([]interface{}, 0, len(events)*7) for _, e := range events { props := e.Properties if props == nil { props = map[string]string{} } propsJSON, _ := json.Marshal(props) placeholders = append(placeholders, fmt.Sprintf("($%d, $%d, $%d, $%d, $%d, $%d, $%d)", len(args)+1, len(args)+2, len(args)+3, len(args)+4, len(args)+5, len(args)+6, len(args)+7)) args = append(args, e.EventID, e.UserID, e.StarID, e.EventType, e.OccurredAt, e.ReceivedAt, string(propsJSON)) } query := fmt.Sprintf(` INSERT INTO %s.events (event_id, user_id, star_id, event_type, occurred_at, received_at, properties) VALUES %s ON CONFLICT (event_id, received_at) DO NOTHING `, r.schema, strings.Join(placeholders, ",")) res, err := r.db.ExecContext(ctx, query, args...) if err != nil { return 0, fmt.Errorf("insert events: %w", err) } n, err := res.RowsAffected() if err != nil { return 0, fmt.Errorf("rows affected: %w", err) } return int(n), nil }