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" ) // SpeciesService provides for CRUD operations type SpeciesService struct{} // Unmarshal satisfies interface Updater and interface Creater func (s SpeciesService) Unmarshal(b []byte) (types.Entity, error) { var sj payloads.Species err := json.Unmarshal(b, &sj) return &sj, err } // List lists species func (s SpeciesService) List(val *url.Values, claims *types.Claims) (types.Entity, *types.AppError) { if val == nil { return nil, newJSONError(errors.ErrMustProvideOptions, http.StatusInternalServerError) } var opt helpers.ListOptions if err := helpers.SchemaDecoder.Decode(&opt, *val); err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } species, err := models.ListSpecies(opt, claims) if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } strainsOpt, err := models.StrainOptsFromSpecies(opt) if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } strains, err := models.ListStrains(*strainsOpt, claims) if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } payload := payloads.ManySpecies{ Species: species, Strains: strains, Meta: &models.SpeciesMeta{ CanAdd: helpers.CanAdd(claims), }, } return &payload, nil } // Get retrieves a single species func (s SpeciesService) Get(id int64, genus string, claims *types.Claims) (types.Entity, *types.AppError) { species, err := models.GetSpecies(id, genus, claims) if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } strains, err := models.StrainsFromSpeciesID(id, genus, claims) if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } payload := payloads.Species{ Species: species, Strains: strains, Meta: &models.SpeciesMeta{ CanAdd: helpers.CanAdd(claims), }, } return &payload, nil } // Update modifies an existing species func (s SpeciesService) Update(id int64, e *types.Entity, genus string, claims *types.Claims) *types.AppError { payload := (*e).(*payloads.Species) payload.Species.UpdatedBy = claims.Sub payload.Species.ID = id genusID, err := models.GenusIDFromName(genus) if err != nil { return newJSONError(err, http.StatusInternalServerError) } payload.Species.SpeciesBase.GenusID = genusID // TODO: fix this count, err := models.DBH.Update(payload.Species.SpeciesBase) if err != nil { 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) if err != nil { return newJSONError(err, http.StatusInternalServerError) } strains, err := models.StrainsFromSpeciesID(id, genus, claims) if err != nil { return newJSONError(err, http.StatusInternalServerError) } payload.Species = species payload.Strains = strains payload.Meta = &models.SpeciesMeta{ CanAdd: helpers.CanAdd(claims), } return nil } // Create initializes a new species func (s SpeciesService) Create(e *types.Entity, genus string, claims *types.Claims) *types.AppError { payload := (*e).(*payloads.Species) payload.Species.CreatedBy = claims.Sub payload.Species.UpdatedBy = claims.Sub genusID, err := models.GenusIDFromName(genus) if err != nil { return newJSONError(err, http.StatusInternalServerError) } payload.Species.SpeciesBase.GenusID = genusID // TODO: fix this err = models.DBH.Insert(payload.Species.SpeciesBase) if err != nil { return newJSONError(err, http.StatusInternalServerError) } // Reload to send back down the wire species, err := models.GetSpecies(payload.Species.ID, genus, claims) if err != nil { return newJSONError(err, http.StatusInternalServerError) } // Note, no strains when new species payload.Species = species payload.Meta = &models.SpeciesMeta{ CanAdd: helpers.CanAdd(claims), } return nil } // Delete deletes a single species func (s SpeciesService) Delete(id int64, genus string, claims *types.Claims) *types.AppError { q := `DELETE FROM species WHERE id=$1;` // TODO: fix this if _, err := models.DBH.Exec(q, id); err != nil { return newJSONError(err, http.StatusInternalServerError) } return nil }