From b87077a1df1b150970420a2974a12bc76f3c1a8d Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 13 Oct 2015 12:38:18 -0700 Subject: [PATCH] Refactoring update handlers. Fixes #16. --- api/characteristics.go | 12 +++++------- api/measurements.go | 11 ++++------- api/species.go | 11 ++++------- api/strains.go | 11 ++++------- api/users.go | 13 ++++++------- errors/measurements.go | 2 ++ models/characteristics.go | 4 ++++ models/interfaces.go | 19 +++++++++++++++++++ models/measurements.go | 4 ++++ models/species.go | 4 ++++ models/strains.go | 4 ++++ models/users.go | 19 +++++++++++++++++++ 12 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 models/interfaces.go diff --git a/api/characteristics.go b/api/characteristics.go index 3926b86..3d05002 100644 --- a/api/characteristics.go +++ b/api/characteristics.go @@ -132,15 +132,13 @@ func (c CharacteristicService) Update(id int64, e *types.Entity, genus string, c payload.Characteristic.CanEdit = helpers.CanEdit(claims, payload.Characteristic.CreatedBy) payload.Characteristic.CharacteristicTypeID = id - // TODO: fix this - count, err := models.DBH.Update(payload.Characteristic.CharacteristicBase) - if err != nil { + + if err := models.Update(payload.Characteristic.CharacteristicBase); err != nil { + if err == errors.ErrCharacteristicNotUpdated { + return newJSONError(err, http.StatusBadRequest) + } return newJSONError(err, http.StatusInternalServerError) } - if count != 1 { - // TODO: fix this - return newJSONError(errors.ErrCharacteristicNotUpdated, http.StatusBadRequest) - } strains, strainOpts, err := models.StrainsFromCharacteristicID(id, genus, claims) if err != nil { diff --git a/api/measurements.go b/api/measurements.go index cfcff88..eb88bf5 100644 --- a/api/measurements.go +++ b/api/measurements.go @@ -95,15 +95,12 @@ func (m MeasurementService) Update(id int64, e *types.Entity, genus string, clai payload.Measurement.TextMeasurementTypeID.Valid = true } - // TODO: fix this - count, err := models.DBH.Update(payload.Measurement.MeasurementBase) - if err != nil { + if err := models.Update(payload.Measurement.MeasurementBase); err != nil { + if err == errors.ErrMeasurementNotUpdated { + return newJSONError(err, http.StatusBadRequest) + } return newJSONError(err, http.StatusInternalServerError) } - if count != 1 { - // TODO: fix this - return newJSONError(errors.ErrStrainNotUpdated, http.StatusBadRequest) - } measurement, err := models.GetMeasurement(id, genus, claims) if err != nil { diff --git a/api/species.go b/api/species.go index e80b5b5..72daf06 100644 --- a/api/species.go +++ b/api/species.go @@ -93,15 +93,12 @@ func (s SpeciesService) Update(id int64, e *types.Entity, genus string, claims * } payload.Species.SpeciesBase.GenusID = genusID - // TODO: fix this - count, err := models.DBH.Update(payload.Species.SpeciesBase) - if err != nil { + if err := models.Update(payload.Species.SpeciesBase); err != nil { + if err == errors.ErrSpeciesNotUpdated { + return newJSONError(err, http.StatusBadRequest) + } return newJSONError(err, http.StatusInternalServerError) } - if count != 1 { - // TODO: fix this - return newJSONError(errors.ErrSpeciesNotUpdated, http.StatusBadRequest) - } // Reload to send back down the wire species, err := models.GetSpecies(id, genus, claims) diff --git a/api/strains.go b/api/strains.go index 93d6d2f..7268f57 100644 --- a/api/strains.go +++ b/api/strains.go @@ -155,15 +155,12 @@ func (s StrainService) Update(id int64, e *types.Entity, genus string, claims *t payload.Strain.UpdatedBy = claims.Sub payload.Strain.ID = id - // TODO: fix this - count, err := models.DBH.Update(payload.Strain.StrainBase) - if err != nil { + if err := models.Update(payload.Strain.StrainBase); err != nil { + if err == errors.ErrStrainNotUpdated { + return newJSONError(err, http.StatusBadRequest) + } return newJSONError(err, http.StatusInternalServerError) } - if count != 1 { - // TODO: fix this - return newJSONError(errors.ErrStrainNotUpdated, http.StatusBadRequest) - } strain, err := models.GetStrain(id, genus, claims) if err != nil { diff --git a/api/users.go b/api/users.go index 309565d..2a20e43 100644 --- a/api/users.go +++ b/api/users.go @@ -109,15 +109,14 @@ func (u UserService) Update(id int64, e *types.Entity, dummy string, claims *typ return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity} } - // TODO: fix this - count, err := models.DBH.Update(user.UserBase) - user.Password = "" - if err != nil { + if err := models.Update(user.UserBase); err != nil { + if err == errors.ErrUserNotUpdated { + return newJSONError(err, http.StatusBadRequest) + } return newJSONError(err, http.StatusInternalServerError) } - if count != 1 { - return newJSONError(errors.ErrUserNotUpdated, http.StatusInternalServerError) - } + + user.Password = "" return nil } diff --git a/errors/measurements.go b/errors/measurements.go index 1a65f4a..63b7d22 100644 --- a/errors/measurements.go +++ b/errors/measurements.go @@ -5,4 +5,6 @@ import "errors" var ( // ErrMeasurementNotFound when not found. ErrMeasurementNotFound = errors.New("Measurement not found") + // ErrMeasurementNotUpdate when not updated. + ErrMeasurementNotUpdated = errors.New("Measurement not updated") ) diff --git a/models/characteristics.go b/models/characteristics.go index cb56ecc..fec69e5 100644 --- a/models/characteristics.go +++ b/models/characteristics.go @@ -28,6 +28,10 @@ func (c *CharacteristicBase) PreUpdate(e modl.SqlExecutor) error { return nil } +func (c *CharacteristicBase) UpdateError() error { + return errors.ErrCharacteristicNotUpdated +} + // CharacteristicBase is what the DB expects for write operations type CharacteristicBase struct { ID int64 `json:"id,omitempty"` diff --git a/models/interfaces.go b/models/interfaces.go new file mode 100644 index 0000000..723ae67 --- /dev/null +++ b/models/interfaces.go @@ -0,0 +1,19 @@ +package models + +import "github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/jmoiron/modl" + +type updater interface { + PreUpdate(modl.SqlExecutor) error + UpdateError() error +} + +func Update(u updater) error { + count, err := DBH.Update(u) + if err != nil { + return err + } + if count != 1 { + return u.UpdateError() + } + return nil +} diff --git a/models/measurements.go b/models/measurements.go index 3ccc945..b10eba1 100644 --- a/models/measurements.go +++ b/models/measurements.go @@ -29,6 +29,10 @@ func (m *MeasurementBase) PreUpdate(e modl.SqlExecutor) error { return nil } +func (m *MeasurementBase) UpdateError() error { + return errors.ErrMeasurementNotUpdated +} + // MeasurementBase is what the DB expects for write operations // There are three types of supported measurements: fixed-text, free-text, // & numerical. The table has a constraint that will allow at most one diff --git a/models/species.go b/models/species.go index 1992e49..3152995 100644 --- a/models/species.go +++ b/models/species.go @@ -29,6 +29,10 @@ func (s *SpeciesBase) PreUpdate(e modl.SqlExecutor) error { return nil } +func (s *SpeciesBase) UpdateError() error { + return errors.ErrSpeciesNotUpdated +} + // SpeciesBase is what the DB expects for write operations. type SpeciesBase struct { ID int64 `db:"id" json:"id"` diff --git a/models/strains.go b/models/strains.go index b314d39..9f98383 100644 --- a/models/strains.go +++ b/models/strains.go @@ -29,6 +29,10 @@ func (s *StrainBase) PreUpdate(e modl.SqlExecutor) error { return nil } +func (s *StrainBase) UpdateError() error { + return errors.ErrStrainNotUpdated +} + // StrainBase is what the DB expects for write operations. type StrainBase struct { ID int64 `db:"id" json:"id"` diff --git a/models/users.go b/models/users.go index 9b04f96..9306bb2 100644 --- a/models/users.go +++ b/models/users.go @@ -5,6 +5,7 @@ import ( "encoding/json" "regexp" + "github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/jmoiron/modl" "github.com/thermokarst/bactdb/Godeps/_workspace/src/golang.org/x/crypto/bcrypt" "github.com/thermokarst/bactdb/errors" "github.com/thermokarst/bactdb/helpers" @@ -15,6 +16,24 @@ func init() { DB.AddTableWithName(UserBase{}, "users").SetKeys(true, "ID") } +// PreInsert is a modl hook. +func (u *UserBase) PreInsert(e modl.SqlExecutor) error { + ct := helpers.CurrentTime() + u.CreatedAt = ct + u.UpdatedAt = ct + return nil +} + +// PreUpdate is a modl hook. +func (u *UserBase) PreUpdate(e modl.SqlExecutor) error { + u.UpdatedAt = helpers.CurrentTime() + return nil +} + +func (u *UserBase) UpdateError() error { + return errors.ErrUserNotUpdated +} + // UserBase is what the DB expects to see for write operations. type UserBase struct { ID int64 `json:"id,omitempty"`