mhs-xapian 1.0.18a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. data/.gitignore +3 -0
  2. data/AUTHORS +1 -0
  3. data/COPYING +340 -0
  4. data/ChangeLog +5876 -0
  5. data/HACKING +101 -0
  6. data/INSTALL +293 -0
  7. data/Makefile +722 -0
  8. data/Makefile.am +26 -0
  9. data/Makefile.in +722 -0
  10. data/NEWS +2110 -0
  11. data/README +59 -0
  12. data/Rakefile +51 -0
  13. data/TODO +47 -0
  14. data/aclocal.m4 +7675 -0
  15. data/config.guess +1501 -0
  16. data/config.h +56 -0
  17. data/config.h.in +55 -0
  18. data/config.status +1298 -0
  19. data/config.sub +1705 -0
  20. data/configure +18536 -0
  21. data/configure.ac +944 -0
  22. data/csharp/.deps/xapian_wrap.Plo +1 -0
  23. data/csharp/AssemblyInfo.cs +40 -0
  24. data/csharp/AssemblyInfo.cs.in +40 -0
  25. data/csharp/Auto.cs +46 -0
  26. data/csharp/BM25Weight.cs +107 -0
  27. data/csharp/BoolWeight.cs +103 -0
  28. data/csharp/Database.cs +275 -0
  29. data/csharp/DateValueRangeProcessor.cs +61 -0
  30. data/csharp/Document.cs +177 -0
  31. data/csharp/ESet.cs +94 -0
  32. data/csharp/ESetIterator.cs +117 -0
  33. data/csharp/Enquire.cs +274 -0
  34. data/csharp/ExpandDecider.cs +76 -0
  35. data/csharp/Flint.cs +58 -0
  36. data/csharp/InMemory.cs +46 -0
  37. data/csharp/MSet.cs +193 -0
  38. data/csharp/MSetIterator.cs +141 -0
  39. data/csharp/Makefile +868 -0
  40. data/csharp/Makefile.am +106 -0
  41. data/csharp/Makefile.in +868 -0
  42. data/csharp/MatchDecider.cs +76 -0
  43. data/csharp/MultiValueSorter.cs +63 -0
  44. data/csharp/NumberValueRangeProcessor.cs +61 -0
  45. data/csharp/PositionIterator.cs +101 -0
  46. data/csharp/PostingIterator.cs +125 -0
  47. data/csharp/Quartz.cs +58 -0
  48. data/csharp/Query.cs +150 -0
  49. data/csharp/QueryParser.cs +174 -0
  50. data/csharp/RSet.cs +102 -0
  51. data/csharp/Remote.cs +100 -0
  52. data/csharp/SWIGTYPE_p_std__string.cs +30 -0
  53. data/csharp/SWIGTYPE_p_std__vectorTXapian__Query_t.cs +30 -0
  54. data/csharp/SWIGTYPE_p_std__vectorTstd__string_t.cs +30 -0
  55. data/csharp/SimpleStopper.cs +64 -0
  56. data/csharp/SmokeTest.cs +178 -0
  57. data/csharp/Sorter.cs +76 -0
  58. data/csharp/Stem.cs +66 -0
  59. data/csharp/Stopper.cs +91 -0
  60. data/csharp/StringValueRangeProcessor.cs +53 -0
  61. data/csharp/TermGenerator.cs +152 -0
  62. data/csharp/TermIterator.cs +125 -0
  63. data/csharp/TradWeight.cs +107 -0
  64. data/csharp/ValueIterator.cs +102 -0
  65. data/csharp/ValueRangeProcessor.cs +76 -0
  66. data/csharp/Version.cs +60 -0
  67. data/csharp/Weight.cs +93 -0
  68. data/csharp/WritableDatabase.cs +153 -0
  69. data/csharp/Xapian.cs +65 -0
  70. data/csharp/XapianPINVOKE.cs +1527 -0
  71. data/csharp/docs/Makefile +450 -0
  72. data/csharp/docs/Makefile.am +16 -0
  73. data/csharp/docs/Makefile.in +450 -0
  74. data/csharp/docs/examples/SimpleExpand.cs +109 -0
  75. data/csharp/docs/examples/SimpleIndex.cs +71 -0
  76. data/csharp/docs/examples/SimpleSearch.cs +78 -0
  77. data/csharp/docs/index.html +211 -0
  78. data/csharp/util.i +233 -0
  79. data/csharp/xapian_wrap.cc +10338 -0
  80. data/csharp/xapian_wrap.h +93 -0
  81. data/depcomp +632 -0
  82. data/extconf.rb +20 -0
  83. data/generic/except.i +80 -0
  84. data/generic/generic.mk +48 -0
  85. data/install-sh +520 -0
  86. data/java-swig/.deps/xapian_wrap.Plo +1 -0
  87. data/java-swig/Auto.java +35 -0
  88. data/java-swig/BM25Weight.java +81 -0
  89. data/java-swig/BoolWeight.java +77 -0
  90. data/java-swig/Database.java +195 -0
  91. data/java-swig/DateValueRangeProcessor.java +51 -0
  92. data/java-swig/Document.java +135 -0
  93. data/java-swig/ESet.java +71 -0
  94. data/java-swig/ESetIterator.java +71 -0
  95. data/java-swig/Enquire.java +246 -0
  96. data/java-swig/ExpandDecider.java +59 -0
  97. data/java-swig/Flint.java +43 -0
  98. data/java-swig/InMemory.java +35 -0
  99. data/java-swig/MSet.java +143 -0
  100. data/java-swig/MSetIterator.java +87 -0
  101. data/java-swig/Makefile +781 -0
  102. data/java-swig/Makefile.am +132 -0
  103. data/java-swig/Makefile.in +781 -0
  104. data/java-swig/MatchDecider.java +59 -0
  105. data/java-swig/MultiValueSorter.java +51 -0
  106. data/java-swig/NumberValueRangeProcessor.java +51 -0
  107. data/java-swig/PositionIterator.java +63 -0
  108. data/java-swig/PostingIterator.java +83 -0
  109. data/java-swig/Quartz.java +43 -0
  110. data/java-swig/Query.java +189 -0
  111. data/java-swig/QueryParser.java +214 -0
  112. data/java-swig/RSet.java +79 -0
  113. data/java-swig/Remote.java +71 -0
  114. data/java-swig/SWIGTYPE_p_std__string.java +25 -0
  115. data/java-swig/SimpleStopper.java +51 -0
  116. data/java-swig/SmokeTest.java +161 -0
  117. data/java-swig/Sorter.java +59 -0
  118. data/java-swig/Stem.java +51 -0
  119. data/java-swig/Stopper.java +63 -0
  120. data/java-swig/StringValueRangeProcessor.java +43 -0
  121. data/java-swig/TermGenerator.java +158 -0
  122. data/java-swig/TermIterator.java +83 -0
  123. data/java-swig/TradWeight.java +81 -0
  124. data/java-swig/ValueIterator.java +67 -0
  125. data/java-swig/ValueRangeProcessor.java +59 -0
  126. data/java-swig/Version.java +47 -0
  127. data/java-swig/Weight.java +68 -0
  128. data/java-swig/WritableDatabase.java +123 -0
  129. data/java-swig/Xapian.java +39 -0
  130. data/java-swig/XapianConstants.java +15 -0
  131. data/java-swig/XapianJNI.java +508 -0
  132. data/java-swig/run-java-test +6 -0
  133. data/java-swig/xapian_wrap.cc +12594 -0
  134. data/java-swig/xapian_wrap.h +91 -0
  135. data/java/Makefile +660 -0
  136. data/java/Makefile.am +35 -0
  137. data/java/Makefile.in +660 -0
  138. data/java/README +76 -0
  139. data/java/SmokeTest.java +148 -0
  140. data/java/native/.deps/Database.Plo +1 -0
  141. data/java/native/.deps/Document.Plo +1 -0
  142. data/java/native/.deps/ESet.Plo +1 -0
  143. data/java/native/.deps/ESetIterator.Plo +1 -0
  144. data/java/native/.deps/Enquire.Plo +1 -0
  145. data/java/native/.deps/MSet.Plo +1 -0
  146. data/java/native/.deps/MSetIterator.Plo +1 -0
  147. data/java/native/.deps/PositionIterator.Plo +1 -0
  148. data/java/native/.deps/Query.Plo +1 -0
  149. data/java/native/.deps/RSet.Plo +1 -0
  150. data/java/native/.deps/Stem.Plo +1 -0
  151. data/java/native/.deps/TermIterator.Plo +1 -0
  152. data/java/native/.deps/WritableDatabase.Plo +1 -0
  153. data/java/native/.deps/org_xapian_XapianJNI.Plo +1 -0
  154. data/java/native/.deps/utils.Plo +1 -0
  155. data/java/native/Database.cc +222 -0
  156. data/java/native/Document.cc +173 -0
  157. data/java/native/ESet.cc +79 -0
  158. data/java/native/ESetIterator.cc +82 -0
  159. data/java/native/Enquire.cc +271 -0
  160. data/java/native/MSet.cc +169 -0
  161. data/java/native/MSetIterator.cc +107 -0
  162. data/java/native/Makefile +594 -0
  163. data/java/native/Makefile.am +51 -0
  164. data/java/native/Makefile.in +594 -0
  165. data/java/native/PositionIterator.cc +64 -0
  166. data/java/native/Query.cc +180 -0
  167. data/java/native/RSet.cc +98 -0
  168. data/java/native/Stem.cc +75 -0
  169. data/java/native/TermIterator.cc +107 -0
  170. data/java/native/WritableDatabase.cc +118 -0
  171. data/java/native/XapianObjectHolder.h +115 -0
  172. data/java/native/org_xapian_XapianJNI.cc +78 -0
  173. data/java/native/org_xapian_XapianJNI.h +1369 -0
  174. data/java/native/utils.cc +51 -0
  175. data/java/native/xapian_jni.h +116 -0
  176. data/java/org/xapian/Database.java +148 -0
  177. data/java/org/xapian/Document.java +135 -0
  178. data/java/org/xapian/ESet.java +66 -0
  179. data/java/org/xapian/ESetIterator.java +97 -0
  180. data/java/org/xapian/Enquire.java +136 -0
  181. data/java/org/xapian/ExpandDecider.java +30 -0
  182. data/java/org/xapian/MSet.java +104 -0
  183. data/java/org/xapian/MSetIterator.java +132 -0
  184. data/java/org/xapian/Makefile +580 -0
  185. data/java/org/xapian/Makefile.am +38 -0
  186. data/java/org/xapian/Makefile.in +580 -0
  187. data/java/org/xapian/MatchDecider.java +30 -0
  188. data/java/org/xapian/PositionIterator.java +89 -0
  189. data/java/org/xapian/Query.java +190 -0
  190. data/java/org/xapian/RSet.java +89 -0
  191. data/java/org/xapian/Stem.java +80 -0
  192. data/java/org/xapian/TermIterator.java +142 -0
  193. data/java/org/xapian/WritableDatabase.java +92 -0
  194. data/java/org/xapian/Xapian.java +114 -0
  195. data/java/org/xapian/XapianJNI.java +444 -0
  196. data/java/org/xapian/errors/AssertionError.java +40 -0
  197. data/java/org/xapian/errors/DatabaseCorruptError.java +40 -0
  198. data/java/org/xapian/errors/DatabaseError.java +40 -0
  199. data/java/org/xapian/errors/DatabaseLockError.java +40 -0
  200. data/java/org/xapian/errors/DatabaseModifiedError.java +40 -0
  201. data/java/org/xapian/errors/DatabaseOpeningError.java +40 -0
  202. data/java/org/xapian/errors/DocNotFoundError.java +40 -0
  203. data/java/org/xapian/errors/FeatureUnavailableError.java +40 -0
  204. data/java/org/xapian/errors/InternalError.java +40 -0
  205. data/java/org/xapian/errors/InvalidArgumentError.java +40 -0
  206. data/java/org/xapian/errors/InvalidOperationError.java +40 -0
  207. data/java/org/xapian/errors/LogicError.java +40 -0
  208. data/java/org/xapian/errors/Makefile +416 -0
  209. data/java/org/xapian/errors/Makefile.am +32 -0
  210. data/java/org/xapian/errors/Makefile.in +416 -0
  211. data/java/org/xapian/errors/NetworkError.java +40 -0
  212. data/java/org/xapian/errors/NetworkTimeoutError.java +40 -0
  213. data/java/org/xapian/errors/RangeError.java +40 -0
  214. data/java/org/xapian/errors/RuntimeError.java +40 -0
  215. data/java/org/xapian/errors/UnimplementedError.java +40 -0
  216. data/java/org/xapian/errors/XapianError.java +40 -0
  217. data/java/org/xapian/errors/XapianRuntimeError.java +49 -0
  218. data/java/org/xapian/examples/Makefile +391 -0
  219. data/java/org/xapian/examples/Makefile.am +8 -0
  220. data/java/org/xapian/examples/Makefile.in +391 -0
  221. data/java/org/xapian/examples/SimpleIndex.java +68 -0
  222. data/java/org/xapian/examples/SimpleSearch.java +71 -0
  223. data/java/run-java-test +6 -0
  224. data/libtool +7618 -0
  225. data/ltmain.sh +6956 -0
  226. data/mhs-xapian.gemspec +368 -0
  227. data/missing +378 -0
  228. data/php/.deps/xapian_wrap.Plo +1 -0
  229. data/php/Makefile +871 -0
  230. data/php/Makefile.am +82 -0
  231. data/php/Makefile.in +871 -0
  232. data/php/docs/Makefile +453 -0
  233. data/php/docs/Makefile.am +19 -0
  234. data/php/docs/Makefile.in +453 -0
  235. data/php/docs/examples/simpleexpand.php4 +108 -0
  236. data/php/docs/examples/simpleexpand.php5 +104 -0
  237. data/php/docs/examples/simpleindex.php4 +76 -0
  238. data/php/docs/examples/simpleindex.php5 +73 -0
  239. data/php/docs/examples/simplesearch.php4 +75 -0
  240. data/php/docs/examples/simplesearch.php5 +72 -0
  241. data/php/docs/index.html +313 -0
  242. data/php/except.i +98 -0
  243. data/php/php4/php_xapian.h +323 -0
  244. data/php/php4/xapian.php +32 -0
  245. data/php/php4/xapian_wrap.cc +27656 -0
  246. data/php/php5/php_xapian.h +319 -0
  247. data/php/php5/xapian.php +1566 -0
  248. data/php/php5/xapian_wrap.cc +24330 -0
  249. data/php/smoketest.php +246 -0
  250. data/php/smoketest4.php +84 -0
  251. data/php/smoketest5.php +79 -0
  252. data/php/util.i +187 -0
  253. data/python/.deps/xapian_wrap.Plo +1 -0
  254. data/python/Makefile +891 -0
  255. data/python/Makefile.am +105 -0
  256. data/python/Makefile.in +891 -0
  257. data/python/doccomments.i +5134 -0
  258. data/python/docs/Makefile +448 -0
  259. data/python/docs/Makefile.am +14 -0
  260. data/python/docs/Makefile.in +448 -0
  261. data/python/docs/examples/simpleexpand.py +98 -0
  262. data/python/docs/examples/simpleindex.py +65 -0
  263. data/python/docs/examples/simplematchdecider.py +78 -0
  264. data/python/docs/examples/simplesearch.py +65 -0
  265. data/python/docs/index.html +420 -0
  266. data/python/except.i +290 -0
  267. data/python/extra.i +1048 -0
  268. data/python/extracomments.i +28 -0
  269. data/python/generate-python-exceptions +189 -0
  270. data/python/generate-python-exceptions.in +189 -0
  271. data/python/modern/xapian.py +5662 -0
  272. data/python/modern/xapian_wrap.cc +35170 -0
  273. data/python/modern/xapian_wrap.h +244 -0
  274. data/python/pythontest.py +1110 -0
  275. data/python/smoketest.py +328 -0
  276. data/python/testsuite.py +382 -0
  277. data/python/util.i +517 -0
  278. data/ruby/.deps/xapian_wrap.Plo +494 -0
  279. data/ruby/.libs/_xapian.bundle +0 -0
  280. data/ruby/.libs/_xapian.bundle.dSYM/Contents/Info.plist +25 -0
  281. data/ruby/.libs/_xapian.bundle.dSYM/Contents/Resources/DWARF/_xapian.bundle +0 -0
  282. data/ruby/.libs/_xapian.la +35 -0
  283. data/ruby/.libs/_xapian.lai +35 -0
  284. data/ruby/Makefile +854 -0
  285. data/ruby/Makefile.am +62 -0
  286. data/ruby/Makefile.in +854 -0
  287. data/ruby/_xapian.la +35 -0
  288. data/ruby/docs/Makefile +487 -0
  289. data/ruby/docs/Makefile.am +50 -0
  290. data/ruby/docs/Makefile.in +487 -0
  291. data/ruby/docs/examples/simpleexpand.rb +98 -0
  292. data/ruby/docs/examples/simpleindex.rb +60 -0
  293. data/ruby/docs/examples/simplematchdecider.rb +74 -0
  294. data/ruby/docs/examples/simplesearch.rb +63 -0
  295. data/ruby/docs/index.html +197 -0
  296. data/ruby/smoketest.rb +211 -0
  297. data/ruby/util.i +232 -0
  298. data/ruby/xapian.rb +280 -0
  299. data/ruby/xapian_wrap.cc +25837 -0
  300. data/ruby/xapian_wrap.h +65 -0
  301. data/ruby/xapian_wrap.lo +12 -0
  302. data/skiptest +2 -0
  303. data/stamp-h1 +1 -0
  304. data/tcl8/.deps/xapian_wrap.Plo +1 -0
  305. data/tcl8/Makefile +835 -0
  306. data/tcl8/Makefile.am +49 -0
  307. data/tcl8/Makefile.in +835 -0
  308. data/tcl8/docs/Makefile +448 -0
  309. data/tcl8/docs/Makefile.am +14 -0
  310. data/tcl8/docs/Makefile.in +448 -0
  311. data/tcl8/docs/examples/simpleexpand.tcl +104 -0
  312. data/tcl8/docs/examples/simpleindex.tcl +68 -0
  313. data/tcl8/docs/examples/simplesearch.tcl +66 -0
  314. data/tcl8/docs/index.html +208 -0
  315. data/tcl8/except.i +48 -0
  316. data/tcl8/pkgIndex.tcl +1 -0
  317. data/tcl8/pkgIndex.tcl.in +1 -0
  318. data/tcl8/run-tcl-test +15 -0
  319. data/tcl8/runtest.tcl +29 -0
  320. data/tcl8/smoketest.tcl +155 -0
  321. data/tcl8/util.i +76 -0
  322. data/tcl8/xapian_wrap.cc +20900 -0
  323. data/xapian-bindings.spec +206 -0
  324. data/xapian-bindings.spec.in +206 -0
  325. data/xapian-version.h +1 -0
  326. data/xapian-version.h.in +1 -0
  327. data/xapian.i +939 -0
  328. metadata +395 -0
@@ -0,0 +1,244 @@
1
+ /* ----------------------------------------------------------------------------
2
+ * This file was automatically generated by SWIG (http://www.swig.org).
3
+ * Version 1.3.32
4
+ *
5
+ * This file is not intended to be easily readable and contains a number of
6
+ * coding conventions designed to improve portability and efficiency. Do not make
7
+ * changes to this file unless you know what you are doing--modify the SWIG
8
+ * interface file instead.
9
+ * ----------------------------------------------------------------------------- */
10
+
11
+ #ifndef SWIG_xapian_WRAP_H_
12
+ #define SWIG_xapian_WRAP_H_
13
+
14
+ #include <map>
15
+ #include <string>
16
+
17
+
18
+ class SwigDirector_MatchDecider : public Xapian::MatchDecider, public Swig::Director {
19
+
20
+ public:
21
+ SwigDirector_MatchDecider(PyObject *self);
22
+ virtual bool operator ()(Xapian::Document const &doc) const;
23
+ virtual ~SwigDirector_MatchDecider();
24
+
25
+
26
+ /* Internal Director utilities */
27
+ public:
28
+ bool swig_get_inner(const char* name) const {
29
+ std::map<std::string, bool>::const_iterator iv = inner.find(name);
30
+ return (iv != inner.end() ? iv->second : false);
31
+ }
32
+
33
+ void swig_set_inner(const char* name, bool val) const
34
+ { inner[name] = val;}
35
+
36
+ private:
37
+ mutable std::map<std::string, bool> inner;
38
+
39
+
40
+ #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
41
+ /* VTable implementation */
42
+ PyObject *swig_get_method(size_t method_index, const char *method_name) const {
43
+ PyObject *method = vtable[method_index];
44
+ if (!method) {
45
+ swig::PyObject_var name = PyString_FromString(method_name);
46
+ method = PyObject_GetAttr(swig_get_self(), name);
47
+ if (method == NULL) {
48
+ std::string msg = "Method in class MatchDecider doesn't exist, undefined ";
49
+ msg += method_name;
50
+ Swig::DirectorMethodException::raise(msg.c_str());
51
+ }
52
+ vtable[method_index] = method;
53
+ };
54
+ return method;
55
+ }
56
+ private:
57
+ mutable swig::PyObject_var vtable[1];
58
+ #endif
59
+
60
+ };
61
+
62
+
63
+ class SwigDirector_ExpandDecider : public Xapian::ExpandDecider, public Swig::Director {
64
+
65
+ public:
66
+ SwigDirector_ExpandDecider(PyObject *self);
67
+ virtual bool operator ()(std::string const &term) const;
68
+ virtual ~SwigDirector_ExpandDecider();
69
+
70
+
71
+ /* Internal Director utilities */
72
+ public:
73
+ bool swig_get_inner(const char* name) const {
74
+ std::map<std::string, bool>::const_iterator iv = inner.find(name);
75
+ return (iv != inner.end() ? iv->second : false);
76
+ }
77
+
78
+ void swig_set_inner(const char* name, bool val) const
79
+ { inner[name] = val;}
80
+
81
+ private:
82
+ mutable std::map<std::string, bool> inner;
83
+
84
+
85
+ #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
86
+ /* VTable implementation */
87
+ PyObject *swig_get_method(size_t method_index, const char *method_name) const {
88
+ PyObject *method = vtable[method_index];
89
+ if (!method) {
90
+ swig::PyObject_var name = PyString_FromString(method_name);
91
+ method = PyObject_GetAttr(swig_get_self(), name);
92
+ if (method == NULL) {
93
+ std::string msg = "Method in class ExpandDecider doesn't exist, undefined ";
94
+ msg += method_name;
95
+ Swig::DirectorMethodException::raise(msg.c_str());
96
+ }
97
+ vtable[method_index] = method;
98
+ };
99
+ return method;
100
+ }
101
+ private:
102
+ mutable swig::PyObject_var vtable[1];
103
+ #endif
104
+
105
+ };
106
+
107
+
108
+ class SwigDirector_Stopper : public Xapian::Stopper, public Swig::Director {
109
+
110
+ public:
111
+ SwigDirector_Stopper(PyObject *self);
112
+ virtual bool operator ()(std::string const &term) const;
113
+ virtual ~SwigDirector_Stopper();
114
+ virtual std::string get_description() const;
115
+
116
+
117
+ /* Internal Director utilities */
118
+ public:
119
+ bool swig_get_inner(const char* name) const {
120
+ std::map<std::string, bool>::const_iterator iv = inner.find(name);
121
+ return (iv != inner.end() ? iv->second : false);
122
+ }
123
+
124
+ void swig_set_inner(const char* name, bool val) const
125
+ { inner[name] = val;}
126
+
127
+ private:
128
+ mutable std::map<std::string, bool> inner;
129
+
130
+
131
+ #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
132
+ /* VTable implementation */
133
+ PyObject *swig_get_method(size_t method_index, const char *method_name) const {
134
+ PyObject *method = vtable[method_index];
135
+ if (!method) {
136
+ swig::PyObject_var name = PyString_FromString(method_name);
137
+ method = PyObject_GetAttr(swig_get_self(), name);
138
+ if (method == NULL) {
139
+ std::string msg = "Method in class Stopper doesn't exist, undefined ";
140
+ msg += method_name;
141
+ Swig::DirectorMethodException::raise(msg.c_str());
142
+ }
143
+ vtable[method_index] = method;
144
+ };
145
+ return method;
146
+ }
147
+ private:
148
+ mutable swig::PyObject_var vtable[2];
149
+ #endif
150
+
151
+ };
152
+
153
+
154
+ struct SwigDirector_ValueRangeProcessor : public Xapian::ValueRangeProcessor, public Swig::Director {
155
+
156
+ public:
157
+ SwigDirector_ValueRangeProcessor(PyObject *self);
158
+ virtual ~SwigDirector_ValueRangeProcessor();
159
+ virtual Xapian::valueno operator ()(std::string &begin, std::string &end);
160
+
161
+
162
+ /* Internal Director utilities */
163
+ public:
164
+ bool swig_get_inner(const char* name) const {
165
+ std::map<std::string, bool>::const_iterator iv = inner.find(name);
166
+ return (iv != inner.end() ? iv->second : false);
167
+ }
168
+
169
+ void swig_set_inner(const char* name, bool val) const
170
+ { inner[name] = val;}
171
+
172
+ private:
173
+ mutable std::map<std::string, bool> inner;
174
+
175
+
176
+ #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
177
+ /* VTable implementation */
178
+ PyObject *swig_get_method(size_t method_index, const char *method_name) const {
179
+ PyObject *method = vtable[method_index];
180
+ if (!method) {
181
+ swig::PyObject_var name = PyString_FromString(method_name);
182
+ method = PyObject_GetAttr(swig_get_self(), name);
183
+ if (method == NULL) {
184
+ std::string msg = "Method in class ValueRangeProcessor doesn't exist, undefined ";
185
+ msg += method_name;
186
+ Swig::DirectorMethodException::raise(msg.c_str());
187
+ }
188
+ vtable[method_index] = method;
189
+ };
190
+ return method;
191
+ }
192
+ private:
193
+ mutable swig::PyObject_var vtable[1];
194
+ #endif
195
+
196
+ };
197
+
198
+
199
+ class SwigDirector_Sorter : public Xapian::Sorter, public Swig::Director {
200
+
201
+ public:
202
+ SwigDirector_Sorter(PyObject *self);
203
+ virtual std::string operator ()(Xapian::Document const &doc) const;
204
+ virtual ~SwigDirector_Sorter();
205
+
206
+
207
+ /* Internal Director utilities */
208
+ public:
209
+ bool swig_get_inner(const char* name) const {
210
+ std::map<std::string, bool>::const_iterator iv = inner.find(name);
211
+ return (iv != inner.end() ? iv->second : false);
212
+ }
213
+
214
+ void swig_set_inner(const char* name, bool val) const
215
+ { inner[name] = val;}
216
+
217
+ private:
218
+ mutable std::map<std::string, bool> inner;
219
+
220
+
221
+ #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
222
+ /* VTable implementation */
223
+ PyObject *swig_get_method(size_t method_index, const char *method_name) const {
224
+ PyObject *method = vtable[method_index];
225
+ if (!method) {
226
+ swig::PyObject_var name = PyString_FromString(method_name);
227
+ method = PyObject_GetAttr(swig_get_self(), name);
228
+ if (method == NULL) {
229
+ std::string msg = "Method in class Sorter doesn't exist, undefined ";
230
+ msg += method_name;
231
+ Swig::DirectorMethodException::raise(msg.c_str());
232
+ }
233
+ vtable[method_index] = method;
234
+ };
235
+ return method;
236
+ }
237
+ private:
238
+ mutable swig::PyObject_var vtable[1];
239
+ #endif
240
+
241
+ };
242
+
243
+
244
+ #endif
@@ -0,0 +1,1110 @@
1
+ # Tests of Python-specific parts of the xapian bindings.
2
+ #
3
+ # Copyright (C) 2007 Lemur Consulting Ltd
4
+ # Copyright (C) 2009 Olly Betts
5
+ #
6
+ # This program is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU General Public License as
8
+ # published by the Free Software Foundation; either version 2 of the
9
+ # License, or (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
+ # USA
20
+
21
+ import sys
22
+ import xapian
23
+ import shutil
24
+
25
+ from testsuite import *
26
+
27
+ def setup_database():
28
+ """Set up and return an inmemory database with 5 documents.
29
+
30
+ """
31
+ db = xapian.inmemory_open()
32
+
33
+ doc = xapian.Document()
34
+ doc.set_data("is it cold?")
35
+ doc.add_term("is")
36
+ doc.add_posting("it", 1)
37
+ doc.add_posting("cold", 2)
38
+ db.add_document(doc)
39
+
40
+ doc = xapian.Document()
41
+ doc.set_data("was it warm?")
42
+ doc.add_posting("was", 1)
43
+ doc.add_posting("it", 2)
44
+ doc.add_posting("warm", 3)
45
+ db.add_document(doc)
46
+ doc.set_data("was it warm? two")
47
+ doc.add_term("two", 2)
48
+ db.add_document(doc)
49
+ doc.set_data("was it warm? three")
50
+ doc.add_term("three", 3)
51
+ db.add_document(doc)
52
+ doc.set_data("was it warm? four it")
53
+ doc.add_term("four", 4)
54
+ doc.add_term("it", 6)
55
+ doc.add_posting("it", 7)
56
+ doc.add_value(5, 'five')
57
+ doc.add_value(9, 'nine')
58
+ doc.add_value(0, 'zero')
59
+ db.add_document(doc)
60
+
61
+ expect(db.get_doccount(), 5)
62
+ return db
63
+
64
+ def test_exception_base():
65
+ """Check that xapian exceptions have Exception as a base class.
66
+
67
+ """
68
+ try:
69
+ raise xapian.InvalidOperationError("Test exception")
70
+ except Exception, e:
71
+ pass
72
+
73
+ def test_mset_iter():
74
+ """Test iterators over MSets.
75
+
76
+ """
77
+ db = setup_database()
78
+ query = xapian.Query(xapian.Query.OP_OR, "was", "it")
79
+
80
+ enquire = xapian.Enquire(db)
81
+ enquire.set_query(query)
82
+ mset = enquire.get_mset(0, 10)
83
+ items = [item for item in mset]
84
+ expect(len(items), 5)
85
+ expect(len(mset), len(items), "Expected number of items to be length of mset")
86
+
87
+ context("testing returned item from mset")
88
+ expect(items[2].docid, 4)
89
+ expect(items[2].rank, 2)
90
+ expect(items[2].percent, 86)
91
+ expect(items[2].collapse_key, '')
92
+ expect(items[2].collapse_count, 0)
93
+ expect(items[2].document.get_data(), 'was it warm? three')
94
+
95
+ if test_legacy_sequence_api:
96
+ context("testing deprecated sequence API")
97
+ expect(len(items[2][:]), 5)
98
+ expect(items[2][0], 4)
99
+ expect(items[2][2], 2)
100
+ expect(items[2][3], 86)
101
+
102
+ # Check iterators for sub-msets against the whole mset.
103
+ for start in xrange(0, 6):
104
+ for maxitems in xrange(0, 6):
105
+ context("checking iterators for sub-mset from %d, maxitems %d" % (start, maxitems))
106
+ submset = enquire.get_mset(start, maxitems)
107
+ num = 0
108
+ for item in submset:
109
+ context("testing hit %d for sub-mset from %d, maxitems %d" % (num, start, maxitems))
110
+ expect(item.rank, num + start)
111
+
112
+ context("comparing iterator item %d for sub-mset from %d, maxitems %d against hit" % (num, start, maxitems))
113
+ hit = submset.get_hit(num)
114
+ expect(hit.docid, item.docid)
115
+ expect(hit.rank, item.rank)
116
+ expect(hit.percent, item.percent)
117
+ expect(hit.document.get_data(), item.document.get_data())
118
+ expect(hit.collapse_key, item.collapse_key)
119
+ expect(hit.collapse_count, item.collapse_count)
120
+
121
+ context("comparing iterator item %d for sub-mset from %d, maxitems %d against hit from whole mset" % (num, start, maxitems))
122
+ hit = mset.get_hit(num + start)
123
+ expect(hit.docid, item.docid)
124
+ expect(hit.rank, item.rank)
125
+ expect(hit.percent, item.percent)
126
+ expect(hit.document.get_data(), item.document.get_data())
127
+ expect(hit.collapse_key, item.collapse_key)
128
+ expect(hit.collapse_count, item.collapse_count)
129
+
130
+ context("comparing iterator item %d for sub-mset from %d, maxitems %d against direct access with []" % (num, start, maxitems))
131
+ expect(submset[num].docid, item.docid)
132
+ expect(submset[num].rank, item.rank)
133
+ expect(submset[num].percent, item.percent)
134
+ expect(submset[num].document.get_data(), item.document.get_data())
135
+ expect(submset[num].collapse_key, item.collapse_key)
136
+ expect(submset[num].collapse_count, item.collapse_count)
137
+
138
+ num += 1
139
+
140
+ context("Checking out of range access to mset, for sub-mset from %d, maxitems %d" % (start, maxitems))
141
+ # Test out-of-range access to mset:
142
+ expect_exception(IndexError, 'Mset index out of range',
143
+ submset.__getitem__, -10)
144
+ expect_exception(IndexError, 'Mset index out of range',
145
+ submset.__getitem__, 10)
146
+ expect_exception(IndexError, 'Mset index out of range',
147
+ submset.__getitem__, -1-len(submset))
148
+ expect_exception(IndexError, 'Mset index out of range',
149
+ submset.__getitem__, len(submset))
150
+
151
+ # Check that the item contents remain valid when the iterator has
152
+ # moved on.
153
+ saved_items = [item for item in submset]
154
+ for num in xrange(len(saved_items)):
155
+ item = saved_items[num]
156
+ context("comparing iterator item %d for sub-mset mset from %d, maxitems %d against saved item" % (num, start, maxitems))
157
+ expect(submset[num].docid, item.docid)
158
+ expect(submset[num].rank, item.rank)
159
+ expect(submset[num].percent, item.percent)
160
+ expect(submset[num].document.get_data(), item.document.get_data())
161
+ expect(submset[num].collapse_key, item.collapse_key)
162
+ expect(submset[num].collapse_count, item.collapse_count)
163
+
164
+ if test_legacy_sequence_api:
165
+ # Test deprecated sequence API.
166
+ num = 0
167
+ for item in submset:
168
+ context("testing hit %d with deprecated APIs for sub-mset from %d, maxitems %d" % (num, start, maxitems))
169
+ hit = submset.get_hit(num)
170
+ expect(len(item[:]), 5)
171
+ expect(item[0], hit.get_docid())
172
+ expect(item[1], hit.get_weight())
173
+ expect(item[2], hit.get_rank())
174
+ expect(item[3], hit.get_percent())
175
+ expect(item[4].get_data(), hit.get_document().get_data())
176
+ num += 1
177
+
178
+ # Check that the right number of items exist in the mset.
179
+ context("checking length of sub-mset from %d, maxitems %d" % (start, maxitems))
180
+ items = [item for item in submset]
181
+ expect(len(items), min(maxitems, 5 - start))
182
+ expect(len(submset), min(maxitems, 5 - start))
183
+
184
+ def test_eset_iter():
185
+ """Test iterators over ESets.
186
+
187
+ """
188
+ db = setup_database()
189
+ query = xapian.Query(xapian.Query.OP_OR, "was", "it")
190
+ rset = xapian.RSet()
191
+ rset.add_document(3)
192
+
193
+ context("getting eset items without a query")
194
+ enquire = xapian.Enquire(db)
195
+ eset = enquire.get_eset(10, rset)
196
+ items = [item for item in eset]
197
+ expect(len(items), 4)
198
+ expect(len(items), len(eset))
199
+
200
+ context("getting eset items with a query")
201
+ enquire = xapian.Enquire(db)
202
+ enquire.set_query(query)
203
+ eset = enquire.get_eset(10, rset)
204
+ items2 = [item for item in eset]
205
+ expect(len(items2), 2)
206
+ expect(len(items2), len(eset))
207
+
208
+ context("comparing eset items with a query to those without")
209
+ expect(items2[0].term, items[0].term)
210
+ expect(items2[1].term, items[2].term)
211
+
212
+ context("comparing eset weights with a query to those without")
213
+ expect(items2[0].weight, items[0].weight)
214
+ expect(items2[1].weight, items[2].weight)
215
+
216
+ if test_legacy_sequence_api:
217
+ context("checking legacy sequence API for eset items")
218
+ expect(items2[0][0], items[0].term)
219
+ expect(items2[1][0], items[2].term)
220
+ expect(items2[0][1], items[0].weight)
221
+ expect(items2[1][1], items[2].weight)
222
+ expect(items2[0][:], [items[0].term, items[0].weight])
223
+ expect(items2[1][:], [items[2].term, items[2].weight])
224
+
225
+ def test_matchingterms_iter():
226
+ """Test Enquire.matching_terms iterator.
227
+
228
+ """
229
+ db = setup_database()
230
+ query = xapian.Query(xapian.Query.OP_OR, ("was", "it", "warm", "two"))
231
+
232
+ enquire = xapian.Enquire(db)
233
+ enquire.set_query(query)
234
+ mset = enquire.get_mset(0, 10)
235
+ for item in mset:
236
+
237
+ # Make a list of the term names
238
+ mterms = []
239
+ for term in enquire.matching_terms(item.docid):
240
+ mterms.append(term)
241
+
242
+ mterms2 = []
243
+ for term in enquire.matching_terms(item):
244
+ mterms2.append(term)
245
+ expect(mterms, mterms2)
246
+
247
+ mterms = []
248
+ for term in enquire.matching_terms(mset.get_hit(0)):
249
+ mterms.append(term)
250
+ expect(mterms, ['it', 'two', 'warm', 'was'])
251
+
252
+ def test_queryterms_iter():
253
+ """Test Query term iterator.
254
+
255
+ """
256
+ db = setup_database()
257
+ query = xapian.Query(xapian.Query.OP_OR, ("was", "it", "warm", "two"))
258
+
259
+ # Make a list of the term names
260
+ terms = []
261
+ for term in query:
262
+ terms.append(term)
263
+ expect(terms, ['it', 'two', 'warm', 'was'])
264
+
265
+ def test_queryparser_stoplist_iter():
266
+ """Test QueryParser stoplist iterator.
267
+
268
+ """
269
+ stemmer = xapian.Stem('en')
270
+
271
+ # Check behaviour without having set a stoplist.
272
+ queryparser = xapian.QueryParser()
273
+ queryparser.set_stemmer(stemmer)
274
+ queryparser.set_stemming_strategy(queryparser.STEM_SOME)
275
+ expect([term for term in queryparser.stoplist()], [])
276
+ query = queryparser.parse_query('to be or not to be is the questions')
277
+ expect([term for term in queryparser.stoplist()], [])
278
+ expect(str(query),
279
+ 'Xapian::Query((Zto:(pos=1) OR Zbe:(pos=2) OR Zor:(pos=3) OR '
280
+ 'Znot:(pos=4) OR Zto:(pos=5) OR Zbe:(pos=6) OR Zis:(pos=7) OR '
281
+ 'Zthe:(pos=8) OR Zquestion:(pos=9)))')
282
+
283
+ # Check behaviour with a stoplist, but no stemmer
284
+ queryparser = xapian.QueryParser()
285
+ stopper = xapian.SimpleStopper()
286
+ stopper.add('to')
287
+ stopper.add('not')
288
+ stopper.add('question')
289
+ queryparser.set_stopper(stopper)
290
+ expect([term for term in queryparser.stoplist()], [])
291
+ query = queryparser.parse_query('to be or not to be is the questions')
292
+
293
+ expect([term for term in queryparser.stoplist()], ['to', 'not', 'to'])
294
+ expect(str(query),
295
+ 'Xapian::Query((be:(pos=2) OR or:(pos=3) OR '
296
+ 'be:(pos=6) OR is:(pos=7) OR '
297
+ 'the:(pos=8) OR questions:(pos=9)))')
298
+
299
+ # Check behaviour with a stoplist and a stemmer
300
+ queryparser.set_stemmer(stemmer)
301
+ queryparser.set_stemming_strategy(queryparser.STEM_SOME)
302
+ expect([term for term in queryparser.stoplist()], ['to', 'not', 'to']) # Shouldn't have changed since previous query.
303
+ query = queryparser.parse_query('to be or not to be is the questions')
304
+
305
+ expect([term for term in queryparser.stoplist()], ['to', 'not', 'to'])
306
+ expect(str(query),
307
+ 'Xapian::Query((Zbe:(pos=2) OR Zor:(pos=3) OR '
308
+ 'Zbe:(pos=6) OR Zis:(pos=7) OR '
309
+ 'Zthe:(pos=8) OR Zquestion:(pos=9)))')
310
+
311
+ def test_queryparser_unstem_iter():
312
+ """Test QueryParser unstemlist iterator.
313
+
314
+ """
315
+ stemmer = xapian.Stem('en')
316
+
317
+ queryparser = xapian.QueryParser()
318
+ expect([term for term in queryparser.unstemlist('to')], [])
319
+ expect([term for term in queryparser.unstemlist('question')], [])
320
+ expect([term for term in queryparser.unstemlist('questions')], [])
321
+ query = queryparser.parse_query('to question questions')
322
+
323
+ expect([term for term in queryparser.unstemlist('to')], ['to'])
324
+ expect([term for term in queryparser.unstemlist('question')], ['question'])
325
+ expect([term for term in queryparser.unstemlist('questions')], ['questions'])
326
+ expect(str(query),
327
+ 'Xapian::Query((to:(pos=1) OR question:(pos=2) OR questions:(pos=3)))')
328
+
329
+
330
+ queryparser = xapian.QueryParser()
331
+ queryparser.set_stemmer(stemmer)
332
+ queryparser.set_stemming_strategy(queryparser.STEM_SOME)
333
+ expect([term for term in queryparser.unstemlist('Zto')], [])
334
+ expect([term for term in queryparser.unstemlist('Zquestion')], [])
335
+ expect([term for term in queryparser.unstemlist('Zquestions')], [])
336
+ query = queryparser.parse_query('to question questions')
337
+
338
+ expect([term for term in queryparser.unstemlist('Zto')], ['to'])
339
+ expect([term for term in queryparser.unstemlist('Zquestion')], ['question', 'questions'])
340
+ expect([term for term in queryparser.unstemlist('Zquestions')], [])
341
+ expect(str(query),
342
+ 'Xapian::Query((Zto:(pos=1) OR Zquestion:(pos=2) OR Zquestion:(pos=3)))')
343
+
344
+ def test_allterms_iter():
345
+ """Test all-terms iterator on Database.
346
+
347
+ """
348
+ db = setup_database()
349
+
350
+ context("making a list of the term names and frequencies")
351
+ terms = []
352
+ freqs = []
353
+ for termitem in db:
354
+ terms.append(termitem.term)
355
+ expect_exception(xapian.InvalidOperationError, 'Iterator does not support wdfs', getattr, termitem, 'wdf')
356
+ freqs.append(termitem.termfreq)
357
+ expect_exception(xapian.InvalidOperationError, 'Iterator does not support position lists', getattr, termitem, 'positer')
358
+
359
+ if test_legacy_sequence_api:
360
+ context("checking legacy sequence API for all terms iterator items")
361
+ i = 0
362
+ for termitem in db:
363
+ termitem = termitem[:]
364
+ expect(termitem[0], terms[i])
365
+ expect(termitem[1], 0)
366
+ expect(termitem[2], freqs[i])
367
+ expect([pos for pos in termitem[3]], [])
368
+ i += 1
369
+
370
+ context("checking that items are no longer valid once the iterator has moved on");
371
+ termitems = []
372
+ for termitem in db:
373
+ termitems.append(termitem)
374
+
375
+ expect(len(termitems), len(terms))
376
+ for i in xrange(len(termitems)):
377
+ expect(termitems[i].term, terms[i])
378
+
379
+ expect(len(termitems), len(freqs))
380
+ for i in xrange(len(termitems)):
381
+ expect_exception(xapian.InvalidOperationError, 'Iterator has moved, and does not support random access', getattr, termitem, 'termfreq')
382
+
383
+ context("checking that restricting the terms iterated with a prefix works")
384
+ prefix_terms = []
385
+ prefix_freqs = []
386
+ for i in xrange(len(terms)):
387
+ if terms[i][0] == 't':
388
+ prefix_terms.append(terms[i])
389
+ prefix_freqs.append(freqs[i])
390
+ i = 0
391
+ for termitem in db.allterms('t'):
392
+ expect(termitem.term, prefix_terms[i])
393
+ expect(termitem.termfreq, prefix_freqs[i])
394
+ i += 1
395
+ expect(len(prefix_terms), i)
396
+
397
+ def test_termlist_iter():
398
+ """Test termlist iterator on Database.
399
+
400
+ """
401
+ db = setup_database()
402
+
403
+ # Make lists of the item contents
404
+ terms = []
405
+ wdfs = []
406
+ freqs = []
407
+ positers = []
408
+ for termitem in db.termlist(3):
409
+ terms.append(termitem.term)
410
+ wdfs.append(termitem.wdf)
411
+ freqs.append(termitem.termfreq)
412
+ positers.append([pos for pos in termitem.positer])
413
+
414
+ expect(terms, ['it', 'two', 'warm', 'was'])
415
+ expect(wdfs, [1, 2, 1, 1])
416
+ expect(freqs, [5, 3, 4, 4])
417
+ expect(positers, [[2], [], [3], [1]])
418
+
419
+ if test_legacy_sequence_api:
420
+ # Test legacy sequence API.
421
+ i = 0
422
+ for termitem in db.termlist(3):
423
+ termitem = termitem[:]
424
+ expect(termitem[0], terms[i])
425
+ expect(termitem[1], wdfs[i])
426
+ expect(termitem[2], freqs[i])
427
+ expect([pos for pos in termitem[3]], positers[i])
428
+ i += 1
429
+
430
+ # Test skip_to().
431
+ tliter = db.termlist(3)
432
+
433
+ # skip to an item before the first item.
434
+ termitem = tliter.skip_to('a')
435
+ expect((termitem.term, termitem.wdf, termitem.termfreq,
436
+ [pos for pos in termitem.positer]), ('it', 1, 5, [2]))
437
+
438
+ # skip forwards to an item.
439
+ termitem = tliter.skip_to('two')
440
+ expect((termitem.term, termitem.wdf, termitem.termfreq,
441
+ [pos for pos in termitem.positer]), ('two', 2, 3, []))
442
+
443
+ # skip to same place (should return same item)
444
+ termitem = tliter.skip_to('two')
445
+ expect((termitem.term, termitem.wdf, termitem.termfreq,
446
+ [pos for pos in termitem.positer]), ('two', 2, 3, []))
447
+
448
+ # next() after a skip_to(), should return next item.
449
+ termitem = tliter.next()
450
+ expect((termitem.term, termitem.wdf, termitem.termfreq,
451
+ [pos for pos in termitem.positer]), ('warm', 1, 4, [3]))
452
+
453
+ # skip to same place (should return same item)
454
+ termitem = tliter.skip_to('warm')
455
+ expect((termitem.term, termitem.wdf, termitem.termfreq,
456
+ [pos for pos in termitem.positer]), ('warm', 1, 4, [3]))
457
+
458
+ # skip backwards (should return same item)
459
+ termitem = tliter.skip_to('a')
460
+
461
+ # skip to after end.
462
+ expect_exception(StopIteration, '', tliter.skip_to, 'zoo')
463
+ # skip backwards (should still return StopIteration).
464
+ expect_exception(StopIteration, '', tliter.skip_to, 'a')
465
+ # next should continue to return StopIteration.
466
+ expect_exception(StopIteration, '', tliter.next)
467
+
468
+
469
+ # Make a list of the terms (so we can test if they're still valid
470
+ # once the iterator has moved on).
471
+ termitems = []
472
+ for termitem in db.termlist(3):
473
+ termitems.append(termitem)
474
+
475
+ expect(len(termitems), len(terms))
476
+ for i in xrange(len(termitems)):
477
+ expect(termitems[i].term, terms[i])
478
+
479
+ expect(len(termitems), len(wdfs))
480
+ for i in xrange(len(termitems)):
481
+ expect(termitems[i].wdf, wdfs[i])
482
+
483
+ expect(len(termitems), len(freqs))
484
+ for i in xrange(len(termitems)):
485
+ expect_exception(xapian.InvalidOperationError,
486
+ 'Iterator has moved, and does not support random access',
487
+ getattr, termitem, 'termfreq')
488
+
489
+ expect(len(termitems), len(freqs))
490
+ for i in xrange(len(termitems)):
491
+ expect_exception(xapian.InvalidOperationError,
492
+ 'Iterator has moved, and does not support random access',
493
+ getattr, termitem, 'positer')
494
+
495
+ def test_dbdocument_iter():
496
+ """Test document terms iterator for document taken from a database.
497
+
498
+ """
499
+ db = setup_database()
500
+
501
+ doc = db.get_document(3)
502
+
503
+ # Make lists of the item contents
504
+ terms = []
505
+ wdfs = []
506
+ freqs = []
507
+ positers = []
508
+ for termitem in doc:
509
+ terms.append(termitem.term)
510
+ wdfs.append(termitem.wdf)
511
+ freqs.append(termitem.termfreq)
512
+ positers.append([pos for pos in termitem.positer])
513
+
514
+ expect(terms, ['it', 'two', 'warm', 'was'])
515
+ expect(wdfs, [1, 2, 1, 1])
516
+ expect(freqs, [5, 3, 4, 4])
517
+ expect(positers, [[2], [], [3], [1]])
518
+
519
+ if test_legacy_sequence_api:
520
+ # Test legacy sequence API.
521
+ i = 0
522
+ for termitem in doc:
523
+ termitem = termitem[:]
524
+ expect(termitem[0], terms[i])
525
+ expect(termitem[1], wdfs[i])
526
+ expect(termitem[2], freqs[i])
527
+ expect([pos for pos in termitem[3]], positers[i])
528
+ i += 1
529
+
530
+ # Make a list of the terms (so we can test if they're still valid
531
+ # once the iterator has moved on).
532
+ termitems = []
533
+ for termitem in doc:
534
+ termitems.append(termitem)
535
+
536
+ expect(len(termitems), len(terms))
537
+ for i in xrange(len(termitems)):
538
+ expect(termitems[i].term, terms[i])
539
+
540
+ expect(len(termitems), len(wdfs))
541
+ for i in xrange(len(termitems)):
542
+ expect(termitems[i].wdf, wdfs[i])
543
+
544
+ expect(len(termitems), len(freqs))
545
+ for i in xrange(len(termitems)):
546
+ expect_exception(xapian.InvalidOperationError,
547
+ 'Iterator has moved, and does not support random access',
548
+ getattr, termitem, 'termfreq')
549
+
550
+ expect(len(termitems), len(freqs))
551
+ for i in xrange(len(termitems)):
552
+ expect_exception(xapian.InvalidOperationError,
553
+ 'Iterator has moved, and does not support random access',
554
+ getattr, termitem, 'positer')
555
+
556
+ def test_newdocument_iter():
557
+ """Test document terms iterator for newly created document.
558
+
559
+ """
560
+ doc = xapian.Document()
561
+ doc.set_data("was it warm? two")
562
+ doc.add_posting("was", 1)
563
+ doc.add_posting("it", 2)
564
+ doc.add_posting("warm", 3)
565
+ doc.add_term("two", 2)
566
+
567
+ # Make lists of the item contents
568
+ terms = []
569
+ wdfs = []
570
+ positers = []
571
+ for termitem in doc:
572
+ terms.append(termitem.term)
573
+ wdfs.append(termitem.wdf)
574
+ expect_exception(xapian.InvalidOperationError,
575
+ "Can't get term frequency from a document termlist "
576
+ "which is not associated with a database.",
577
+ getattr, termitem, 'termfreq')
578
+ positers.append([pos for pos in termitem.positer])
579
+
580
+ expect(terms, ['it', 'two', 'warm', 'was'])
581
+ expect(wdfs, [1, 2, 1, 1])
582
+ expect(positers, [[2], [], [3], [1]])
583
+
584
+ if test_legacy_sequence_api:
585
+ # Test legacy sequence API.
586
+ i = 0
587
+ for termitem in doc:
588
+ expect(termitem[0], terms[i])
589
+ expect(termitem[1], wdfs[i])
590
+ expect([pos for pos in termitem[3]], positers[i])
591
+ i += 1
592
+
593
+ # Make a list of the terms (so we can test if they're still valid
594
+ # once the iterator has moved on).
595
+ termitems = []
596
+ for termitem in doc:
597
+ termitems.append(termitem)
598
+
599
+ expect(len(termitems), len(terms))
600
+ for i in xrange(len(termitems)):
601
+ expect(termitems[i].term, terms[i])
602
+
603
+ expect(len(termitems), len(wdfs))
604
+ for i in xrange(len(termitems)):
605
+ expect(termitems[i].wdf, wdfs[i])
606
+
607
+ for i in xrange(len(termitems)):
608
+ expect_exception(xapian.InvalidOperationError,
609
+ 'Iterator has moved, and does not support random access',
610
+ getattr, termitems[i], 'termfreq')
611
+
612
+ expect(len(termitems), len(positers))
613
+ for i in xrange(len(termitems)):
614
+ expect_exception(xapian.InvalidOperationError,
615
+ 'Iterator has moved, and does not support random access',
616
+ getattr, termitems[i], 'positer')
617
+
618
+ def test_postinglist_iter():
619
+ """Test postinglist iterator on Database.
620
+
621
+ """
622
+ db = setup_database()
623
+
624
+ # Make lists of the item contents
625
+ docids = []
626
+ doclengths = []
627
+ wdfs = []
628
+ positers = []
629
+ for posting in db.postlist('it'):
630
+ docids.append(posting.docid)
631
+ doclengths.append(posting.doclength)
632
+ wdfs.append(posting.wdf)
633
+ positers.append([pos for pos in posting.positer])
634
+
635
+ expect(docids, [1, 2, 3, 4, 5])
636
+ expect(doclengths, [3, 3, 5, 8, 19])
637
+ expect(wdfs, [1, 1, 1, 1, 8])
638
+ expect(positers, [[1], [2], [2], [2], [2, 7]])
639
+
640
+ if test_legacy_sequence_api:
641
+ # Test legacy sequence API.
642
+ i = 0
643
+ for posting in db.postlist('it'):
644
+ posting = posting[:]
645
+ expect(posting[0], docids[i])
646
+ expect(posting[1], doclengths[i])
647
+ expect(posting[2], wdfs[i])
648
+ expect([pos for pos in posting[3]], positers[i])
649
+ i += 1
650
+
651
+ # Test skip_to().
652
+ pliter = db.postlist('it')
653
+
654
+ # skip to an item before the first item.
655
+ posting = pliter.skip_to(0)
656
+ expect((posting.docid, posting.doclength, posting.wdf,
657
+ [pos for pos in posting.positer]), (1, 3, 1, [1]))
658
+
659
+ # skip forwards to an item.
660
+ posting = pliter.skip_to(3)
661
+ expect((posting.docid, posting.doclength, posting.wdf,
662
+ [pos for pos in posting.positer]), (3, 5, 1, [2]))
663
+
664
+ # skip to same place (should return same item)
665
+ posting = pliter.skip_to(3)
666
+ expect((posting.docid, posting.doclength, posting.wdf,
667
+ [pos for pos in posting.positer]), (3, 5, 1, [2]))
668
+
669
+ # next() after a skip_to(), should return next item.
670
+ posting = pliter.next()
671
+ expect((posting.docid, posting.doclength, posting.wdf,
672
+ [pos for pos in posting.positer]), (4, 8, 1, [2]))
673
+
674
+ # skip to same place (should return same item)
675
+ posting = pliter.skip_to(4)
676
+ expect((posting.docid, posting.doclength, posting.wdf,
677
+ [pos for pos in posting.positer]), (4, 8, 1, [2]))
678
+
679
+ # skip backwards (should return same item)
680
+ posting = pliter.skip_to(2)
681
+ expect((posting.docid, posting.doclength, posting.wdf,
682
+ [pos for pos in posting.positer]), (4, 8, 1, [2]))
683
+
684
+ # skip to after end.
685
+ expect_exception(StopIteration, '', pliter.skip_to, 6)
686
+ # skip backwards (should still return StopIteration).
687
+ expect_exception(StopIteration, '', pliter.skip_to, 6)
688
+ # next should continue to return StopIteration.
689
+ expect_exception(StopIteration, '', pliter.next)
690
+
691
+
692
+ # Make a list of the postings (so we can test if they're still valid once
693
+ # the iterator has moved on).
694
+ postings = []
695
+ for posting in db.postlist('it'):
696
+ postings.append(posting)
697
+
698
+ expect(len(postings), len(docids))
699
+ for i in xrange(len(postings)):
700
+ expect(postings[i].docid, docids[i])
701
+
702
+ expect(len(postings), len(doclengths))
703
+ for i in xrange(len(postings)):
704
+ expect(postings[i].doclength, doclengths[i])
705
+
706
+ expect(len(postings), len(wdfs))
707
+ for i in xrange(len(postings)):
708
+ expect(postings[i].wdf, wdfs[i])
709
+
710
+ expect(len(postings), len(positers))
711
+ for i in xrange(len(postings)):
712
+ expect_exception(xapian.InvalidOperationError,
713
+ 'Iterator has moved, and does not support random access',
714
+ getattr, postings[i], 'positer')
715
+
716
+ def test_position_iter():
717
+ """Test position iterator for a document in a database.
718
+
719
+ """
720
+ db = setup_database()
721
+
722
+ doc = db.get_document(5)
723
+
724
+ # Make lists of the item contents
725
+ positions = []
726
+ for position in db.positionlist(5, 'it'):
727
+ positions.append(position)
728
+
729
+ expect(positions, [2, 7])
730
+
731
+ def test_value_iter():
732
+ """Test iterators over list of values in a document.
733
+
734
+ """
735
+ db = setup_database()
736
+ doc = db.get_document(5)
737
+
738
+ if test_legacy_sequence_api:
739
+ items = [item for item in doc.values()]
740
+ expect(len(items), 3)
741
+ expect(items[0].num, 0)
742
+ expect(items[0].value, 'zero')
743
+ expect(items[0][:], [0, 'zero'])
744
+ expect(items[1].num, 5)
745
+ expect(items[1].value, 'five')
746
+ expect(items[1][:], [5, 'five'])
747
+ expect(items[2].num, 9)
748
+ expect(items[2].value, 'nine')
749
+ expect(items[2][:], [9, 'nine'])
750
+
751
+ def test_synonyms_iter():
752
+ """Test iterators over list of synonyms in a database.
753
+
754
+ """
755
+ dbpath = 'db_test_synonyms_iter'
756
+ db = xapian.WritableDatabase(dbpath, xapian.DB_CREATE_OR_OVERWRITE)
757
+
758
+ db.add_synonym('hello', 'hi')
759
+ db.add_synonym('hello', 'howdy')
760
+
761
+ expect([item for item in db.synonyms('foo')], [])
762
+ expect([item for item in db.synonyms('hello')], ['hi', 'howdy'])
763
+ expect([item for item in db.synonym_keys()], ['hello'])
764
+ expect([item for item in db.synonym_keys('foo')], [])
765
+ expect([item for item in db.synonym_keys('he')], ['hello'])
766
+ expect([item for item in db.synonym_keys('hello')], ['hello'])
767
+
768
+ dbr=xapian.Database(dbpath)
769
+ expect([item for item in dbr.synonyms('foo')], [])
770
+ expect([item for item in dbr.synonyms('hello')], [])
771
+ expect([item for item in dbr.synonym_keys()], [])
772
+ expect([item for item in dbr.synonym_keys('foo')], [])
773
+ expect([item for item in dbr.synonym_keys('he')], [])
774
+ expect([item for item in dbr.synonym_keys('hello')], [])
775
+
776
+ db.flush()
777
+
778
+ expect([item for item in db.synonyms('foo')], [])
779
+ expect([item for item in db.synonyms('hello')], ['hi', 'howdy'])
780
+ expect([item for item in db.synonym_keys()], ['hello'])
781
+ expect([item for item in db.synonym_keys('foo')], [])
782
+ expect([item for item in db.synonym_keys('he')], ['hello'])
783
+ expect([item for item in db.synonym_keys('hello')], ['hello'])
784
+
785
+ dbr=xapian.Database(dbpath)
786
+ expect([item for item in dbr.synonyms('foo')] , [])
787
+ expect([item for item in dbr.synonyms('hello')], ['hi', 'howdy'])
788
+ expect([item for item in dbr.synonym_keys()], ['hello'])
789
+ expect([item for item in dbr.synonym_keys('foo')], [])
790
+ expect([item for item in dbr.synonym_keys('he')], ['hello'])
791
+ expect([item for item in dbr.synonym_keys('hello')], ['hello'])
792
+
793
+ del db
794
+ del dbr
795
+ shutil.rmtree(dbpath)
796
+
797
+ def test_metadata_keys_iter():
798
+ """Test iterators over list of metadata keys in a database.
799
+
800
+ """
801
+ dbpath = 'flinttest_metadata_iter'
802
+ db = xapian.WritableDatabase(dbpath, xapian.DB_CREATE_OR_OVERWRITE)
803
+
804
+ db.set_metadata('author', 'richard')
805
+ db.set_metadata('item1', 'hello')
806
+ db.set_metadata('item1', 'hi')
807
+ db.set_metadata('item2', 'howdy')
808
+ db.set_metadata('item3', '')
809
+ db.set_metadata('item4', 'goodbye')
810
+ db.set_metadata('item4', '')
811
+ db.set_metadata('type', 'greeting')
812
+
813
+ expect([item for item in db.metadata_keys()],
814
+ ['author', 'item1', 'item2', 'type'])
815
+ expect([item for item in db.metadata_keys('foo')], [])
816
+ expect([item for item in db.metadata_keys('item')], ['item1', 'item2'])
817
+ expect([item for item in db.metadata_keys('it')], ['item1', 'item2'])
818
+ expect([item for item in db.metadata_keys('type')], ['type'])
819
+
820
+ dbr=xapian.Database(dbpath)
821
+ expect([item for item in dbr.metadata_keys()], [])
822
+ expect([item for item in dbr.metadata_keys('foo')], [])
823
+ expect([item for item in dbr.metadata_keys('item')], [])
824
+ expect([item for item in dbr.metadata_keys('it')], [])
825
+ expect([item for item in dbr.metadata_keys('type')], [])
826
+
827
+ db.flush()
828
+ expect([item for item in db.metadata_keys()],
829
+ ['author', 'item1', 'item2', 'type'])
830
+ expect([item for item in db.metadata_keys('foo')], [])
831
+ expect([item for item in db.metadata_keys('item')], ['item1', 'item2'])
832
+ expect([item for item in db.metadata_keys('it')], ['item1', 'item2'])
833
+ expect([item for item in db.metadata_keys('type')], ['type'])
834
+
835
+ dbr=xapian.Database(dbpath)
836
+ expect([item for item in dbr.metadata_keys()],
837
+ ['author', 'item1', 'item2', 'type'])
838
+ expect([item for item in dbr.metadata_keys('foo')], [])
839
+ expect([item for item in dbr.metadata_keys('item')], ['item1', 'item2'])
840
+ expect([item for item in dbr.metadata_keys('it')], ['item1', 'item2'])
841
+ expect([item for item in dbr.metadata_keys('type')], ['type'])
842
+
843
+ del db
844
+ del dbr
845
+ shutil.rmtree(dbpath)
846
+
847
+ def test_spell():
848
+ """Test basic spelling correction features.
849
+
850
+ """
851
+ dbpath = 'db_test_spell'
852
+ db = xapian.WritableDatabase(dbpath, xapian.DB_CREATE_OR_OVERWRITE)
853
+
854
+ db.add_spelling('hello')
855
+ db.add_spelling('mell', 2)
856
+ expect(db.get_spelling_suggestion('hell'), 'mell')
857
+ expect([(item.term, item.termfreq) for item in db.spellings()], [('hello', 1), ('mell', 2)])
858
+ dbr=xapian.Database(dbpath)
859
+ expect(dbr.get_spelling_suggestion('hell'), '')
860
+ expect([(item.term, item.termfreq) for item in dbr.spellings()], [])
861
+ db.flush()
862
+ dbr=xapian.Database(dbpath)
863
+ expect(db.get_spelling_suggestion('hell'), 'mell')
864
+ expect(dbr.get_spelling_suggestion('hell'), 'mell')
865
+ expect([(item.term, item.termfreq) for item in dbr.spellings()], [('hello', 1), ('mell', 2)])
866
+
867
+ del db
868
+ del dbr
869
+ shutil.rmtree(dbpath)
870
+
871
+ def test_queryparser_custom_vrp():
872
+ """Test QueryParser with a custom (in python) ValueRangeProcessor.
873
+
874
+ """
875
+ class MyVRP(xapian.ValueRangeProcessor):
876
+ def __init__(self):
877
+ xapian.ValueRangeProcessor.__init__(self)
878
+
879
+ def __call__(self, begin, end):
880
+ return (7, "A"+begin, "B"+end)
881
+
882
+ queryparser = xapian.QueryParser()
883
+ myvrp = MyVRP()
884
+
885
+ queryparser.add_valuerangeprocessor(myvrp)
886
+ query = queryparser.parse_query('5..8')
887
+
888
+ expect(str(query),
889
+ 'Xapian::Query(VALUE_RANGE 7 A5 B8)')
890
+
891
+ def test_queryparser_custom_vrp_deallocation():
892
+ """Test that QueryParser doesn't delete ValueRangeProcessors too soon.
893
+
894
+ """
895
+ class MyVRP(xapian.ValueRangeProcessor):
896
+ def __init__(self):
897
+ xapian.ValueRangeProcessor.__init__(self)
898
+
899
+ def __call__(self, begin, end):
900
+ return (7, "A"+begin, "B"+end)
901
+
902
+ def make_parser():
903
+ queryparser = xapian.QueryParser()
904
+ myvrp = MyVRP()
905
+ queryparser.add_valuerangeprocessor(myvrp)
906
+ return queryparser
907
+
908
+ queryparser = make_parser()
909
+ query = queryparser.parse_query('5..8')
910
+
911
+ expect(str(query),
912
+ 'Xapian::Query(VALUE_RANGE 7 A5 B8)')
913
+
914
+ def test_scale_weight():
915
+ """Test query OP_SCALE_WEIGHT feature.
916
+
917
+ """
918
+ db = setup_database()
919
+ for mult in (0, 1, 2.5):
920
+ context("checking queries with OP_SCALE_WEIGHT with a multipler of %r" %
921
+ mult)
922
+ query1 = xapian.Query("it")
923
+ query2 = xapian.Query(xapian.Query.OP_SCALE_WEIGHT, query1, mult)
924
+
925
+ enquire = xapian.Enquire(db)
926
+ enquire.set_query(query1)
927
+ mset1 = enquire.get_mset(0, 10)
928
+ enquire.set_query(query2)
929
+ mset2 = enquire.get_mset(0, 10)
930
+ if mult <= 0:
931
+ expected = [(0, item.docid) for item in mset1]
932
+ expected.sort()
933
+ else:
934
+ expected = [(int(item.weight * mult * 1000000), item.docid) for item in mset1]
935
+ expect([(int(item.weight * 1000000), item.docid) for item in mset2], expected)
936
+
937
+ context("checking queries with OP_SCALE_WEIGHT with a multipler of -1")
938
+ query1 = xapian.Query("it")
939
+ expect_exception(xapian.InvalidArgumentError,
940
+ "Xapian::Query: SCALE_WEIGHT requires a non-negative parameter.",
941
+ xapian.Query,
942
+ xapian.Query.OP_SCALE_WEIGHT, query1, -1)
943
+
944
+
945
+ def test_weight_normalise():
946
+ """Test normalising of query weights using the OP_SCALE_WEIGHT feature.
947
+
948
+ This test first runs a search (asking for no results) to get the maximum
949
+ possible weight for a query, and then checks that the results of
950
+ MSet.get_max_possible() match this.
951
+
952
+ This tests that the get_max_possible() value is correct (though it isn't
953
+ guaranteed to be at a tight bound), and that the SCALE_WEIGHT query can
954
+ compensate correctly.
955
+
956
+ """
957
+ db = setup_database()
958
+ for query in (
959
+ "it",
960
+ "was",
961
+ "it was",
962
+ "it was four",
963
+ "it was four five",
964
+ "\"was it warm\" four notpresent",
965
+ "notpresent",
966
+ ):
967
+ context("checking query %r using OP_SCALE_WEIGHT to normalise the weights" % query)
968
+ qp = xapian.QueryParser()
969
+ query1 = qp.parse_query(query)
970
+ enquire = xapian.Enquire(db)
971
+ enquire.set_query(query1)
972
+ mset1 = enquire.get_mset(0, 0)
973
+
974
+ # Check the max_attained value is 0 - this gives us some reassurance
975
+ # that the match didn't actually do the work of calculating any
976
+ # results.
977
+ expect(mset1.get_max_attained(), 0)
978
+
979
+ max_possible = mset1.get_max_possible()
980
+ mult = 1.0 / max_possible
981
+ query2 = xapian.Query(xapian.Query.OP_SCALE_WEIGHT, query1, mult)
982
+
983
+ enquire = xapian.Enquire(db)
984
+ enquire.set_query(query2)
985
+ mset2 = enquire.get_mset(0, 10)
986
+ # max_possible should be 1 (excluding rounding errors) for mset2
987
+ expect(int(mset2.get_max_possible() * 1000000.0 + 0.5), 1000000)
988
+ for item in mset2:
989
+ expect(item.weight > 0, True)
990
+ expect(item.weight <= 1, True)
991
+
992
+ del db
993
+
994
+ def test_director_exception():
995
+ """Test handling of an exception raised in a director.
996
+
997
+ """
998
+ dbpath = 'db_test_value_stats'
999
+ db = setup_database()
1000
+ query = xapian.Query('it')
1001
+ enq = xapian.Enquire(db)
1002
+ enq.set_query(query)
1003
+ class TestException(Exception):
1004
+ def __init__(self, a, b):
1005
+ Exception.__init__(self, a + b)
1006
+
1007
+ rset = xapian.RSet()
1008
+ rset.add_document(1)
1009
+ class EDecider(xapian.ExpandDecider):
1010
+ def __call__(self, term):
1011
+ raise TestException("foo", "bar")
1012
+ edecider = EDecider()
1013
+ expect_exception(TestException, "foobar", edecider, "foo")
1014
+ expect_exception(TestException, "foobar", enq.get_eset, 10, rset, edecider)
1015
+
1016
+ class MDecider(xapian.MatchDecider):
1017
+ def __call__(self, doc):
1018
+ raise TestException("foo", "bar")
1019
+ mdecider = MDecider()
1020
+ expect_exception(TestException, "foobar", mdecider, xapian.Document())
1021
+ expect_exception(TestException, "foobar", enq.get_mset, 0, 10, None, mdecider)
1022
+
1023
+ # The legacy sequence API is only supported for Python >= 2.3 so don't try
1024
+ # testing it for Python 2.2.
1025
+ vinfo = sys.version_info
1026
+ test_legacy_sequence_api = vinfo[0] > 2 or (vinfo[0] == 2 and vinfo[1] >= 3)
1027
+
1028
+ def test_preserve_query_parser_stopper():
1029
+ """Test preservation of stopper set on query parser.
1030
+
1031
+ """
1032
+ def make_qp():
1033
+ queryparser = xapian.QueryParser()
1034
+ stopper = xapian.SimpleStopper()
1035
+ stopper.add('to')
1036
+ stopper.add('not')
1037
+ queryparser.set_stopper(stopper)
1038
+ del stopper
1039
+ return queryparser
1040
+ queryparser = make_qp()
1041
+ query = queryparser.parse_query('to be')
1042
+ expect([term for term in queryparser.stoplist()], ['to'])
1043
+
1044
+ def test_preserve_term_generator_stopper():
1045
+ """Test preservation of stopper set on term generator.
1046
+
1047
+ """
1048
+ def make_tg():
1049
+ termgen = xapian.TermGenerator()
1050
+ termgen.set_stemmer(xapian.Stem('en'))
1051
+ stopper = xapian.SimpleStopper()
1052
+ stopper.add('to')
1053
+ stopper.add('not')
1054
+ termgen.set_stopper(stopper)
1055
+ del stopper
1056
+ return termgen
1057
+ termgen = make_tg()
1058
+
1059
+ termgen.index_text('to be')
1060
+ doc = termgen.get_document()
1061
+ terms = [term.term for term in doc.termlist()]
1062
+ terms.sort()
1063
+ expect(terms, ['Zbe', 'be', 'to'])
1064
+
1065
+ def test_preserve_enquire_sorter():
1066
+ """Test preservation of sorter set on enquire.
1067
+
1068
+ """
1069
+ db = xapian.inmemory_open()
1070
+ doc = xapian.Document()
1071
+ doc.add_term('foo')
1072
+ doc.add_value(1, '1')
1073
+ db.add_document(doc)
1074
+ db.add_document(doc)
1075
+
1076
+ def make_enq1(db):
1077
+ enq = xapian.Enquire(db)
1078
+ sorter = xapian.MultiValueSorter()
1079
+ enq.set_sort_by_key(sorter, ascending = True)
1080
+ del sorter
1081
+ return enq
1082
+ enq = make_enq1(db)
1083
+ enq.set_query(xapian.Query('foo'))
1084
+ enq.get_mset(0, 10)
1085
+
1086
+ def make_enq2(db):
1087
+ enq = xapian.Enquire(db)
1088
+ sorter = xapian.MultiValueSorter()
1089
+ enq.set_sort_by_key_then_relevance(sorter, reverse = True)
1090
+ del sorter
1091
+ return enq
1092
+ enq = make_enq2(db)
1093
+ enq.set_query(xapian.Query('foo'))
1094
+ enq.get_mset(0, 10)
1095
+
1096
+ def make_enq3(db):
1097
+ enq = xapian.Enquire(db)
1098
+ sorter = xapian.MultiValueSorter()
1099
+ enq.set_sort_by_relevance_then_key(sorter, True)
1100
+ del sorter
1101
+ return enq
1102
+ enq = make_enq3(db)
1103
+ enq.set_query(xapian.Query('foo'))
1104
+ enq.get_mset(0, 10)
1105
+
1106
+ # Run all tests (ie, callables with names starting "test_").
1107
+ if not runtests(globals(), sys.argv[1:]):
1108
+ sys.exit(1)
1109
+
1110
+ # vim:syntax=python:set expandtab: