Files
core/internal/history/backfill.go

69 lines
2.3 KiB
Go

package history
import (
"context"
"database/sql"
)
type BackfillCurrentFromObservationsResult struct {
UpdatedComponentTypes int64 `json:"updated_component_types"`
UpdatedInstallationSlots int64 `json:"updated_installation_slots"`
}
func (s *Service) BackfillCurrentFromObservations(ctx context.Context) (BackfillCurrentFromObservationsResult, error) {
if s == nil || s.db == nil {
return BackfillCurrentFromObservationsResult{}, sql.ErrConnDone
}
tx, err := s.db.BeginTx(ctx, &sql.TxOptions{})
if err != nil {
return BackfillCurrentFromObservationsResult{}, err
}
defer func() { _ = tx.Rollback() }()
res1, err := tx.ExecContext(ctx, `
UPDATE parts p
LEFT JOIN observations o ON o.id = (
SELECT o2.id
FROM observations o2
WHERE o2.part_id = p.id
AND JSON_EXTRACT(o2.details, '$.component_type') IS NOT NULL
ORDER BY o2.observed_at DESC, o2.created_at DESC, o2.id DESC
LIMIT 1
)
SET p.component_type = NULLIF(JSON_UNQUOTE(JSON_EXTRACT(o.details, '$.component_type')), '')
WHERE (p.component_type IS NULL OR p.component_type = '')`)
if err != nil {
return BackfillCurrentFromObservationsResult{}, err
}
res2, err := tx.ExecContext(ctx, `
UPDATE installations i
LEFT JOIN observations o ON o.id = (
SELECT o2.id
FROM observations o2
WHERE o2.part_id = i.part_id
ORDER BY o2.observed_at DESC, o2.created_at DESC, o2.id DESC
LIMIT 1
)
SET i.slot_name = COALESCE(
i.slot_name,
NULLIF(JSON_UNQUOTE(JSON_EXTRACT(o.details, '$.slot')), ''),
NULLIF(JSON_UNQUOTE(JSON_EXTRACT(o.details, '$.attributes.location')), ''),
CASE
WHEN JSON_EXTRACT(o.details, '$.attributes.socket') IS NULL THEN NULL
ELSE CONCAT('Socket ', JSON_UNQUOTE(JSON_EXTRACT(o.details, '$.attributes.socket')))
END,
NULLIF(JSON_UNQUOTE(JSON_EXTRACT(o.details, '$.attributes.bdf')), '')
)
WHERE i.removed_at IS NULL AND (i.slot_name IS NULL OR i.slot_name = '')`)
if err != nil {
return BackfillCurrentFromObservationsResult{}, err
}
if err := tx.Commit(); err != nil {
return BackfillCurrentFromObservationsResult{}, err
}
updatedTypes, _ := res1.RowsAffected()
updatedSlots, _ := res2.RowsAffected()
return BackfillCurrentFromObservationsResult{UpdatedComponentTypes: updatedTypes, UpdatedInstallationSlots: updatedSlots}, nil
}