Skip to content

Commit

Permalink
fix(search): Dispatch for search
Browse files Browse the repository at this point in the history
  • Loading branch information
dustmop committed Apr 1, 2021
1 parent 75b42e1 commit 8570abf
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 88 deletions.
16 changes: 9 additions & 7 deletions api/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ import (

// SearchHandlers wraps a requests struct to interface with http.HandlerFunc
type SearchHandlers struct {
lib.SearchMethods
Instance *lib.Instance
}

// NewSearchHandlers allocates a SearchHandlers pointer
func NewSearchHandlers(inst *lib.Instance) *SearchHandlers {
req := lib.NewSearchMethods(inst)
return &SearchHandlers{*req}
return &SearchHandlers{Instance: inst}
}

// SearchHandler is the endpoint for searching qri
Expand All @@ -35,12 +34,15 @@ func (h *SearchHandlers) searchHandler(w http.ResponseWriter, r *http.Request) {
return
}

res, err := h.SearchMethods.Search(r.Context(), params)
got, _, err := h.Instance.Dispatch(r.Context(), "search.search", params)
if err != nil {
log.Infof("search error: %s", err.Error())
util.WriteErrResponse(w, http.StatusBadRequest, err)
util.RespondWithError(w, err)
return
}
res, ok := got.([]lib.SearchResult)
if !ok {
util.RespondWithDispatchTypeError(w, got)
return
}

util.WriteResponse(w, res)
}
1 change: 0 additions & 1 deletion cmd/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ type Factory interface {
RemoteMethods() (*lib.RemoteMethods, error)
RegistryClientMethods() (*lib.RegistryClientMethods, error)
ProfileMethods() (*lib.ProfileMethods, error)
SearchMethods() (*lib.SearchMethods, error)
RenderMethods() (*lib.RenderMethods, error)
}

Expand Down
5 changes: 0 additions & 5 deletions cmd/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,6 @@ func (t TestFactory) ProfileMethods() (*lib.ProfileMethods, error) {
return lib.NewProfileMethods(t.inst), nil
}

// SearchMethods generates a lib.SearchMethods from internal state
func (t TestFactory) SearchMethods() (*lib.SearchMethods, error) {
return lib.NewSearchMethods(t.inst), nil
}

// RenderMethods generates a lib.RenderMethods from internal state
func (t TestFactory) RenderMethods() (*lib.RenderMethods, error) {
return lib.NewRenderMethods(t.inst), nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (o *LogbookOptions) Complete(f Factory, args []string) (err error) {
return err
}

// Logbook executes the Logbook command
// LogEntries gets entries from the logbook
func (o *LogbookOptions) LogEntries() error {
printRefSelect(o.ErrOut, o.Refs)

Expand Down
8 changes: 0 additions & 8 deletions cmd/qri.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,6 @@ func (o *QriOptions) ProfileMethods() (m *lib.ProfileMethods, err error) {
return lib.NewProfileMethods(o.inst), nil
}

// SearchMethods generates a lib.SearchMethods from internal state
func (o *QriOptions) SearchMethods() (*lib.SearchMethods, error) {
if err := o.Init(); err != nil {
return nil, err
}
return lib.NewSearchMethods(o.inst), nil
}

// RenderMethods generates a lib.RenderMethods from internal state
func (o *QriOptions) RenderMethods() (*lib.RenderMethods, error) {
if err := o.Init(); err != nil {
Expand Down
19 changes: 11 additions & 8 deletions cmd/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ type SearchOptions struct {
Page int
// Reindex bool

SearchMethods *lib.SearchMethods
Instance *lib.Instance
}

// Complete adds any missing configuration that can only be added just before calling Run
func (o *SearchOptions) Complete(f Factory, args []string) (err error) {
if o.Instance, err = f.Instance(); err != nil {
return err
}
if len(args) != 0 {
o.Query = args[0]
}
o.SearchMethods, err = f.SearchMethods()
return
}

Expand All @@ -79,6 +81,9 @@ func (o *SearchOptions) Validate() error {

// Run executes the search command
func (o *SearchOptions) Run() (err error) {
ctx := context.TODO()
inst := o.Instance

o.StartSpinner()
defer o.StopSpinner()

Expand All @@ -88,18 +93,16 @@ func (o *SearchOptions) Run() (err error) {
page := apiutil.NewPage(o.Page, o.PageSize)

p := &lib.SearchParams{
QueryString: o.Query,
Limit: page.Limit(),
Offset: page.Offset(),
Query: o.Query,
Limit: page.Limit(),
Offset: page.Offset(),
}

ctx := context.TODO()
results, err := o.SearchMethods.Search(ctx, p)
results, err := inst.Search().Search(ctx, p)
if err != nil {
return err
}

// o.StopSpinner()
switch o.Format {
case "":
fmt.Fprintf(o.Out, "showing %d results for '%s'\n", len(results), o.Query)
Expand Down
26 changes: 9 additions & 17 deletions cmd/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ func TestSearchComplete(t *testing.T) {
continue
}

if opt.SearchMethods == nil {
t.Errorf("case %d, opt.SearchMethods not set.", i)
run.IOReset()
continue
}
run.IOReset()
}
}
Expand Down Expand Up @@ -168,8 +163,11 @@ func TestSearchRun(t *testing.T) {

f, err := NewTestFactoryInstanceOptions(ctx, run.RootPath, lib.OptRegistryClient(rc))
if err != nil {
t.Errorf("error creating new test factory: %s", err)
return
t.Fatal(err)
}
inst, err := f.Instance()
if err != nil {
t.Fatal(err)
}

cases := []struct {
Expand All @@ -184,17 +182,11 @@ func TestSearchRun(t *testing.T) {
}

for i, c := range cases {
sr, err := f.SearchMethods()
if err != nil {
t.Errorf("case %d, error creating dataset request: %s", i, err)
continue
}

opt := &SearchOptions{
IOStreams: run.Streams,
Query: c.query,
Format: c.format,
SearchMethods: sr,
IOStreams: run.Streams,
Query: c.query,
Format: c.format,
Instance: inst,
}

err = opt.Run()
Expand Down
1 change: 1 addition & 0 deletions lib/dispatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ func (inst *Instance) RegisterMethods() {
inst.registerOne("fsi", inst.Filesys(), fsiImpl{}, reg)
inst.registerOne("log", inst.Log(), logImpl{}, reg)
inst.registerOne("peer", inst.Peer(), peerImpl{}, reg)
inst.registerOne("search", inst.Search(), searchImpl{}, reg)
inst.registerOne("sql", inst.SQL(), sqlImpl{}, reg)
inst.registerOne("transform", inst.Transform(), transformImpl{}, reg)
inst.regMethods = &regMethodSet{reg: reg}
Expand Down
2 changes: 1 addition & 1 deletion lib/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ func PushToRegistry(ctx context.Context, t *testing.T, inst *Instance, refstr st
}

func SearchFor(ctx context.Context, t *testing.T, inst *Instance, term string) []SearchResult {
results, err := NewSearchMethods(inst).Search(ctx, &SearchParams{QueryString: term})
results, err := inst.Search().Search(ctx, &SearchParams{Query: term})
if err != nil {
t.Fatal(err)
}
Expand Down
5 changes: 5 additions & 0 deletions lib/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,11 @@ func (inst *Instance) Peer() PeerMethods {
return PeerMethods{d: inst}
}

// Search returns the SearchMethods that Instance has registered
func (inst *Instance) Search() SearchMethods {
return SearchMethods{d: inst}
}

// SQL returns the SQLMethods that Instance has registered
func (inst *Instance) SQL() SQLMethods {
return SQLMethods{d: inst}
Expand Down
6 changes: 6 additions & 0 deletions lib/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/qri-io/qri/logbook"
"github.com/qri-io/qri/p2p"
"github.com/qri-io/qri/profile"
"github.com/qri-io/qri/registry/regclient"
"github.com/qri-io/qri/remote"
"github.com/qri-io/qri/repo"
"github.com/qri-io/qri/stats"
Expand Down Expand Up @@ -146,6 +147,11 @@ func (s *scope) Profiles() profile.Store {
return s.inst.profiles
}

// RegistryClient returns a client that can send requests to the registry
func (s *scope) RegistryClient() *regclient.Client {
return s.inst.registry
}

// RemoteClient exposes the instance client for making requests to remotes
func (s *scope) RemoteClient() remote.Client {
return s.inst.remoteClient
Expand Down
66 changes: 35 additions & 31 deletions lib/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,35 @@ package lib

import (
"context"
"fmt"
"net/http"

"github.com/qri-io/dataset"
"github.com/qri-io/qri/registry/regclient"
"github.com/qri-io/qri/repo"
)

// SearchMethods encapsulates business logic for the qri search command
// TODO (b5): switch to using an Instance instead of separate fields
// SearchMethods groups together methods for search
type SearchMethods struct {
inst *Instance
d dispatcher
}

// NewSearchMethods creates SearchMethods from a qri Instance
func NewSearchMethods(inst *Instance) *SearchMethods {
return &SearchMethods{inst: inst}
// Name returns the name of this method group
func (m SearchMethods) Name() string {
return "search"
}

// CoreRequestsName implements the requests
func (m SearchMethods) CoreRequestsName() string { return "search" }
// Attributes defines attributes for each method
func (m SearchMethods) Attributes() map[string]AttributeSet {
return map[string]AttributeSet{
"search": {AESearch, "POST"},
}
}

// SearchParams defines paremeters for the search Method
type SearchParams struct {
QueryString string `json:"q"`
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
Query string `json:"q"`
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
}

// UnmarshalFromRequest implements a custom deserialization-from-HTTP request
Expand All @@ -45,8 +47,8 @@ func (p *SearchParams) UnmarshalFromRequest(r *http.Request) error {
p.Limit = lp.Limit
p.Offset = lp.Offset

if p.QueryString == "" {
p.QueryString = r.FormValue("q")
if p.Query == "" {
p.Query = r.FormValue("q")
}

return nil
Expand All @@ -60,30 +62,32 @@ type SearchResult struct {
}

// Search queries for items on qri related to given parameters
func (m *SearchMethods) Search(ctx context.Context, p *SearchParams) ([]SearchResult, error) {
if m.inst.http != nil {
res := []SearchResult{}
err := m.inst.http.Call(ctx, AESearch, p, &res)
if err != nil {
return nil, err
}
return res, nil
}
if p == nil {
return nil, fmt.Errorf("error: search params cannot be nil")
func (m SearchMethods) Search(ctx context.Context, p *SearchParams) ([]SearchResult, error) {
got, _, err := m.d.Dispatch(ctx, dispatchMethodName(m, "search"), p)
if res, ok := got.([]SearchResult); ok {
return res, err
}
return nil, dispatchReturnError(got, err)
}

// Implementations for FSI methods follow

reg := m.inst.registry
if reg == nil {
// searchImpl holds the method implementations for search
type searchImpl struct{}

// Search queries for items on qri related to given parameters
func (searchImpl) Search(scope scope, p *SearchParams) ([]SearchResult, error) {
client := scope.RegistryClient()
if client == nil {
return nil, repo.ErrNoRegistry
}
params := &regclient.SearchParams{
QueryString: p.QueryString,
Limit: p.Limit,
Offset: p.Offset,
Query: p.Query,
Limit: p.Limit,
Offset: p.Offset,
}

regResults, err := reg.Search(params)
regResults, err := client.Search(params)
if err != nil {
return nil, err
}
Expand Down
4 changes: 1 addition & 3 deletions lib/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ func TestSearch(t *testing.T) {
inst := NewInstanceFromConfigAndNode(ctx, config.DefaultConfig(), node)
inst.registry = rc

m := NewSearchMethods(inst)

p := &SearchParams{"nuun", 0, 100}
got, err := m.Search(ctx, p)
got, err := inst.Search().Search(ctx, p)
if err != nil {
t.Error(err)
}
Expand Down
10 changes: 5 additions & 5 deletions registry/regclient/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ type SearchFilter struct {
// SearchParams contains the parameters that are passed to a
// Client.Search method
type SearchParams struct {
QueryString string
Filters []SearchFilter
Limit int
Offset int
Query string
Filters []SearchFilter
Limit int
Offset int
}

// Search makes a registry search request
func (c Client) Search(p *SearchParams) ([]*dataset.Dataset, error) {
params := &registry.SearchParams{
Q: p.QueryString,
Q: p.Query,
//Filters: p.Filters,
Limit: p.Limit,
Offset: p.Offset,
Expand Down
2 changes: 1 addition & 1 deletion registry/regclient/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestSearchMethods(t *testing.T) {
Location: srv.URL,
})

searchParams := &SearchParams{QueryString: "presidents", Limit: 100, Offset: 0}
searchParams := &SearchParams{Query: "presidents", Limit: 100, Offset: 0}
// TODO: need to add tests that actually inspect the search results
_, err := c.Search(searchParams)
if err != nil {
Expand Down

0 comments on commit 8570abf

Please sign in to comment.