| package model |
| |
| import ( |
| "context" |
| "database/sql" |
| "fmt" |
| |
| "github.com/golang/glog" |
| ) |
| |
| func (s *sqlModel) SubmitPeerCheckResults(ctx context.Context, checkName string, res []*PeerCheckResult) error { |
| tx := s.db.MustBeginTx(ctx, &sql.TxOptions{}) |
| defer tx.Rollback() |
| |
| glog.Infof("SubmitPeerCheckResults:") |
| for _, r := range res { |
| glog.Infof(" - %+v", *r) |
| } |
| |
| q := ` |
| UPDATE peer_checks |
| SET delete = true |
| WHERE check_name = $1 |
| ` |
| if _, err := tx.ExecContext(ctx, q, checkName); err != nil { |
| return fmt.Errorf("UPDATE for deletion peer_checks: %v", err) |
| } |
| |
| seenASNs := make(map[int64]bool) |
| |
| for _, pcr := range res { |
| seenASNs[pcr.PeerASN] = true |
| |
| q = ` |
| INSERT INTO peer_checks |
| (peer_id, check_name, check_time, check_status, check_message, delete) |
| SELECT |
| peers.id, :check_name, :check_time, :check_status, :check_message, false |
| FROM peers |
| WHERE peers.asn = :asn |
| ON CONFLICT (peer_id, check_name) |
| DO UPDATE SET |
| check_time = :check_time, |
| check_status = :check_status, |
| check_message = :check_message, |
| delete = false |
| ` |
| status := "uknown" |
| switch pcr.Status { |
| case PeerCheckStatus_Okay: |
| status = "okay" |
| case PeerCheckStatus_Failed: |
| status = "failed" |
| case PeerCheckStatus_SoftFailed: |
| glog.Infof("Skipping soft failure: %+v", pcr) |
| continue |
| } |
| cr := sqlPeerCheck{ |
| CheckName: pcr.CheckName, |
| CheckTime: pcr.Time.UnixNano(), |
| CheckStatus: status, |
| CheckMessage: pcr.Message, |
| ASN: fmt.Sprintf("%d", pcr.PeerASN), |
| } |
| if _, err := tx.NamedExecContext(ctx, q, cr); err != nil { |
| return fmt.Errorf("INSERT peer_checks: %v", err) |
| } |
| } |
| |
| q = ` |
| DELETE FROM peer_checks |
| WHERE delete = true |
| AND check_name = $1 |
| ` |
| if _, err := tx.ExecContext(ctx, q, checkName); err != nil { |
| return fmt.Errorf("DELETE FROM peer_checks: %v", err) |
| } |
| |
| return tx.Commit() |
| } |