From a8cfc8fe8b23a5100c8ee66f130589eb5f2eba55 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 7 Jul 2015 13:07:52 -0800 Subject: [PATCH] Species/Strain cleanup, split out species list --- species.go | 111 +++++++++++++++++++++++++++++------------------------ strains.go | 67 ++++++++++++++++---------------- 2 files changed, 93 insertions(+), 85 deletions(-) diff --git a/species.go b/species.go index 2a99e3d..54e8b59 100644 --- a/species.go +++ b/species.go @@ -98,31 +98,7 @@ func (s SpeciesService) list(val *url.Values, claims Claims) (entity, *appError) return nil, newJSONError(err, http.StatusInternalServerError) } - var vals []interface{} - sql := `SELECT sp.*, g.genus_name, array_agg(st.id) AS strains, - 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 - LEFT OUTER JOIN strains st ON st.species_id=sp.id` - vals = append(vals, opt.Genus) - - if len(opt.Ids) != 0 { - var conds []string - s := "sp.id IN (" - for i, id := range opt.Ids { - s = s + fmt.Sprintf("$%v,", i+2) // start param index at 2 - vals = append(vals, id) - } - s = s[:len(s)-1] + ")" - conds = append(conds, s) - sql += " WHERE (" + strings.Join(conds, ") AND (") + ")" - } - - sql += " GROUP BY sp.id, g.genus_name;" - - species := make(ManySpecies, 0) - err := DBH.Select(&species, sql, vals...) + species, err := listSpecies(opt) if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } @@ -139,12 +115,12 @@ func (s SpeciesService) list(val *url.Values, claims Claims) (entity, *appError) edit_list := make(map[int64]int64) - for _, v := range species { + for _, v := range *species { edit_list[v.Id] = v.CreatedBy } payload := ManySpeciesPayload{ - Species: &species, + Species: species, Strains: strains, Meta: &SpeciesMeta{ CanAdd: canAdd(claims), @@ -155,30 +131,6 @@ func (s SpeciesService) list(val *url.Values, claims Claims) (entity, *appError) return &payload, nil } -func strainOptsFromSpecies(opt ListOptions) (*ListOptions, error) { - relatedStrainIds := make([]int64, 0) - - if opt.Ids == nil { - q := `SELECT DISTINCT st.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(&relatedStrainIds, q, opt.Genus); err != nil { - return nil, err - } - } else { - var vals []interface{} - var count int64 = 1 - q := fmt.Sprintf("SELECT DISTINCT id FROM strains WHERE %s;", valsIn("species_id", opt.Ids, &vals, &count)) - - if err := DBH.Select(&relatedStrainIds, q, vals...); err != nil { - return nil, err - } - } - - return &ListOptions{Genus: opt.Genus, Ids: relatedStrainIds}, nil -} - 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, @@ -270,3 +222,60 @@ func genusIdFromName(genus_name string) (int64, error) { } return genus_id.Id, nil } + +func strainOptsFromSpecies(opt ListOptions) (*ListOptions, error) { + relatedStrainIds := make([]int64, 0) + + if opt.Ids == nil { + q := `SELECT DISTINCT st.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(&relatedStrainIds, q, opt.Genus); err != nil { + return nil, err + } + } else { + var vals []interface{} + var count int64 = 1 + q := fmt.Sprintf("SELECT DISTINCT id FROM strains WHERE %s;", valsIn("species_id", opt.Ids, &vals, &count)) + + if err := DBH.Select(&relatedStrainIds, q, vals...); err != nil { + return nil, err + } + } + + return &ListOptions{Genus: opt.Genus, Ids: relatedStrainIds}, nil +} + +func listSpecies(opt ListOptions) (*ManySpecies, error) { + var vals []interface{} + + q := `SELECT sp.*, g.genus_name, array_agg(st.id) AS strains, + 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 + LEFT OUTER JOIN strains st ON st.species_id=sp.id` + vals = append(vals, opt.Genus) + + if len(opt.Ids) != 0 { + var conds []string + s := "sp.id IN (" + for i, id := range opt.Ids { + s = s + fmt.Sprintf("$%v,", i+2) // start param index at 2 + vals = append(vals, id) + } + s = s[:len(s)-1] + ")" + conds = append(conds, s) + q += " WHERE (" + strings.Join(conds, ") AND (") + ")" + } + + q += " GROUP BY sp.id, g.genus_name;" + + species := make(ManySpecies, 0) + err := DBH.Select(&species, q, vals...) + if err != nil { + return nil, err + } + return &species, nil +} diff --git a/strains.go b/strains.go index f3eb3a7..339ce9c 100644 --- a/strains.go +++ b/strains.go @@ -84,7 +84,6 @@ func (s StrainService) list(val *url.Values, claims Claims) (entity, *appError) } strains, err := listStrains(opt) - if err != nil { return nil, newJSONError(err, http.StatusInternalServerError) } @@ -92,39 +91,6 @@ func (s StrainService) list(val *url.Values, claims Claims) (entity, *appError) return strains, nil } -func listStrains(opt ListOptions) (*Strains, error) { - var vals []interface{} - - sql := `SELECT st.*, array_agg(m.id) AS measurements, COUNT(m) AS total_measurements, - 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 - LEFT OUTER JOIN measurements m ON m.strain_id=st.id` - vals = append(vals, opt.Genus) - - if len(opt.Ids) != 0 { - var conds []string - s := "st.id IN (" - for i, id := range opt.Ids { - s = s + fmt.Sprintf("$%v,", i+2) // start param index at 2 - vals = append(vals, id) - } - s = s[:len(s)-1] + ")" - conds = append(conds, s) - sql += " WHERE (" + strings.Join(conds, ") AND (") + ")" - } - - sql += " GROUP BY st.id, st.species_id, sp.species_name;" - - strains := make(Strains, 0) - err := DBH.Select(&strains, sql, vals...) - if err != nil { - return nil, err - } - return &strains, nil -} - func (s StrainService) get(id int64, genus string, claims Claims) (entity, *appError) { var strain Strain q := `SELECT st.*, array_agg(m.id) AS measurements, COUNT(m) AS total_measurements, @@ -173,3 +139,36 @@ func (s StrainService) create(e *entity, claims Claims) *appError { } return nil } + +func listStrains(opt ListOptions) (*Strains, error) { + var vals []interface{} + + q := `SELECT st.*, array_agg(m.id) AS measurements, COUNT(m) AS total_measurements, + 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 + LEFT OUTER JOIN measurements m ON m.strain_id=st.id` + vals = append(vals, opt.Genus) + + if len(opt.Ids) != 0 { + var conds []string + s := "st.id IN (" + for i, id := range opt.Ids { + s = s + fmt.Sprintf("$%v,", i+2) // start param index at 2 + vals = append(vals, id) + } + s = s[:len(s)-1] + ")" + conds = append(conds, s) + q += " WHERE (" + strings.Join(conds, ") AND (") + ")" + } + + q += " GROUP BY st.id, st.species_id, sp.species_name;" + + strains := make(Strains, 0) + err := DBH.Select(&strains, q, vals...) + if err != nil { + return nil, err + } + return &strains, nil +}