123 lines
3.2 KiB
Go
123 lines
3.2 KiB
Go
package database
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/apex/log"
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Measurement model
|
|
type Measurement struct {
|
|
ID int64 `db:"id"`
|
|
Name string `db:"name"`
|
|
StartTime time.Time `db:"start_time"`
|
|
EndTime time.Time `db:"end_time"`
|
|
Summary string `db:"summary"` // XXX this should be JSON
|
|
ASN int64 `db:"asn"`
|
|
IP string `db:"ip"`
|
|
CountryCode string `db:"country"`
|
|
State string `db:"state"`
|
|
Failure string `db:"failure"`
|
|
ReportFilePath string `db:"report_file"`
|
|
ReportID string `db:"report_id"`
|
|
Input string `db:"input"`
|
|
MeasurementID string `db:"measurement_id"`
|
|
ResultID string `db:"result_id"`
|
|
}
|
|
|
|
// SetGeoIPInfo for the Measurement
|
|
func (m *Measurement) SetGeoIPInfo() error {
|
|
return nil
|
|
}
|
|
|
|
// CreateMeasurement writes the measurement to the database a returns a pointer
|
|
// to the Measurement
|
|
func CreateMeasurement(db *sqlx.DB, m Measurement) (*Measurement, error) {
|
|
res, err := db.NamedExec(`INSERT INTO measurements
|
|
(name, start_time,
|
|
summary, asn, ip, country,
|
|
state, failure, report_file,
|
|
report_id, input, measurement_id,
|
|
result_id)
|
|
VALUES (:name,:start_time,
|
|
:asn,:ip,:country,
|
|
:state,:failure,:report_file,
|
|
:report_id,:input,
|
|
:result_id)`,
|
|
m)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "creating measurement")
|
|
}
|
|
id, err := res.LastInsertId()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "creating measurement")
|
|
}
|
|
m.ID = id
|
|
return &m, nil
|
|
}
|
|
|
|
// Result model
|
|
type Result struct {
|
|
ID int64 `db:"id"`
|
|
Name string `db:"name"`
|
|
StartTime time.Time `db:"start_time"`
|
|
Runtime float64 `db:"runtime"` // Runtime is expressed in Microseconds
|
|
Summary string `db:"summary"` // XXX this should be JSON
|
|
Done bool `db:"done"`
|
|
DataUsageUp int64 `db:"data_usage_up"`
|
|
DataUsageDown int64 `db:"data_usage_down"`
|
|
|
|
started time.Time
|
|
}
|
|
|
|
// Started marks the Result as having started
|
|
func (r *Result) Started(db *sqlx.DB) error {
|
|
r.started = time.Now()
|
|
return nil
|
|
}
|
|
|
|
// Finished marks the result as done and sets the runtime
|
|
func (r *Result) Finished(db *sqlx.DB) error {
|
|
if r.Done == true || r.Runtime != 0 {
|
|
return errors.New("Result is already finished")
|
|
}
|
|
r.Runtime = float64(time.Now().Sub(r.started)) / float64(time.Microsecond)
|
|
r.Done = true
|
|
|
|
res, err := db.NamedExec(`UPDATE results
|
|
SET done = true, runtime = :runtime
|
|
WHERE id = :id`, r)
|
|
if err != nil {
|
|
return errors.Wrap(err, "updating result")
|
|
}
|
|
count, err := res.RowsAffected()
|
|
if err != nil {
|
|
return errors.Wrap(err, "updating result")
|
|
}
|
|
if count != 1 {
|
|
return errors.New("inconsistent update count")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CreateResult writes the Result to the database a returns a pointer
|
|
// to the Result
|
|
func CreateResult(db *sqlx.DB, r Result) (*Result, error) {
|
|
log.Debugf("Creating result %v", r)
|
|
res, err := db.NamedExec(`INSERT INTO results
|
|
(name, start_time)
|
|
VALUES (:name,:start_time)`,
|
|
r)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "creating result")
|
|
}
|
|
id, err := res.LastInsertId()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "creating result")
|
|
}
|
|
r.ID = id
|
|
return &r, nil
|
|
}
|