// This function is subject to change, depending on what the client actually // expects. This may not be entirely correct. func formatRunShow(run *report.Report) map[string]interface{} { reportMap := util.MapifyObject(run) resources := reportMap["resources"] delete(reportMap, "resources") reportFmt := make(map[string]interface{}) reportFmt["run_detail"] = reportMap reportFmt["resources"] = resources return reportFmt }
func (p *PostgresSearch) Search(idx string, q string, rows int, sortOrder string, start int, partialData map[string]interface{}) ([]map[string]interface{}, error) { // check that the endpoint actually exists sqlStmt := "SELECT 1 FROM goiardi.search_collections WHERE organization_id = $1 AND name = $2" stmt, serr := datastore.Dbh.Prepare(sqlStmt) if serr != nil { return nil, serr } defer stmt.Close() var zzz int serr = stmt.QueryRow(1, idx).Scan(&zzz) // don't care about zzz if serr != nil { if serr == sql.ErrNoRows { serr = fmt.Errorf("I don't know how to search for %s data objects.", idx) } return nil, serr } // Special case "goodness". If the search term is "*:*" with no // qualifiers, short circuit everything and just get a list of the // distinct items. var qresults []string if q == "*:*" { logger.Debugf("Searching '*:*' on %s, short circuiting", idx) var builtinIdx bool if idx == "node" || idx == "client" || idx == "environment" || idx == "role" { builtinIdx = true sqlStmt = fmt.Sprintf("SELECT COALESCE(ARRAY_AGG(name), '{}'::text[]) FROM goiardi.%ss WHERE organization_id = $1", idx) } else { sqlStmt = "SELECT COALESCE(ARRAY_AGG(orig_name), '{}'::text[]) FROM goiardi.data_bag_items JOIN goiardi.data_bags ON goiardi.data_bag_items.data_bag_id = goiardi.data_bags.id WHERE goiardi.data_bags.organization_id = $1 AND goiardi.data_bags.name = $2" } var res util.StringSlice stmt, err := datastore.Dbh.Prepare(sqlStmt) if err != nil { return nil, err } defer stmt.Close() if builtinIdx { err = stmt.QueryRow(1).Scan(&res) } else { err = stmt.QueryRow(1, idx).Scan(&res) } if err != nil && err != sql.ErrNoRows { return nil, err } qresults = res } else { // keep up with the ersatz solr. qq := &Tokenizer{Buffer: q} qq.Init() if err := qq.Parse(); err != nil { return nil, err } qq.Execute() qchain := qq.Evaluate() pgQ := &PgQuery{idx: idx, queryChain: qchain} err := pgQ.execute() if err != nil { return nil, err } qresults, err = pgQ.results() if err != nil { return nil, err } } // THE WRONG WAY: // Eventually, ordering by the keys themselves would be awesome. objs := getResults(idx, qresults) res := make([]map[string]interface{}, len(objs)) for i, r := range objs { switch r := r.(type) { case *client.Client: jc := map[string]interface{}{ "name": r.Name, "chef_type": r.ChefType, "json_class": r.JSONClass, "admin": r.Admin, "public_key": r.PublicKey(), "validator": r.Validator, } res[i] = jc default: res[i] = util.MapifyObject(r) } } /* If we're doing partial search, tease out the fields we want. */ if partialData != nil { var err error res, err = formatPartials(res, objs, partialData) if err != nil { return nil, err } } // and at long last, sort ss := strings.Split(sortOrder, " ") sortKey := ss[0] if sortKey == "id" { sortKey = "name" } var ordering string if len(ss) > 1 { ordering = strings.ToLower(ss[1]) } else { ordering = "asc" } sortResults := results{res, sortKey} if ordering == "desc" { sort.Sort(sort.Reverse(sortResults)) } else { sort.Sort(sortResults) } res = sortResults.res end := start + rows if end > len(res) { end = len(res) } res = res[start:end] return res, nil }
// Search parses the given query string and search the given index for any // matching results. func (t *TrieSearch) Search(idx string, query string, rows int, sortOrder string, start int, partialData map[string]interface{}) ([]map[string]interface{}, error) { m.Lock() defer m.Unlock() qq := &Tokenizer{Buffer: query} qq.Init() if err := qq.Parse(); err != nil { return nil, err } qq.Execute() qchain := qq.Evaluate() d := make(map[string]indexer.Document) solrQ := &SolrQuery{queryChain: qchain, idxName: idx, docs: d} _, err := solrQ.execute() if err != nil { return nil, err } qresults := solrQ.results() objs := getResults(idx, qresults) res := make([]map[string]interface{}, len(objs)) for i, r := range objs { switch r := r.(type) { case *client.Client: jc := map[string]interface{}{ "name": r.Name, "chef_type": r.ChefType, "json_class": r.JSONClass, "admin": r.Admin, "public_key": r.PublicKey(), "validator": r.Validator, } res[i] = jc default: res[i] = util.MapifyObject(r) } } /* If we're doing partial search, tease out the fields we want. */ if partialData != nil { res, err = formatPartials(res, objs, partialData) if err != nil { return nil, err } } // and at long last, sort ss := strings.Split(sortOrder, " ") sortKey := ss[0] if sortKey == "id" { sortKey = "name" } var ordering string if len(ss) > 1 { ordering = strings.ToLower(ss[1]) } else { ordering = "asc" } sortResults := results{res, sortKey} if ordering == "desc" { sort.Sort(sort.Reverse(sortResults)) } else { sort.Sort(sortResults) } res = sortResults.res end := start + rows if end > len(res) { end = len(res) } res = res[start:end] return res, nil }