Skip to content

Commit a2046d6

Browse files
committed
fix(stats): gets stats with no structure
Hook the `lib.Get` (which fetches `Stats` if `Selection="stats"`, into the `statsHandler`. `lib.Get` correctly fetches fsi datasets as well as versioned datasets. If we don't have a structure, such as a case where we are using `fsi` and the user has removed their `structure.json`, stats should detect a structure and use that detected structure.schema to calculate stats.
1 parent df5bedc commit a2046d6

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

api/datasets.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -653,17 +653,24 @@ func (h DatasetHandlers) bodyHandler(w http.ResponseWriter, r *http.Request) {
653653
}
654654

655655
func (h DatasetHandlers) statsHandler(w http.ResponseWriter, r *http.Request) {
656-
p := &lib.StatsParams{
657-
Ref: HTTPPathToQriPath(r.URL.Path[len("/stats/"):]),
656+
p := lib.GetParams{
657+
Path: HTTPPathToQriPath(r.URL.Path[len("/stats/"):]),
658+
UseFSI: r.FormValue("fsi") == "true",
659+
Selector: "stats",
658660
}
659-
res := &lib.StatsResponse{}
660-
if err := h.Stats(p, res); err != nil {
661+
res := lib.GetResult{}
662+
err := h.Get(&p, &res)
663+
if err != nil {
664+
if err == repo.ErrNoHistory || err == fsi.ErrNoLink {
665+
util.WriteErrResponse(w, http.StatusUnprocessableEntity, err)
666+
return
667+
}
661668
util.WriteErrResponse(w, http.StatusInternalServerError, err)
662669
return
663670
}
664671

665672
statsMap := &[]map[string]interface{}{}
666-
if err := json.Unmarshal(res.StatsBytes, statsMap); err != nil {
673+
if err := json.Unmarshal(res.Bytes, statsMap); err != nil {
667674
log.Errorf("error unmarshalling stats: %s", err)
668675
util.WriteErrResponse(w, http.StatusInternalServerError, fmt.Errorf("error writing stats"))
669676
return

lib/datasets.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import (
88
"io/ioutil"
99
"net/rpc"
1010
"os"
11+
"path/filepath"
1112

1213
"github.com/ghodss/yaml"
1314
"github.com/qri-io/dag"
1415
"github.com/qri-io/dataset"
16+
"github.com/qri-io/dataset/detect"
1517
"github.com/qri-io/jsonschema"
1618
"github.com/qri-io/qfs"
1719
"github.com/qri-io/qri/base"
@@ -901,6 +903,20 @@ func (r *DatasetRequests) Stats(p *StatsParams, res *StatsResponse) (err error)
901903
return
902904
}
903905
}
906+
if p.Dataset.Structure == nil || p.Dataset.Structure.IsEmpty() {
907+
p.Dataset.Structure = &dataset.Structure{}
908+
p.Dataset.Structure.Format = filepath.Ext(p.Dataset.BodyFile().FileName())
909+
p.Dataset.Structure.Schema, _, err = detect.Schema(p.Dataset.Structure, p.Dataset.BodyFile())
910+
if err != nil {
911+
return err
912+
}
913+
// TODO (ramfox): this feels gross, but since we consume the reader when
914+
// detecting the schema, we need to open up the file again, since we don't
915+
// have the option to seek back to the front
916+
if err = p.Dataset.OpenBodyFile(ctx, r.node.Repo.Filesystem()); err != nil {
917+
return err
918+
}
919+
}
904920
reader, err := r.inst.stats.JSON(ctx, p.Dataset)
905921
if err != nil {
906922
return err

0 commit comments

Comments
 (0)