109 lines
5.4 KiB
Go
109 lines
5.4 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.cin.su/m/Assistant/contracts/world"
|
|
worlddomain "git.cin.su/m/Assistant/modules/world/domain"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type WorldRepository struct{ pool *pgxpool.Pool }
|
|
|
|
func OpenWorld(ctx context.Context, config ContinuityConfig) (*WorldRepository, error) {
|
|
pool, err := openPool(ctx, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &WorldRepository{pool: pool}, nil
|
|
}
|
|
|
|
func (r *WorldRepository) Close() { r.pool.Close() }
|
|
|
|
func (r *WorldRepository) SaveKindDefinition(ctx context.Context, value world.WorldObjectKindDefinition) error {
|
|
if err := worlddomain.ValidateKindDefinition(value); err != nil {
|
|
return err
|
|
}
|
|
var parentOwner, parentKind, parentID string
|
|
var parentRevision *uint64
|
|
if value.ParentKindRef != nil {
|
|
parentOwner, parentKind, parentID = value.ParentKindRef.OwnerNamespace, value.ParentKindRef.SemanticKind, string(value.ParentKindRef.StableID)
|
|
if value.ParentKindRef.Revision != nil {
|
|
revision := uint64(*value.ParentKindRef.Revision)
|
|
parentRevision = &revision
|
|
}
|
|
}
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO world.kind_definitions(kind_definition_id,kind_key,revision,display_name,parent_owner_namespace,parent_semantic_kind,parent_stable_id,parent_revision,lifecycle,definition_digest,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) ON CONFLICT(kind_definition_id) DO NOTHING`, value.ID, value.KindKey, value.Revision, value.DisplayName, parentOwner, parentKind, parentID, parentRevision, value.Lifecycle, value.DefinitionDigest, value.RecordedAt)
|
|
return err
|
|
}
|
|
|
|
func (r *WorldRepository) SaveObject(ctx context.Context, value world.WorldObject) error {
|
|
if err := worlddomain.ValidateObject(value); err != nil {
|
|
return err
|
|
}
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO world.objects(world_object_id,principal_id,kind_owner_namespace,kind_semantic_kind,kind_stable_id,kind_revision,lifecycle,created_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT(world_object_id) DO NOTHING`, value.ID, value.PrincipalID, value.KindDefinitionRef.OwnerNamespace, value.KindDefinitionRef.SemanticKind, value.KindDefinitionRef.StableID, value.KindRevision, value.Lifecycle, value.CreatedAt)
|
|
return err
|
|
}
|
|
|
|
func (r *WorldRepository) SaveAlias(ctx context.Context, value world.WorldAlias) error {
|
|
if err := worlddomain.ValidateAlias(value); err != nil {
|
|
return err
|
|
}
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO world.aliases(world_alias_id,principal_id,world_object_id,alias,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5) ON CONFLICT(world_alias_id) DO NOTHING`, value.ID, value.PrincipalID, value.ObjectID, value.Alias, value.RecordedAt)
|
|
return err
|
|
}
|
|
|
|
func (r *WorldRepository) SaveFacetDefinition(ctx context.Context, value world.FacetDefinition) error {
|
|
if err := worlddomain.ValidateFacetDefinition(value); err != nil {
|
|
return err
|
|
}
|
|
payload, err := json.Marshal(value.ValueType)
|
|
if err != nil {
|
|
return fmt.Errorf("encode facet value type: %w", err)
|
|
}
|
|
_, err = r.pool.Exec(ctx, `INSERT INTO world.facet_definitions(facet_definition_id,kind_key,revision,facet_key,value_type,definition_digest,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7) ON CONFLICT(facet_definition_id) DO NOTHING`, value.ID, value.KindKey, value.Revision, value.FacetKey, payload, value.DefinitionDigest, value.RecordedAt)
|
|
return err
|
|
}
|
|
|
|
func (r *WorldRepository) SaveRelationDefinition(ctx context.Context, value world.RelationDefinition) error {
|
|
if err := worlddomain.ValidateRelationDefinition(value); err != nil {
|
|
return err
|
|
}
|
|
_, err := r.pool.Exec(ctx, `INSERT INTO world.relation_definitions(relation_definition_id,kind_key,revision,relation_key,target_kind_key,definition_digest,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7) ON CONFLICT(relation_definition_id) DO NOTHING`, value.ID, value.KindKey, value.Revision, value.RelationKey, value.TargetKindKey, value.DefinitionDigest, value.RecordedAt)
|
|
return err
|
|
}
|
|
|
|
func (r *WorldRepository) SaveResolution(ctx context.Context, value world.IdentityResolutionDecisionRecord) error {
|
|
if err := worlddomain.ValidateResolution(value); err != nil {
|
|
return err
|
|
}
|
|
candidates, err := json.Marshal(value.Candidates)
|
|
if err != nil {
|
|
return fmt.Errorf("encode resolution candidates: %w", err)
|
|
}
|
|
evidence, err := json.Marshal(value.Evidence)
|
|
if err != nil {
|
|
return fmt.Errorf("encode resolution evidence: %w", err)
|
|
}
|
|
_, err = r.pool.Exec(ctx, `INSERT INTO world.identity_resolution_decisions(resolution_decision_id,principal_id,candidates,decision,evidence,confidence_millis,decided_at_unix_millis,revision) VALUES($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT(resolution_decision_id) DO NOTHING`, value.ID, value.PrincipalID, candidates, value.Decision, evidence, value.ConfidenceMillis, value.DecidedAt, value.Revision)
|
|
return err
|
|
}
|
|
|
|
func (r *WorldRepository) SaveLineage(ctx context.Context, value world.WorldLineage) error {
|
|
if err := worlddomain.ValidateLineage(value); err != nil {
|
|
return err
|
|
}
|
|
sources, err := json.Marshal(value.SourceRefs)
|
|
if err != nil {
|
|
return fmt.Errorf("encode lineage sources: %w", err)
|
|
}
|
|
successors, err := json.Marshal(value.SuccessorRefs)
|
|
if err != nil {
|
|
return fmt.Errorf("encode lineage successors: %w", err)
|
|
}
|
|
_, err = r.pool.Exec(ctx, `INSERT INTO world.lineage(lineage_id,operation,source_refs,successor_refs,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5) ON CONFLICT(lineage_id) DO NOTHING`, value.ID, value.Operation, sources, successors, value.RecordedAt)
|
|
return err
|
|
}
|