Improve UI views for assets/components/failures and timeline details
This commit is contained in:
@@ -12,6 +12,11 @@ type InstallationRepository struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
type ComponentObservationMeta struct {
|
||||
ComponentType string
|
||||
Location string
|
||||
}
|
||||
|
||||
func NewInstallationRepository(db *sql.DB) *InstallationRepository {
|
||||
return &InstallationRepository{db: db}
|
||||
}
|
||||
@@ -92,3 +97,129 @@ func (r *InstallationRepository) ListCurrentComponentIDsByAssets(ctx context.Con
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *InstallationRepository) ListLatestFirmwareByComponentIDs(ctx context.Context, componentIDs []string) (map[string]string, error) {
|
||||
result := make(map[string]string, len(componentIDs))
|
||||
if len(componentIDs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
placeholders := make([]string, len(componentIDs))
|
||||
args := make([]any, 0, len(componentIDs))
|
||||
for i, componentID := range componentIDs {
|
||||
placeholders[i] = "?"
|
||||
args = append(args, componentID)
|
||||
}
|
||||
|
||||
query := `SELECT o.part_id, o.firmware_version
|
||||
FROM observations o
|
||||
WHERE o.part_id IN (` + strings.Join(placeholders, ",") + `)
|
||||
AND o.firmware_version IS NOT NULL
|
||||
AND o.id = (
|
||||
SELECT o2.id
|
||||
FROM observations o2
|
||||
WHERE o2.part_id = o.part_id
|
||||
AND o2.firmware_version IS NOT NULL
|
||||
ORDER BY o2.observed_at DESC, o2.created_at DESC, o2.id DESC
|
||||
LIMIT 1
|
||||
)`
|
||||
|
||||
rows, err := r.db.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var componentID string
|
||||
var firmware string
|
||||
if err := rows.Scan(&componentID, &firmware); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[componentID] = firmware
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *InstallationRepository) ListLatestObservationMetaByComponentIDs(ctx context.Context, componentIDs []string) (map[string]ComponentObservationMeta, error) {
|
||||
result := make(map[string]ComponentObservationMeta, len(componentIDs))
|
||||
if len(componentIDs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
placeholders := make([]string, len(componentIDs))
|
||||
args := make([]any, 0, len(componentIDs))
|
||||
for i, componentID := range componentIDs {
|
||||
placeholders[i] = "?"
|
||||
args = append(args, componentID)
|
||||
}
|
||||
|
||||
query := `SELECT
|
||||
o.part_id,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(o.details, '$.component_type')) AS component_type,
|
||||
COALESCE(
|
||||
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')), '')
|
||||
) AS location
|
||||
FROM observations o
|
||||
WHERE o.part_id IN (` + strings.Join(placeholders, ",") + `)
|
||||
AND o.id = (
|
||||
SELECT o2.id
|
||||
FROM observations o2
|
||||
WHERE o2.part_id = o.part_id
|
||||
ORDER BY o2.observed_at DESC, o2.created_at DESC, o2.id DESC
|
||||
LIMIT 1
|
||||
)`
|
||||
|
||||
rows, err := r.db.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var componentID string
|
||||
var componentType sql.NullString
|
||||
var location sql.NullString
|
||||
if err := rows.Scan(&componentID, &componentType, &location); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[componentID] = ComponentObservationMeta{
|
||||
ComponentType: strings.TrimSpace(componentType.String),
|
||||
Location: strings.TrimSpace(location.String),
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *InstallationRepository) GetCurrentAssetIDByComponent(ctx context.Context, componentID string) (*string, error) {
|
||||
var assetID string
|
||||
row := r.db.QueryRowContext(ctx,
|
||||
`SELECT machine_id
|
||||
FROM installations
|
||||
WHERE part_id = ? AND removed_at IS NULL
|
||||
ORDER BY installed_at DESC, created_at DESC, id DESC
|
||||
LIMIT 1`,
|
||||
componentID,
|
||||
)
|
||||
if err := row.Scan(&assetID); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &assetID, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user