blob: 3494882d4c279df769c4f43303756fa11de6f0cc [file] [log] [blame]
package impl
import (
"fmt"
"io"
"os"
"sort"
"veyron2/query"
"veyron2/rt"
"veyron2/storage"
"veyron2/storage/vstore"
// TODO(rjkroege@google.com): Replace with the appropriate vom2 functionality
// when available.
_ "veyron/services/store/typeregistryhack"
)
func indenter(w io.Writer, indent int) {
for i := 0; i < indent; i++ {
fmt.Fprintf(w, "\t")
}
}
// Prints a single QueryResult to the provided io.Writer.
func printResult(qr storage.QueryResult, w io.Writer, indent int) {
// TODO(rjkroege@google.com): Consider permitting the user to provide a Go
// template to format output.
if v := qr.Value(); v != nil {
indenter(w, indent)
fmt.Fprintf(w, "%s: %#v\n", qr.Name(), v)
} else {
// Force fields to be consistently ordered.
fields := qr.Fields()
names := make([]string, 0, len(fields))
for k, _ := range fields {
names = append(names, k)
}
sort.Strings(names)
indenter(w, indent)
fmt.Fprintf(w, "%s: map[string]interface {}{\n", qr.Name())
for _, k := range names {
f := fields[k]
switch v := f.(type) {
case storage.QueryStream:
indenter(w, indent+1)
fmt.Fprintf(w, "%s: {\n", k)
printStream(v, w, indent+2)
indenter(w, indent+1)
fmt.Fprintf(w, "},\n")
default:
indenter(w, indent+1)
fmt.Fprintf(w, "\"%s\":%#v,\n", k, v)
}
}
indenter(w, indent)
fmt.Fprintf(w, "},\n")
}
}
func printStream(qs storage.QueryStream, w io.Writer, indent int) error {
for qs.Advance() {
printResult(qs.Value(), w, indent)
}
if err := qs.Err(); err != nil {
return err
}
return nil
}
func RunQuery(queryRoot, queryString string) error {
ctx := rt.R().TODOContext()
return printStream(vstore.New().Bind(queryRoot).Query(ctx, query.Query{queryString}), os.Stdout, 0)
}