xapian_db 1.3.5.4 → 1.3.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0a8125904c6b19bde0907e2be6ff7ad9f319927
4
- data.tar.gz: 6ada801fee29d59e484e7813c8b6dbd1664a802b
3
+ metadata.gz: 8fcb96848f64b5fb55dee7fcd4cd2fa246c3161b
4
+ data.tar.gz: d084663854eccb8578c0cc6f8c91244034a51f37
5
5
  SHA512:
6
- metadata.gz: ecd0e5c8e4fb4cf239f71b5b3279cc2ecbfdc7c76f63e2b493e2b6e3908e14db99566edd269e582179492bd4cf40056fe44893030f82d24ab503d537730dbc8b
7
- data.tar.gz: 442bf0b4d19ca49fe230133fc03119fd3d8e6b555a0e30a8276c667a3addaf0a0613bcdbbb2165906aee28c4870db189647cccda10f972caa4eb8127f0880ae1
6
+ metadata.gz: 9887f97d274399336ff92f7ee41d9b6d9a89df483a355b28673891bd4c96acc8541548e5dc95e2cd15e90739fc72480d6bbedf1dad96de488f0a4cc12424ac44
7
+ data.tar.gz: 86a87a39b867e19bf1ba8115b94657ea924628c0a62c670bd4cc68069b590196c7414dd471e1b76937ebf4debc463c7361b67af6b1adb99bd64a8edf95dd4fb7
@@ -1,3 +1,27 @@
1
+ ##1.3.7 (January 12th, 2016)
2
+
3
+ Breaking Changes:
4
+
5
+ - search methods accept either a limit option OR page / per_page options, not both
6
+
7
+ Fixes:
8
+
9
+ - `XapianDb.database.delete_docs_of_class(klass)` now deletes docs of all descendants of `klass`, too (if tracked)
10
+
11
+ Changes:
12
+
13
+ - Ability to declare dependenices between blueprints
14
+ - Support for result ordering
15
+ - added a indexer preprocess callback to manipulate the terms that the indexer will index
16
+
17
+ ##1.3.6 (August 14th, 2015)
18
+
19
+ Changes:
20
+
21
+ - The required Ruby version is now 2.0.0 since we started using keyword parameters in method definitions
22
+ - Ability do define and handle dependencies between blueprints (see README)
23
+ - explicit order option for searches
24
+
1
25
  ##1.3.5.4 (Jan 13th, 2015)
2
26
 
3
27
  Fixes:
@@ -32,9 +32,9 @@ I tried hard but I couldn't find such a thing so I decided to write it, based on
32
32
 
33
33
  == Requirements
34
34
 
35
- * ruby 1.9.2 or newer
35
+ * ruby 2.0.0 or newer
36
36
  * rails 3.0 or newer (if you want to use it with rails)
37
- * xapian-core and xapian-ruby binaries installed
37
+ * xapian-core and xapian-ruby binaries 1.2.x installed
38
38
 
39
39
  == Installing xapian binaries
40
40
 
@@ -194,6 +194,32 @@ are ordered by relevance and - within the same relevance - by the natural sort o
194
194
  end
195
195
  end
196
196
 
197
+ You can specify a Ruby method for preprocessing the indexed terms. The method needs to be a class method that takes one argument (the terms to be indexed) and
198
+ returns a string. You can configure it globaly in the config or on a blueprint. For example, this setup will make words with accented e characters searchable
199
+ by their accentless form:
200
+
201
+ class Util
202
+ def self.strip_accents(terms)
203
+ terms.gsub(/[éèêëÉÈÊË]/, "e")
204
+ end
205
+ end
206
+
207
+ XapianDb::Config.setup do |config|
208
+ config.indexer_preprocess_callback UtilT.method(:strip_accents)
209
+ end
210
+
211
+ You may use attributes from associated objects in a blueprint; if you do that and an associated object is updated, your objects should be reindexed, too. You can tell XapnaDB about those dependencies like so:
212
+
213
+ XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
214
+ blueprint.attribue :address, :as => :json
215
+
216
+ blueprint.dependency :Address, when_changed: %i(street zip city) do |address|
217
+ Person.joins{ address }.where{ adresses.id == my{ address.id } }
218
+ end
219
+ end
220
+
221
+ The block you supply to the dependency declaration must return a collection of objects that should get reindexed, too.
222
+
197
223
  If you want to manage the (re)indexing of your objects on your own, turn off autoindexing in your blueprint:
198
224
 
199
225
  XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
@@ -246,6 +272,10 @@ You can query attributes:
246
272
 
247
273
  results = XapianDb.search "name:Foo"
248
274
 
275
+ You can force the sort order:
276
+
277
+ results = XapianDb.search "name:Foo", order: [:name]
278
+
249
279
  You can query objects of a specific class:
250
280
 
251
281
  results = Person.search "name:Foo"
@@ -105,9 +105,9 @@ module XapianDb
105
105
 
106
106
  # Update an object in the index
107
107
  # @param [Object] obj An instance of a class with a blueprint configuration
108
- def self.index(obj, commit=true)
108
+ def self.index(obj, commit=true, changed_attrs: [])
109
109
  writer = @block_writer || XapianDb::Config.writer
110
- writer.index obj, commit
110
+ writer.index obj, commit, changed_attrs: changed_attrs
111
111
  end
112
112
 
113
113
  # Remove a document from the index
@@ -119,11 +119,11 @@ module XapianDb
119
119
 
120
120
  # Update or delete a xapian document belonging to an object depending on the ignore_if logic(if present)
121
121
  # @param [Object] object An instance of a class with a blueprint configuration
122
- def self.reindex(object, commit=true)
122
+ def self.reindex(object, commit=true, changed_attrs: [])
123
123
  writer = @block_writer || XapianDb::Config.writer
124
124
  blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class.name
125
125
  if blueprint.should_index?(object)
126
- writer.index object, commit
126
+ writer.index object, commit, changed_attrs: changed_attrs
127
127
  else
128
128
  writer.delete_doc_with object.xapian_id, commit
129
129
  end
@@ -191,5 +191,4 @@ module XapianDb
191
191
  @block_writer = nil
192
192
  end
193
193
  end
194
-
195
194
  end
@@ -49,7 +49,12 @@ module XapianDb
49
49
  # add the after commit logic, unless the blueprint has autoindexing turned off
50
50
  if XapianDb::DocumentBlueprint.blueprint_for(klass.name).autoindex?
51
51
  after_commit do
52
- XapianDb.reindex(self) unless self.destroyed?
52
+ unless self.destroyed?
53
+ XapianDb.reindex(self, true, changed_attrs: self.previous_changes.keys)
54
+ XapianDb::DocumentBlueprint.dependencies_for(klass.name, self.previous_changes.keys).each do |dependency|
55
+ dependency.block.call(self).each{ |model| XapianDb.reindex model, true, changed_attrs: self.previous_changes.keys }
56
+ end
57
+ end
53
58
  end
54
59
  end
55
60
 
@@ -64,7 +69,6 @@ module XapianDb
64
69
  XapianDb.reindex_class(klass, options)
65
70
  end
66
71
  end
67
-
68
72
  end
69
73
 
70
74
  # Implement the document helper methods on a module
@@ -76,7 +80,7 @@ module XapianDb
76
80
 
77
81
  # Implement access to the model id
78
82
  define_method :id do
79
- return @id unless @d.nil?
83
+ return @id unless @id.nil?
80
84
  # retrieve the class and id from data
81
85
  klass_name, id = data.split("-")
82
86
  @id = id.to_i
@@ -90,11 +94,8 @@ module XapianDb
90
94
  klass = constantize klass_name
91
95
  @indexed_object = klass.find(id.to_i)
92
96
  end
93
-
94
97
  end
95
-
96
98
  end
97
-
98
99
  end
99
100
  end
100
101
  end
@@ -32,7 +32,7 @@ module XapianDb
32
32
  end
33
33
 
34
34
  # Install delegates for the config instance variables
35
- [:database, :adapter, :writer, :stemmer, :stopper].each do |attr|
35
+ [:database, :adapter, :writer, :stemmer, :stopper, :preprocess_terms].each do |attr|
36
36
  define_method attr do
37
37
  @config.nil? ? nil : @config.instance_variable_get("@_#{attr}")
38
38
  end
@@ -183,5 +183,21 @@ module XapianDb
183
183
  @_enabled_query_flags.delete flag
184
184
  end
185
185
 
186
+ # Set the indexer preprocess callback.
187
+ # @param [Method] method a class method; needs to take one parameter and return a string.
188
+ # @example
189
+ # class Util
190
+ # def self.strip_accents(terms)
191
+ # terms.gsub(/[éèêëÉÈÊË]/, "e")
192
+ # end
193
+ # end
194
+ #
195
+ # XapianDb::Config.setup do |config|
196
+ # config.indexer_preprocess_callback Util.method(:strip_accents)
197
+ # end
198
+ def indexer_preprocess_callback(method)
199
+ @_preprocess_terms = method
200
+ end
201
+
186
202
  end
187
203
  end
@@ -35,10 +35,19 @@ module XapianDb
35
35
  true
36
36
  end
37
37
 
38
- # Delete all docs of a specific class
38
+ # Delete all docs of a specific class.
39
+ #
40
+ # If `klass` tracks its descendants, then docs of any subclasses will be deleted, too.
41
+ # (ActiveRecord does this by default; the gem 'descendants_tracker' offers an alternative.)
42
+ #
39
43
  # @param [Class] klass A class that has a {XapianDb::DocumentBlueprint} configuration
40
44
  def delete_docs_of_class(klass)
41
45
  writer.delete_document("C#{klass}")
46
+ if klass.respond_to? :descendants
47
+ klass.descendants.each do |subclass|
48
+ writer.delete_document("C#{subclass}")
49
+ end
50
+ end
42
51
  true
43
52
  end
44
53
 
@@ -73,6 +82,12 @@ module XapianDb
73
82
  enquiry.query = query
74
83
  sort_indices = opts.delete :sort_indices
75
84
  sort_decending = opts.delete :sort_decending
85
+ order = opts.delete :order
86
+ raise ArgumentError.new "you can't use sort_indices and order, only one of them" if sort_indices && order
87
+
88
+ if order
89
+ sort_indices = order.map{ |attr_name| XapianDb::DocumentBlueprint.value_number_for attr_name.to_sym }
90
+ end
76
91
 
77
92
  sorter = Xapian::MultiValueKeyMaker.new
78
93
  if sort_indices
@@ -80,7 +95,7 @@ module XapianDb
80
95
  enquiry.set_sort_by_key_then_relevance(sorter, sort_decending)
81
96
  else
82
97
  sorter.add_value DocumentBlueprint.value_number_for(:natural_sort_order)
83
- enquiry.set_sort_by_relevance_then_key sorter, true
98
+ enquiry.set_sort_by_relevance_then_key sorter, false
84
99
  end
85
100
 
86
101
  opts[:spelling_suggestion] = @query_parser.spelling_suggestion
@@ -50,6 +50,7 @@ module XapianDb
50
50
  # We can always do a field search on the name of the indexed class
51
51
  @searchable_prefixes << "indexed_class"
52
52
  @attributes = @blueprints.values.map { |blueprint| blueprint.attribute_names}.flatten.compact.uniq.sort || []
53
+ blueprint
53
54
  end
54
55
 
55
56
  # reset the blueprint setup
@@ -66,11 +67,17 @@ module XapianDb
66
67
  # Get all configured classes
67
68
  # @return [Array<Class>]
68
69
  def configured_classes
69
- if @blueprints
70
- @blueprints.keys.map {|class_name| XapianDb::Utilities.constantize(class_name) }
71
- else
72
- []
73
- end
70
+ if @blueprints
71
+ @blueprints.keys.map {|class_name| XapianDb::Utilities.constantize(class_name) }
72
+ else
73
+ []
74
+ end
75
+ end
76
+
77
+ def dependencies_for(klass_name, changed_attrs)
78
+ @blueprints.values.map(&:dependencies)
79
+ .flatten
80
+ .select{ |dependency| dependency.dependent_on == klass_name && dependency.interested_in?(changed_attrs) }
74
81
  end
75
82
 
76
83
  # Get the blueprint for a class
@@ -167,7 +174,6 @@ module XapianDb
167
174
  end
168
175
  end
169
176
  end
170
-
171
177
  end
172
178
 
173
179
  # ---------------------------------------------------------------------------------
@@ -258,15 +264,17 @@ module XapianDb
258
264
  # Blueprint DSL methods
259
265
  # ---------------------------------------------------------------------------------
260
266
 
261
- attr_reader :lazy_base_query, :_natural_sort_order
267
+ attr_reader :lazy_base_query, :_natural_sort_order, :dependencies
262
268
 
263
269
  # Construct the blueprint
264
270
  def initialize
265
271
  @attributes_hash = {}
266
272
  @indexed_methods_hash = {}
267
273
  @type_map = {}
274
+ @dependencies = []
268
275
  @_natural_sort_order = :id
269
276
  @autoindex = true
277
+ @indexer_preprocess_callback = nil
270
278
  end
271
279
 
272
280
  # Set the adapter
@@ -377,7 +385,7 @@ module XapianDb
377
385
  @ignore_expression = block
378
386
  end
379
387
 
380
- # Define a base query to select one or all objects of the indexed class. The reason for a
388
+ # Define a base query to select one or all objects of the indexed class. The reason for a
381
389
  # base query is to optimize the query avoiding th 1+n problematic. The base query should only
382
390
  # include joins(...) and includes(...) calls.
383
391
  # @param [expression] a base query expression
@@ -400,6 +408,33 @@ module XapianDb
400
408
  @_natural_sort_order = name || block
401
409
  end
402
410
 
411
+ def dependency(klass_name, when_changed: [], &block)
412
+ @dependencies << Dependency.new(klass_name.to_s, when_changed, block)
413
+ end
414
+
415
+ # Set the indexer preprocess callback.
416
+ # @param [Method] method a class method; needs to take one parameter and return a string.
417
+ # @example
418
+ # class Util
419
+ # def self.strip_accents(terms)
420
+ # terms.gsub(/[éèêëÉÈÊË]/, "e")
421
+ # end
422
+ # end
423
+ #
424
+ # XapianDb::DocumentBlueprint.setup(:IndexedObject) do |blueprint|
425
+ # blueprint.attribute :name
426
+ # blueprint.indexer_preprocess_callback Util.method(:strip_accents)
427
+ # end
428
+ def indexer_preprocess_callback(method)
429
+ @indexer_preprocess_callback = method
430
+ end
431
+
432
+ # Reader for indexer_preprocess_callback.
433
+ # Returns the terms preprocessing method for this blueprint, the global method from config or nil.
434
+ def preprocess_terms
435
+ @indexer_preprocess_callback || XapianDb::Config.preprocess_terms
436
+ end
437
+
403
438
  # Options for an indexed method
404
439
  class IndexOptions
405
440
 
@@ -414,7 +449,24 @@ module XapianDb
414
449
  @no_split = options[:no_split]
415
450
  @block = options[:block]
416
451
  end
452
+ end
453
+
454
+ class Dependency
455
+
456
+ attr_reader :dependent_on, :trigger_attributes, :block
457
+
458
+ # Constructor
459
+ # @param [String] klass_name Name of the dependent class
460
+ # @param [Array] trigger_attributes List of attributes to watch for changes (if empty, triggers on any change)
461
+ # @option [Block] block Block that is called when changes are detected; the block must return an array of indexeable objects
462
+ def initialize(klass_name, trigger_attributes, block)
463
+ @dependent_on, @trigger_attributes, @block = klass_name, trigger_attributes.map(&:to_s), block
464
+ end
417
465
 
466
+ def interested_in?(changed_attrs)
467
+ return true if @trigger_attributes.empty?
468
+ (@trigger_attributes & changed_attrs).any?
469
+ end
418
470
  end
419
471
 
420
472
  private
@@ -431,7 +483,5 @@ module XapianDb
431
483
  @reserved_method_names ||= Xapian::Document.instance_methods
432
484
  @reserved_method_names.include?(attr_name.to_sym)
433
485
  end
434
-
435
486
  end
436
-
437
487
  end
@@ -13,7 +13,7 @@ module XapianDb
13
13
  def index_task(options)
14
14
  klass = constantize options[:class]
15
15
  obj = klass.respond_to?(:get) ? klass.get(options[:id]) : klass.find(options[:id])
16
- DirectWriter.index obj
16
+ DirectWriter.index obj, true, changed_attrs: options[:changed_attrs]
17
17
  end
18
18
 
19
19
  def delete_doc_task(options)
@@ -24,7 +24,6 @@ module XapianDb
24
24
  klass = constantize options[:class]
25
25
  DirectWriter.reindex_class klass, :verbose => false
26
26
  end
27
-
28
27
  end
29
28
  end
30
- end
29
+ end
@@ -18,8 +18,8 @@ module XapianDb
18
18
 
19
19
  # Update an object in the index
20
20
  # @param [Object] obj An instance of a class with a blueprint configuration
21
- def index(obj, commit=true)
22
- beanstalk.put( {:task => "index_task", :class => obj.class.name, :id => obj.id }.to_json )
21
+ def index(obj, commit=true, changed_attrs: [])
22
+ beanstalk.put( { :task => "index_task", :class => obj.class.name, :id => obj.id, :changed_attrs => changed_attrs }.to_json )
23
23
  end
24
24
 
25
25
  # Remove an object from the index
@@ -17,11 +17,11 @@ module XapianDb
17
17
  class << self
18
18
 
19
19
  # Update an object in the index
20
- # @param [Object] obj An instance of a class with a blueprint configuration
21
- def index(obj, commit=true)
22
- blueprint = XapianDb::DocumentBlueprint.blueprint_for(obj.class.name)
20
+ # @param [Object] object An instance of a class with a blueprint configuration
21
+ def index(object, commit=true, changed_attrs: [])
22
+ blueprint = XapianDb::DocumentBlueprint.blueprint_for(object.class.name)
23
23
  indexer = XapianDb::Indexer.new(XapianDb.database, blueprint)
24
- doc = indexer.build_document_for(obj)
24
+ doc = indexer.build_document_for(object)
25
25
  XapianDb.database.store_doc(doc)
26
26
  XapianDb.database.commit if commit
27
27
  end
@@ -35,10 +35,10 @@ module XapianDb
35
35
 
36
36
  # Update or delete a xapian document belonging to an object depending on the ignore_if logic(if present)
37
37
  # @param [Object] object An instance of a class with a blueprint configuration
38
- def reindex(object, commit=true)
38
+ def reindex(object, commit=true, changed_attrs: [])
39
39
  blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class.name
40
40
  if blueprint.should_index?(object)
41
- index object, commit
41
+ index object, commit, changed_attrs: changed_attrs
42
42
  else
43
43
  delete_doc_with object.xapian_id, commit
44
44
  end
@@ -12,7 +12,7 @@ module XapianDb
12
12
 
13
13
  # Update an object in the index
14
14
  # @param [Object] obj An instance of a class with a blueprint configuration
15
- def index(obj, commit=true); end
15
+ def index(obj, commit=true, changed_attrs: []); end
16
16
 
17
17
  # Remove an object from the index
18
18
  # @param [String] xapian_id The document id
@@ -28,4 +28,4 @@ module XapianDb
28
28
  end
29
29
  end
30
30
  end
31
- end
31
+ end
@@ -22,7 +22,7 @@ module XapianDb
22
22
  def index(options)
23
23
  klass = constantize options['class']
24
24
  obj = klass.respond_to?('get') ? klass.get(options['id']) : klass.find(options['id'])
25
- DirectWriter.index obj
25
+ DirectWriter.index obj, true, changed_attrs: options[:changed_attrs]
26
26
  end
27
27
 
28
28
  def delete_doc(options)
@@ -34,7 +34,6 @@ module XapianDb
34
34
  DirectWriter.reindex_class klass, :verbose => false
35
35
  end
36
36
  end
37
-
38
37
  end
39
38
  end
40
39
  end
@@ -12,8 +12,8 @@ module XapianDb
12
12
 
13
13
  # Update an object in the index
14
14
  # @param [Object] obj An instance of a class with a blueprint configuration
15
- def index(obj, commit=true)
16
- Resque.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id
15
+ def index(obj, commit=true, changed_attrs: [])
16
+ Resque.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id, changed_attrs: changed_attrs
17
17
  end
18
18
 
19
19
  # Remove an object from the index
@@ -33,7 +33,6 @@ module XapianDb
33
33
  end
34
34
  private :worker_class
35
35
  end
36
-
37
36
  end
38
37
  end
39
38
  end
@@ -26,7 +26,7 @@ module XapianDb
26
26
  def index(options)
27
27
  klass = constantize options['class']
28
28
  obj = klass.respond_to?('get') ? klass.get(options['id']) : klass.find(options['id'])
29
- DirectWriter.index obj
29
+ DirectWriter.index obj, true, changed_attrs: options[:changed_attrs]
30
30
  end
31
31
 
32
32
  def delete_doc(options)
@@ -16,8 +16,8 @@ module XapianDb
16
16
 
17
17
  # Update an object in the index
18
18
  # @param [Object] obj An instance of a class with a blueprint configuration
19
- def index(obj, commit=true)
20
- Sidekiq::Client.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id
19
+ def index(obj, commit=true, changed_attrs: [])
20
+ Sidekiq::Client.enqueue worker_class, :index, :class => obj.class.name, :id => obj.id, :changed_attrs => changed_attrs
21
21
  end
22
22
 
23
23
  # Remove an object from the index
@@ -37,7 +37,6 @@ module XapianDb
37
37
  end
38
38
  private :worker_class
39
39
  end
40
-
41
40
  end
42
41
  end
43
42
  end
@@ -20,7 +20,7 @@ module XapianDb
20
20
 
21
21
  # Update an object in the index
22
22
  # @param [Object] obj An instance of a class with a blueprint configuration
23
- def index(obj, commit=false)
23
+ def index(obj, commit=false, changed_attrs: [])
24
24
  @index_requests << obj
25
25
  end
26
26
 
@@ -45,8 +45,6 @@ module XapianDb
45
45
  @delete_requests.each { |xapian_id| writer.delete_doc_with xapian_id, false }
46
46
  XapianDb.database.commit
47
47
  end
48
-
49
48
  end
50
-
51
49
  end
52
- end
50
+ end
@@ -86,6 +86,7 @@ module XapianDb
86
86
  values = get_values_to_index_from obj
87
87
  values.each do |value|
88
88
  terms = value.to_s.downcase
89
+ terms = @blueprint.preprocess_terms.call(terms) if @blueprint.preprocess_terms
89
90
  terms = split(terms) if XapianDb::Config.term_splitter_count > 0 && !options.no_split
90
91
  # Add value with field name
91
92
  term_generator.index_text(terms, options.weight, "X#{method.upcase}") if options.prefixed
@@ -46,6 +46,7 @@ module XapianDb
46
46
  # @param [Hash] options
47
47
  # @option options [Integer] :db_size The current size (nr of docs) of the database
48
48
  # @option options [Integer] :limit The maximum number of documents to retrieve
49
+ # @option options [Integer] :offset The index of the first result to retrieve
49
50
  # @option options [Integer] :page (1) The page number to retrieve
50
51
  # @option options [Integer] :per_page (10) How many docs per page? Ignored if a limit option is given
51
52
  # @option options [String] :spelling_suggestion (nil) The spelling corrected query (if a language is configured)
@@ -56,25 +57,32 @@ module XapianDb
56
57
  db_size = params.delete :db_size
57
58
  @spelling_suggestion = params.delete :spelling_suggestion
58
59
  limit = params.delete :limit
60
+ offset = params.delete :offset
59
61
  page = params.delete :page
60
62
  per_page = params.delete :per_page
61
63
  raise ArgumentError.new "unsupported options for resultset: #{params}" if params.size > 0
62
64
  raise ArgumentError.new "db_size option is required" unless db_size
63
65
 
66
+ unless (page.nil? && per_page.nil?) || (limit.nil? && offset.nil?)
67
+ raise ArgumentError.new "Impossible combination of parameters. Either pass page and/or per_page, or limit and/or offset."
68
+ end
69
+
70
+ calculated_page = offset.nil? || limit.nil? ? nil : (offset.to_f / limit.to_f) + 1
71
+
64
72
  limit = limit.nil? ? db_size : limit.to_i
65
- per_page = per_page.nil? ? limit : per_page.to_i
66
- page = page.nil? ? 1 : page.to_i
67
- offset = (page - 1) * per_page
68
- count = offset + per_page < limit ? per_page : limit - offset
73
+ per_page = per_page.nil? ? limit.to_i : per_page.to_i
74
+ page = page.nil? ? (calculated_page.nil? ? 1 : calculated_page) : page.to_i
75
+ offset = offset.nil? ? (page - 1) * per_page : offset.to_i
76
+ count = per_page < limit ? per_page : limit
69
77
 
78
+ return build_empty_resultset if (page - 1) * per_page > db_size
70
79
  result_window = enquiry.mset(offset, count)
71
80
  @hits = result_window.matches_estimated
72
81
  return build_empty_resultset if @hits == 0
73
- raise ArgumentError.new "page #{@page} does not exist" if @hits > 0 && offset >= limit
74
82
 
75
83
  self.replace result_window.matches.map{|match| decorate(match).document}
76
84
  @total_pages = (@hits / per_page.to_f).ceil
77
- @current_page = page
85
+ @current_page = (page == page.to_i) ? page.to_i : page
78
86
  @limit_value = per_page
79
87
  end
80
88
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xapian_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5.4
4
+ version: 1.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gernot Kogler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-13 00:00:00.000000000 Z
11
+ date: 2016-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daemons
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 2.3.1
47
+ version: 2.99.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 2.3.1
54
+ version: 2.99.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: simplecov
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 1.2.15.1
145
+ version: 1.2.22
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 1.2.15.1
152
+ version: 1.2.22
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: pry-rails
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: descendants_tracker
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: XapianDb is a ruby gem that combines features of nosql databases and
168
182
  fulltext indexing. It is based on Xapian, an efficient and powerful indexing library
169
183
  email: gernot.kogler (at) garaio (dot) com
@@ -239,7 +253,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
239
253
  requirements:
240
254
  - - ">="
241
255
  - !ruby/object:Gem::Version
242
- version: '0'
256
+ version: 2.0.0
243
257
  required_rubygems_version: !ruby/object:Gem::Requirement
244
258
  requirements:
245
259
  - - ">="