From 52bfe5df6ca954e7e90f7a4f148ddf59322d3d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arturo=20Filast=C3=B2?= Date: Mon, 17 Sep 2018 17:30:29 +0200 Subject: [PATCH] Add support for deleting measurements --- internal/database/actions.go | 29 +++++++++--- internal/database/actions_test.go | 74 +++++++++++++++++++++++++++++++ internal/database/database.go | 5 +++ 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/internal/database/actions.go b/internal/database/actions.go index bb0ea74..d712e16 100644 --- a/internal/database/actions.go +++ b/internal/database/actions.go @@ -3,6 +3,7 @@ package database import ( "database/sql" "encoding/json" + "os" "reflect" "time" @@ -112,24 +113,40 @@ func ListResults(sess sqlbuilder.Database) ([]ResultNetwork, []ResultNetwork, er incompleteResults := []ResultNetwork{} req := sess.Select( - "networks.id AS network_id", - "results.id AS result_id", db.Raw("networks.*"), db.Raw("results.*"), ).From("results"). - Join("networks").On("results.network_id = networks.id"). - OrderBy("results.start_time") + Join("networks").On("results.network_id = networks.network_id"). + OrderBy("results.result_start_time") - if err := req.Where("is_done = true").All(&doneResults); err != nil { + if err := req.Where("result_is_done = true").All(&doneResults); err != nil { return doneResults, incompleteResults, errors.Wrap(err, "failed to get result done list") } - if err := req.Where("is_done = false").All(&incompleteResults); err != nil { + if err := req.Where("result_is_done = false").All(&incompleteResults); err != nil { return doneResults, incompleteResults, errors.Wrap(err, "failed to get result done list") } return doneResults, incompleteResults, nil } +// DeleteResult will delete a particular result and the relative measurement on +// disk. +func DeleteResult(sess sqlbuilder.Database, resultID int64) error { + var result Result + res := sess.Collection("results").Find("result_id", resultID) + if err := res.One(&result); err != nil { + log.WithError(err).Error("error in obtaining the result") + return err + } + if err := res.Delete(); err != nil { + log.WithError(err).Error("failed to delete the result directory") + return err + } + + os.RemoveAll(result.MeasurementDir) + return nil +} + // CreateMeasurement writes the measurement to the database a returns a pointer // to the Measurement func CreateMeasurement(sess sqlbuilder.Database, reportID sql.NullString, testName string, resultID int64, reportFilePath string, urlID sql.NullInt64) (*Measurement, error) { diff --git a/internal/database/actions_test.go b/internal/database/actions_test.go index 608aa3d..152a6b8 100644 --- a/internal/database/actions_test.go +++ b/internal/database/actions_test.go @@ -84,6 +84,80 @@ func TestMeasurementWorkflow(t *testing.T) { } } +func TestDeleteResult(t *testing.T) { + tmpfile, err := ioutil.TempFile("", "dbtest") + if err != nil { + t.Fatal(err) + } + fmt.Printf("%s", tmpfile.Name()) + //defer os.Remove(tmpfile.Name()) + + tmpdir, err := ioutil.TempDir("", "oonitest") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + sess, err := Connect(tmpfile.Name()) + if err != nil { + t.Fatal(err) + } + + location := utils.LocationInfo{ + ASN: 0, + CountryCode: "IT", + NetworkName: "Unknown", + } + network, err := CreateNetwork(sess, &location) + if err != nil { + t.Fatal(err) + } + + result, err := CreateResult(sess, tmpdir, "websites", network.ID) + if err != nil { + t.Fatal(err) + } + + reportID := sql.NullString{String: "", Valid: false} + testName := "antani" + resultID := result.ID + reportFilePath := tmpdir + urlID := sql.NullInt64{Int64: 0, Valid: false} + + m1, err := CreateMeasurement(sess, reportID, testName, resultID, reportFilePath, urlID) + if err != nil { + t.Fatal(err) + } + + var m2 Measurement + err = sess.Collection("measurements").Find("measurement_id", m1.ID).One(&m2) + if err != nil { + t.Fatal(err) + } + if m2.ResultID != m1.ResultID { + t.Error("result_id mismatch") + } + + err = DeleteResult(sess, resultID) + if err != nil { + t.Fatal(err) + } + totalResults, err := sess.Collection("results").Find().Count() + if err != nil { + t.Fatal(err) + } + totalMeasurements, err := sess.Collection("measurements").Find().Count() + if err != nil { + t.Fatal(err) + } + if totalResults != 0 { + t.Fatal("results should be zero") + } + if totalMeasurements != 0 { + t.Fatal("measurements should be zero") + } +} + func TestNetworkCreate(t *testing.T) { tmpfile, err := ioutil.TempFile("", "dbtest") if err != nil { diff --git a/internal/database/database.go b/internal/database/database.go index 8da63f7..577e022 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -30,8 +30,13 @@ func RunMigrations(db *sql.DB) error { func Connect(path string) (db sqlbuilder.Database, err error) { settings := sqlite.ConnectionURL{ Database: path, + Options: map[string]string{"_foreign_keys": "1"}, } sess, err := sqlite.Open(settings) + if err != nil { + log.WithError(err).Error("failed to open the DB") + return nil, err + } err = RunMigrations(sess.Driver().(*sql.DB)) if err != nil {