This repository has been archived on 2025-03-30. You can view files and clone it, but cannot push or open issues or pull requests.
bactdb/api/measurements.go

157 lines
4.6 KiB
Go

package api
import (
"encoding/json"
"net/http"
"net/url"
"github.com/thermokarst/bactdb/errors"
"github.com/thermokarst/bactdb/helpers"
"github.com/thermokarst/bactdb/models"
"github.com/thermokarst/bactdb/payloads"
"github.com/thermokarst/bactdb/types"
)
// MeasurementService provides for CRUD operations.
type MeasurementService struct{}
// Unmarshal satisfies interface Updater and interface Creater.
func (m MeasurementService) Unmarshal(b []byte) (types.Entity, error) {
var mj payloads.Measurement
err := json.Unmarshal(b, &mj)
return &mj, err
}
// List lists all measurements.
func (m MeasurementService) List(val *url.Values, claims *types.Claims) (types.Entity, *types.AppError) {
if val == nil {
return nil, newJSONError(errors.ErrMustProvideOptions, http.StatusInternalServerError)
}
var opt helpers.MeasurementListOptions
if err := helpers.SchemaDecoder.Decode(&opt, *val); err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
measurements, err := models.ListMeasurements(opt, claims)
if err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
charOpts, err := models.CharacteristicOptsFromMeasurements(opt)
if err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
characteristics, err := models.ListCharacteristics(*charOpts, claims)
if err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
strainOpts, err := models.StrainOptsFromMeasurements(opt)
if err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
strains, err := models.ListStrains(*strainOpts, claims)
if err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
payload := payloads.Measurements{
Characteristics: characteristics,
Strains: strains,
Measurements: measurements,
}
return &payload, nil
}
// Get retrieves a single measurement.
func (m MeasurementService) Get(id int64, genus string, claims *types.Claims) (types.Entity, *types.AppError) {
measurement, err := models.GetMeasurement(id, genus, claims)
if err != nil {
return nil, newJSONError(err, http.StatusInternalServerError)
}
payload := payloads.Measurement{
Measurement: measurement,
}
return &payload, nil
}
// Update modifies a single measurement.
func (m MeasurementService) Update(id int64, e *types.Entity, genus string, claims *types.Claims) *types.AppError {
payload := (*e).(*payloads.Measurement)
payload.Measurement.UpdatedBy = claims.Sub
payload.Measurement.ID = id
if payload.Measurement.TextMeasurementType.Valid {
id, err := models.GetTextMeasurementTypeID(payload.Measurement.TextMeasurementType.String)
if err != nil {
return newJSONError(err, http.StatusInternalServerError)
}
payload.Measurement.TextMeasurementTypeID.Int64 = id
payload.Measurement.TextMeasurementTypeID.Valid = true
}
if err := models.Update(payload.Measurement.MeasurementBase); err != nil {
if err == errors.ErrMeasurementNotUpdated {
return newJSONError(err, http.StatusBadRequest)
}
if err, ok := err.(types.ValidationError); ok {
return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity}
}
return newJSONError(err, http.StatusInternalServerError)
}
measurement, err := models.GetMeasurement(id, genus, claims)
if err != nil {
return newJSONError(err, http.StatusInternalServerError)
}
payload.Measurement = measurement
return nil
}
// Delete deletes a single measurement.
func (m MeasurementService) Delete(id int64, genus string, claims *types.Claims) *types.AppError {
measurement, err := models.GetMeasurement(id, genus, claims)
if err != nil {
return newJSONError(err, http.StatusInternalServerError)
}
if !measurement.CanEdit {
return newJSONError(errors.ErrMeasurementNotDeleted, http.StatusForbidden)
}
if err := models.Delete(measurement.MeasurementBase); err != nil {
return newJSONError(err, http.StatusInternalServerError)
}
return nil
}
// Create initializes a new measurement.
func (m MeasurementService) Create(e *types.Entity, genus string, claims *types.Claims) *types.AppError {
payload := (*e).(*payloads.Measurement)
payload.Measurement.CreatedBy = claims.Sub
payload.Measurement.UpdatedBy = claims.Sub
if err := models.Create(payload.Measurement.MeasurementBase); err != nil {
if err, ok := err.(types.ValidationError); ok {
return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity}
}
return newJSONError(err, http.StatusInternalServerError)
}
measurement, err := models.GetMeasurement(payload.Measurement.ID, genus, claims)
if err != nil {
return newJSONError(err, http.StatusInternalServerError)
}
payload.Measurement = measurement
return nil
}