diff options
| author | Arun Isaac | 2026-09-23 01:47:30 +0100 |
|---|---|---|
| committer | Arun Isaac | 2026-09-23 02:00:52 +0100 |
| commit | 502566073c07eac6a91131847691cc0dbc093b18 (patch) | |
| tree | 0965d6996003bd77866aa9ef5a7a1053941b0d96 | |
| parent | af2d7193314ee6b814c01bc38c9c599ee90fb004 (diff) | |
| download | guile-xapian-502566073c07eac6a91131847691cc0dbc093b18.tar.gz guile-xapian-502566073c07eac6a91131847691cc0dbc093b18.tar.lz guile-xapian-502566073c07eac6a91131847691cc0dbc093b18.zip | |
Replace query combinator with C++ query builder.
We need composite queries to have more than two subqueries. The only way to do this is to provide Xapian::Query with an iterator. And to do this, we need to drop down to C++.
| -rw-r--r-- | xapian.i.in | 19 | ||||
| -rw-r--r-- | xapian/xapian.scm | 27 |
2 files changed, 28 insertions, 18 deletions
diff --git a/xapian.i.in b/xapian.i.in index 84695e9..ba923d4 100644 --- a/xapian.i.in +++ b/xapian.i.in @@ -1,5 +1,5 @@ /* guile-xapian --- Guile bindings for Xapian - * Copyright © 2020, 2023–2024 Arun Isaac <arunisaac@systemreboot.net> + * Copyright © 2020, 2023–2024, 2026 Arun Isaac <arunisaac@systemreboot.net> * Copyright © 2021, 2022 Bob131 <bob@bob131.so> * * This file is part of guile-xapian. @@ -206,3 +206,20 @@ class GuileXapianFieldProcessorWrapper ~GuileXapianFieldProcessorWrapper(); Xapian::Query operator()(std::string const&); }; + +// Build query from subqueries. This needs to be in C++ because we +// need to provide Xapian::Query with an iterator. +%{ + Xapian::Query guile_xapian_build_query(Xapian::Query::op op, SCM subqueries) { + int length = scm_to_int(scm_length(subqueries)); + Xapian::Query **subqueries_arr = (Xapian::Query**) malloc(length * sizeof(Xapian::Query*)); + for (int i=0; i<length; i++) + SWIG_ConvertPtr(scm_list_ref(subqueries, scm_from_int(i)), + (void**)&subqueries_arr[i], + SWIGTYPE_p_Xapian__Query, + 0); + return Xapian::Query(op, subqueries_arr, subqueries_arr + length); + } +%} + +Xapian::Query guile_xapian_build_query(Xapian::Query::op, SCM); diff --git a/xapian/xapian.scm b/xapian/xapian.scm index d71bbe1..00a4896 100644 --- a/xapian/xapian.scm +++ b/xapian/xapian.scm @@ -299,17 +299,12 @@ on the database object." "Return a @code{Query} object for @var{term}." (new-Query term)) -(define (query-combine combine-operator default . queries) - (reduce-right (cut new-Query combine-operator <> <>) - default - queries)) - (define (query-and . queries) "Return a query matching only documents matching all @var{queries}. In a weighted context, the weight is the sum of the weights for all queries." - (apply query-combine (Query-OP-AND) (Query-MatchAll) queries)) + (guile-xapian-build-query (Query-OP-AND) queries)) (define (query-or . queries) "Return a query matching documents which at least one of @var{queries} @@ -317,7 +312,7 @@ match. In a weighted context, the weight is the sum of the weights for matching queries." - (apply query-combine (Query-OP-OR) (Query-MatchNothing) queries)) + (guile-xapian-build-query (Query-OP-OR) queries)) (define (query-xor . queries) "Return a query matching documents which an odd number of @var{queries} @@ -325,7 +320,7 @@ match. In a weighted context, the weight is the sum of the weights for matching queries." - (apply query-combine (Query-OP-XOR) (Query-MatchNothing) queries)) + (guile-xapian-build-query (Query-OP-XOR) queries)) (define (query-filter . queries) "Return a query matching only documents matching all @var{queries}, @@ -333,19 +328,17 @@ but only take weight from the first of @var{queries}. In a non-weighted context, @code{query-filter} and @code{query-and} are equivalent." - (apply query-combine (Query-OP-FILTER) (Query-MatchAll) queries)) + (guile-xapian-build-query (Query-OP-FILTER) queries)) -(define (query-phrase first-query . other-queries) - "Return a query matching only documents where @var{first-query} and all -of @var{other-queries} match near and in order. All queries must be -single-term queries (constructed using @code{query}) or single-term -queries composed with @code{query-or}. +(define (query-phrase . queries) + "Return a query matching only documents where all @var{queries} match +near and in order. All queries must be single-term +queries (constructed using @code{query}) or single-term queries +composed with @code{query-or}. In a weighted context, the weight is the sum of the weights for all queries." - (new-Query (Query-OP-PHRASE) - first-query - (apply query-or other-queries))) + (guile-xapian-build-query (Query-OP-PHRASE) queries)) (define* (prefixed-range-processor slot proc #:key (prefix "") repeated?) |
