|
a/src/rcldb/rclquery.cpp |
|
b/src/rcldb/rclquery.cpp |
|
... |
|
... |
52 |
} else {
|
52 |
} else {
|
53 |
return df;
|
53 |
return df;
|
54 |
}
|
54 |
}
|
55 |
}
|
55 |
}
|
56 |
|
56 |
|
57 |
// Sort helper class
|
57 |
// Sort helper class. As Xapian sorting is lexicographic, we do some
|
|
|
58 |
// special processing for special fields like dates and sizes. User
|
|
|
59 |
// custom field data will have to be processed before insertion to
|
|
|
60 |
// achieve equivalent results.
|
58 |
class QSorter : public Xapian::Sorter {
|
61 |
class QSorter : public Xapian::Sorter {
|
59 |
public:
|
62 |
public:
|
60 |
QSorter(const string& f)
|
63 |
QSorter(const string& f)
|
61 |
: m_fld(docfToDatf(f) + "=")
|
64 |
: m_fld(docfToDatf(f) + "=")
|
62 |
{
|
65 |
{
|
63 |
m_ismtime = !m_fld.compare("dmtime=");
|
66 |
m_ismtime = !m_fld.compare("dmtime=");
|
|
|
67 |
m_issize = !m_fld.compare("fbytes=") || !m_fld.compare("dbytes=");
|
64 |
}
|
68 |
}
|
65 |
|
69 |
|
66 |
virtual std::string operator()(const Xapian::Document& xdoc) const
|
70 |
virtual std::string operator()(const Xapian::Document& xdoc) const
|
67 |
{
|
71 |
{
|
68 |
string data = xdoc.get_data();
|
72 |
string data = xdoc.get_data();
|
|
... |
|
... |
86 |
if (i1 >= data.length())
|
90 |
if (i1 >= data.length())
|
87 |
return string();
|
91 |
return string();
|
88 |
i2 = data.find_first_of("\n\r", i1);
|
92 |
i2 = data.find_first_of("\n\r", i1);
|
89 |
if (i2 == string::npos)
|
93 |
if (i2 == string::npos)
|
90 |
return string();
|
94 |
return string();
|
|
|
95 |
|
|
|
96 |
string term = data.substr(i1, i2-i1);
|
|
|
97 |
if (m_ismtime) {
|
|
|
98 |
return term;
|
|
|
99 |
} else if (m_issize) {
|
|
|
100 |
// Left zeropad values for appropriate numeric sorting
|
|
|
101 |
leftzeropad(term, 12);
|
|
|
102 |
return term;
|
91 |
|
103 |
}
|
|
|
104 |
|
92 |
// Process data for better sorting. We should actually do the
|
105 |
// Process data for better sorting. We should actually do the
|
93 |
// unicode thing
|
106 |
// unicode thing
|
94 |
// (http://unicode.org/reports/tr10/#Introduction), but just
|
107 |
// (http://unicode.org/reports/tr10/#Introduction), but just
|
95 |
// removing accents and majuscules will remove the most
|
108 |
// removing accents and majuscules will remove the most
|
96 |
// glaring weirdnesses (or not, depending on your national
|
109 |
// glaring weirdnesses (or not, depending on your national
|
97 |
// approach to collating...)
|
110 |
// approach to collating...)
|
98 |
string term = data.substr(i1, i2-i1);
|
|
|
99 |
string sortterm;
|
111 |
string sortterm;
|
100 |
// We're not even sure the term is utf8 here (ie: url)
|
112 |
// We're not even sure the term is utf8 here (ie: url)
|
101 |
if (!unacmaybefold(term, sortterm, "UTF-8", true)) {
|
113 |
if (!unacmaybefold(term, sortterm, "UTF-8", true)) {
|
102 |
sortterm = term;
|
114 |
sortterm = term;
|
103 |
}
|
115 |
}
|
|
... |
|
... |
112 |
}
|
124 |
}
|
113 |
|
125 |
|
114 |
private:
|
126 |
private:
|
115 |
string m_fld;
|
127 |
string m_fld;
|
116 |
bool m_ismtime;
|
128 |
bool m_ismtime;
|
|
|
129 |
bool m_issize;
|
117 |
};
|
130 |
};
|
118 |
|
131 |
|
119 |
Query::Query(Db *db)
|
132 |
Query::Query(Db *db)
|
120 |
: m_nq(new Native(this)), m_db(db), m_sorter(0), m_sortAscending(true),
|
133 |
: m_nq(new Native(this)), m_db(db), m_sorter(0), m_sortAscending(true),
|
121 |
m_collapseDuplicates(false), m_resCnt(-1)
|
134 |
m_collapseDuplicates(false), m_resCnt(-1)
|