Return species payload on PUT and POST
This commit is contained in:
parent
a8cfc8fe8b
commit
b5b6643dcc
2 changed files with 91 additions and 49 deletions
136
species.go
136
species.go
|
@ -39,7 +39,6 @@ type SpeciesBase struct {
|
|||
DeletedBy NullInt64 `db:"deleted_by" json:"deletedBy"`
|
||||
}
|
||||
|
||||
// Species & SpeciesJSON(s) are what ember expects to see
|
||||
type Species struct {
|
||||
*SpeciesBase
|
||||
GenusName string `db:"genus_name" json:"genusName"`
|
||||
|
@ -67,14 +66,6 @@ type ManySpeciesPayload struct {
|
|||
Meta *SpeciesMeta `json:"meta"`
|
||||
}
|
||||
|
||||
type SpeciesJSON struct {
|
||||
Species *Species `json:"species"`
|
||||
}
|
||||
|
||||
func (s *Species) marshal() ([]byte, error) {
|
||||
return json.Marshal(&SpeciesJSON{Species: s})
|
||||
}
|
||||
|
||||
func (s *SpeciesPayload) marshal() ([]byte, error) {
|
||||
return json.Marshal(s)
|
||||
}
|
||||
|
@ -84,9 +75,9 @@ func (s *ManySpeciesPayload) marshal() ([]byte, error) {
|
|||
}
|
||||
|
||||
func (s SpeciesService) unmarshal(b []byte) (entity, error) {
|
||||
var sj SpeciesJSON
|
||||
var sj SpeciesPayload
|
||||
err := json.Unmarshal(b, &sj)
|
||||
return sj.Species, err
|
||||
return &sj, err
|
||||
}
|
||||
|
||||
func (s SpeciesService) list(val *url.Values, claims Claims) (entity, *appError) {
|
||||
|
@ -132,35 +123,18 @@ func (s SpeciesService) list(val *url.Values, claims Claims) (entity, *appError)
|
|||
}
|
||||
|
||||
func (s SpeciesService) get(id int64, genus string, claims Claims) (entity, *appError) {
|
||||
var species Species
|
||||
q := `SELECT sp.*, g.genus_name, array_agg(st.id) AS strains,
|
||||
COUNT(st) AS total_strains, 0 AS sort_order
|
||||
FROM species sp
|
||||
INNER JOIN genera g ON g.id=sp.genus_id AND LOWER(g.genus_name)=$1
|
||||
LEFT OUTER JOIN strains st ON st.species_id=sp.id
|
||||
WHERE sp.id=$2
|
||||
GROUP BY sp.id, g.genus_name;`
|
||||
if err := DBH.SelectOne(&species, q, genus, id); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, ErrSpeciesNotFoundJSON
|
||||
}
|
||||
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
opt := ListOptions{Genus: genus, Ids: []int64{id}}
|
||||
|
||||
strains_opt, err := strainOptsFromSpecies(opt)
|
||||
species, err := getSpecies(id, genus)
|
||||
if err != nil {
|
||||
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
strains, err := listStrains(*strains_opt)
|
||||
strains, err := strainsFromSpeciesId(id, genus)
|
||||
if err != nil {
|
||||
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
payload := SpeciesPayload{
|
||||
Species: &species,
|
||||
Species: species,
|
||||
Strains: strains,
|
||||
Meta: &SpeciesMeta{
|
||||
CanAdd: canAdd(claims),
|
||||
|
@ -172,45 +146,76 @@ func (s SpeciesService) get(id int64, genus string, claims Claims) (entity, *app
|
|||
}
|
||||
|
||||
func (s SpeciesService) update(id int64, e *entity, claims Claims) *appError {
|
||||
species := (*e).(*Species)
|
||||
species.UpdatedBy = claims.Sub
|
||||
species.UpdatedAt = currentTime()
|
||||
species.Id = id
|
||||
payload := (*e).(*SpeciesPayload)
|
||||
payload.Species.UpdatedBy = claims.Sub
|
||||
payload.Species.UpdatedAt = currentTime()
|
||||
payload.Species.Id = id
|
||||
|
||||
genus_id, err := genusIdFromName(species.GenusName)
|
||||
genus_id, err := genusIdFromName(payload.Species.GenusName)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
species.SpeciesBase.GenusID = genus_id
|
||||
payload.Species.SpeciesBase.GenusID = genus_id
|
||||
|
||||
count, err := DBH.Update(species.SpeciesBase)
|
||||
count, err := DBH.Update(payload.Species.SpeciesBase)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
if count != 1 {
|
||||
return ErrSpeciesNotUpdatedJSON
|
||||
}
|
||||
|
||||
species, err := getSpecies(id, payload.Species.GenusName)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
strains, err := strainsFromSpeciesId(id, payload.Species.GenusName)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
payload.Species = species
|
||||
payload.Strains = strains
|
||||
payload.Meta = &SpeciesMeta{
|
||||
CanAdd: canAdd(claims),
|
||||
CanEdit: canEdit(claims, map[int64]int64{payload.Species.Id: payload.Species.CreatedBy}),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s SpeciesService) create(e *entity, claims Claims) *appError {
|
||||
species := (*e).(*Species)
|
||||
payload := (*e).(*SpeciesPayload)
|
||||
ct := currentTime()
|
||||
species.CreatedBy = claims.Sub
|
||||
species.CreatedAt = ct
|
||||
species.UpdatedBy = claims.Sub
|
||||
species.UpdatedAt = ct
|
||||
payload.Species.CreatedBy = claims.Sub
|
||||
payload.Species.CreatedAt = ct
|
||||
payload.Species.UpdatedBy = claims.Sub
|
||||
payload.Species.UpdatedAt = ct
|
||||
|
||||
genus_id, err := genusIdFromName(species.GenusName)
|
||||
genus_id, err := genusIdFromName(payload.Species.GenusName)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
species.SpeciesBase.GenusID = genus_id
|
||||
payload.Species.SpeciesBase.GenusID = genus_id
|
||||
|
||||
err = DBH.Insert(species.SpeciesBase)
|
||||
err = DBH.Insert(payload.Species.SpeciesBase)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
species, err := getSpecies(payload.Species.Id, payload.Species.GenusName)
|
||||
if err != nil {
|
||||
return newJSONError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Note, no strains when new species
|
||||
|
||||
payload.Species = species
|
||||
payload.Meta = &SpeciesMeta{
|
||||
CanAdd: canAdd(claims),
|
||||
CanEdit: canEdit(claims, map[int64]int64{payload.Species.Id: payload.Species.CreatedBy}),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -247,6 +252,25 @@ func strainOptsFromSpecies(opt ListOptions) (*ListOptions, error) {
|
|||
return &ListOptions{Genus: opt.Genus, Ids: relatedStrainIds}, nil
|
||||
}
|
||||
|
||||
func strainsFromSpeciesId(id int64, genus string) (*Strains, error) {
|
||||
opt := ListOptions{
|
||||
Genus: genus,
|
||||
Ids: []int64{id},
|
||||
}
|
||||
|
||||
strains_opt, err := strainOptsFromSpecies(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
strains, err := listStrains(*strains_opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return strains, nil
|
||||
}
|
||||
|
||||
func listSpecies(opt ListOptions) (*ManySpecies, error) {
|
||||
var vals []interface{}
|
||||
|
||||
|
@ -254,7 +278,7 @@ func listSpecies(opt ListOptions) (*ManySpecies, error) {
|
|||
COUNT(st) AS total_strains,
|
||||
rank() OVER (ORDER BY sp.species_name ASC) AS sort_order
|
||||
FROM species sp
|
||||
INNER JOIN genera g ON g.id=sp.genus_id AND LOWER(g.genus_name)=$1
|
||||
INNER JOIN genera g ON g.id=sp.genus_id AND LOWER(g.genus_name)=LOWER($1)
|
||||
LEFT OUTER JOIN strains st ON st.species_id=sp.id`
|
||||
vals = append(vals, opt.Genus)
|
||||
|
||||
|
@ -279,3 +303,21 @@ func listSpecies(opt ListOptions) (*ManySpecies, error) {
|
|||
}
|
||||
return &species, nil
|
||||
}
|
||||
|
||||
func getSpecies(id int64, genus string) (*Species, error) {
|
||||
var species Species
|
||||
q := `SELECT sp.*, g.genus_name, array_agg(st.id) AS strains,
|
||||
COUNT(st) AS total_strains, 0 AS sort_order
|
||||
FROM species sp
|
||||
INNER JOIN genera g ON g.id=sp.genus_id AND LOWER(g.genus_name)=LOWER($1)
|
||||
LEFT OUTER JOIN strains st ON st.species_id=sp.id
|
||||
WHERE sp.id=$2
|
||||
GROUP BY sp.id, g.genus_name;`
|
||||
if err := DBH.SelectOne(&species, q, genus, id); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, ErrSpeciesNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &species, nil
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ type StrainService struct{}
|
|||
// StrainBase is what the DB expects to see for inserts/updates
|
||||
type StrainBase struct {
|
||||
Id int64 `db:"id" json:"id"`
|
||||
SpeciesId int64 `db:"species_id" json:"species,string"` // quirk in ember select
|
||||
SpeciesId int64 `db:"species_id" json:"species"`
|
||||
StrainName string `db:"strain_name" json:"strainName"`
|
||||
TypeStrain bool `db:"type_strain" json:"typeStrain"`
|
||||
AccessionNumbers string `db:"accession_numbers" json:"accessionNumbers"`
|
||||
|
@ -147,7 +147,7 @@ func listStrains(opt ListOptions) (*Strains, error) {
|
|||
rank() OVER (ORDER BY sp.species_name ASC, st.type_strain ASC, st.strain_name ASC) AS sort_order
|
||||
FROM strains st
|
||||
INNER JOIN species sp ON sp.id=st.species_id
|
||||
INNER JOIN genera g ON g.id=sp.genus_id AND LOWER(g.genus_name)=$1
|
||||
INNER JOIN genera g ON g.id=sp.genus_id AND LOWER(g.genus_name)=LOWER($1)
|
||||
LEFT OUTER JOIN measurements m ON m.strain_id=st.id`
|
||||
vals = append(vals, opt.Genus)
|
||||
|
||||
|
|
Reference in a new issue