/* * Pass a query to the catalog and return the number of objects found. * Only the given columns are retrieved. * * Args: * q - (in) object describing the query * * filename - (in) filename to hold results, or null * * result - (out) reference to object used to access the results * * The return value is the number of rows found, or 0 if none were found. * A return value of -1 indicates an error. */ int AstroCatalog::query(const AstroQuery& q, const char* filename, QueryResult& result) { if (! isCatalog(entry_)) return wrongServType(entry_); // generate the URL for a standard query in buf (using ostringstream) char* result_buf = NULL; int nlines = 0; // if the first URL doesn't work, try the others, if specified const char* urls[3]; urls[0] = entry_->url(); urls[1] = entry_->backup1(); urls[2] = entry_->backup2(); char url[10000]; char* ctype = (char *)""; for (int i = 0; i < 3 && urls[i]; i++) { if (genHttpQuery(url, sizeof(url), q, urls[i]) != 0) return -1; // send the query result_buf = http_.get(url, nlines); ctype = http_.content_type(); if (!ctype) ctype = (char *)""; if (result_buf != NULL && strcmp(ctype, "text/html") != 0) break; // don't go to backup URL if it was a request for authorization if (http_.authorizationRequired()) break; } if (result_buf == NULL) return -1; // error in http get // check the Content-type of the return data if (strcmp(ctype, "text/html") == 0) { // most likely an error message http_.html_error(result_buf); return -1; } // note the catalog config entry in the results // (This contains important info, such as the location of the id, a and dec cols) result.entry(entry_, result_buf); if (result.init(result_buf) != 0) return -1; // error // sort result ? // note: do this before truncating to maxRows to get correct results if (q.numSortCols()) result.sort(q.numSortCols(), q.sortCols(), q.sortOrder()); if (q.maxRows() && result.numRows() > q.maxRows()) { more_ = 1; result.numRows(q.maxRows()); } else { more_ = 0; } // if we didn't already, note the catalog's column heading info if (info_.numCols() <= 0 && info_.init(result.numCols(), result.colNames(), "", 1) != 0) return -1; if (filename && result.save(filename) != 0) return -1; return result.numRows(); }
void HTTPSearchService::handleQuery(const Statement& state, EvHttpRequestContext* pCtx) const { IndexReaderPtr pIndexReader = m_searchRes.getIndexReader(); FIRTEX_ASSERT2(pIndexReader.isNotNull()); try { TimeProbe probe; probe.start(); QueryParser parser(pIndexReader->getAnalyzerMapper(), m_searchRes.getDefaultField()); IndexSearcher searcher(pIndexReader); QueryHitsPtr pHits = searcher.search(state, parser); QueryResult result; if (pHits.isNotNull()) { FieldSelectClausePtr pFieldClause = state.getFieldSelectClause(); QueryClausePtr pQueryClause = state.getQueryClause(); if (pFieldClause.isNotNull() && pQueryClause.isNotNull()) { QueryPtr pQuery = parser.parse(pQueryClause->getQueryString()); FIRTEX_ASSERT2(pQuery.isNotNull()); FieldSelector selector(pIndexReader->getDocSchema()); for (size_t i = 0; i < pFieldClause->getFieldCount(); ++i) { const FieldSelectClause::SnippetParam& param = pFieldClause->getField(i); FieldFilterPtr pFieldFilter; if (param.snippet) { SnippetGenerator* pSnippetGen = new SnippetGenerator(); pFieldFilter.reset(pSnippetGen); if (!pSnippetGen->init(pQuery, parser.getAnalyzerMapper(), param.field, param.preTag, param.postTag, param.separator)) { FX_LOG(ERROR, "Init snippet generator for field: [%s] FAILED", param.field.c_str()); sendErrorMessage("Init snippet generator for field: " + param.field + " FAILED", pCtx); return; } } if (!selector.addField(param.field, pFieldFilter)) { FX_LOG(ERROR, "Invalid field: [%s]", param.field.c_str()); } } result.init(selector, pIndexReader, *pHits); } else { result.init(pIndexReader, *pHits); } } probe.stop(); result.setTimeCost(probe.elapsed() / 1000); FX_QUERY_TRACE(INFO, result.getTracer(), "search phase time [%d]", (int32_t)result.getTimeCost()); stringstream ss; XMLResultFormatter formatter; formatter.format(result, ss); sendResponse(ss.str(), pCtx); } catch(const FirteXException& e) { FX_LOG(ERROR, "Handle request FAILED: [%s], reason: [%s]", pCtx->getQuery().c_str(), e.what().c_str()); sendErrorMessage("Handle request failed", pCtx); } }