Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func New() *cobra.Command {
cmd.AddCommand(ServerCommand())
cmd.AddCommand(NamespaceCmd())
cmd.AddCommand(SchemaCmd())
cmd.AddCommand(SearchCmd())

// Help topics
cmdx.SetHelp(cmd)
Expand Down
110 changes: 110 additions & 0 deletions cmd/search.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cmd

import (
"context"
"fmt"
"os"
"strconv"
"strings"

"github.com/MakeNowJust/heredoc"
"github.com/odpf/salt/printer"
stencilv1beta1 "github.com/odpf/stencil/server/odpf/stencil/v1beta1"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)

func SearchCmd() *cobra.Command {
var host, namespaceID, schemaID string
var versionID int32
var history bool
var req stencilv1beta1.SearchRequest

cmd := &cobra.Command{
Use: "search",
Aliases: []string{"search"},
Short: "Search",
Long: "Search your queries on schemas",
Example: heredoc.Doc(`
$ stencil search <query> --namespace=<namespace> --schema=<schema> --version=<version> --history=<history>
`),
Annotations: map[string]string{
"group:core": "true",
},
RunE: func(cmd *cobra.Command, args []string) error {
s := printer.Spin("")
defer s.Stop()

conn, err := grpc.Dial(host, grpc.WithInsecure())
if err != nil {
return err
}
defer conn.Close()

query := args[0]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add check for args length. Otherwise it will panic if search query not given.

req.Query = query
req.NamespaceId = namespaceID
req.SchemaId = schemaID

if versionID != 0 {
req.Version = &stencilv1beta1.SearchRequest_VersionId{
VersionId: versionID,
}
} else if history {
req.Version = &stencilv1beta1.SearchRequest_History{
History: history,
}
}

client := stencilv1beta1.NewStencilServiceClient(conn)
res, err := client.Search(context.Background(), &req)
if err != nil {
return err
}

hits := res.GetHits()
meta := res.GetMeta()

report := [][]string{}
s.Stop()

if len(hits) == 0 {
fmt.Printf("No results found")
return nil
}

fmt.Printf(" \nShowing %d result(s) \n", len(hits))

report = append(report, []string{"INDEX", "NAMESPACE", "SCHEMA", "FIELDS", "TYPES", "VERSION"})
for i, h := range hits {
report = append(report, []string{
strconv.Itoa(i + 1),
h.GetNamespaceId(),
h.GetSchemaId(),
strings.Join(h.GetFields(), ","),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output of search results are unreadable if more number of matching field names or messages present. Maybe we can print each field/type name in separate row to make it more user friendly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right! How about this @harikrishnakanchi?

Also, I am thinking of removing the "NAMESPACE" and "SCHEMA" details as well, since their values will be the same as the user passed in flags.

Showing 2 result(s) 
                                                      
1)                                                    
FIELD: stencil.One.field_one                          
TYPE: stencil.One                                     
VERSION: 1                                            
                                                      
2)                                                    
FIELD: stencil.One.field_one,stencil.One.Two.field_two
TYPE: stencil.One,stencil.One.Two                     
VERSION: 2                                            
     
TOTAL
2

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like this should be good.

Namespace Schema version Type Fields
org schema-name 1 odpf.stencil.One odpf.stencil.One.field_one, odpf.stencil.One.field_one

With this we need to group fields by type name. Currently it just returns all matching fields and all matching type. Fields can be segregated by type then show it.

strings.Join(h.GetTypes(), ","),
strconv.Itoa(int(h.GetVersionId())),
})
}
printer.Table(os.Stdout, report)

report = [][]string{}
report = append(report, []string{"\nTOTAL"})
report = append(report, []string{strconv.Itoa(int(meta.GetTotal()))})
printer.Table(os.Stdout, report)

return nil
},
}

cmd.Flags().StringVar(&host, "host", "", "stencil host address eg: localhost:8000")
cmd.MarkFlagRequired("host")
cmd.Flags().StringVarP(&namespaceID, "namespace", "n", "", "parent namespace ID")
cmd.MarkFlagRequired("namespace")
cmd.Flags().StringVarP(&schemaID, "schema", "s", "", "related schema ID")
cmd.MarkFlagRequired("schema")
cmd.Flags().Int32VarP(&versionID, "version", "v", 0, "version of the schema")
cmd.Flags().BoolVarP(&history, "history", "h", false, "set this to enable history")

return cmd
}