xapian_db 1.2.2.2 → 1.2.3
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 +13 -0
- data/README.rdoc +12 -11
- data/lib/xapian_db/adapters/datamapper_adapter.rb +4 -2
- data/lib/xapian_db/config.rb +6 -2
- data/lib/xapian_db/database.rb +4 -4
- data/lib/xapian_db/document_blueprint.rb +65 -23
- data/lib/xapian_db/index_writers/beanstalk_writer.rb +1 -6
- data/lib/xapian_db/index_writers/direct_writer.rb +9 -7
- data/lib/xapian_db/indexer.rb +1 -1
- data/lib/xapian_db/model_extenders/active_record.rb +13 -0
- data/lib/xapian_db/model_extenders/datamapper.rb +16 -0
- data/lib/xapian_db/railtie.rb +11 -0
- data/lib/xapian_db/resultset.rb +1 -1
- data/lib/xapian_db/utilities.rb +2 -0
- data/lib/xapian_db.rb +4 -3
- data/tasks/xapian_rebuild_index.rake +11 -0
- metadata +22 -21
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
##1.2.3 (December 12th, 2011)
|
2
|
+
|
3
|
+
Changes:
|
4
|
+
|
5
|
+
- avoid eager loading of model classes in a rails app. The blueprint configuration file (xapian_blueprints.rb) caused all referenced classes
|
6
|
+
to get loaded and parsed on every request. While not a problem in production environments, it could be a huge performance hit in development
|
7
|
+
(especially when using the asset pipleline with many assets).
|
8
|
+
The solution is based on the proof of concept by [Yves Senn](http://github.com/senny). Simply use symbols or strings instead of the classes in
|
9
|
+
your xapian_blueprints.rb and wrap base_queries inside a block. See the README for updated informations on how to configure blueprints.
|
10
|
+
- added a rails example app using datamapper
|
11
|
+
- added a rake task to rebuild the index
|
12
|
+
- internal refactorings / optimizations
|
13
|
+
|
1
14
|
##1.2.2.2 (November 29th, 2011)
|
2
15
|
|
3
16
|
Changes:
|
data/README.rdoc
CHANGED
@@ -84,9 +84,10 @@ If you do not configure settings for an environment in this file, xapian_db appl
|
|
84
84
|
|
85
85
|
=== Configure an index blueprint
|
86
86
|
|
87
|
-
In order to get your models indexed, you must configure a document blueprint for each class you want to index
|
87
|
+
In order to get your models indexed, you must configure a document blueprint for each class you want to index. You can pass the class name as a
|
88
|
+
symbol or as a string (if the class is namespaced):
|
88
89
|
|
89
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
90
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
90
91
|
blueprint.attribute :name, :weight => 10
|
91
92
|
blueprint.attribute :first_name
|
92
93
|
end
|
@@ -100,7 +101,7 @@ If you want to index additional data but do not need access to it from a search
|
|
100
101
|
|
101
102
|
If you want to declare multiple attributes or indexes with default options, you can do this in one statement:
|
102
103
|
|
103
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
104
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
104
105
|
blueprint.attributes :name, :first_name, :profession
|
105
106
|
blueprint.index :notes, :remarks, :cv
|
106
107
|
end
|
@@ -109,7 +110,7 @@ Note that you cannot add options using this mass declaration syntax (e.g. <code>
|
|
109
110
|
|
110
111
|
Use blocks for complex evaluations of attributes or indexed values:
|
111
112
|
|
112
|
-
XapianDb::DocumentBlueprint.setup(IndexedObject) do |blueprint|
|
113
|
+
XapianDb::DocumentBlueprint.setup(:IndexedObject) do |blueprint|
|
113
114
|
blueprint.attribute :complex do
|
114
115
|
if @id == 1
|
115
116
|
"One"
|
@@ -121,7 +122,7 @@ Use blocks for complex evaluations of attributes or indexed values:
|
|
121
122
|
|
122
123
|
You may add a filter expression to exclude objects from the index. This is handy to skip objects that are not active, for example:
|
123
124
|
|
124
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
125
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
125
126
|
blueprint.attributes :name, :first_name, :profession
|
126
127
|
blueprint.index :notes, :remarks, :cv
|
127
128
|
blueprint.ignore_if {active == false}
|
@@ -129,7 +130,7 @@ You may add a filter expression to exclude objects from the index. This is handy
|
|
129
130
|
|
130
131
|
You can add a type information to an attribute. As of now the special types :string, :date and :number are supported (and required for range queries):
|
131
132
|
|
132
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
133
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
133
134
|
blueprint.attribute :age, :as => :number
|
134
135
|
blueprint.attribute :date_of_birth, :as => :date
|
135
136
|
blueprint.attribute :name, :as => :string
|
@@ -138,14 +139,14 @@ You can add a type information to an attribute. As of now the special types :str
|
|
138
139
|
You can override the global adapter configuration in a specific blueprint. Let's say you use ActiveRecord, but you have
|
139
140
|
one more class that is not stored in the database, but you want it to be indexed:
|
140
141
|
|
141
|
-
XapianDb::DocumentBlueprint.setup(SpecialClass) do |blueprint|
|
142
|
+
XapianDb::DocumentBlueprint.setup(:SpecialClass) do |blueprint|
|
142
143
|
blueprint.adapter :generic
|
143
144
|
blueprint.index :some_stuff
|
144
145
|
end
|
145
146
|
|
146
147
|
If you use associations in your blueprints, it might be a good idea to specify a base query to speed up rebuild_xapian_index calls (avoiding 1+n queries):
|
147
148
|
|
148
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
149
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
149
150
|
blueprint.index :addresses
|
150
151
|
blueprint.base_query Person.includes(:addresses)
|
151
152
|
end
|
@@ -153,11 +154,11 @@ If you use associations in your blueprints, it might be a good idea to specify a
|
|
153
154
|
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
|
154
155
|
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:
|
155
156
|
|
156
|
-
XapianDb::DocumentBlueprint.setup(House) do |blueprint|
|
157
|
+
XapianDb::DocumentBlueprint.setup(:House) do |blueprint|
|
157
158
|
blueprint.natural_sort_order :number
|
158
159
|
end
|
159
160
|
|
160
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
161
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
161
162
|
blueprint.natural_sort_order do
|
162
163
|
"#{surname} #{name}"
|
163
164
|
end
|
@@ -227,7 +228,7 @@ On class queries you can specifiy order options:
|
|
227
228
|
|
228
229
|
If you define an attribute with a supported type, you can do range searches:
|
229
230
|
|
230
|
-
XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
231
|
+
XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
231
232
|
blueprint.attribute :age, :as => :number
|
232
233
|
blueprint.attribute :date_of_birth, :as => :date
|
233
234
|
blueprint.attribute :name, :as => :string
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require "#{File.dirname(__FILE__)}/../model_extenders/datamapper"
|
4
|
+
|
3
5
|
module XapianDb
|
4
6
|
module Adapters
|
5
7
|
|
@@ -40,7 +42,7 @@ module XapianDb
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def order_condition(primary_key)
|
43
|
-
|
45
|
+
primary_key.to_sym
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
@@ -48,7 +50,7 @@ module XapianDb
|
|
48
50
|
|
49
51
|
# add the after save logic
|
50
52
|
after :save do
|
51
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass
|
53
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass.to_s
|
52
54
|
if blueprint.should_index?(self)
|
53
55
|
XapianDb.index(self)
|
54
56
|
else
|
data/lib/xapian_db/config.rb
CHANGED
@@ -85,8 +85,12 @@ module XapianDb
|
|
85
85
|
# - :active_record ({XapianDb::Adapters::ActiveRecordAdapter})
|
86
86
|
# - :datamapper ({XapianDb::Adapters::DatamapperAdapter})
|
87
87
|
def adapter(type)
|
88
|
-
|
89
|
-
|
88
|
+
begin
|
89
|
+
@_adapter = XapianDb::Adapters.const_get("#{camelize(type.to_s)}Adapter")
|
90
|
+
rescue NameError
|
91
|
+
require File.dirname(__FILE__) + "/adapters/#{type}_adapter"
|
92
|
+
@_adapter = XapianDb::Adapters.const_get("#{camelize(type.to_s)}Adapter")
|
93
|
+
end
|
90
94
|
end
|
91
95
|
|
92
96
|
# Set the index writer
|
data/lib/xapian_db/database.rb
CHANGED
@@ -130,13 +130,13 @@ module XapianDb
|
|
130
130
|
# return an empty hash if no search expression is given
|
131
131
|
return {} if expression.nil? || expression.strip.empty?
|
132
132
|
value_number = XapianDb::DocumentBlueprint.value_number_for(attribute)
|
133
|
-
query_parser
|
134
|
-
query = query_parser.parse(expression)
|
135
|
-
enquiry = Xapian::Enquire.new(
|
133
|
+
@query_parser ||= QueryParser.new(self)
|
134
|
+
query = @query_parser.parse(expression)
|
135
|
+
enquiry = Xapian::Enquire.new(reader)
|
136
136
|
enquiry.query = query
|
137
137
|
enquiry.collapse_key = value_number
|
138
138
|
facets = {}
|
139
|
-
enquiry.mset(0,
|
139
|
+
enquiry.mset(0, size).matches.each do |match|
|
140
140
|
facet_value = YAML::load match.document.value(value_number)
|
141
141
|
# We must add 1 to the collapse_count since collapse_count means
|
142
142
|
# "how many other matches are there?"
|
@@ -5,13 +5,13 @@ module XapianDb
|
|
5
5
|
# A document blueprint describes the mapping of an object to a Xapian document
|
6
6
|
# for a given class.
|
7
7
|
# @example A simple document blueprint configuration for the class Person
|
8
|
-
# XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
8
|
+
# XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
9
9
|
# blueprint.attribute :name, :weight => 10
|
10
10
|
# blueprint.attribute :first_name
|
11
11
|
# blueprint.index :remarks
|
12
12
|
# end
|
13
13
|
# @example A document blueprint configuration with a complex attribute for the class Person
|
14
|
-
# XapianDb::DocumentBlueprint.setup(Person) do |blueprint|
|
14
|
+
# XapianDb::DocumentBlueprint.setup(:Person) do |blueprint|
|
15
15
|
# blueprint.attribute :complex, :weight => 10 do
|
16
16
|
# # add some logic here to evaluate the value of 'complex'
|
17
17
|
# end
|
@@ -31,41 +31,76 @@ module XapianDb
|
|
31
31
|
# - adapter (see {#adapter} for details)
|
32
32
|
# - attribute (see {#attribute} for details)
|
33
33
|
# - index (see {#index} for details)
|
34
|
-
def setup(
|
34
|
+
def setup(klass_or_name, &block)
|
35
|
+
if klass_or_name.is_a?(Class)
|
36
|
+
warn "xapian_db: XapianDb::DocumentBlueprint.setup(Class) is deprecated; use XapianDb::DocumentBlueprint.setup(Symbol) or XapianDb::DocumentBlueprint.setup(String) instead"
|
37
|
+
name = klass_or_name.name
|
38
|
+
else
|
39
|
+
name = klass_or_name.to_s
|
40
|
+
end
|
35
41
|
@blueprints ||= {}
|
36
42
|
blueprint = DocumentBlueprint.new
|
37
43
|
yield blueprint if block_given? # configure the blueprint through the block
|
38
44
|
validate_type_consistency_on blueprint
|
45
|
+
|
39
46
|
# Remove a previously loaded blueprint for this class to avoid stale blueprint definitions
|
40
|
-
@blueprints.delete_if { |indexed_class, blueprint| indexed_class
|
41
|
-
@blueprints[
|
42
|
-
|
43
|
-
|
47
|
+
@blueprints.delete_if { |indexed_class, blueprint| indexed_class == name }
|
48
|
+
@blueprints[name] = blueprint
|
49
|
+
|
50
|
+
# lazy load the adapter
|
51
|
+
unless defined? blueprint._adapter
|
52
|
+
adapter_file = blueprint._adapter.name.split("::").last.downcase + "_adapter"
|
53
|
+
require File.dirname(__FILE__) + "../adapters/#{adapter_file}"
|
54
|
+
end
|
55
|
+
|
56
|
+
# Needed to add class helper methods to indexed pure ruby classes
|
57
|
+
if eval("defined?(#{name}) && #{name}.is_a?(Class)")
|
58
|
+
blueprint._adapter.add_class_helper_methods_to XapianDb::Utilities.constantize(name)
|
59
|
+
end
|
44
60
|
|
45
61
|
@searchable_prefixes = @blueprints.values.map { |blueprint| blueprint.searchable_prefixes }.flatten.compact.uniq || []
|
62
|
+
|
46
63
|
# We can always do a field search on the name of the indexed class
|
47
64
|
@searchable_prefixes << "indexed_class"
|
48
65
|
@attributes = @blueprints.values.map { |blueprint| blueprint.attribute_names}.flatten.compact.uniq.sort || []
|
49
66
|
end
|
50
67
|
|
68
|
+
# is a blueprint configured for the given name?
|
69
|
+
# @return [Boolean]
|
70
|
+
def configured?(name)
|
71
|
+
@blueprints && @blueprints.has_key?(name.to_s)
|
72
|
+
end
|
73
|
+
|
51
74
|
# Get all configured classes
|
52
75
|
# @return [Array<Class>]
|
53
76
|
def configured_classes
|
54
|
-
|
77
|
+
if @blueprints
|
78
|
+
@blueprints.keys.map {|class_name| XapianDb::Utilities.constantize(class_name) }
|
79
|
+
else
|
80
|
+
[]
|
81
|
+
end
|
55
82
|
end
|
56
83
|
|
57
84
|
# Get the blueprint for a class
|
58
85
|
# @return [DocumentBlueprint]
|
59
|
-
def blueprint_for(
|
86
|
+
def blueprint_for(klass_or_name)
|
60
87
|
if @blueprints
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
88
|
+
if klass_or_name.is_a?(Class)
|
89
|
+
warn "xapian_db: blueprint_for(Class) is deprecated; use blueprint_for(Symbol) or blueprint_for(String) instead"
|
90
|
+
key = klass_or_name.name
|
91
|
+
else
|
92
|
+
key = klass_or_name.to_s
|
93
|
+
end
|
94
|
+
while key != "Object" && key != "BasicObject"
|
95
|
+
if @blueprints.has_key? key
|
96
|
+
return @blueprints[key]
|
97
|
+
else
|
98
|
+
klass = XapianDb::Utilities.constantize key
|
99
|
+
key = klass.superclass.name
|
100
|
+
end
|
65
101
|
end
|
66
|
-
raise "Blueprint for class #{klass} is not defined"
|
67
102
|
end
|
68
|
-
|
103
|
+
return nil
|
69
104
|
end
|
70
105
|
|
71
106
|
# Get the value number for an attribute. Please note that this is not the index in the values
|
@@ -197,8 +232,7 @@ module XapianDb
|
|
197
232
|
end
|
198
233
|
|
199
234
|
# Let the adapter add its document helper methods (if any)
|
200
|
-
|
201
|
-
adapter.add_doc_helper_methods_to(@accessors_module)
|
235
|
+
_adapter.add_doc_helper_methods_to(@accessors_module)
|
202
236
|
@accessors_module
|
203
237
|
end
|
204
238
|
|
@@ -206,8 +240,7 @@ module XapianDb
|
|
206
240
|
# Blueprint DSL methods
|
207
241
|
# ---------------------------------------------------------------------------------
|
208
242
|
|
209
|
-
|
210
|
-
attr_reader :_base_query, :_natural_sort_order
|
243
|
+
attr_reader :lazy_base_query, :_natural_sort_order
|
211
244
|
|
212
245
|
# Construct the blueprint
|
213
246
|
def initialize
|
@@ -227,6 +260,11 @@ module XapianDb
|
|
227
260
|
@_adapter = XapianDb::Adapters.const_get("#{camelize(type.to_s)}Adapter")
|
228
261
|
end
|
229
262
|
|
263
|
+
# return the adpater to use for this blueprint
|
264
|
+
def _adapter
|
265
|
+
@_adapter || XapianDb::Config.adapter || XapianDb::Adapters::GenericAdapter
|
266
|
+
end
|
267
|
+
|
230
268
|
# Add an attribute to the blueprint. Attributes will be stored in the xapian documents an can be
|
231
269
|
# accessed from a search result.
|
232
270
|
# @param [String] name The name of the method that delivers the value for the attribute
|
@@ -235,7 +273,7 @@ module XapianDb
|
|
235
273
|
# @option options [Boolean] :index (true) Should the attribute be indexed?
|
236
274
|
# @option options [Symbol] :as should add type info for range queries (:date, :numeric)
|
237
275
|
# @example For complex attribute configurations you may pass a block:
|
238
|
-
# XapianDb::DocumentBlueprint.setup(IndexedObject) do |blueprint|
|
276
|
+
# XapianDb::DocumentBlueprint.setup(:IndexedObject) do |blueprint|
|
239
277
|
# blueprint.attribute :complex do
|
240
278
|
# if @id == 1
|
241
279
|
# "One"
|
@@ -308,14 +346,18 @@ module XapianDb
|
|
308
346
|
@ignore_expression = block
|
309
347
|
end
|
310
348
|
|
311
|
-
|
349
|
+
# Define a base query to select one or all objects of the indexed class. The reason for a
|
312
350
|
# base query is to optimize the query avoiding th 1+n problematic. The base query should only
|
313
351
|
# include joins(...) and includes(...) calls.
|
314
352
|
# @param [expression] a base query expression
|
315
353
|
# @example Include the adresses
|
316
354
|
# blueprint.base_query Person.includes(:addresses)
|
317
|
-
def base_query(expression)
|
318
|
-
|
355
|
+
def base_query(expression = nil, &block)
|
356
|
+
if expression
|
357
|
+
warn "xapian_db: directly passing a base query in a blueprint configuration is deprecated, wrap them in a block"
|
358
|
+
block = lambda { expression }
|
359
|
+
end
|
360
|
+
@lazy_base_query = block
|
319
361
|
end
|
320
362
|
|
321
363
|
# Define the natural sort order.
|
@@ -33,15 +33,10 @@ module XapianDb
|
|
33
33
|
beanstalk.put( { :task => "reindex_class_task", :class => klass.name }.to_yaml )
|
34
34
|
end
|
35
35
|
|
36
|
-
private
|
37
|
-
|
38
36
|
def beanstalk
|
39
37
|
@beanstalk ||= Beanstalk::Pool.new([XapianDb::Config.beanstalk_daemon_url])
|
40
38
|
end
|
41
|
-
|
42
39
|
end
|
43
|
-
|
44
40
|
end
|
45
|
-
|
46
41
|
end
|
47
|
-
end
|
42
|
+
end
|
@@ -19,7 +19,7 @@ module XapianDb
|
|
19
19
|
# Update an object in the index
|
20
20
|
# @param [Object] obj An instance of a class with a blueprint configuration
|
21
21
|
def index(obj, commit=true)
|
22
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for(obj.class)
|
22
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for(obj.class.name)
|
23
23
|
indexer = XapianDb::Indexer.new(XapianDb.database, blueprint)
|
24
24
|
doc = indexer.build_document_for(obj)
|
25
25
|
XapianDb.database.store_doc(doc)
|
@@ -36,7 +36,7 @@ module XapianDb
|
|
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
38
|
def reindex(object, commit=true)
|
39
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class
|
39
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class.name
|
40
40
|
if blueprint.should_index?(object)
|
41
41
|
index object, commit
|
42
42
|
else
|
@@ -50,13 +50,15 @@ module XapianDb
|
|
50
50
|
# @option options [Boolean] :verbose (false) Should the reindexing give status informations?
|
51
51
|
def reindex_class(klass, options={})
|
52
52
|
opts = {:verbose => false}.merge(options)
|
53
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass
|
54
|
-
|
55
|
-
primary_key = adapter.primary_key_for(klass)
|
53
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass.name
|
54
|
+
primary_key = blueprint._adapter.primary_key_for(klass)
|
56
55
|
XapianDb.database.delete_docs_of_class(klass)
|
57
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for(klass)
|
58
56
|
indexer = XapianDb::Indexer.new(XapianDb.database, blueprint)
|
59
|
-
|
57
|
+
if blueprint.lazy_base_query
|
58
|
+
base_query = blueprint.lazy_base_query.call
|
59
|
+
else
|
60
|
+
base_query = klass
|
61
|
+
end
|
60
62
|
show_progressbar = false
|
61
63
|
obj_count = base_query.count
|
62
64
|
if opts[:verbose]
|
data/lib/xapian_db/indexer.rb
CHANGED
@@ -19,7 +19,7 @@ module XapianDb
|
|
19
19
|
# @return [Xapian::Document] The xapian document (see http://xapian.org/docs/sourcedoc/html/classXapian_1_1Document.html)
|
20
20
|
def build_document_for(obj)
|
21
21
|
@obj = obj
|
22
|
-
@blueprint = DocumentBlueprint.blueprint_for(@obj.class)
|
22
|
+
@blueprint = DocumentBlueprint.blueprint_for(@obj.class.name)
|
23
23
|
@xapian_doc = Xapian::Document.new
|
24
24
|
@xapian_doc.data = @obj.xapian_id
|
25
25
|
store_fields
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module XapianDb
|
2
|
+
module ModelExtenders
|
3
|
+
module ActiveRecord
|
4
|
+
def inherited(klass)
|
5
|
+
super
|
6
|
+
if XapianDb::DocumentBlueprint.configured? klass.name
|
7
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass.name
|
8
|
+
blueprint._adapter.add_class_helper_methods_to klass
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class << self
|
5
|
+
alias_method :included_dm, :included
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.included(model)
|
9
|
+
included_dm model
|
10
|
+
if XapianDb::DocumentBlueprint.configured? model.name
|
11
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for model.name
|
12
|
+
blueprint._adapter.add_class_helper_methods_to model
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/xapian_db/railtie.rb
CHANGED
@@ -9,11 +9,22 @@ module XapianDb
|
|
9
9
|
# @author Gernot Kogler
|
10
10
|
class Railtie < ::Rails::Railtie
|
11
11
|
|
12
|
+
# require our rake tasks
|
13
|
+
rake_tasks do
|
14
|
+
load "#{File.dirname(__FILE__)}/../../tasks/xapian_rebuild_index.rake"
|
15
|
+
end
|
16
|
+
|
12
17
|
# require our generators
|
13
18
|
generators do
|
14
19
|
require "#{File.dirname(__FILE__)}/../generators/install_generator.rb"
|
15
20
|
end
|
16
21
|
|
22
|
+
initializer "xapian_db.active_record" do |app|
|
23
|
+
ActiveSupport.on_load :active_record do
|
24
|
+
ActiveRecord::Base.extend XapianDb::ModelExtenders::ActiveRecord
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
config.before_configuration do
|
18
29
|
|
19
30
|
# Read the database configuration file if there is one
|
data/lib/xapian_db/resultset.rb
CHANGED
@@ -103,7 +103,7 @@ module XapianDb
|
|
103
103
|
# @return [Xapian::Match] the decorated match
|
104
104
|
def decorate(match)
|
105
105
|
klass_name = match.document.values[0].value
|
106
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for
|
106
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass_name
|
107
107
|
match.document.extend blueprint.accessors_module
|
108
108
|
match.document.instance_variable_set :@score, match.percent
|
109
109
|
match
|
data/lib/xapian_db/utilities.rb
CHANGED
data/lib/xapian_db.rb
CHANGED
@@ -9,8 +9,9 @@
|
|
9
9
|
require 'xapian'
|
10
10
|
require 'yaml'
|
11
11
|
|
12
|
-
do_not_require = %w(update_stopwords
|
13
|
-
|
12
|
+
do_not_require = %w(update_stopwords railtie base_adapter generic_adapter active_record_adapter datamapper_adapter
|
13
|
+
beanstalk_writer resque_writer utilities install_generator datamapper)
|
14
|
+
files = Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").reject{|path| do_not_require.include?(File.basename(path, ".rb"))}
|
14
15
|
# Require these first
|
15
16
|
require "#{File.dirname(__FILE__)}/xapian_db/utilities"
|
16
17
|
require "#{File.dirname(__FILE__)}/xapian_db/adapters/base_adapter"
|
@@ -120,7 +121,7 @@ module XapianDb
|
|
120
121
|
# @param [Object] object An instance of a class with a blueprint configuration
|
121
122
|
def self.reindex(object, commit=true)
|
122
123
|
writer = @block_writer || XapianDb::Config.writer
|
123
|
-
blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class
|
124
|
+
blueprint = XapianDb::DocumentBlueprint.blueprint_for object.class.name
|
124
125
|
if blueprint.should_index?(object)
|
125
126
|
writer.index object, commit
|
126
127
|
else
|
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.
|
4
|
+
version: 1.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
13
|
-
default_executable:
|
12
|
+
date: 2011-12-13 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: daemons
|
17
|
-
requirement: &
|
16
|
+
requirement: &70136488601320 !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
@@ -22,10 +21,10 @@ dependencies:
|
|
22
21
|
version: 1.0.10
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements: *
|
24
|
+
version_requirements: *70136488601320
|
26
25
|
- !ruby/object:Gem::Dependency
|
27
26
|
name: guard
|
28
|
-
requirement: &
|
27
|
+
requirement: &70136488600860 !ruby/object:Gem::Requirement
|
29
28
|
none: false
|
30
29
|
requirements:
|
31
30
|
- - ! '>='
|
@@ -33,10 +32,10 @@ dependencies:
|
|
33
32
|
version: '0'
|
34
33
|
type: :development
|
35
34
|
prerelease: false
|
36
|
-
version_requirements: *
|
35
|
+
version_requirements: *70136488600860
|
37
36
|
- !ruby/object:Gem::Dependency
|
38
37
|
name: rspec
|
39
|
-
requirement: &
|
38
|
+
requirement: &70136488600080 !ruby/object:Gem::Requirement
|
40
39
|
none: false
|
41
40
|
requirements:
|
42
41
|
- - ! '>='
|
@@ -44,10 +43,10 @@ dependencies:
|
|
44
43
|
version: 2.3.1
|
45
44
|
type: :development
|
46
45
|
prerelease: false
|
47
|
-
version_requirements: *
|
46
|
+
version_requirements: *70136488600080
|
48
47
|
- !ruby/object:Gem::Dependency
|
49
48
|
name: simplecov
|
50
|
-
requirement: &
|
49
|
+
requirement: &70136488599340 !ruby/object:Gem::Requirement
|
51
50
|
none: false
|
52
51
|
requirements:
|
53
52
|
- - ! '>='
|
@@ -55,10 +54,10 @@ dependencies:
|
|
55
54
|
version: 0.3.7
|
56
55
|
type: :development
|
57
56
|
prerelease: false
|
58
|
-
version_requirements: *
|
57
|
+
version_requirements: *70136488599340
|
59
58
|
- !ruby/object:Gem::Dependency
|
60
59
|
name: beanstalk-client
|
61
|
-
requirement: &
|
60
|
+
requirement: &70136488615000 !ruby/object:Gem::Requirement
|
62
61
|
none: false
|
63
62
|
requirements:
|
64
63
|
- - ! '>='
|
@@ -66,10 +65,10 @@ dependencies:
|
|
66
65
|
version: 1.1.0
|
67
66
|
type: :development
|
68
67
|
prerelease: false
|
69
|
-
version_requirements: *
|
68
|
+
version_requirements: *70136488615000
|
70
69
|
- !ruby/object:Gem::Dependency
|
71
70
|
name: rake
|
72
|
-
requirement: &
|
71
|
+
requirement: &70136488614460 !ruby/object:Gem::Requirement
|
73
72
|
none: false
|
74
73
|
requirements:
|
75
74
|
- - ! '>='
|
@@ -77,10 +76,10 @@ dependencies:
|
|
77
76
|
version: '0'
|
78
77
|
type: :development
|
79
78
|
prerelease: false
|
80
|
-
version_requirements: *
|
79
|
+
version_requirements: *70136488614460
|
81
80
|
- !ruby/object:Gem::Dependency
|
82
81
|
name: progressbar
|
83
|
-
requirement: &
|
82
|
+
requirement: &70136488613860 !ruby/object:Gem::Requirement
|
84
83
|
none: false
|
85
84
|
requirements:
|
86
85
|
- - ! '>='
|
@@ -88,10 +87,10 @@ dependencies:
|
|
88
87
|
version: '0'
|
89
88
|
type: :development
|
90
89
|
prerelease: false
|
91
|
-
version_requirements: *
|
90
|
+
version_requirements: *70136488613860
|
92
91
|
- !ruby/object:Gem::Dependency
|
93
92
|
name: resque
|
94
|
-
requirement: &
|
93
|
+
requirement: &70136488613340 !ruby/object:Gem::Requirement
|
95
94
|
none: false
|
96
95
|
requirements:
|
97
96
|
- - ! '>='
|
@@ -99,7 +98,7 @@ dependencies:
|
|
99
98
|
version: 1.19.0
|
100
99
|
type: :development
|
101
100
|
prerelease: false
|
102
|
-
version_requirements: *
|
101
|
+
version_requirements: *70136488613340
|
103
102
|
description: XapianDb is a ruby gem that combines features of nosql databases and
|
104
103
|
fulltext indexing. It is based on Xapian, an efficient and powerful indexing library
|
105
104
|
email: gernot.kogler (at) garaio (dot) com
|
@@ -125,6 +124,8 @@ files:
|
|
125
124
|
- lib/xapian_db/index_writers/resque_writer.rb
|
126
125
|
- lib/xapian_db/index_writers/transactional_writer.rb
|
127
126
|
- lib/xapian_db/indexer.rb
|
127
|
+
- lib/xapian_db/model_extenders/active_record.rb
|
128
|
+
- lib/xapian_db/model_extenders/datamapper.rb
|
128
129
|
- lib/xapian_db/query_parser.rb
|
129
130
|
- lib/xapian_db/railtie.rb
|
130
131
|
- lib/xapian_db/repositories/stemmer.rb
|
@@ -147,11 +148,11 @@ files:
|
|
147
148
|
- lib/xapian_db/stopwords/update_stopwords.rb
|
148
149
|
- lib/xapian_db/utilities.rb
|
149
150
|
- lib/xapian_db.rb
|
151
|
+
- tasks/xapian_rebuild_index.rake
|
150
152
|
- LICENSE
|
151
153
|
- README.rdoc
|
152
154
|
- CHANGELOG.md
|
153
155
|
- Rakefile
|
154
|
-
has_rdoc: true
|
155
156
|
homepage: https://github.com/garaio/xapian_db
|
156
157
|
licenses: []
|
157
158
|
post_install_message:
|
@@ -178,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
179
|
version: 1.3.6
|
179
180
|
requirements: []
|
180
181
|
rubyforge_project:
|
181
|
-
rubygems_version: 1.
|
182
|
+
rubygems_version: 1.8.12
|
182
183
|
signing_key:
|
183
184
|
specification_version: 3
|
184
185
|
summary: Ruby library to use a Xapian db as a key/value store with high performance
|