feat: complete split camera credentials (#50)

This commit is contained in:
ila
2026-08-13 12:23:47 +08:00
parent 6075433402
commit 136caf189e
+86
View File
@@ -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()
}