xapian_db 1.2.1.1 → 1.2.2

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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ##1.2.2 (November 15th, 2011)
2
+
3
+ Features:
4
+
5
+ - resultset accepts limit and paging options as strings
6
+ - added natural sort order option for blueprints (see README for details)
7
+
8
+ IMPORTANT: FULL INDEX REBUILD REQUIRED FOR THIS RELEASE!
9
+
1
10
  ##1.2.1.1 (November 10th, 2011)
2
11
 
3
12
  Fixes:
data/README.rdoc CHANGED
@@ -143,6 +143,19 @@ If you use associations in your blueprints, it might be a good idea to specify a
143
143
  blueprint.base_query Person.includes(:addresses)
144
144
  end
145
145
 
146
+ You can specify a natural sort order for each class using a method symbol or a block. If you don't specify an order expression in your xapian query, the matches
147
+ are ordered by relevance and - within the same relevance - by the natural sort order. If you don't specify the natural sort order, it defaults to id. Examples:
148
+
149
+ XapianDb::DocumentBlueprint.setup(House) do |blueprint|
150
+ blueprint.natural_sort_order :number
151
+ end
152
+
153
+ XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
154
+ blueprint.natural_sort_order do
155
+ "#{surname} #{name}"
156
+ end
157
+ end
158
+
146
159
  Place these configurations either into the corresponding class or - I prefer to have the index configurations outside
147
160
  the models - into the file config/xapian_blueprints.rb.
148
161
 
@@ -74,10 +74,13 @@ module XapianDb
74
74
  sort_indices = opts.delete :sort_indices
75
75
  sort_decending = opts.delete :sort_decending
76
76
 
77
+ sorter = Xapian::MultiValueKeyMaker.new
77
78
  if sort_indices
78
- sorter = Xapian::MultiValueKeyMaker.new
79
79
  sort_indices.each { |index| sorter.add_value index }
80
80
  enquiry.set_sort_by_key_then_relevance(sorter, sort_decending)
81
+ else
82
+ sorter.add_value DocumentBlueprint.value_number_for(:natural_sort_order)
83
+ enquiry.set_sort_by_relevance_then_key sorter, true
81
84
  end
82
85
 
83
86
  opts[:spelling_suggestion] = @query_parser.spelling_suggestion
@@ -74,12 +74,13 @@ module XapianDb
74
74
  # @param [attribute] The name of an attribute
75
75
  # @return [Integer] The value number
76
76
  def value_number_for(attribute)
77
- raise ArgumentError.new "attribute #{attribute} is not configured in any blueprint" if @attributes.nil?
78
77
  return 0 if attribute.to_sym == :indexed_class
78
+ return 1 if attribute.to_sym == :natural_sort_order
79
+ raise ArgumentError.new "attribute #{attribute} is not configured in any blueprint" if @attributes.nil?
79
80
  position = @attributes.index attribute.to_sym
80
81
  if position
81
- # We add 1 because value slot 0 is reserved for the class name
82
- return position + 1
82
+ # We add 2 because slot 0 and 1 are reserved for indexed_class and natural_sort_order
83
+ return position + 2
83
84
  else
84
85
  raise ArgumentError.new "attribute #{attribute} is not configured in any blueprint"
85
86
  end
@@ -206,13 +207,14 @@ module XapianDb
206
207
  # ---------------------------------------------------------------------------------
207
208
 
208
209
  attr_accessor :_adapter
209
- attr_reader :_base_query
210
+ attr_reader :_base_query, :_natural_sort_order
210
211
 
211
212
  # Construct the blueprint
212
213
  def initialize
213
- @attributes_hash = {}
214
+ @attributes_hash = {}
214
215
  @indexed_methods_hash = {}
215
- @type_map = {}
216
+ @type_map = {}
217
+ @_natural_sort_order = :id
216
218
  end
217
219
 
218
220
  # Set the adapter
@@ -316,6 +318,15 @@ module XapianDb
316
318
  @_base_query = expression
317
319
  end
318
320
 
321
+ # Define the natural sort order.
322
+ # @param [String] name The name of the method that delivers the sort expression
323
+ # @param [Block] &block An optional block for complex configurations
324
+ # Pass a method name or a block, but not both
325
+ def natural_sort_order(name=nil, &block)
326
+ raise ArgumentError.new("natural_sort_order accepts a method name or a block, but not both") if name && block
327
+ @_natural_sort_order = name || block
328
+ end
329
+
319
330
  # Options for an indexed method
320
331
  class IndexOptions
321
332
 
@@ -32,15 +32,22 @@ module XapianDb
32
32
  # Store all configured fields
33
33
  def store_fields
34
34
 
35
- # We store the class name of the object at position 0
36
- @xapian_doc.add_value(0, @obj.class.name)
35
+ # class name of the object goes to position 0
36
+ @xapian_doc.add_value 0, @obj.class.name
37
+ # natural sort order goes to position 1
38
+ if @blueprint._natural_sort_order.is_a? Proc
39
+ sort_value = @obj.instance_eval &@blueprint._natural_sort_order
40
+ else
41
+ sort_value = @obj.send @blueprint._natural_sort_order
42
+ end
43
+ @xapian_doc.add_value 1, sort_value.to_s
37
44
 
38
45
  @blueprint.attribute_names.each do |attribute|
39
46
  block = @blueprint.block_for_attribute attribute
40
47
  if block
41
- value = @obj.instance_eval(&block)
48
+ value = @obj.instance_eval &block
42
49
  else
43
- value = @obj.send(attribute)
50
+ value = @obj.send attribute
44
51
  end
45
52
 
46
53
  codec = XapianDb::TypeCodec.codec_for @blueprint.type_map[attribute]
@@ -63,12 +63,11 @@ module XapianDb
63
63
  raise ArgumentError.new "unsupported options for resultset: #{options}" if options.size > 0
64
64
  raise ArgumentError.new "db_size option is required" unless db_size
65
65
 
66
-
67
- limit ||= @hits
68
- per_page ||= limit
66
+ limit = limit.nil? ? @hits : limit.to_i
67
+ per_page = per_page.nil? ? limit : per_page.to_i
68
+ page = page.nil? ? 1 : page.to_i
69
+ offset = (page - 1) * per_page
69
70
  @total_pages = (limit / per_page.to_f).ceil
70
- page = page.nil? ? 1 : page.to_i
71
- offset = (page - 1) * per_page
72
71
  count = offset + per_page < limit ? per_page : limit - offset
73
72
  raise ArgumentError.new "page #{@page} does not exist" if @hits > 0 && offset >= limit
74
73
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xapian_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1.1
4
+ version: 1.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-10 00:00:00.000000000 +01:00
12
+ date: 2011-11-15 00:00:00.000000000 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: daemons
17
- requirement: &70195167722940 !ruby/object:Gem::Requirement
17
+ requirement: &70092616807260 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.0.10
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70195167722940
25
+ version_requirements: *70092616807260
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: xapian-ruby
28
- requirement: &70195167722480 !ruby/object:Gem::Requirement
28
+ requirement: &70092616806800 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,21 @@ dependencies:
33
33
  version: 1.2.6
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70195167722480
36
+ version_requirements: *70092616806800
37
+ - !ruby/object:Gem::Dependency
38
+ name: guard
39
+ requirement: &70092616806420 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *70092616806420
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: rspec
39
- requirement: &70195167722020 !ruby/object:Gem::Requirement
50
+ requirement: &70092616822240 !ruby/object:Gem::Requirement
40
51
  none: false
41
52
  requirements:
42
53
  - - ! '>='
@@ -44,10 +55,10 @@ dependencies:
44
55
  version: 2.3.1
45
56
  type: :development
46
57
  prerelease: false
47
- version_requirements: *70195167722020
58
+ version_requirements: *70092616822240
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: simplecov
50
- requirement: &70195167721560 !ruby/object:Gem::Requirement
61
+ requirement: &70092616821640 !ruby/object:Gem::Requirement
51
62
  none: false
52
63
  requirements:
53
64
  - - ! '>='
@@ -55,10 +66,10 @@ dependencies:
55
66
  version: 0.3.7
56
67
  type: :development
57
68
  prerelease: false
58
- version_requirements: *70195167721560
69
+ version_requirements: *70092616821640
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: beanstalk-client
61
- requirement: &70195167737400 !ruby/object:Gem::Requirement
72
+ requirement: &70092616821140 !ruby/object:Gem::Requirement
62
73
  none: false
63
74
  requirements:
64
75
  - - ! '>='
@@ -66,10 +77,10 @@ dependencies:
66
77
  version: 1.1.0
67
78
  type: :development
68
79
  prerelease: false
69
- version_requirements: *70195167737400
80
+ version_requirements: *70092616821140
70
81
  - !ruby/object:Gem::Dependency
71
82
  name: rake
72
- requirement: &70195167736960 !ruby/object:Gem::Requirement
83
+ requirement: &70092616820720 !ruby/object:Gem::Requirement
73
84
  none: false
74
85
  requirements:
75
86
  - - ! '>='
@@ -77,10 +88,10 @@ dependencies:
77
88
  version: '0'
78
89
  type: :development
79
90
  prerelease: false
80
- version_requirements: *70195167736960
91
+ version_requirements: *70092616820720
81
92
  - !ruby/object:Gem::Dependency
82
93
  name: progressbar
83
- requirement: &70195167736440 !ruby/object:Gem::Requirement
94
+ requirement: &70092616820240 !ruby/object:Gem::Requirement
84
95
  none: false
85
96
  requirements:
86
97
  - - ! '>='
@@ -88,10 +99,10 @@ dependencies:
88
99
  version: '0'
89
100
  type: :development
90
101
  prerelease: false
91
- version_requirements: *70195167736440
102
+ version_requirements: *70092616820240
92
103
  - !ruby/object:Gem::Dependency
93
104
  name: resque
94
- requirement: &70195167735900 !ruby/object:Gem::Requirement
105
+ requirement: &70092616819740 !ruby/object:Gem::Requirement
95
106
  none: false
96
107
  requirements:
97
108
  - - ! '>='
@@ -99,7 +110,7 @@ dependencies:
99
110
  version: 1.19.0
100
111
  type: :development
101
112
  prerelease: false
102
- version_requirements: *70195167735900
113
+ version_requirements: *70092616819740
103
114
  description: XapianDb is a ruby gem that combines features of nosql databases and
104
115
  fulltext indexing. It is based on Xapian, an efficient and powerful indexing library
105
116
  email: gernot.kogler (at) garaio (dot) com