2014-03-11 02:47:18 +00:00
/ *
Copyright 2014 The Camlistore Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"strings"
"camlistore.org/pkg/cmdmain"
"camlistore.org/pkg/search"
2015-11-20 22:27:00 +00:00
"go4.org/strutil"
2014-03-11 02:47:18 +00:00
)
type searchCmd struct {
server string
limit int
describe bool
2015-01-18 04:28:59 +00:00
rawQuery bool
2014-03-11 02:47:18 +00:00
}
func init ( ) {
cmdmain . RegisterCommand ( "search" , func ( flags * flag . FlagSet ) cmdmain . CommandRunner {
cmd := new ( searchCmd )
flags . StringVar ( & cmd . server , "server" , "" , "Server to search. " + serverFlagHelp )
flags . IntVar ( & cmd . limit , "limit" , 0 , "Limit number of results. 0 is default. Negative means no limit." )
flags . BoolVar ( & cmd . describe , "describe" , false , "Describe results as well." )
2015-01-18 04:28:59 +00:00
flags . BoolVar ( & cmd . rawQuery , "rawquery" , false , "If true, the provided JSON is a SearchQuery, and not a Constraint. In this case, the -limit flag if non-zero is applied after parsing the JSON." )
2014-03-11 02:47:18 +00:00
return cmd
} )
}
func ( c * searchCmd ) Describe ( ) string {
return "Execute a search query"
}
func ( c * searchCmd ) Usage ( ) {
fmt . Fprintf ( os . Stderr , "Usage: camtool [globalopts] search <expr or Constraint JSON>\n" )
}
func ( c * searchCmd ) Examples ( ) [ ] string {
return [ ] string {
` "loc:paris is:portrait" # expression ` ,
` ' { "blobrefPrefix":"sha1-f00d"}' # SearchConstraint JSON ` ,
` - # piped from stdin ` ,
}
}
func ( c * searchCmd ) RunCommand ( args [ ] string ) error {
if len ( args ) != 1 {
return cmdmain . UsageError ( "requires search expression or Constraint JSON" )
}
q := args [ 0 ]
if q == "-" {
slurp , err := ioutil . ReadAll ( cmdmain . Stdin )
if err != nil {
return err
}
q = string ( slurp )
}
q = strings . TrimSpace ( q )
req := & search . SearchQuery {
Limit : c . limit ,
}
2015-01-18 04:28:59 +00:00
if c . rawQuery {
req . Limit = 0 // clear it if they provided it
if err := json . NewDecoder ( strings . NewReader ( q ) ) . Decode ( & req ) ; err != nil {
return err
}
if c . limit != 0 {
req . Limit = c . limit
}
} else if strutil . IsPlausibleJSON ( q ) {
2014-03-11 02:47:18 +00:00
cs := new ( search . Constraint )
if err := json . NewDecoder ( strings . NewReader ( q ) ) . Decode ( & cs ) ; err != nil {
return err
}
req . Constraint = cs
} else {
req . Expression = q
}
if c . describe {
req . Describe = & search . DescribeRequest { }
}
cl := newClient ( c . server )
2014-07-21 20:20:17 +00:00
res , err := cl . Query ( req )
2014-03-11 02:47:18 +00:00
if err != nil {
return err
}
resj , err := json . MarshalIndent ( res , "" , " " )
if err != nil {
return err
}
resj = append ( resj , '\n' )
_ , err = os . Stdout . Write ( resj )
return err
}