1 /* Copyright (C) 2008 J.F.Dockes
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the
14  *   Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17 #ifndef _rclquery_h_included_
18 #define _rclquery_h_included_
19 #include <string>
20 #include <vector>
21 
22 #include <memory>
23 #include "searchdata.h"
24 
25 #ifndef NO_NAMESPACES
26 namespace Rcl {
27 #endif
28 
29 class Db;
30 class Doc;
31 
32 enum abstract_result {
33     ABSRES_ERROR = 0,
34     ABSRES_OK = 1,
35     ABSRES_TRUNC = 2,
36     ABSRES_TERMMISS = 4
37 };
38 
39 // Snippet entry for makeDocAbstract
40 class Snippet {
41 public:
Snippet(int page,const std::string & snip)42     Snippet(int page, const std::string& snip)
43         : page(page), snippet(snip) {}
setTerm(const std::string & trm)44     Snippet& setTerm(const std::string& trm) {
45         term = trm;
46         return *this;
47     }
48     int page;
49     std::string term;
50     std::string snippet;
51 };
52 
53 
54 /**
55  * An Rcl::Query is a question (SearchData) applied to a
56  * database. Handles access to the results. Somewhat equivalent to a
57  * cursor in an rdb.
58  *
59  */
60 class Query {
61 public:
62     Query(Db *db);
63     ~Query();
64 
65     Query(const Query &) = delete;
66     Query& operator=(const Query &) = delete;
67 
68     /** Get explanation about last error */
getReason()69     std::string getReason() const {
70         return m_reason;
71     }
72 
73     /** Choose sort order. Must be called before setQuery */
74     void setSortBy(const std::string& fld, bool ascending = true);
getSortBy()75     const std::string& getSortBy() const {
76         return m_sortField;
77     }
getSortAscending()78     bool getSortAscending() const {
79         return m_sortAscending;
80     }
81 
82     /** Return or filter results with identical content checksum */
setCollapseDuplicates(bool on)83     void setCollapseDuplicates(bool on) {
84         m_collapseDuplicates = on;
85     }
86 
87     /** Accept data describing the search and query the index. This can
88      * be called repeatedly on the same object which gets reinitialized each
89      * time.
90      */
91     bool setQuery(std::shared_ptr<SearchData> q);
92 
93 
94     /**  Get results count for current query.
95      *
96      * @param useestimate Use get_matches_estimated() if true, else
97      *     get_matches_lower_bound()
98      * @param checkatleast checkatleast parameter to get_mset(). Use -1 for
99      *     full scan.
100      */
101     int getResCnt(int checkatleast=1000, bool useestimate=false);
102 
103     /** Get document at rank i in current query results. */
104     bool getDoc(int i, Doc &doc, bool fetchtext = false);
105 
106     /** Get possibly expanded list of query terms */
107     bool getQueryTerms(std::vector<std::string>& terms);
108 
109     /** Build synthetic abstract for document, extracting chunks relevant for
110      * the input query. This uses index data only (no access to the file) */
111     // Abstract returned as one string
112     bool makeDocAbstract(const Doc &doc, std::string& abstract);
113     // Returned as a snippets vector
114     bool makeDocAbstract(const Doc &doc, std::vector<std::string>& abstract);
115     // Returned as a vector of pair<page,snippet> page is 0 if unknown
116     int makeDocAbstract(const Doc &doc, std::vector<Snippet>& abst,
117                         int maxoccs= -1, int ctxwords= -1,bool sortbypage=false);
118     /** Retrieve page number for first match for "significant" query term
119      *  @param term returns the chosen term */
120     int getFirstMatchPage(const Doc &doc, std::string& term);
121 
122     /** Retrieve a reference to the searchData we are using */
getSD()123     std::shared_ptr<SearchData> getSD() {
124         return m_sd;
125     }
126 
127     /** Expand query to look for documents like the one passed in */
128     std::vector<std::string> expand(const Doc &doc);
129 
130     /** Return the Db we're set for */
whatDb()131     Db *whatDb() const {
132         return m_db;
133     }
134 
135     /* make this public for access from embedded Db::Native */
136     class Native;
137     Native *m_nq;
138 
139 private:
140     std::string m_reason; // Error explanation
141     Db    *m_db;
142     void  *m_sorter{nullptr};
143     std::string m_sortField;
144     bool   m_sortAscending{true};
145     bool   m_collapseDuplicates{false};
146     int    m_resCnt{-1};
147     std::shared_ptr<SearchData> m_sd;
148     int    m_snipMaxPosWalk{1000000};
149 };
150 
151 #ifndef NO_NAMESPACES
152 }
153 #endif // NO_NAMESPACES
154 
155 
156 #endif /* _rclquery_h_included_ */
157