feat: complete split camera credentials (#50)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package admission
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var ErrNotFound = errors.New("admission result not found")
|
||||
|
||||
type Store interface {
|
||||
Save(context.Context, Result) error
|
||||
Get(context.Context, string) (Result, error)
|
||||
}
|
||||
|
||||
type MemoryStore struct {
|
||||
mu sync.RWMutex
|
||||
results map[string]Result
|
||||
}
|
||||
|
||||
func NewMemoryStore() *MemoryStore { return &MemoryStore{results: map[string]Result{}} }
|
||||
func (s *MemoryStore) Save(_ context.Context, result Result) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.results[result.DeviceID] = result
|
||||
return nil
|
||||
}
|
||||
func (s *MemoryStore) Get(_ context.Context, deviceID string) (Result, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
result, ok := s.results[deviceID]
|
||||
if !ok {
|
||||
return Result{}, ErrNotFound
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type PostgresStore struct{ database *sql.DB }
|
||||
|
||||
func NewPostgresStore(database *sql.DB) *PostgresStore { return &PostgresStore{database: database} }
|
||||
func (s *PostgresStore) Save(ctx context.Context, result Result) error {
|
||||
tx, err := s.database.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
_, err = tx.ExecContext(ctx, `INSERT INTO sense_admission_results(device_id,address,status,detail,checked_at) VALUES($1,$2,$3,$4,$5) ON CONFLICT(device_id) DO UPDATE SET address=EXCLUDED.address,status=EXCLUDED.status,detail=EXCLUDED.detail,checked_at=EXCLUDED.checked_at`, result.DeviceID, result.Address, result.Status, result.Detail, result.CheckedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = tx.ExecContext(ctx, `DELETE FROM sense_admission_profiles WHERE device_id=$1`, result.DeviceID); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, profile := range result.Profiles {
|
||||
_, err = tx.ExecContext(ctx, `INSERT INTO sense_admission_profiles(device_id,token,name,width,height,encoding,stream_uri,kind,verification_status,verification_latency_ms,verification_detail) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)`, result.DeviceID, profile.Token, profile.Name, profile.Width, profile.Height, profile.Encoding, profile.StreamURI, profile.Kind, profile.Verification.Status, profile.Verification.LatencyMS, profile.Verification.Detail)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
func (s *PostgresStore) Get(ctx context.Context, deviceID string) (Result, error) {
|
||||
var result Result
|
||||
err := s.database.QueryRowContext(ctx, `SELECT device_id,address,status,detail,checked_at FROM sense_admission_results WHERE device_id=$1`, deviceID).Scan(&result.DeviceID, &result.Address, &result.Status, &result.Detail, &result.CheckedAt)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return Result{}, ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
rows, err := s.database.QueryContext(ctx, `SELECT token,name,width,height,encoding,stream_uri,kind,verification_status,verification_latency_ms,verification_detail FROM sense_admission_profiles WHERE device_id=$1 ORDER BY width*height DESC`, deviceID)
|
||||
if err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var profile Profile
|
||||
if err := rows.Scan(&profile.Token, &profile.Name, &profile.Width, &profile.Height, &profile.Encoding, &profile.StreamURI, &profile.Kind, &profile.Verification.Status, &profile.Verification.LatencyMS, &profile.Verification.Detail); err != nil {
|
||||
return Result{}, err
|
||||
}
|
||||
result.Profiles = append(result.Profiles, profile)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user