1 Tcl8 bindings for Xapian
2 ************************
4 The Tcl8 bindings for Xapian are packaged in the ``xapian`` namespace,
5 and largely follow the C++ API, with the following differences and
6 additions. Tcl8 strings and lists, etc., are converted automatically
7 in the bindings, so generally it should just work as expected.
9 The ``examples`` subdirectory contains examples showing how to use the
10 Tcl8 bindings based on the simple examples from ``xapian-examples``:
11 `simpleindex.tcl <examples/simpleindex.tcl>`_,
12 `simplesearch.tcl <examples/simplesearch.tcl>`_,
13 `simpleexpand.tcl <examples/simpleexpand.tcl>`_.
18 In Xapian 1.0.0 and later, the Xapian::Stem, Xapian::QueryParser, and
19 Xapian::TermGenerator classes all assume text is in UTF-8. Tcl8 uses
20 UTF-8 as its internal representation, except that ASCII nul (character value
21 0) is represented as the overlong (and thus invalid) UTF-8 sequence
22 ``\xc0\x80``. We don't currently convert this to/from
23 ``\x00`` so you should avoid passing strings containing ASCII nul
24 between Tcl and Xapian.
30 To destroy an object ``obj``, you need to use one of
31 ``obj -delete`` or ``rename obj ""``
32 (either should work, but see below).
34 SWIG's Tcl wrapping doesn't handle an object returned by a factory function
35 correctly. This only matters for the Xapian::WritableDatabase class, and we
36 avoid wrapping the problematic ``Xapian::Chert::open`` factory function to
37 avoid setting a trap for the unwary.
38 You can just use a ``Xapian::WritableDatabase`` constructor
39 instead (and specify a backend by passing ``$::xapian::DB_BACKEND_GLASS`` or
40 similar in the flags).
42 As of Xapian 1.1.0, you can explicitly close the database, so the lack
43 of a call to the destructor isn't an issue:
47 xapian::WritableDatabase xapiandb testdir $::xapian::DB_CREATE_OR_OVERWRITE
50 If you want compatibility with Xapian 1.0.x, then
51 Michael Schlenker reports that this form works (i.e. the destructor gets
56 xapian::WritableDatabase xapiandb testdir $::xapian::DB_CREATE_OR_OVERWRITE
59 However, apparently none of these forms work:
63 xapian::WritableDatabase xapiandb testdir $::xapian::DB_CREATE_OR_OVERWRITE
67 set db [xapian::WritableDatabase xapiandb testdir $::xapian::DB_CREATE_OR_OVERWRITE]
70 set db [xapian::WritableDatabase xapiandb testdir $::xapian::DB_CREATE_OR_OVERWRITE]
77 Xapian::Error exceptions can be handled in Tcl like so:
82 # Code which might throw an exception.
84 # Code to handle exceptions.
85 # $errorCode is "XAPIAN <error_class>" (e.g. "XAPIAN DocNotFoundError".)
86 # $msg is the result of calling get_msg() on the Xapian::Error object.
93 All iterators support ``next`` and ``equals`` methods
94 to move through and test iterators (as for all language bindings).
95 MSetIterator and ESetIterator also support ``prev``.
97 Iterator dereferencing
98 ######################
100 C++ iterators are often dereferenced to get information, eg
101 ``(*it)``. With Tcl8 these are all mapped to named methods, as
104 .. table:: Iterator deferencing methods
106 +------------------+----------------------+
107 | Iterator | Dereferencing method |
108 +==================+======================+
109 | PositionIterator | ``get_termpos`` |
110 +------------------+----------------------+
111 | PostingIterator | ``get_docid`` |
112 +------------------+----------------------+
113 | TermIterator | ``get_term`` |
114 +------------------+----------------------+
115 | ValueIterator | ``get_value`` |
116 +------------------+----------------------+
117 | MSetIterator | ``get_docid`` |
118 +------------------+----------------------+
119 | ESetIterator | ``get_term`` |
120 +------------------+----------------------+
122 Other methods, such as ``MSetIterator::get_document``, are
123 available under the same names.
129 MSet objects have some additional methods to simplify access (these
130 work using the C++ array dereferencing):
132 .. table:: MSet additional methods
134 +---------------------------------------+--------------------------------------------------+
135 | Method name | Explanation |
136 +=======================================+==================================================+
137 | ``mset get_hit index`` | returns MSetIterator at index |
138 +---------------------------------------+--------------------------------------------------+
139 | ``mset get_document_percentage index``| ``mset convert_to_percent [mset get_hit index]`` |
140 +---------------------------------------+--------------------------------------------------+
141 | ``mset get_document index`` | ``[mset get_hit index] get_document`` |
142 +---------------------------------------+--------------------------------------------------+
143 | ``mset get_docid index`` | ``[mset get_hit index] get_docid`` |
144 +---------------------------------------+--------------------------------------------------+
150 The C++ API contains a few non-class functions (the Database factory
151 functions, and some functions reporting version information), which are
152 wrapped like so for Tcl:
154 - ``Xapian::version_string()`` is wrapped as ``xapian::version_string``
155 - ``Xapian::major_version()`` is wrapped as ``xapian::major_version``
156 - ``Xapian::minor_version()`` is wrapped as ``xapian::minor_version``
157 - ``Xapian::revision()`` is wrapped as ``xapian::revision``
158 - ``Xapian::Auto::open_stub()`` is wrapped as ``xapian::open_stub``
159 - ``Xapian::Chert::open()`` is wrapped as ``xapian::chert_open`` (but note that the WritableDatabase version isn't wrapped - see the 'Destructors' section above for an explanation - and this function is deprecated anyway).
160 - ``Xapian::InMemory::open()`` is wrapped as ``xapian::inmemory_open``
161 - ``Xapian::Remote::open()`` is wrapped as ``xapian::remote_open`` (both the TCP and "program" versions are wrapped - the SWIG wrapper checks the parameter list to decide which to call).
162 - ``Xapian::Remote::open_writable()`` is wrapped as ``xapian::remote_open_writable`` (both the TCP and "program" versions are wrapped - the SWIG wrapper checks the parameter list to decide which to call).
168 For Tcl, constants are wrapped as ``$xapian::CONSTANT_NAME``
169 or ``$xapian::ClassName_CONSTANT_NAME``.
170 So ``Xapian::DB_CREATE_OR_OPEN`` is available as
171 ``$xapian::DB_CREATE_OR_OPEN``, ``Xapian::Query::OP_OR`` is
172 available as ``$xapian::Query_OP_OR``, and so on.
177 In C++ there's a Xapian::Query constructor which takes a query operator and
178 start/end iterators specifying a number of terms or queries, plus an optional
179 parameter. In Tcl, this is wrapped to accept a Tcl list
180 to give the terms/queries, and you can specify
181 a mixture of terms and queries if you wish. For example:
186 set terms [list "hello" "world"]
187 xapian::Query subq $xapian::Query_OP_AND $terms
188 xapian::Query bar_term "bar" 2
189 xapian::Query query $xapian::Query_OP_AND [list subq "foo" bar_term]
192 MatchAll and MatchNothing
193 -------------------------
195 As of Xapian 1.1.1, these are wrapped for Tcl as
196 ``$xapian::Query_MatchAll`` and
197 ``$xapian::Query_MatchNothing``.
202 There is an additional method ``get_matching_terms`` which takes
203 an MSetIterator and returns a list of terms in the current query which
204 match the document given by that iterator. You may find this
205 more convenient than using the TermIterator directly.