79 lines
2.8 KiB
Go
79 lines
2.8 KiB
Go
package media
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
var ErrNotFound = errors.New("media route not found")
|
|
|
|
type Store interface {
|
|
Save(context.Context, Route) error
|
|
Get(context.Context, string) (Route, error)
|
|
List(context.Context) ([]Route, error)
|
|
}
|
|
type MemoryStore struct {
|
|
mu sync.RWMutex
|
|
items map[string]Route
|
|
}
|
|
|
|
func NewMemoryStore() *MemoryStore { return &MemoryStore{items: map[string]Route{}} }
|
|
func (s *MemoryStore) Save(_ context.Context, item Route) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.items[item.ID] = item
|
|
return nil
|
|
}
|
|
func (s *MemoryStore) Get(_ context.Context, id string) (Route, error) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
item, ok := s.items[id]
|
|
if !ok {
|
|
return Route{}, ErrNotFound
|
|
}
|
|
return item, nil
|
|
}
|
|
func (s *MemoryStore) List(_ context.Context) ([]Route, error) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
items := make([]Route, 0, len(s.items))
|
|
for _, item := range s.items {
|
|
items = append(items, item)
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
type PostgresStore struct{ database *sql.DB }
|
|
|
|
func NewPostgresStore(db *sql.DB) *PostgresStore { return &PostgresStore{database: db} }
|
|
func (s *PostgresStore) Save(ctx context.Context, item Route) error {
|
|
_, err := s.database.ExecContext(ctx, `INSERT INTO sense_media_routes(id,device_id,profile_token,path,desired,actual,readers,detail,version,updated_at) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) ON CONFLICT(id) DO UPDATE SET desired=EXCLUDED.desired,actual=EXCLUDED.actual,readers=EXCLUDED.readers,detail=EXCLUDED.detail,version=EXCLUDED.version,updated_at=EXCLUDED.updated_at`, item.ID, item.DeviceID, item.ProfileToken, item.Path, item.Desired, item.Actual, item.Readers, item.Detail, item.Version, item.UpdatedAt)
|
|
return err
|
|
}
|
|
func (s *PostgresStore) Get(ctx context.Context, id string) (Route, error) {
|
|
var item Route
|
|
err := s.database.QueryRowContext(ctx, `SELECT id,device_id,profile_token,path,desired,actual,readers,detail,version,updated_at FROM sense_media_routes WHERE id=$1`, id).Scan(&item.ID, &item.DeviceID, &item.ProfileToken, &item.Path, &item.Desired, &item.Actual, &item.Readers, &item.Detail, &item.Version, &item.UpdatedAt)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return Route{}, ErrNotFound
|
|
}
|
|
return item, err
|
|
}
|
|
func (s *PostgresStore) List(ctx context.Context) ([]Route, error) {
|
|
rows, err := s.database.QueryContext(ctx, `SELECT id,device_id,profile_token,path,desired,actual,readers,detail,version,updated_at FROM sense_media_routes ORDER BY updated_at DESC`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []Route
|
|
for rows.Next() {
|
|
var item Route
|
|
if err := rows.Scan(&item.ID, &item.DeviceID, &item.ProfileToken, &item.Path, &item.Desired, &item.Actual, &item.Readers, &item.Detail, &item.Version, &item.UpdatedAt); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, item)
|
|
}
|
|
return items, rows.Err()
|
|
}
|