diff --git a/server.go b/server.go index bfc66c7..f319ae6 100644 --- a/server.go +++ b/server.go @@ -36,7 +36,7 @@ import ( var db *sql.DB func executeQuery(rw http.ResponseWriter, req *http.Request) { - var request jsonRequest + var request jsonQueryRequest if err := json.NewDecoder(req.Body).Decode(&request); err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return @@ -49,6 +49,9 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) { } context := queryContext{geo, convertFeatures(request.Profile), request.WalkingDist} + entries := getRecords(context) + + foundEntries := findRecords(entries, featureMap(request.Features), request.MinScore) // function runQuery(query, callback) { // query.profile = fixupProfile(query.profile); diff --git a/types.go b/types.go index 5e411fa..4d9ed40 100644 --- a/types.go +++ b/types.go @@ -35,7 +35,7 @@ type jsonGeo struct { Valid bool `json:"valid"` } -type jsonRequest struct { +type jsonQueryRequest struct { Features jsonFeatureMap `json:"features"` Geo *jsonGeo `json:"geo"` HintSteps int `json:"hintSteps"` @@ -46,6 +46,38 @@ type jsonRequest struct { WalkingDist float64 `json:"walkingDist"` } +type jsonColumn struct { + Hints []jsonProjection `json:"hints"` + Steps int `json:"steps"` + Value float64 `json:"value"` +} + +type jsonProjection struct { + Sample float64 `json:"sample"` + Stats jsonStats `json:"stats"` +} + +type jsonStats struct { + Compatibility float64 `json:"compatibility"` + Count int `json:"count"` +} + +type jsonRecord struct { + Name string `json:"name"` + Score float64 `json:"score"` + DistanceToUser float64 `json:"distanceToUser"` + DistanceToStn float64 `json:"distanceToStn"` + ClosestStn string `json:"closestStn"` + AccessCount int `json:"accessCount"` + Id int `json:"id"` +} + +type jsonQueryResponse struct { + Columns map[string]jsonColumn `json:"columns"` + Count int `json:"count"` + Items []jsonRecord `json:"items"` +} + type jsonCategory struct { Description string `json:"description"` Id int `json:"id"` @@ -97,6 +129,7 @@ type geoContext struct { type record struct { accessCount int + closestStn string compatibility float64 distanceToStn float64 distanceToUser float64 @@ -105,6 +138,7 @@ type record struct { id int name string score float64 + url string } type records []record diff --git a/util.go b/util.go index c073d42..b590992 100644 --- a/util.go +++ b/util.go @@ -78,14 +78,15 @@ func stepRange(bounds queryBounds, steps int, callback func(float64)) { } } -func findRecords(entries records, features featureMap, minScore float64) { - var foundRecords records +func findRecords(entries records, features featureMap, minScore float64) records { + var foundEntries records walkMatches(entries, features, minScore, func(record record, score float64) { - foundRecords = append(foundRecords, record) + foundEntries = append(foundEntries, record) }) - sort.Sort(foundRecords) + sort.Sort(foundEntries) + return foundEntries } func project(entries records, features featureMap, featureName string, minScore float64, bounds queryBounds, steps int) []queryProjection { @@ -191,3 +192,33 @@ func computeRecordPopularity(entries records, context queryContext) { record.features["compatibility"] = compatibility } } + +func getRecords(context queryContext) records { + rows, err := db.Query("SELECT name, url, delicious, accomodating, affordable, atmospheric, latitude, longitude, distanceToStn, closestStn, accessCount, id FROM reviews") + if err != nil { + log.Fatal(err) + } + + var entries []record + for rows.Next() { + var name, url, closestStn string + var delicious, accomodating, affordable, atmospheric, latitude, longitude, distanceToStn float64 + var accessCount, id int + + rows.Scan(&name, &url, &delicious, &accomodating, &affordable, &atmospheric, &latitude, &longitude, &distanceToStn, &closestStn, &accessCount, &id) + + entry := record{name: name, url: url, distanceToStn: distanceToStn, closestStn: closestStn, accessCount: accessCount, id: id} + entry.features["delicious"] = delicious + entry.features["accomodating"] = accomodating + entry.features["affordable"] = affordable + entry.features["atmospheric"] = atmospheric + entry.geo = geoContext{latitude, longitude} + + entries = append(entries, entry) + } + if err := rows.Err(); err != nil { + log.Fatal(err) + } + + return entries +}