74 lines
4.2 KiB
Go
74 lines
4.2 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
"git.cin.su/m/Assistant/contracts/situation"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type SituationRepository struct{ pool *pgxpool.Pool }
|
|
|
|
func OpenSituation(ctx context.Context, config ContinuityConfig) (*SituationRepository, error) {
|
|
pool, err := openPool(ctx, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &SituationRepository{pool: pool}, nil
|
|
}
|
|
func (r *SituationRepository) Close() { r.pool.Close() }
|
|
func (r *SituationRepository) Save(ctx context.Context, binding situation.FocusBinding) error {
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO situation.focus_bindings (focus_binding_id, actor_id, session_id, workspace_id, project_id, goal_id, scope_id, active) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT (focus_binding_id) DO UPDATE SET active=EXCLUDED.active`, binding.ID, binding.ActorID, binding.SessionID, binding.Workspace, binding.ProjectID, binding.GoalID, binding.ScopeID, binding.Active)
|
|
return err
|
|
}
|
|
func (r *SituationRepository) ByRuntime(ctx context.Context, runtime situation.RuntimeBinding) ([]situation.FocusBinding, error) {
|
|
rows, err := r.pool.Query(ctx, `SELECT focus_binding_id, actor_id, session_id, workspace_id, project_id, goal_id, scope_id, active FROM situation.focus_bindings WHERE session_id=$1 AND workspace_id=$2`, runtime.SessionID, runtime.Workspace)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var bindings []situation.FocusBinding
|
|
for rows.Next() {
|
|
var binding situation.FocusBinding
|
|
if err := rows.Scan(&binding.ID, &binding.ActorID, &binding.SessionID, &binding.Workspace, &binding.ProjectID, &binding.GoalID, &binding.ScopeID, &binding.Active); err != nil {
|
|
return nil, err
|
|
}
|
|
bindings = append(bindings, binding)
|
|
}
|
|
return bindings, rows.Err()
|
|
}
|
|
|
|
func (r *SituationRepository) ListProjects(ctx context.Context) ([]situation.ProjectDescriptor, error) {
|
|
rows, err := r.pool.Query(ctx, `SELECT p.project_id, p.display_name, p.recorded_at_unix_millis, COALESCE(array_agg(a.alias ORDER BY a.alias) FILTER (WHERE a.alias IS NOT NULL), '{}') FROM situation.projects p LEFT JOIN situation.project_aliases a ON a.project_id=p.project_id GROUP BY p.project_id, p.display_name, p.recorded_at_unix_millis ORDER BY p.display_name`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var projects []situation.ProjectDescriptor
|
|
for rows.Next() {
|
|
var project situation.ProjectDescriptor
|
|
var aliases []string
|
|
if err := rows.Scan(&project.ID, &project.DisplayName, &project.RecordedAtUnixMillis, &aliases); err != nil {
|
|
return nil, err
|
|
}
|
|
for _, alias := range aliases {
|
|
project.Aliases = append(project.Aliases, situation.ProjectAlias(strings.ToLower(alias)))
|
|
}
|
|
projects = append(projects, project)
|
|
}
|
|
return projects, rows.Err()
|
|
}
|
|
|
|
func (r *SituationRepository) ActiveProjectFocus(ctx context.Context, actorID identity.ActorID, principalID identity.PrincipalID) (situation.ActiveProjectFocus, error) {
|
|
var focus situation.ActiveProjectFocus
|
|
err := r.pool.QueryRow(ctx, `SELECT actor_id,principal_id,project_id,project_display_name,provenance,confidence_millis,source_utterance_id,updated_at_unix_millis FROM situation.active_project_focus WHERE actor_id=$1 AND principal_id=$2`, actorID, principalID).Scan(&focus.ActorID, &focus.PrincipalID, &focus.ProjectID, &focus.ProjectDisplayName, &focus.Provenance, &focus.ConfidenceMillis, &focus.SourceUtteranceID, &focus.UpdatedAtUnixMillis)
|
|
return focus, err
|
|
}
|
|
|
|
func (r *SituationRepository) SaveActiveProjectFocus(ctx context.Context, focus situation.ActiveProjectFocus) error {
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO situation.active_project_focus(actor_id,principal_id,project_id,project_display_name,provenance,confidence_millis,source_utterance_id,updated_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT(actor_id,principal_id) DO UPDATE SET project_id=EXCLUDED.project_id, project_display_name=EXCLUDED.project_display_name, provenance=EXCLUDED.provenance, confidence_millis=EXCLUDED.confidence_millis, source_utterance_id=EXCLUDED.source_utterance_id, updated_at_unix_millis=EXCLUDED.updated_at_unix_millis`, focus.ActorID, focus.PrincipalID, focus.ProjectID, focus.ProjectDisplayName, focus.Provenance, focus.ConfidenceMillis, focus.SourceUtteranceID, focus.UpdatedAtUnixMillis)
|
|
return err
|
|
}
|