Beispiel #1
0
/*
 * 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);
    }
}