New strain payload
This commit is contained in:
parent
b5b6643dcc
commit
49fdb7d41e
1 changed files with 124 additions and 37 deletions
161
strains.go
161
strains.go
|
@ -42,7 +42,6 @@ type StrainBase struct {
|
||||||
DeletedBy NullInt64 `db:"deleted_by" json:"deletedBy"`
|
DeletedBy NullInt64 `db:"deleted_by" json:"deletedBy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strain & StrainJSON(s) are what ember expects to see
|
|
||||||
type Strain struct {
|
type Strain struct {
|
||||||
*StrainBase
|
*StrainBase
|
||||||
Measurements NullSliceInt64 `db:"measurements" json:"measurements"`
|
Measurements NullSliceInt64 `db:"measurements" json:"measurements"`
|
||||||
|
@ -52,26 +51,35 @@ type Strain struct {
|
||||||
|
|
||||||
type Strains []*Strain
|
type Strains []*Strain
|
||||||
|
|
||||||
type StrainJSON struct {
|
type StrainMeta struct {
|
||||||
Strain *Strain `json:"strain"`
|
CanAdd bool `json:"canAdd"`
|
||||||
|
CanEdit []int64 `json:"canEdit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StrainsJSON struct {
|
type StrainPayload struct {
|
||||||
Strains *Strains `json:"strains"`
|
Strain *Strain `json:"strain"`
|
||||||
|
Species *ManySpecies `json:"species"`
|
||||||
|
Meta *StrainMeta `json:"meta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Strain) marshal() ([]byte, error) {
|
type StrainsPayload struct {
|
||||||
return json.Marshal(&StrainJSON{Strain: s})
|
Strains *Strains `json:"strains"`
|
||||||
|
Species *ManySpecies `json:"species"`
|
||||||
|
Meta *StrainMeta `json:"meta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Strains) marshal() ([]byte, error) {
|
func (s *StrainPayload) marshal() ([]byte, error) {
|
||||||
return json.Marshal(&StrainsJSON{Strains: s})
|
return json.Marshal(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StrainsPayload) marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StrainService) unmarshal(b []byte) (entity, error) {
|
func (s StrainService) unmarshal(b []byte) (entity, error) {
|
||||||
var sj StrainJSON
|
var sj StrainPayload
|
||||||
err := json.Unmarshal(b, &sj)
|
err := json.Unmarshal(b, &sj)
|
||||||
return sj.Strain, err
|
return &sj, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StrainService) list(val *url.Values, claims Claims) (entity, *appError) {
|
func (s StrainService) list(val *url.Values, claims Claims) (entity, *appError) {
|
||||||
|
@ -88,55 +96,92 @@ func (s StrainService) list(val *url.Values, claims Claims) (entity, *appError)
|
||||||
return nil, newJSONError(err, http.StatusInternalServerError)
|
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strains, nil
|
species_opt, err := speciesOptsFromStrains(opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
species, err := listSpecies(*species_opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
edit_list := make(map[int64]int64)
|
||||||
|
|
||||||
|
for _, v := range *strains {
|
||||||
|
edit_list[v.Id] = v.CreatedBy
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := StrainsPayload{
|
||||||
|
Strains: strains,
|
||||||
|
Species: species,
|
||||||
|
Meta: &StrainMeta{
|
||||||
|
CanAdd: canAdd(claims),
|
||||||
|
CanEdit: canEdit(claims, edit_list),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &payload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StrainService) get(id int64, genus string, claims Claims) (entity, *appError) {
|
func (s StrainService) get(id int64, genus string, claims Claims) (entity, *appError) {
|
||||||
var strain Strain
|
strain, err := getStrain(id, genus)
|
||||||
q := `SELECT st.*, array_agg(m.id) AS measurements, COUNT(m) AS total_measurements,
|
if err != nil {
|
||||||
0 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
|
|
||||||
LEFT OUTER JOIN measurements m ON m.strain_id=st.id
|
|
||||||
WHERE st.id=$2
|
|
||||||
GROUP BY st.id, st.species_id;`
|
|
||||||
if err := DBH.SelectOne(&strain, q, genus, id); err != nil {
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
return nil, ErrStrainNotFoundJSON
|
|
||||||
}
|
|
||||||
return nil, newJSONError(err, http.StatusInternalServerError)
|
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
return &strain, nil
|
|
||||||
|
species, err := getSpecies(strain.SpeciesId, genus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newJSONError(err, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
var many_species ManySpecies = []*Species{species}
|
||||||
|
|
||||||
|
payload := StrainPayload{
|
||||||
|
Strain: strain,
|
||||||
|
Species: &many_species,
|
||||||
|
Meta: &StrainMeta{
|
||||||
|
CanAdd: canAdd(claims),
|
||||||
|
CanEdit: canEdit(claims, map[int64]int64{strain.Id: strain.CreatedBy}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &payload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StrainService) update(id int64, e *entity, claims Claims) *appError {
|
func (s StrainService) update(id int64, e *entity, claims Claims) *appError {
|
||||||
strain := (*e).(*Strain)
|
payload := (*e).(*StrainPayload)
|
||||||
strain.UpdatedBy = claims.Sub
|
payload.Strain.UpdatedBy = claims.Sub
|
||||||
strain.UpdatedAt = currentTime()
|
payload.Strain.UpdatedAt = currentTime()
|
||||||
strain.Id = id
|
payload.Strain.Id = id
|
||||||
|
|
||||||
count, err := DBH.Update(strain.StrainBase)
|
count, err := DBH.Update(payload.Strain.StrainBase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newJSONError(err, http.StatusInternalServerError)
|
return newJSONError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
if count != 1 {
|
if count != 1 {
|
||||||
return ErrStrainNotUpdatedJSON
|
return ErrStrainNotUpdatedJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add species and meta to payload
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StrainService) create(e *entity, claims Claims) *appError {
|
func (s StrainService) create(e *entity, claims Claims) *appError {
|
||||||
strain := (*e).(*Strain)
|
payload := (*e).(*StrainPayload)
|
||||||
ct := currentTime()
|
ct := currentTime()
|
||||||
strain.CreatedBy = claims.Sub
|
payload.Strain.CreatedBy = claims.Sub
|
||||||
strain.CreatedAt = ct
|
payload.Strain.CreatedAt = ct
|
||||||
strain.UpdatedBy = claims.Sub
|
payload.Strain.UpdatedBy = claims.Sub
|
||||||
strain.UpdatedAt = ct
|
payload.Strain.UpdatedAt = ct
|
||||||
|
|
||||||
if err := DBH.Insert(strain.StrainBase); err != nil {
|
if err := DBH.Insert(payload.Strain.StrainBase); err != nil {
|
||||||
return newJSONError(err, http.StatusInternalServerError)
|
return newJSONError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add species and meta to payload
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,3 +217,45 @@ func listStrains(opt ListOptions) (*Strains, error) {
|
||||||
}
|
}
|
||||||
return &strains, nil
|
return &strains, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getStrain(id int64, genus string) (*Strain, error) {
|
||||||
|
var strain Strain
|
||||||
|
q := `SELECT st.*, array_agg(m.id) AS measurements,
|
||||||
|
COUNT(m) AS total_measurements, 0 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)=LOWER($1)
|
||||||
|
LEFT OUTER JOIN measurements m ON m.strain_id=st.id
|
||||||
|
WHERE st.id=$2
|
||||||
|
GROUP BY st.id, st.species_id;`
|
||||||
|
if err := DBH.SelectOne(&strain, q, genus, id); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, ErrStrainNotFound
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &strain, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func speciesOptsFromStrains(opt ListOptions) (*ListOptions, error) {
|
||||||
|
relatedSpeciesIds := make([]int64, 0)
|
||||||
|
|
||||||
|
if opt.Ids == nil {
|
||||||
|
q := `SELECT DISTINCT st.species_id
|
||||||
|
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)=LOWER($1);`
|
||||||
|
if err := DBH.Select(&relatedSpeciesIds, q, opt.Genus); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var vals []interface{}
|
||||||
|
var count int64 = 1
|
||||||
|
q := fmt.Sprintf("SELECT DISTINCT species_id FROM strains WHERE %s;", valsIn("id", opt.Ids, &vals, &count))
|
||||||
|
if err := DBH.Select(&relatedSpeciesIds, q, vals...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ListOptions{Genus: opt.Genus, Ids: relatedSpeciesIds}, nil
|
||||||
|
}
|
||||||
|
|
Reference in a new issue