59 lines
2.6 KiB
Go
59 lines
2.6 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"git.cin.su/m/Assistant/contracts/capability"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
var ErrCapabilityHealthNotFound = errors.New("capability health not found")
|
|
|
|
type CapabilityRepository struct{ pool *pgxpool.Pool }
|
|
|
|
func OpenCapability(ctx context.Context, config ContinuityConfig) (*CapabilityRepository, error) {
|
|
dsn := fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s", config.Host, config.Port, config.Database, config.User, config.Password)
|
|
pool, err := pgxpool.New(ctx, dsn)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &CapabilityRepository{pool: pool}, nil
|
|
}
|
|
|
|
func (r *CapabilityRepository) Close() { r.pool.Close() }
|
|
|
|
func (r *CapabilityRepository) SaveHealth(ctx context.Context, health capability.Health) error {
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO capability.health (capability_id, state, reason, revision, semantic_version, observed_at_unix_millis) VALUES ($1,$2,$3,$4,$5,$6) ON CONFLICT (capability_id) DO UPDATE SET state=EXCLUDED.state, reason=EXCLUDED.reason, revision=EXCLUDED.revision, semantic_version=EXCLUDED.semantic_version, observed_at_unix_millis=EXCLUDED.observed_at_unix_millis WHERE capability.health.revision < EXCLUDED.revision`, health.CapabilityID, health.State, health.Reason, health.Revision, health.SemanticVersion, health.ObservedAtUnixMillis)
|
|
return err
|
|
}
|
|
|
|
func (r *CapabilityRepository) LoadHealth(ctx context.Context, id capability.CapabilityID) (capability.Health, error) {
|
|
var health capability.Health
|
|
err := r.pool.QueryRow(ctx, `SELECT capability_id, state, reason, revision, semantic_version, observed_at_unix_millis FROM capability.health WHERE capability_id=$1`, id).Scan(&health.CapabilityID, &health.State, &health.Reason, &health.Revision, &health.SemanticVersion, &health.ObservedAtUnixMillis)
|
|
if err != nil {
|
|
return capability.Health{}, fmt.Errorf("load capability health: %w", err)
|
|
}
|
|
return health, nil
|
|
}
|
|
|
|
func (r *CapabilityRepository) RebuildHealthProjection(ctx context.Context) (int64, error) {
|
|
tx, err := r.pool.Begin(ctx)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer tx.Rollback(ctx)
|
|
if _, err = tx.Exec(ctx, `DELETE FROM capability.health_projection`); err != nil {
|
|
return 0, err
|
|
}
|
|
result, err := tx.Exec(ctx, `INSERT INTO capability.health_projection (capability_id, state, reason, revision, semantic_version, observed_at_unix_millis) SELECT capability_id, state, reason, revision, semantic_version, observed_at_unix_millis FROM capability.health`)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if err = tx.Commit(ctx); err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected(), nil
|
|
}
|