From 136caf189ec0959f04a2da12209a59f2e81930bb Mon Sep 17 00:00:00 2001 From: ila <2+ila@noreply.git.ilapage.cn> Date: Thu, 13 Aug 2026 12:23:47 +0800 Subject: [PATCH] feat: complete split camera credentials (#50) --- Sense/server/app/sense/admission/store.go | 86 +++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Sense/server/app/sense/admission/store.go diff --git a/Sense/server/app/sense/admission/store.go b/Sense/server/app/sense/admission/store.go new file mode 100644 index 0000000..39c5571 --- /dev/null +++ b/Sense/server/app/sense/admission/store.go @@ -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() +} +