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
data/python/except.i ADDED
@@ -0,0 +1,290 @@
1
+ /* python/except.i: Custom Python exception handling.
2
+ * Warning: This file is generated by ./generate-python-exceptions
3
+ * - do not modify directly!
4
+ *
5
+ * Copyright 2007 Lemur Consulting Ltd
6
+ * Copyright 2007 Olly Betts
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation; either version 2 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ */
22
+ namespace Xapian {
23
+
24
+ %exceptionclass Error;
25
+ %ignore Error::get_description;
26
+ %extend Error {
27
+ std::string __str__() const {
28
+ std::string desc($self->get_msg());
29
+ if (!$self->get_context().empty()) {
30
+ desc += " (context: ";
31
+ desc += $self->get_context();
32
+ desc += ')';
33
+ }
34
+ if ($self->get_error_string()) {
35
+ desc += " (";
36
+ desc += $self->get_error_string();
37
+ desc += ')';
38
+ }
39
+ return desc;
40
+ }
41
+ }
42
+ %exceptionclass LogicError;
43
+ %exceptionclass RuntimeError;
44
+ %exceptionclass AssertionError;
45
+ %exceptionclass InvalidArgumentError;
46
+ %exceptionclass InvalidOperationError;
47
+ %exceptionclass UnimplementedError;
48
+ %exceptionclass DatabaseError;
49
+ %exceptionclass DatabaseCorruptError;
50
+ %exceptionclass DatabaseCreateError;
51
+ %exceptionclass DatabaseLockError;
52
+ %exceptionclass DatabaseModifiedError;
53
+ %exceptionclass DatabaseOpeningError;
54
+ %exceptionclass DatabaseVersionError;
55
+ %exceptionclass DocNotFoundError;
56
+ %exceptionclass FeatureUnavailableError;
57
+ %exceptionclass InternalError;
58
+ %exceptionclass NetworkError;
59
+ %exceptionclass NetworkTimeoutError;
60
+ %exceptionclass QueryParserError;
61
+ %exceptionclass RangeError;
62
+ }
63
+ %include "xapian/error.h"
64
+
65
+ %{
66
+ // Use our own DirectorException class to signal python exceptions in director
67
+ // methods, to avoid the unwanted side effects of the default SWIG mechanism.
68
+ // This can be removed once we're using a SWIG version with the patch linked to
69
+ // from ticket #289 merged into it.
70
+ class XapianDirectorException {
71
+ };
72
+
73
+ static void XapianSetPythonException() {
74
+ try {
75
+ throw;
76
+ } catch (XapianDirectorException &e) {
77
+ /* This happens if a python error occurred in a director method. The
78
+ * original Python error state should still be set, so we don't need to
79
+ * do anything. */
80
+ } catch (Swig::DirectorException &e) {
81
+ /* This happens if a director raised an exception. The standard SWIG
82
+ * director exception handling code sets the Python error state, so we
83
+ * don't need to do anything. */
84
+ } catch (const Xapian::RangeError &e) {
85
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::RangeError(e)),
86
+ SWIGTYPE_p_Xapian__RangeError,
87
+ SWIG_POINTER_OWN),
88
+ "Xapian::RangeError",
89
+ SWIGTYPE_p_Xapian__RangeError);
90
+ } catch (const Xapian::QueryParserError &e) {
91
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::QueryParserError(e)),
92
+ SWIGTYPE_p_Xapian__QueryParserError,
93
+ SWIG_POINTER_OWN),
94
+ "Xapian::QueryParserError",
95
+ SWIGTYPE_p_Xapian__QueryParserError);
96
+ } catch (const Xapian::NetworkTimeoutError &e) {
97
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::NetworkTimeoutError(e)),
98
+ SWIGTYPE_p_Xapian__NetworkTimeoutError,
99
+ SWIG_POINTER_OWN),
100
+ "Xapian::NetworkTimeoutError",
101
+ SWIGTYPE_p_Xapian__NetworkTimeoutError);
102
+ } catch (const Xapian::NetworkError &e) {
103
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::NetworkError(e)),
104
+ SWIGTYPE_p_Xapian__NetworkError,
105
+ SWIG_POINTER_OWN),
106
+ "Xapian::NetworkError",
107
+ SWIGTYPE_p_Xapian__NetworkError);
108
+ } catch (const Xapian::InternalError &e) {
109
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::InternalError(e)),
110
+ SWIGTYPE_p_Xapian__InternalError,
111
+ SWIG_POINTER_OWN),
112
+ "Xapian::InternalError",
113
+ SWIGTYPE_p_Xapian__InternalError);
114
+ } catch (const Xapian::FeatureUnavailableError &e) {
115
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::FeatureUnavailableError(e)),
116
+ SWIGTYPE_p_Xapian__FeatureUnavailableError,
117
+ SWIG_POINTER_OWN),
118
+ "Xapian::FeatureUnavailableError",
119
+ SWIGTYPE_p_Xapian__FeatureUnavailableError);
120
+ } catch (const Xapian::DocNotFoundError &e) {
121
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DocNotFoundError(e)),
122
+ SWIGTYPE_p_Xapian__DocNotFoundError,
123
+ SWIG_POINTER_OWN),
124
+ "Xapian::DocNotFoundError",
125
+ SWIGTYPE_p_Xapian__DocNotFoundError);
126
+ } catch (const Xapian::DatabaseVersionError &e) {
127
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseVersionError(e)),
128
+ SWIGTYPE_p_Xapian__DatabaseVersionError,
129
+ SWIG_POINTER_OWN),
130
+ "Xapian::DatabaseVersionError",
131
+ SWIGTYPE_p_Xapian__DatabaseVersionError);
132
+ } catch (const Xapian::DatabaseOpeningError &e) {
133
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseOpeningError(e)),
134
+ SWIGTYPE_p_Xapian__DatabaseOpeningError,
135
+ SWIG_POINTER_OWN),
136
+ "Xapian::DatabaseOpeningError",
137
+ SWIGTYPE_p_Xapian__DatabaseOpeningError);
138
+ } catch (const Xapian::DatabaseModifiedError &e) {
139
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseModifiedError(e)),
140
+ SWIGTYPE_p_Xapian__DatabaseModifiedError,
141
+ SWIG_POINTER_OWN),
142
+ "Xapian::DatabaseModifiedError",
143
+ SWIGTYPE_p_Xapian__DatabaseModifiedError);
144
+ } catch (const Xapian::DatabaseLockError &e) {
145
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseLockError(e)),
146
+ SWIGTYPE_p_Xapian__DatabaseLockError,
147
+ SWIG_POINTER_OWN),
148
+ "Xapian::DatabaseLockError",
149
+ SWIGTYPE_p_Xapian__DatabaseLockError);
150
+ } catch (const Xapian::DatabaseCreateError &e) {
151
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseCreateError(e)),
152
+ SWIGTYPE_p_Xapian__DatabaseCreateError,
153
+ SWIG_POINTER_OWN),
154
+ "Xapian::DatabaseCreateError",
155
+ SWIGTYPE_p_Xapian__DatabaseCreateError);
156
+ } catch (const Xapian::DatabaseCorruptError &e) {
157
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseCorruptError(e)),
158
+ SWIGTYPE_p_Xapian__DatabaseCorruptError,
159
+ SWIG_POINTER_OWN),
160
+ "Xapian::DatabaseCorruptError",
161
+ SWIGTYPE_p_Xapian__DatabaseCorruptError);
162
+ } catch (const Xapian::DatabaseError &e) {
163
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::DatabaseError(e)),
164
+ SWIGTYPE_p_Xapian__DatabaseError,
165
+ SWIG_POINTER_OWN),
166
+ "Xapian::DatabaseError",
167
+ SWIGTYPE_p_Xapian__DatabaseError);
168
+ } catch (const Xapian::UnimplementedError &e) {
169
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::UnimplementedError(e)),
170
+ SWIGTYPE_p_Xapian__UnimplementedError,
171
+ SWIG_POINTER_OWN),
172
+ "Xapian::UnimplementedError",
173
+ SWIGTYPE_p_Xapian__UnimplementedError);
174
+ } catch (const Xapian::InvalidOperationError &e) {
175
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::InvalidOperationError(e)),
176
+ SWIGTYPE_p_Xapian__InvalidOperationError,
177
+ SWIG_POINTER_OWN),
178
+ "Xapian::InvalidOperationError",
179
+ SWIGTYPE_p_Xapian__InvalidOperationError);
180
+ } catch (const Xapian::InvalidArgumentError &e) {
181
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::InvalidArgumentError(e)),
182
+ SWIGTYPE_p_Xapian__InvalidArgumentError,
183
+ SWIG_POINTER_OWN),
184
+ "Xapian::InvalidArgumentError",
185
+ SWIGTYPE_p_Xapian__InvalidArgumentError);
186
+ } catch (const Xapian::AssertionError &e) {
187
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::AssertionError(e)),
188
+ SWIGTYPE_p_Xapian__AssertionError,
189
+ SWIG_POINTER_OWN),
190
+ "Xapian::AssertionError",
191
+ SWIGTYPE_p_Xapian__AssertionError);
192
+ } catch (const Xapian::RuntimeError &e) {
193
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::RuntimeError(e)),
194
+ SWIGTYPE_p_Xapian__RuntimeError,
195
+ SWIG_POINTER_OWN),
196
+ "Xapian::RuntimeError",
197
+ SWIGTYPE_p_Xapian__RuntimeError);
198
+ } catch (const Xapian::LogicError &e) {
199
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::LogicError(e)),
200
+ SWIGTYPE_p_Xapian__LogicError,
201
+ SWIG_POINTER_OWN),
202
+ "Xapian::LogicError",
203
+ SWIGTYPE_p_Xapian__LogicError);
204
+ } catch (const Xapian::Error &e) {
205
+ SWIG_Python_Raise(SWIG_NewPointerObj((new Xapian::Error(e)),
206
+ SWIGTYPE_p_Xapian__Error,
207
+ SWIG_POINTER_OWN),
208
+ "Xapian::Error",
209
+ SWIGTYPE_p_Xapian__Error);
210
+ } catch (const std::exception& e) {
211
+ SWIG_Error(SWIG_RuntimeError, e.what());
212
+ } catch (...) {
213
+ SWIG_Error(SWIG_UnknownError, "unknown error in Xapian");
214
+ }
215
+ }
216
+ %}
217
+
218
+ /* Note that we have to re-acquire the GIL in the catch() here, because
219
+ * XapianSetPythonException accesses Python data structures. */
220
+ %exception {
221
+ try {
222
+ $action
223
+ } catch (...) {
224
+ SWIG_PYTHON_THREAD_END_ALLOW;
225
+ XapianSetPythonException();
226
+ SWIG_fail;
227
+ }
228
+ }
229
+
230
+ /* The following exception directives are for the methods defined by
231
+ * director classes, which don't drop the GIL in the first place. */
232
+ %exception Xapian::MatchDecider::operator() {
233
+ try {
234
+ $action
235
+ } catch (...) {
236
+ XapianSetPythonException();
237
+ SWIG_fail;
238
+ }
239
+ }
240
+ %exception Xapian::ExpandDecider::operator() {
241
+ try {
242
+ $action
243
+ } catch (...) {
244
+ XapianSetPythonException();
245
+ SWIG_fail;
246
+ }
247
+ }
248
+ %exception Xapian::Stopper::operator() {
249
+ try {
250
+ $action
251
+ } catch (...) {
252
+ XapianSetPythonException();
253
+ SWIG_fail;
254
+ }
255
+ }
256
+ %exception Xapian::ValueRangeProcessor::operator() {
257
+ try {
258
+ $action
259
+ } catch (...) {
260
+ XapianSetPythonException();
261
+ SWIG_fail;
262
+ }
263
+ }
264
+ %exception Xapian::Sorter::operator() {
265
+ try {
266
+ $action
267
+ } catch (...) {
268
+ XapianSetPythonException();
269
+ SWIG_fail;
270
+ }
271
+ }
272
+ %exception Xapian::Stopper::get_description {
273
+ try {
274
+ $action
275
+ } catch (...) {
276
+ XapianSetPythonException();
277
+ SWIG_fail;
278
+ }
279
+ }
280
+
281
+ /* If a Python error is raised by a call to a director function, the following
282
+ * code should cause a C++ exception to be thrown.
283
+ */
284
+ %feature("director:except") {
285
+ if ($error != NULL) {
286
+ throw XapianDirectorException();
287
+ }
288
+ }
289
+
290
+ /* vim:syntax=cpp:set noexpandtab: */
data/python/extra.i ADDED
@@ -0,0 +1,1048 @@
1
+ %{
2
+ /* python/extra.i: Xapian scripting python interface additional code.
3
+ *
4
+ * Copyright (C) 2003,2004,2005 James Aylett
5
+ * Copyright (C) 2005,2006,2007,2009 Olly Betts
6
+ * Copyright (C) 2007 Lemur Consulting Ltd
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation; either version 2 of the
11
+ * License, or (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21
+ * USA
22
+ */
23
+ %}
24
+
25
+ %pythoncode %{
26
+
27
+ # Set the documentation format - this is used by tools like "epydoc" to decide
28
+ # how to format the documentation strings.
29
+ __docformat__ = "restructuredtext en"
30
+
31
+ class _SequenceMixIn(object):
32
+ """Simple mixin class which provides a sequence API to a class.
33
+
34
+ This is used to support the legacy API to iterators used for releases of
35
+ Xapian earlier than 1.0. It will be removed once this legacy API is
36
+ removed in release 1.1.
37
+
38
+ """
39
+
40
+ __slots__ = ('_sequence_items', )
41
+ def __init__(self, *args):
42
+ """Initialise the sequence.
43
+
44
+ *args holds the list of properties or property names to be returned, in
45
+ the order they are returned by the sequence API.
46
+
47
+ If an item in the list is a string, it is considered to be a property
48
+ name; otherwise, it is considered to be a property value, and is
49
+ returned without doing an attribute lookup. (Yes, this is a nasty
50
+ hack. No, I don't care, because this is only a temporary piece of
51
+ internal code.)
52
+
53
+ """
54
+ self._sequence_items = args
55
+
56
+ def __len__(self):
57
+ """Get the length of the sequence.
58
+
59
+ Doesn't evaluate any of the lazily evaluated properties.
60
+
61
+ """
62
+ return len(self._sequence_items)
63
+
64
+ def _get_single_item(self, index):
65
+ """Get a single item.
66
+
67
+ Used by __getitem__ to get individual items.
68
+
69
+ """
70
+ if not isinstance(index, basestring):
71
+ return index
72
+ return getattr(self, index)
73
+
74
+ def __getitem__(self, key):
75
+ """Get an item, or a slice of items, from the sequence.
76
+
77
+ If any of the items are lazily evaluated properties, they will be
78
+ evaluated here.
79
+
80
+ """
81
+ if isinstance(key, slice):
82
+ return [self._get_single_item(i) for i in self._sequence_items[key]]
83
+ return self._get_single_item(self._sequence_items[key])
84
+
85
+ def __iter__(self):
86
+ """Make an iterator for over the sequence.
87
+
88
+ This simply copies the items into a list, and returns an iterator over
89
+ it. Any lazily evaluated properties will be evaluated here.
90
+
91
+ """
92
+ return iter(self[:])
93
+
94
+
95
+ ##################################
96
+ # Support for iteration of MSets #
97
+ ##################################
98
+
99
+ class MSetItem(_SequenceMixIn):
100
+ """An item returned from iteration of the MSet.
101
+
102
+ The item supports access to the following attributes and properties:
103
+
104
+ - `docid`: The Xapian document ID corresponding to this MSet item.
105
+ - `weight`: The weight corresponding to this MSet item.
106
+ - `rank`: The rank of this MSet item. The rank is the position in the
107
+ total set of matching documents of this item. The highest document is
108
+ given a rank of 0. If the MSet did not start at the highest matching
109
+ document, because a non-zero 'start' parameter was supplied to
110
+ get_mset(), the first document in the MSet will have a rank greater than
111
+ 0 (in fact, it will be equal to the value of 'start' supplied to
112
+ get_mset()).
113
+ - `percent`: The percentage score assigned to this MSet item.
114
+ - `document`: The document for this MSet item. This can be used to access
115
+ the document data, or any other information stored in the document (such
116
+ as term lists). It is lazily evaluated.
117
+ - `collapse_key`: The value of the key which was used for collapsing.
118
+ - `collapse_count`: An estimate of the number of documents that have been
119
+ collapsed into this one.
120
+
121
+ The collapse count estimate will always be less than or equal to the actual
122
+ number of other documents satisfying the match criteria with the same
123
+ collapse key as this document. If may be 0 even though there are other
124
+ documents with the same collapse key which satisfying the match criteria.
125
+ However if this method returns non-zero, there definitely are other such
126
+ documents. So this method may be used to inform the user that there are
127
+ "at least N other matches in this group", or to control whether to offer a
128
+ "show other documents in this group" feature (but note that it may not
129
+ offer it in every case where it would show other documents).
130
+
131
+ """
132
+
133
+ __slots__ = ('_mset', '_firstitem', 'docid', 'weight', 'rank',
134
+ 'percent', 'collapse_key', 'collapse_count', '_document', )
135
+
136
+ def __init__(self, iter, mset):
137
+ self._mset = mset
138
+ self._firstitem = self._mset.get_firstitem()
139
+ self.docid = iter.get_docid()
140
+ self.weight = iter.get_weight()
141
+ self.rank = iter.get_rank()
142
+ self.percent = iter.get_percent()
143
+ self.collapse_key = iter.get_collapse_key()
144
+ self.collapse_count = iter.get_collapse_count()
145
+ self._document = None
146
+ _SequenceMixIn.__init__(self, 'docid', 'weight', 'rank', 'percent', 'document')
147
+
148
+ def _get_document(self):
149
+ if self._document is None:
150
+ self._document = self._mset._get_hit_internal(self.rank - self._firstitem).get_document()
151
+ return self._document
152
+
153
+ # Deprecated methods: to be removed in 1.1.0
154
+ def get_docid(self):
155
+ "Deprecated method: use the `docid` property instead."
156
+ return self.docid
157
+ def get_weight(self):
158
+ "Deprecated method: use the `weight` property instead."
159
+ return self.weight
160
+ def get_rank(self):
161
+ "Deprecated method: use the `rank` property instead."
162
+ return self.rank
163
+ def get_percent(self):
164
+ "Deprecated method: use the `percent` property instead."
165
+ return self.percent
166
+ def get_collapse_key(self):
167
+ "Deprecated method: use the `collapse_key` property instead."
168
+ return self.collapse_key
169
+ def get_collapse_count(self):
170
+ "Deprecated method: use the `collapse_count` property instead."
171
+ return self.collapse_count
172
+ def get_document(self):
173
+ "Deprecated method: use the `document` property instead."
174
+ return self.document
175
+
176
+ document = property(_get_document, doc="The document object corresponding to this MSet item.")
177
+
178
+ class MSetIter(object):
179
+ """An iterator over the items in an MSet.
180
+
181
+ The iterator will return MSetItem objects, which will be evaluated lazily
182
+ where appropriate.
183
+
184
+ """
185
+ __slots__ = ('_iter', '_end', '_mset')
186
+ def __init__(self, mset):
187
+ self._iter = mset.begin()
188
+ self._end = mset.end()
189
+ self._mset = mset
190
+
191
+ def __iter__(self):
192
+ return self
193
+
194
+ def next(self):
195
+ if self._iter == self._end:
196
+ raise StopIteration
197
+ else:
198
+ r = MSetItem(self._iter, self._mset)
199
+ self._iter.next()
200
+ return r
201
+
202
+
203
+ # Modify the MSet to allow access to the python iterators, and have other
204
+ # convenience methods.
205
+
206
+ def _mset_gen_iter(self):
207
+ """Return an iterator over the MSet.
208
+
209
+ The iterator will return MSetItem objects, which will be evaluated lazily
210
+ where appropriate.
211
+
212
+ """
213
+ return MSetIter(self)
214
+ MSet.__iter__ = _mset_gen_iter
215
+
216
+ MSet.__len__ = MSet.size
217
+
218
+ def _mset_getitem(self, index):
219
+ """Get an item from the MSet.
220
+
221
+ The supplied index is relative to the start of the MSet, not the absolute
222
+ rank of the item.
223
+
224
+ Returns an MSetItem.
225
+
226
+ """
227
+ if index < 0:
228
+ index += len(self)
229
+ if index < 0 or index >= len(self):
230
+ raise IndexError("Mset index out of range")
231
+ return MSetItem(self._get_hit_internal(index), self)
232
+ MSet.__getitem__ = _mset_getitem
233
+ MSet.get_hit = _mset_getitem
234
+
235
+ def _mset_contains(self, index):
236
+ """Check if the Mset contains an item at the given index
237
+
238
+ The supplied index is relative to the start of the MSet, not the absolute
239
+ rank of the item.
240
+
241
+ """
242
+ return key >= 0 and key < len(self)
243
+ MSet.__contains__ = _mset_contains
244
+
245
+
246
+ ##################################
247
+ # Support for iteration of ESets #
248
+ ##################################
249
+
250
+ class ESetItem(_SequenceMixIn):
251
+ """An item returned from iteration of the ESet.
252
+
253
+ The item supports access to the following attributes:
254
+
255
+ - `term`: The term corresponding to this ESet item.
256
+ - `weight`: The weight corresponding to this ESet item.
257
+
258
+ """
259
+ __slots__ = ('term', 'weight')
260
+
261
+ def __init__(self, iter):
262
+ self.term = iter.get_term()
263
+ self.weight = iter.get_weight()
264
+ _SequenceMixIn.__init__(self, 'term', 'weight')
265
+
266
+ class ESetIter(object):
267
+ """An iterator over the items in an ESet.
268
+
269
+ The iterator will return ESetItem objects.
270
+
271
+ """
272
+ __slots__ = ('_iter', '_end')
273
+ def __init__(self, eset):
274
+ self._iter = eset.begin()
275
+ self._end = eset.end()
276
+
277
+ def __iter__(self):
278
+ return self
279
+
280
+ def next(self):
281
+ if self._iter == self._end:
282
+ raise StopIteration
283
+ else:
284
+ r = ESetItem(self._iter)
285
+ self._iter.next()
286
+ return r
287
+
288
+ # Modify the ESet to allow access to the python iterators, and have other
289
+ # convenience methods.
290
+
291
+ def _eset_gen_iter(self):
292
+ """Return an iterator over the ESet.
293
+
294
+ The iterator will return ESetItem objects.
295
+
296
+ """
297
+ return ESetIter(self)
298
+ ESet.__iter__ = _eset_gen_iter
299
+
300
+ ESet.__len__ = ESet.size
301
+
302
+
303
+ #######################################
304
+ # Support for iteration of term lists #
305
+ #######################################
306
+
307
+ class TermListItem(_SequenceMixIn):
308
+ """An item returned from iteration of a term list.
309
+
310
+ The item supports access to the following attributes and properties:
311
+
312
+ - `term`: The term corresponding to this TermListItem.
313
+ - `wdf`: The within document frequency of this term.
314
+ - `termfreq`: The number of documents in the collection which are indexed
315
+ by the term
316
+ - `positer`: An iterator over the positions which the term appears at in
317
+ the document. This is only available until the iterator which returned
318
+ this item next moves.
319
+
320
+ """
321
+ __slots__ = ('_iter', 'term', '_wdf', '_termfreq')
322
+
323
+ def __init__(self, iter, term):
324
+ self._iter = iter
325
+ self.term = term
326
+ self._wdf = None
327
+ self._termfreq = None
328
+
329
+ if iter._has_wdf == TermIter.EAGER:
330
+ self._wdf = iter._iter.get_wdf()
331
+ if iter._has_termfreq == TermIter.EAGER:
332
+ self._termfreq = iter._iter.get_termfreq()
333
+
334
+ # Support for sequence API
335
+ sequence = ['term', 'wdf', 'termfreq', 'positer']
336
+ if iter._has_wdf == TermIter.INVALID:
337
+ sequence[1] = 0
338
+ if iter._has_termfreq == TermIter.INVALID:
339
+ sequence[2] = 0
340
+ if iter._has_positions == TermIter.INVALID:
341
+ sequence[3] = PositionIter()
342
+ _SequenceMixIn.__init__(self, *sequence)
343
+
344
+ def _get_wdf(self):
345
+ """Get the within-document-frequency of the current term.
346
+
347
+ This will raise a InvalidOperationError exception if the iterator this
348
+ item came from doesn't support within-document-frequencies.
349
+
350
+ """
351
+ if self._wdf is None:
352
+ if self._iter._has_wdf == TermIter.INVALID:
353
+ raise InvalidOperationError("Iterator does not support wdfs")
354
+ if self.term is not self._iter._lastterm:
355
+ raise InvalidOperationError("Iterator has moved, and does not support random access")
356
+ self._wdf = self._iter._iter.get_wdf()
357
+ return self._wdf
358
+ wdf = property(_get_wdf, doc=
359
+ """The within-document-frequency of the current term (if meaningful).
360
+
361
+ This will raise a InvalidOperationError exception if the iterator
362
+ this item came from doesn't support within-document-frequencies.
363
+
364
+ """)
365
+
366
+ def _get_termfreq(self):
367
+ """Get the term frequency.
368
+
369
+ This is the number of documents in the collection which are indexed by
370
+ the term.
371
+
372
+ This will raise a InvalidOperationError exception if the iterator this
373
+ item came from doesn't support term frequencies.
374
+
375
+ """
376
+ if self._termfreq is None:
377
+ if self._iter._has_termfreq == TermIter.INVALID:
378
+ raise InvalidOperationError("Iterator does not support term frequencies")
379
+ if self.term is not self._iter._lastterm:
380
+ raise InvalidOperationError("Iterator has moved, and does not support random access")
381
+ self._termfreq = self._iter._iter.get_termfreq()
382
+ return self._termfreq
383
+ termfreq = property(_get_termfreq, doc=
384
+ """The term frequency of the current term (if meaningful).
385
+
386
+ This is the number of documents in the collection which are indexed by the
387
+ term.
388
+
389
+ This will raise a InvalidOperationError exception if the iterator
390
+ this item came from doesn't support term frequencies.
391
+
392
+ """)
393
+
394
+ def _get_positer(self):
395
+ """Get a position list iterator.
396
+
397
+ The iterator will return integers representing the positions that the
398
+ term occurs at.
399
+
400
+ This will raise a InvalidOperationError exception if the iterator this
401
+ item came from doesn't support position lists, or if the iterator has
402
+ moved on since the item was returned from it.
403
+
404
+ """
405
+ if self._iter._has_positions == TermIter.INVALID:
406
+ raise InvalidOperationError("Iterator does not support position lists")
407
+ # Access to position lists is always lazy, so we don't need to check
408
+ # _has_positions.
409
+ if self.term is not self._iter._lastterm:
410
+ raise InvalidOperationError("Iterator has moved, and does not support random access")
411
+ return PositionIter(self._iter._iter.positionlist_begin(),
412
+ self._iter._iter.positionlist_end())
413
+ positer = property(_get_positer, doc=
414
+ """A position iterator for the current term (if meaningful).
415
+
416
+ The iterator will return integers representing the positions that the term
417
+ occurs at.
418
+
419
+ This will raise a InvalidOperationError exception if the iterator this item
420
+ came from doesn't support position lists, or if the iterator has moved on
421
+ since the item was returned from it.
422
+
423
+ """)
424
+
425
+
426
+ class TermIter(object):
427
+ """An iterator over a term list.
428
+
429
+ The iterator will return TermListItem objects, which will be evaluated
430
+ lazily where appropriate.
431
+
432
+ """
433
+ __slots__ = ('_iter', '_end', '_has_termfreq', '_has_wdf',
434
+ '_has_positions', '_return_strings', '_lastterm', '_moved')
435
+
436
+ INVALID = 0
437
+ LAZY = 1
438
+ EAGER = 2
439
+
440
+ def __init__(self, start, end, has_termfreq=INVALID,
441
+ has_wdf=INVALID, has_positions=INVALID,
442
+ return_strings=False):
443
+ self._iter = start
444
+ self._end = end
445
+ self._has_termfreq = has_termfreq
446
+ self._has_wdf = has_wdf
447
+ self._has_positions = has_positions
448
+ assert(has_positions != TermIter.EAGER) # Can't do eager access to position lists
449
+ self._return_strings = return_strings
450
+ self._lastterm = None # Used to test if the iterator has moved
451
+
452
+ # _moved is True if we've moved onto the next item. This is needed so
453
+ # that the iterator doesn't have to move on until just before next() is
454
+ # called: since the iterator starts by pointing at a valid item, we
455
+ # can't just call self._iter.next() unconditionally at the start of our
456
+ # next() method.
457
+ self._moved = True
458
+
459
+ def __iter__(self):
460
+ return self
461
+
462
+ def next(self):
463
+ if not self._moved:
464
+ self._iter.next()
465
+ self._moved = True
466
+
467
+ if self._iter == self._end:
468
+ self._lastterm = None
469
+ raise StopIteration
470
+ else:
471
+ self._lastterm = self._iter.get_term()
472
+ self._moved = False
473
+ if self._return_strings:
474
+ return self._lastterm
475
+ return TermListItem(self, self._lastterm)
476
+
477
+ def skip_to(self, term):
478
+ """Skip the iterator forward.
479
+
480
+ The iterator is advanced to the first term at or after the current
481
+ position which is greater than or equal to the supplied term.
482
+
483
+ If there are no such items, this will raise StopIteration.
484
+
485
+ This returns the item which the iterator is moved to. The subsequent
486
+ item will be returned the next time that next() is called (unless
487
+ skip_to() is called again first).
488
+
489
+ """
490
+ if self._iter != self._end:
491
+ self._iter.skip_to(term)
492
+
493
+ if self._iter == self._end:
494
+ self._lastterm = None
495
+ self._moved = True
496
+ raise StopIteration
497
+
498
+ # Update self._lastterm if the iterator has moved.
499
+ # TermListItems compare a saved value of lastterm with self._lastterm
500
+ # with the object identity comparator, so it is important to ensure
501
+ # that it does not get modified if the new term compares equal.
502
+ newterm = self._iter.get_term()
503
+ if newterm != self._lastterm:
504
+ self._lastterm = newterm
505
+
506
+ self._moved = False
507
+ if self._return_strings:
508
+ return self._lastterm
509
+ return TermListItem(self, self._lastterm)
510
+
511
+ # Modify Enquire to add a "matching_terms()" method.
512
+ def _enquire_gen_iter(self, which):
513
+ """Get an iterator over the terms which match a given match set item.
514
+
515
+ The match set item to consider is specified by the `which` parameter, which
516
+ may be a document ID, or an MSetItem object.
517
+
518
+ The iterator will return string objects.
519
+
520
+ """
521
+ if isinstance(which, MSetItem):
522
+ which = which.docid
523
+ return TermIter(self.get_matching_terms_begin(which),
524
+ self.get_matching_terms_end(which),
525
+ return_strings=True)
526
+ Enquire.matching_terms = _enquire_gen_iter
527
+
528
+ # get_matching_terms() is deprecated, but does just the same as
529
+ # matching_terms()
530
+ Enquire.get_matching_terms = _enquire_gen_iter
531
+
532
+ # Modify Query to add an "__iter__()" method.
533
+ def _query_gen_iter(self):
534
+ """Get an iterator over the terms in a query.
535
+
536
+ The iterator will return string objects.
537
+
538
+ """
539
+ return TermIter(self.get_terms_begin(),
540
+ self.get_terms_end(),
541
+ return_strings=True)
542
+ Query.__iter__ = _query_gen_iter
543
+
544
+ # Modify Database to add an "__iter__()" method and an "allterms()" method.
545
+ def _database_gen_allterms_iter(self, prefix=None):
546
+ """Get an iterator over all the terms in the database.
547
+
548
+ The iterator will return TermListItem objects, but these will not support
549
+ access to wdf, or position information.
550
+
551
+ Access to term frequency information is only available until the iterator
552
+ has moved on.
553
+
554
+ If prefix is supplied, only terms which start with that prefix will be
555
+ returned.
556
+
557
+ """
558
+ if prefix is None:
559
+ return TermIter(self.allterms_begin(), self.allterms_end(),
560
+ has_termfreq=TermIter.LAZY)
561
+ else:
562
+ return TermIter(self.allterms_begin(prefix), self.allterms_end(prefix),
563
+ has_termfreq=TermIter.LAZY)
564
+ Database.__iter__ = _database_gen_allterms_iter
565
+ Database.allterms = _database_gen_allterms_iter
566
+
567
+ # Modify Database to add a "termlist()" method.
568
+ def _database_gen_termlist_iter(self, docid):
569
+ """Get an iterator over all the terms which index a given document ID.
570
+
571
+ The iterator will return TermListItem objects.
572
+
573
+ Access to term frequency and position information is only available until
574
+ the iterator has moved on.
575
+
576
+ """
577
+ # Note: has_termfreq is set to LAZY because most databases don't store term
578
+ # frequencies in the termlist (because this would require updating many termlist
579
+ # entries for every document update), so access to the term frequency requires a
580
+ # separate lookup.
581
+ return TermIter(self.termlist_begin(docid), self.termlist_end(docid),
582
+ has_termfreq=TermIter.LAZY,
583
+ has_wdf=TermIter.EAGER,
584
+ has_positions=TermIter.LAZY)
585
+ Database.termlist = _database_gen_termlist_iter
586
+
587
+ # Modify Database to add a "spellings()" method.
588
+ def _database_gen_spellings_iter(self):
589
+ """Get an iterator which returns all the spelling correction targets
590
+
591
+ The iterator will return TermListItem objects. Only the term frequency is
592
+ available; wdf and positions are not meaningful.
593
+
594
+ """
595
+ return TermIter(self.spellings_begin(), self.spellings_end(),
596
+ has_termfreq=TermIter.EAGER,
597
+ has_wdf=TermIter.INVALID,
598
+ has_positions=TermIter.INVALID)
599
+ Database.spellings = _database_gen_spellings_iter
600
+
601
+ # Modify Database to add a "synonyms()" method.
602
+ def _database_gen_synonyms_iter(self, term):
603
+ """Get an iterator which returns all the synonyms for a given term.
604
+
605
+ The term to return synonyms for is specified by the `term` parameter.
606
+
607
+ The iterator will return string objects.
608
+
609
+ """
610
+ return TermIter(self.synonyms_begin(term),
611
+ self.synonyms_end(term),
612
+ return_strings=True)
613
+ Database.synonyms = _database_gen_synonyms_iter
614
+
615
+ # Modify Database to add a "synonym_keys()" method.
616
+ def _database_gen_synonym_keys_iter(self, prefix=""):
617
+ """Get an iterator which returns all the terms which have synonyms.
618
+
619
+ The iterator will return string objects.
620
+
621
+ If `prefix` is non-empty, only terms with this prefix are returned.
622
+
623
+ """
624
+ return TermIter(self.synonym_keys_begin(prefix),
625
+ self.synonym_keys_end(prefix),
626
+ return_strings=True)
627
+ Database.synonym_keys = _database_gen_synonym_keys_iter
628
+
629
+ # Modify Database to add a "metadata_keys()" method, instead of direct access
630
+ # to metadata_keys_begin and metadata_keys_end.
631
+ def _database_gen_metadata_keys_iter(self, prefix=""):
632
+ """Get an iterator which returns all the metadata keys.
633
+
634
+ The iterator will return string objects.
635
+
636
+ If `prefix` is non-empty, only metadata keys with this prefix are returned.
637
+
638
+ """
639
+ return TermIter(self._metadata_keys_begin(prefix),
640
+ self._metadata_keys_end(prefix),
641
+ return_strings=True)
642
+ Database.metadata_keys = _database_gen_metadata_keys_iter
643
+
644
+ # Modify Document to add an "__iter__()" method and a "termlist()" method.
645
+ def _document_gen_termlist_iter(self):
646
+ """Get an iterator over all the terms in a document.
647
+
648
+ The iterator will return TermListItem objects.
649
+
650
+ Access to term frequency and position information is only available until
651
+ the iterator has moved on.
652
+
653
+ Note that term frequency information is only meaningful for a document
654
+ retrieved from a database. If term frequency information is requested for
655
+ a document which was freshly created, an InvalidOperationError will be
656
+ raised.
657
+
658
+ """
659
+ # Note: document termlist iterators may be implemented entirely in-memory
660
+ # (in which case access to all items could be allowed eagerly), but may
661
+ # also be implemented by returning a database termlist (for documents which
662
+ # are stored in a database, rather than freshly created). We choose the
663
+ # most conservative settings, to avoid doing eager access when lazy access
664
+ # would be more appropriate.
665
+ return TermIter(self.termlist_begin(), self.termlist_end(),
666
+ has_termfreq=TermIter.LAZY,
667
+ has_wdf=TermIter.EAGER,
668
+ has_positions=TermIter.LAZY)
669
+ Document.__iter__ = _document_gen_termlist_iter
670
+ Document.termlist = _document_gen_termlist_iter
671
+
672
+ # Modify QueryParser to add a "stoplist()" method.
673
+ def _queryparser_gen_stoplist_iter(self):
674
+ """Get an iterator over all the stopped terms from the previous query.
675
+
676
+ This returns an iterator over all the terms which were omitted from the
677
+ previously parsed query due to being considered to be stopwords. Each
678
+ instance of a word omitted from the query is represented in the returned
679
+ list, in the order in which the
680
+
681
+ The iterator will return string objects.
682
+
683
+ """
684
+ return TermIter(self.stoplist_begin(), self.stoplist_end(),
685
+ return_strings=True)
686
+ QueryParser.stoplist = _queryparser_gen_stoplist_iter
687
+
688
+ # Modify QueryParser to add an "unstemlist()" method.
689
+ def _queryparser_gen_unstemlist_iter(self, tname):
690
+ """Get an iterator over all the unstemmed forms of a stemmed term.
691
+
692
+ This returns an iterator which returns all the unstemmed words which were
693
+ stemmed to the stemmed form specifed by `tname` when parsing the previous
694
+ query. Each instance of a word which stems to `tname` is returned by the
695
+ iterator in the order in which the words appeared in the query - an
696
+ individual unstemmed word may thus occur multiple times.
697
+
698
+ The iterator will return string objects.
699
+
700
+ """
701
+ return TermIter(self.unstem_begin(tname), self.unstem_end(tname),
702
+ return_strings=True)
703
+ QueryParser.unstemlist = _queryparser_gen_unstemlist_iter
704
+
705
+ # When we set a ValueRangeProcessor into the QueryParser, keep a python
706
+ # reference so it won't be deleted. This hack can probably be removed once
707
+ # xapian bug #186 is fixed.
708
+ __queryparser_add_valuerangeprocessor_orig = QueryParser.add_valuerangeprocessor
709
+ def _queryparser_add_valuerangeprocessor(self, vrproc):
710
+ if not hasattr(self, '_vrps'):
711
+ self._vrps = []
712
+ self._vrps.append(vrproc)
713
+ return __queryparser_add_valuerangeprocessor_orig(self, vrproc)
714
+ _queryparser_add_valuerangeprocessor.__doc__ = __queryparser_add_valuerangeprocessor_orig.__doc__
715
+ QueryParser.add_valuerangeprocessor = _queryparser_add_valuerangeprocessor
716
+ del _queryparser_add_valuerangeprocessor
717
+
718
+ # When we set a Stopper into the QueryParser, keep a python reference so it
719
+ # won't be deleted. This hack can probably be removed once xapian bug #186 is
720
+ # fixed.
721
+ __queryparser_set_stopper_orig = QueryParser.set_stopper
722
+ def _queryparser_set_stopper(self, stopper):
723
+ self._stopper = stopper
724
+ return __queryparser_set_stopper_orig(self, stopper)
725
+ _queryparser_set_stopper.__doc__ = __queryparser_set_stopper_orig.__doc__
726
+ QueryParser.set_stopper = _queryparser_set_stopper
727
+ del _queryparser_set_stopper
728
+
729
+ # When we set a Stopper into the TermGenerator, keep a python reference so it
730
+ # won't be deleted. This hack can probably be removed once xapian bug #186 is
731
+ # fixed.
732
+ __termgenerator_set_stopper_orig = TermGenerator.set_stopper
733
+ def _termgenerator_set_stopper(self, stopper):
734
+ self._stopper = stopper
735
+ return __termgenerator_set_stopper_orig(self, stopper)
736
+ _termgenerator_set_stopper.__doc__ = __termgenerator_set_stopper_orig.__doc__
737
+ TermGenerator.set_stopper = _termgenerator_set_stopper
738
+ del _termgenerator_set_stopper
739
+
740
+ def _enquire_check_deprec_args(reverse, kwargs, methodname):
741
+ """Check the keyword arguments to one of the enquire set_sort_* methods.
742
+
743
+ """
744
+ if reverse is not None:
745
+ if 'ascending' in kwargs:
746
+ raise TypeError('Only one of "reverse" and "ascending" may be specified')
747
+ if len(kwargs) != 0:
748
+ raise TypeError('Only keyword arguments allowed are "reverse" and "ascending"')
749
+ else:
750
+ if 'ascending' in kwargs:
751
+ reverse = kwargs.get('ascending')
752
+ del kwargs['ascending']
753
+ else:
754
+ reverse = True
755
+ if len(kwargs) != 0:
756
+ raise TypeError('Only keyword arguments allowed are "reverse" and "ascending"')
757
+ return reverse
758
+
759
+ # When we set a Sorter on enquire, keep a python reference so it won't be
760
+ # deleted. This hack can probably be removed once xapian bug #186 is fixed.
761
+ __enquire_set_sort_by_key_orig = Enquire.set_sort_by_key
762
+ def _enquire_set_sort_by_key(self, sorter, reverse=None, **kwargs):
763
+ self._sorter = sorter
764
+ reverse = _enquire_check_deprec_args(reverse, kwargs, "set_sort_by_key")
765
+ return __enquire_set_sort_by_key_orig(self, sorter, reverse)
766
+ _enquire_set_sort_by_key.__doc__ = __enquire_set_sort_by_key_orig.__doc__
767
+ Enquire.set_sort_by_key = _enquire_set_sort_by_key
768
+ del _enquire_set_sort_by_key
769
+
770
+ __enquire_set_sort_by_key_then_relevance_orig = Enquire.set_sort_by_key_then_relevance
771
+ def _enquire_set_sort_by_key_then_relevance(self, sorter, reverse=None, **kwargs):
772
+ self._sorter = sorter
773
+ reverse = _enquire_check_deprec_args(reverse, kwargs, "set_sort_by_key_then_relevance")
774
+ return __enquire_set_sort_by_key_then_relevance_orig(self, sorter, reverse)
775
+ _enquire_set_sort_by_key_then_relevance.__doc__ = __enquire_set_sort_by_key_then_relevance_orig.__doc__
776
+ Enquire.set_sort_by_key_then_relevance = _enquire_set_sort_by_key_then_relevance
777
+ del _enquire_set_sort_by_key_then_relevance
778
+
779
+ __enquire_set_sort_by_relevance_then_key_orig = Enquire.set_sort_by_relevance_then_key
780
+ def _enquire_set_sort_by_relevance_then_key(self, sorter, reverse=None, **kwargs):
781
+ self._sorter = sorter
782
+ reverse = _enquire_check_deprec_args(reverse, kwargs, "set_sort_by_relevance_then_key")
783
+ return __enquire_set_sort_by_relevance_then_key_orig(self, sorter, reverse)
784
+ _enquire_set_sort_by_relevance_then_key.__doc__ = __enquire_set_sort_by_relevance_then_key_orig.__doc__
785
+ Enquire.set_sort_by_relevance_then_key = _enquire_set_sort_by_relevance_then_key
786
+ del _enquire_set_sort_by_relevance_then_key
787
+
788
+ __enquire_set_sort_by_value_orig = Enquire.set_sort_by_value
789
+ def _enquire_set_sort_by_value(self, sort_key, reverse=None, **kwargs):
790
+ reverse = _enquire_check_deprec_args(reverse, kwargs, "set_sort_by_value")
791
+ return __enquire_set_sort_by_value_orig(self, sort_key, reverse)
792
+ _enquire_set_sort_by_value.__doc__ = __enquire_set_sort_by_value_orig.__doc__
793
+ Enquire.set_sort_by_value = _enquire_set_sort_by_value
794
+ del _enquire_set_sort_by_value
795
+
796
+ __enquire_set_sort_by_relevance_then_value_orig = Enquire.set_sort_by_relevance_then_value
797
+ def _enquire_set_sort_by_relevance_then_value(self, sort_key, reverse=None, **kwargs):
798
+ reverse = _enquire_check_deprec_args(reverse, kwargs, "set_sort_by_relevance_then_value")
799
+ return __enquire_set_sort_by_relevance_then_value_orig(self, sort_key, reverse)
800
+ _enquire_set_sort_by_relevance_then_value.__doc__ = __enquire_set_sort_by_relevance_then_value_orig.__doc__
801
+ Enquire.set_sort_by_relevance_then_value = _enquire_set_sort_by_relevance_then_value
802
+ del _enquire_set_sort_by_relevance_then_value
803
+
804
+ __enquire_set_sort_by_value_then_relevance_orig = Enquire.set_sort_by_value_then_relevance
805
+ def _enquire_set_sort_by_value_then_relevance(self, sort_key, reverse=None, **kwargs):
806
+ reverse = _enquire_check_deprec_args(reverse, kwargs, "set_sort_by_value_then_relevance")
807
+ return __enquire_set_sort_by_value_then_relevance_orig(self, sort_key, reverse)
808
+ _enquire_set_sort_by_value_then_relevance.__doc__ = __enquire_set_sort_by_value_then_relevance_orig.__doc__
809
+ Enquire.set_sort_by_value_then_relevance = _enquire_set_sort_by_value_then_relevance
810
+ del _enquire_set_sort_by_value_then_relevance
811
+
812
+
813
+ ##########################################
814
+ # Support for iteration of posting lists #
815
+ ##########################################
816
+
817
+ class PostingItem(_SequenceMixIn):
818
+ """An item returned from iteration of a posting list.
819
+
820
+ The item supports access to the following attributes and properties:
821
+
822
+ - `docid`: The document ID corresponding to this PostingItem.
823
+ - `doclength`: The length of the document corresponding to this
824
+ PostingItem.
825
+ - `wdf`: The within document frequency of the term which the posting list
826
+ is for in the document corresponding to this PostingItem.
827
+ - `positer`: An iterator over the positions which the term corresponing to
828
+ this posting list occurs at in the document corresponding to this
829
+ PostingItem. This is only available until the iterator which returned
830
+ this item next moves.
831
+
832
+ """
833
+ __slots__ = ('_iter', 'docid', 'doclength', 'wdf',)
834
+
835
+ def __init__(self, iter):
836
+ self._iter = iter
837
+ self.docid = iter._iter.get_docid()
838
+ self.doclength = iter._iter.get_doclength()
839
+ self.wdf = iter._iter.get_wdf()
840
+
841
+ # Support for sequence API
842
+ sequence = ['docid', 'doclength', 'wdf', 'positer']
843
+ if not iter._has_positions:
844
+ sequence[3] = PositionIter()
845
+ _SequenceMixIn.__init__(self, *sequence)
846
+
847
+ def _get_positer(self):
848
+ """Get a position list iterator.
849
+
850
+ The iterator will return integers representing the positions that the
851
+ term occurs at in the document corresponding to this PostingItem.
852
+
853
+ This will raise a InvalidOperationError exception if the iterator this
854
+ item came from doesn't support position lists, or if the iterator has
855
+ moved on since the item was returned from it.
856
+
857
+ """
858
+ if not self._iter._has_positions:
859
+ raise InvalidOperationError("Iterator does not support position lists")
860
+ if self._iter._iter == self._iter._end or \
861
+ self.docid != self._iter._iter.get_docid():
862
+ raise InvalidOperationError("Iterator has moved, and does not support random access")
863
+ return PositionIter(self._iter._iter.positionlist_begin(),
864
+ self._iter._iter.positionlist_end())
865
+ positer = property(_get_positer, doc=
866
+ """A position iterator for the current posting (if meaningful).
867
+
868
+ The iterator will return integers representing the positions that the term
869
+ occurs at.
870
+
871
+ This will raise a InvalidOperationError exception if the iterator this item
872
+ came from doesn't support position lists, or if the iterator has moved on
873
+ since the item was returned from it.
874
+
875
+ """)
876
+
877
+
878
+ class PostingIter(object):
879
+ """An iterator over a posting list.
880
+
881
+ The iterator will return PostingItem objects, which will be evaluated
882
+ lazily where appropriate.
883
+
884
+ """
885
+ __slots__ = ('_iter', '_end', '_has_positions', '_moved')
886
+
887
+ def __init__(self, start, end, has_positions=False):
888
+ self._iter = start
889
+ self._end = end
890
+ self._has_positions = has_positions
891
+
892
+ # _moved is True if we've moved onto the next item. This is needed so
893
+ # that the iterator doesn't have to move on until just before next() is
894
+ # called: since the iterator starts by pointing at a valid item, we
895
+ # can't just call self._iter.next() unconditionally at the start of our
896
+ # next() method.
897
+ self._moved = True
898
+
899
+ def __iter__(self):
900
+ return self
901
+
902
+ def next(self):
903
+ if not self._moved:
904
+ self._iter.next()
905
+ self._moved = True
906
+
907
+ if self._iter == self._end:
908
+ raise StopIteration
909
+ else:
910
+ self._moved = False
911
+ return PostingItem(self)
912
+
913
+ def skip_to(self, docid):
914
+ """Skip the iterator forward.
915
+
916
+ The iterator is advanced to the first document with a document ID
917
+ which is greater than or equal to the supplied document ID.
918
+
919
+ If there are no such items, this will raise StopIteration.
920
+
921
+ This returns the item which the iterator is moved to. The subsequent
922
+ item will be returned the next time that next() is called (unless
923
+ skip_to() is called again first).
924
+
925
+ """
926
+ if self._iter != self._end:
927
+ self._iter.skip_to(docid)
928
+ if self._iter == self._end:
929
+ self._moved = True
930
+ raise StopIteration
931
+ self._moved = False
932
+ return PostingItem(self)
933
+
934
+ def _database_gen_postlist_iter(self, tname):
935
+ """Get an iterator over the postings which are indexed by a given term.
936
+
937
+ If `tname` is empty, an iterator over all the documents will be returned
938
+ (this will contain one entry for each document, will always return a wdf of
939
+ 1, and will not allow access to a position iterator).
940
+
941
+ """
942
+ if len(tname) != 0:
943
+ return PostingIter(self.postlist_begin(tname), self.postlist_end(tname),
944
+ has_positions=True)
945
+ else:
946
+ return PostingIter(self.postlist_begin(tname), self.postlist_end(tname))
947
+ Database.postlist = _database_gen_postlist_iter
948
+
949
+
950
+ ###########################################
951
+ # Support for iteration of position lists #
952
+ ###########################################
953
+
954
+ class PositionIter(object):
955
+ """An iterator over a position list.
956
+
957
+ The iterator will return integers, in ascending order.
958
+
959
+ """
960
+ def __init__(self, start = 0, end = 0):
961
+ self.iter = start
962
+ self.end = end
963
+
964
+ def __iter__(self):
965
+ return self
966
+
967
+ def next(self):
968
+ if self.iter==self.end:
969
+ raise StopIteration
970
+ else:
971
+ r = self.iter.get_termpos()
972
+ self.iter.next()
973
+ return r
974
+
975
+ # Modify Database to add a "positionlist()" method.
976
+ def _database_gen_positionlist_iter(self, docid, tname):
977
+ """Get an iterator over all the positions in a given document of a term.
978
+
979
+ The iterator will return integers, in ascending order.
980
+
981
+ """
982
+ return PositionIter(self.positionlist_begin(docid, tname), self.positionlist_end(docid, tname))
983
+ Database.positionlist = _database_gen_positionlist_iter
984
+
985
+ ########################################
986
+ # Support for iteration of value lists #
987
+ ########################################
988
+
989
+ class ValueItem(_SequenceMixIn):
990
+ """An item returned from iteration of the values in a document.
991
+
992
+ The item supports access to the following attributes:
993
+
994
+ - `num`: The number of the value.
995
+ - `value`: The contents of the value.
996
+
997
+ """
998
+
999
+ __slots__ = ('num', 'value', )
1000
+
1001
+ def __init__(self, num, value):
1002
+ self.num = num
1003
+ self.value = value
1004
+ _SequenceMixIn.__init__(self, 'num', 'value')
1005
+
1006
+ class ValueIter(object):
1007
+ """An iterator over all the values stored in a document.
1008
+
1009
+ The iterator will return ValueItem objects, in ascending order of value number.
1010
+
1011
+ """
1012
+ def __init__(self, start, end):
1013
+ self.iter = start
1014
+ self.end = end
1015
+
1016
+ def __iter__(self):
1017
+ return self
1018
+
1019
+ def next(self):
1020
+ if self.iter==self.end:
1021
+ raise StopIteration
1022
+ else:
1023
+ r = ValueItem(self.iter.get_valueno(), self.iter.get_value())
1024
+ self.iter.next()
1025
+ return r
1026
+
1027
+ # Modify Document to add a "values()" method.
1028
+ def _document_gen_values_iter(self):
1029
+ """Get an iterator over all the values stored in a document.
1030
+
1031
+ The iterator will return ValueItem objects, in ascending order of value number.
1032
+
1033
+ """
1034
+ return ValueIter(self.values_begin(), self.values_end())
1035
+ Document.values = _document_gen_values_iter
1036
+
1037
+ # Set the list of names which should be public.
1038
+ # Note that this needs to happen at the end of xapian.py.
1039
+ __all__ = []
1040
+ for item in dir():
1041
+ if item.startswith('_') or item.endswith('_swigregister') or item.endswith('Iterator'):
1042
+ continue
1043
+ __all__.append(item)
1044
+ __all__ = tuple(__all__)
1045
+
1046
+ %}
1047
+
1048
+ /* vim:syntax=python:set expandtab: */