68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package history
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
|
|
"reanimator/internal/idgen"
|
|
)
|
|
|
|
type FailureProjectionInput struct {
|
|
Source string
|
|
ExternalID string
|
|
PartID string
|
|
MachineID *string
|
|
FailureType string
|
|
FailureTime time.Time
|
|
Details *string
|
|
}
|
|
|
|
func (s *Service) UpsertFailureProjectionWithTx(ctx context.Context, tx *sql.Tx, in FailureProjectionInput) error {
|
|
if tx == nil {
|
|
return ErrConflict
|
|
}
|
|
var existingID string
|
|
err := tx.QueryRowContext(ctx, `
|
|
SELECT id
|
|
FROM failure_events
|
|
WHERE source = ?
|
|
AND part_id = ?
|
|
AND ((machine_id IS NULL AND ? IS NULL) OR machine_id = ?)
|
|
AND failure_type = ?
|
|
AND failure_time = ?
|
|
AND COALESCE(details, '') = COALESCE(?, '')
|
|
LIMIT 1`,
|
|
in.Source,
|
|
in.PartID,
|
|
in.MachineID,
|
|
in.MachineID,
|
|
in.FailureType,
|
|
in.FailureTime.UTC(),
|
|
in.Details,
|
|
).Scan(&existingID)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
if err != sql.ErrNoRows {
|
|
return err
|
|
}
|
|
|
|
id, err := s.generateID(ctx, tx, idgen.FailureEvent)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.ExecContext(ctx, `
|
|
INSERT INTO failure_events (id, source, external_id, part_id, machine_id, failure_type, failure_time, details)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
ON DUPLICATE KEY UPDATE
|
|
part_id = VALUES(part_id),
|
|
machine_id = VALUES(machine_id),
|
|
failure_type = VALUES(failure_type),
|
|
failure_time = VALUES(failure_time),
|
|
details = VALUES(details)`,
|
|
id, in.Source, in.ExternalID, in.PartID, in.MachineID, in.FailureType, in.FailureTime.UTC(), in.Details,
|
|
)
|
|
return err
|
|
}
|