feat(routing): routing_profiles 表 + Profile 类型 + store(双方言)
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
dbx "github.com/wangjia/pangolin/server/internal/db"
|
||||
)
|
||||
|
||||
// Store wraps a *sql.DB and exposes the routing_profiles CRUD the routing
|
||||
// package needs.
|
||||
type Store struct {
|
||||
db *sql.DB
|
||||
dialect dbx.Dialect
|
||||
}
|
||||
|
||||
// NewStore creates a Store backed by the given connection pool (MySQL or SQLite).
|
||||
func NewStore(db *sql.DB) *Store { return &Store{db: db, dialect: dbx.DialectForDB(db)} }
|
||||
|
||||
// Get returns the user's routing profile, or (nil, nil) if none is set yet
|
||||
// (caller should fall back to Default()).
|
||||
func (s *Store) Get(ctx context.Context, userID int64) (*Profile, error) {
|
||||
var raw string
|
||||
err := s.db.QueryRowContext(ctx,
|
||||
`SELECT profile_json FROM routing_profiles WHERE user_id = ?`, userID).Scan(&raw)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("store.Get: %w", err)
|
||||
}
|
||||
var p Profile
|
||||
if err := json.Unmarshal([]byte(raw), &p); err != nil {
|
||||
return nil, fmt.Errorf("store.Get: unmarshal: %w", err)
|
||||
}
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// Upsert creates or overwrites the user's routing profile.
|
||||
func (s *Store) Upsert(ctx context.Context, userID int64, p *Profile) error {
|
||||
raw, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return fmt.Errorf("store.Upsert: marshal: %w", err)
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
q := `INSERT INTO routing_profiles (user_id, profile_json, updated_at) VALUES (?,?,?) ` +
|
||||
s.dialect.Upsert([]string{"user_id"},
|
||||
"profile_json = EXCLUDED.profile_json", "updated_at = EXCLUDED.updated_at")
|
||||
if _, err := s.db.ExecContext(ctx, q, userID, string(raw), now); err != nil {
|
||||
return fmt.Errorf("store.Upsert: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user