xspond-xapian-ruby 0.1 → 0.1.1

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 (4) hide show
  1. data/ext/extconf.rb +1 -1
  2. data/lib/xapian.rb +63 -23
  3. data/tests/smoketest.rb +18 -10
  4. metadata +2 -2
data/ext/extconf.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'mkmf'
2
2
 
3
- XAPIAN_RUBY_VERSION = 0.1
3
+ XAPIAN_RUBY_VERSION = '0.1.1'
4
4
 
5
5
  # Shamelessly borrowed from the RMagick project
6
6
  # Thanks!
data/lib/xapian.rb CHANGED
@@ -49,21 +49,64 @@ module Xapian
49
49
  # underlying Iterator
50
50
  def _safelyIterate(dangerousStart, dangerousEnd) #:nodoc:
51
51
  retval = Array.new
52
-
52
+
53
53
  item = dangerousStart
54
54
  lastTerm = dangerousEnd
55
-
55
+
56
56
  return retval if dangerousStart.equals(dangerousEnd)
57
57
 
58
- begin
58
+ begin
59
59
  retval.push(yield(item))
60
60
  item.next()
61
- end while not item.equals(lastTerm) # must use primitive C++ comparator
62
-
61
+ end while not item.equals(lastTerm) # must use primitive C++ comparator
62
+
63
63
  return retval
64
64
  end # _safelyIterate
65
65
  module_function :_safelyIterate
66
66
 
67
+ # A class to wrap safelyIterate to eliminate the overhead of generating an array
68
+ #
69
+ # new takes the start iterorator, end iterator, and a block used to generate an
70
+ # appropriate Ruby object to wrap the underlying Iterator
71
+ class ProxyIterator
72
+ instance_methods.each {|name| undef_method name if name !~ /^(__|instance_eval)/ }
73
+
74
+ include Enumerable
75
+
76
+ def initialize(object, dangerousStart, dangerousEnd, &block)
77
+ @object = object
78
+ @dangerousStart = dangerousStart
79
+ @dangerousEnd = @object.send(dangerousEnd)
80
+ @block = block
81
+ @proxy_target = nil
82
+ end
83
+
84
+ def each
85
+ # if the array is already loaded use it
86
+ # otherwise use iterator
87
+ if @proxy_target
88
+ @proxy_target.each {|i| yield(i) }
89
+ else
90
+ item = @object.send(@dangerousStart)
91
+ # Must use .equals NOT ==
92
+ while !item.equals(@dangerousEnd)
93
+ yield(@block.call(item))
94
+ item.next
95
+ end
96
+ end
97
+ end
98
+
99
+ def method_missing(method, *args)
100
+ self.load_target.send(method, *args)
101
+ end
102
+
103
+ protected
104
+
105
+ def load_target
106
+ @proxy_target ||= self.entries
107
+ end
108
+ end
109
+
67
110
  #--
68
111
  ### safe Ruby wrapper for the dangerous C++ Xapian::TermIterator class
69
112
  class Xapian::Term
@@ -85,7 +128,7 @@ module Xapian
85
128
  # non-iterative data.
86
129
  # (MSetIterator is not dangerous, but it is inconvenient to use from a Ruby
87
130
  # idiom, so we wrap it..)
88
- class Xapian::Match
131
+ class Xapian::Match
89
132
  attr_accessor :docid, :document, :rank, :weight, :collapse_count, :percent
90
133
 
91
134
  def initialize(docid, document, rank, weight, collapse_count, percent)
@@ -98,7 +141,7 @@ module Xapian
98
141
  end # initialize
99
142
 
100
143
  def ==(other)
101
- return other.is_a?(Xapian::Match) && other.docid == @docid && other.rank == @rank &&
144
+ return other.is_a?(Xapian::Match) && other.docid == @docid && other.rank == @rank &&
102
145
  other.weight == @weight && other.collapse_count == @collapse_count && other.percent == @percent
103
146
  end
104
147
 
@@ -124,7 +167,7 @@ module Xapian
124
167
  # Ruby wrapper for Xapian::ValueIterator
125
168
  class Xapian::Value
126
169
  attr_accessor :value, :valueno
127
-
170
+
128
171
  def initialize(value, valueno)
129
172
  @value = value
130
173
  @valueno = valueno
@@ -139,13 +182,13 @@ module Xapian
139
182
  # Extend Xapian::Document with a nice wrapper for its nasty input_iterators
140
183
  class Xapian::Document
141
184
  def terms
142
- Xapian._safelyIterate(self._dangerous_termlist_begin(), self._dangerous_termlist_end()) { |item|
185
+ ProxyIterator.new(self, :_dangerous_termlist_begin, :_dangerous_termlist_end) { |item|
143
186
  Xapian::Term.new(item.term, item.wdf)
144
187
  }
145
188
  end # terms
146
189
 
147
190
  def values
148
- Xapian._safelyIterate(self._dangerous_values_begin(), self._dangerous_values_end()) { |item|
191
+ ProxyIterator.new(self, :_dangerous_values_begin, :_dangerous_values_end) { |item|
149
192
  Xapian::Value.new(item.value, item.valueno)
150
193
  }
151
194
  end # terms
@@ -156,7 +199,7 @@ module Xapian
156
199
  # Extend Xapian::Query with a nice wrapper for its dangerous iterators
157
200
  class Xapian::Query
158
201
  def terms
159
- Xapian._safelyIterate(self._dangerous_terms_begin(), self._dangerous_terms_end()) { |item|
202
+ ProxyIterator.new(self, :_dangerous_terms_begin, :_dangerous_terms_end) { |item|
160
203
  Xapian::Term.new(item.term, item.wdf)
161
204
  # termfreq is not supported by TermIterators from Queries
162
205
  }
@@ -169,7 +212,7 @@ module Xapian
169
212
  # Get matching terms for some document.
170
213
  # document can be either a Xapian::DocID or a Xapian::MSetIterator
171
214
  def matching_terms(document)
172
- Xapian._safelyIterate(self._dangerous_matching_terms_begin(document),
215
+ Xapian._safelyIterate(self._dangerous_matching_terms_begin(document),
173
216
  self._dangerous_matching_terms_end(document)) { |item|
174
217
  Xapian::Term.new(item.term, item.wdf)
175
218
  }
@@ -180,8 +223,7 @@ module Xapian
180
223
  # programming idiom. So we wrap them.
181
224
  class Xapian::MSet
182
225
  def matches
183
- Xapian._safelyIterate(self._begin(),
184
- self._end()) { |item|
226
+ ProxyIterator.new(self, :_begin, :_end) { |item|
185
227
  Xapian::Match.new(item.docid, item.document, item.rank, item.weight, item.collapse_count, item.percent)
186
228
  }
187
229
 
@@ -192,10 +234,9 @@ module Xapian
192
234
  # programming idiom. So we wrap them.
193
235
  class Xapian::ESet
194
236
  def terms
195
- Xapian._safelyIterate(self._begin(),
196
- self._end()) { |item|
197
- # note: in the ExpandTerm wrapper, we implicitly rename
198
- # ESetIterator#termname() (defined in xapian.i) to ExpandTerm#term()
237
+ ProxyIterator.new(self, :_begin, :_end) { |item|
238
+ # note: in the ExpandTerm wrapper, we implicitly rename
239
+ # ESetIterator#termname() (defined in xapian.i) to ExpandTerm#term()
199
240
  Xapian::ExpandTerm.new(item.termname, item.weight)
200
241
  }
201
242
 
@@ -225,8 +266,7 @@ module Xapian
225
266
  class Xapian::Database
226
267
  # Returns an Array of all Xapian::Terms for this database.
227
268
  def allterms
228
- Xapian._safelyIterate(self._dangerous_allterms_begin(),
229
- self._dangerous_allterms_end()) { |item|
269
+ ProxyIterator.new(self, :_dangerous_allterms_begin, :_dangerous_allterms_end) { |item|
230
270
  Xapian::Term.new(item.term, 0, item.termfreq)
231
271
  }
232
272
  end # allterms
@@ -234,10 +274,10 @@ module Xapian
234
274
  # Returns an Array of Xapian::Postings for the given term.
235
275
  # term is a string.
236
276
  def postlist(term)
237
- Xapian._safelyIterate(self._dangerous_postlist_begin(term),
277
+ Xapian._safelyIterate(self._dangerous_postlist_begin(term),
238
278
  self._dangerous_postlist_end(term)) { |item|
239
279
  Xapian::Posting.new(item.docid, item.doclength, item.wdf)
240
- }
280
+ }
241
281
  end # postlist(term)
242
282
 
243
283
  # Returns an Array of Terms for the given docid.
@@ -247,7 +287,7 @@ module Xapian
247
287
  Xapian::Term.new(item.term, item.wdf, item.termfreq)
248
288
  }
249
289
  end # termlist(docid)
250
-
290
+
251
291
 
252
292
  # Returns an Array of Xapian::Termpos objects for the given term (a String)
253
293
  # in the given docid.
data/tests/smoketest.rb CHANGED
@@ -34,7 +34,7 @@ end
34
34
 
35
35
  class XapianSmoketest < Test::Unit::TestCase
36
36
 
37
- def setup
37
+ def setup
38
38
  @stem = Xapian::Stem.new("english")
39
39
 
40
40
  @doc = Xapian::Document.new()
@@ -43,7 +43,7 @@ class XapianSmoketest < Test::Unit::TestCase
43
43
  @doc.add_posting(@stem.call("there"), 2)
44
44
  @doc.add_posting(@stem.call("anybody"), 3)
45
45
  @doc.add_posting(@stem.call("out"), 4)
46
- @doc.add_posting(@stem.call("there"), 5)
46
+ @doc.add_posting(@stem.call("there"), 5)
47
47
  @doc.add_term("XYzzy")
48
48
 
49
49
  @db = Xapian::inmemory_open()
@@ -61,7 +61,7 @@ class XapianSmoketest < Test::Unit::TestCase
61
61
  end # test_version
62
62
 
63
63
  def test_stem
64
- assert_equal("Xapian::Stem(english)", @stem.description())
64
+ assert_equal("Xapian::Stem(english)", @stem.description())
65
65
 
66
66
  assert_equal("is", @stem.call("is"))
67
67
  assert_equal("go", @stem.call("going"))
@@ -84,6 +84,14 @@ class XapianSmoketest < Test::Unit::TestCase
84
84
 
85
85
  end # test_document
86
86
 
87
+ def test_document_terms
88
+ terms = @doc.terms
89
+
90
+ assert_not_nil(terms.find {|i| i.term == "there" })
91
+ assert_not_nil(terms.find {|i| i.term == "out" })
92
+ assert_equal(terms.size, terms.map {|i| i }.size)
93
+ end
94
+
87
95
  def test_001_database
88
96
  assert_not_nil(@db)
89
97
  assert_equal("WritableDatabase()", @db.description())
@@ -91,7 +99,7 @@ class XapianSmoketest < Test::Unit::TestCase
91
99
  end # test_database
92
100
 
93
101
  def test_002_queries
94
- assert_equal("Xapian::Query((smoke OR test OR terms))",
102
+ assert_equal("Xapian::Query((smoke OR test OR terms))",
95
103
  Xapian::Query.new(Xapian::Query::OP_OR ,["smoke", "test", "terms"]).description())
96
104
 
97
105
  phraseQuery = Xapian::Query.new(Xapian::Query::OP_PHRASE ,["smoke", "test", "tuple"])
@@ -100,9 +108,9 @@ class XapianSmoketest < Test::Unit::TestCase
100
108
  assert_equal("Xapian::Query((smoke PHRASE 3 test PHRASE 3 tuple))", phraseQuery.description())
101
109
  assert_equal("Xapian::Query((smoke XOR (smoke PHRASE 3 test PHRASE 3 tuple) XOR string))", xorQuery.description())
102
110
 
103
- assert_equal([Xapian::Term.new("smoke", 1),
104
- Xapian::Term.new("string", 1),
105
- Xapian::Term.new("test", 1),
111
+ assert_equal([Xapian::Term.new("smoke", 1),
112
+ Xapian::Term.new("string", 1),
113
+ Xapian::Term.new("test", 1),
106
114
  Xapian::Term.new("tuple", 1)], xorQuery.terms())
107
115
 
108
116
  assert_equal(Xapian::Query::OP_ELITE_SET, 10)
@@ -111,7 +119,7 @@ class XapianSmoketest < Test::Unit::TestCase
111
119
  def test_003_enquire
112
120
  @enq = Xapian::Enquire.new(@db)
113
121
  assert_not_nil(@enq)
114
-
122
+
115
123
  @enq.query = Xapian::Query.new(Xapian::Query::OP_OR, "there", "is")
116
124
  mset = @enq.mset(0, 10)
117
125
 
@@ -126,7 +134,7 @@ class XapianSmoketest < Test::Unit::TestCase
126
134
  def test_004_mset_iterator
127
135
  @enq = Xapian::Enquire.new(@db)
128
136
  assert_not_nil(@enq)
129
-
137
+
130
138
  @enq.query = Xapian::Query.new(Xapian::Query::OP_OR, "there", "is")
131
139
  mset = @enq.mset(0, 10)
132
140
 
@@ -152,7 +160,7 @@ class XapianSmoketest < Test::Unit::TestCase
152
160
  def test_006_database_allterms
153
161
  assert_equal(5, @db.allterms.size())
154
162
  end
155
-
163
+
156
164
  # Feature test for Database.postlist
157
165
  def test_007_database_postlist
158
166
  assert_equal(1, @db.postlist("there").size())
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xspond-xapian-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Weidendorf
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-03-10 00:00:00 -07:00
13
+ date: 2009-03-11 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16