xapian_db 0.5.7 → 0.5.8
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 +10 -0
- data/README.rdoc +18 -0
- data/lib/xapian_db/adapters/active_record_adapter.rb +6 -6
- data/lib/xapian_db/adapters/datamapper_adapter.rb +4 -4
- data/lib/xapian_db/config.rb +5 -11
- data/lib/xapian_db/document_blueprint.rb +2 -7
- data/lib/xapian_db/index_writers/transactional_writer.rb +51 -0
- data/lib/xapian_db/railtie.rb +3 -4
- data/lib/xapian_db/utilities.rb +16 -0
- data/lib/xapian_db.rb +44 -2
- metadata +28 -4
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
##0.5.8 (March 22th, 2011)
|
2
|
+
|
3
|
+
Fixes:
|
4
|
+
|
5
|
+
- automatic reindexing of a changed object now works when using beanstalk and the worker rake task
|
6
|
+
|
7
|
+
Features:
|
8
|
+
|
9
|
+
- support for transactions (see the README for details)
|
10
|
+
|
1
11
|
##0.5.7 (March 7th, 2011)
|
2
12
|
|
3
13
|
Fixes:
|
data/README.rdoc
CHANGED
@@ -116,6 +116,14 @@ You may add a filter expression to exclude objects from the index. This is handy
|
|
116
116
|
blueprint.ignore_if {active == false}
|
117
117
|
end
|
118
118
|
|
119
|
+
You can override the global adapter configuration in a specific blueprint. Let's say you use ActiveRecord, but you have
|
120
|
+
one more class that is not stored in the database, but you want it to be indexed:
|
121
|
+
|
122
|
+
XapianDb::DocumentBlueprint.setup(SpecialClass) do |blueprint|
|
123
|
+
blueprint.adapter :generic
|
124
|
+
blueprint.index :some_stuff
|
125
|
+
end
|
126
|
+
|
119
127
|
place these configurations either into the corresponding class or - I prefer to have the index configurations outside
|
120
128
|
the models - into the file config/xapian_blueprints.rb.
|
121
129
|
|
@@ -226,6 +234,16 @@ A global facet search always groups the results by the class of the indexed obje
|
|
226
234
|
|
227
235
|
At the class level, any attribute can be used for a facet query.
|
228
236
|
|
237
|
+
=== Transactions
|
238
|
+
|
239
|
+
You can execute a block of code inside a XapianDb transaction. This ensures that the changed objects in your block will get reindexed
|
240
|
+
only if the block does not raise an exception.
|
241
|
+
|
242
|
+
XapianDb.transaction do
|
243
|
+
object1.save
|
244
|
+
object2.save
|
245
|
+
end
|
246
|
+
|
229
247
|
== Production setup
|
230
248
|
|
231
249
|
Since Xapian allows only one database instance to write to the index, the default setup of XapianDb will not work
|
@@ -10,7 +10,7 @@ module XapianDb
|
|
10
10
|
# This adapter does the following:
|
11
11
|
# - adds the instance method <code>xapian_id</code> to an indexed class
|
12
12
|
# - adds the class method <code>rebuild_xapian_index</code> to an indexed class
|
13
|
-
# - adds an after
|
13
|
+
# - adds an after commit block to an indexed class to update the index
|
14
14
|
# - adds an after destroy block to an indexed class to update the index
|
15
15
|
# - adds the instance method <code>indexed_object</code> to the module that will be included
|
16
16
|
# in every found xapian document
|
@@ -38,24 +38,24 @@ module XapianDb
|
|
38
38
|
klass.class_eval do
|
39
39
|
|
40
40
|
# add the after save logic
|
41
|
-
|
41
|
+
after_commit do
|
42
42
|
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass
|
43
43
|
if blueprint.should_index?(self)
|
44
|
-
XapianDb
|
44
|
+
XapianDb.index(self)
|
45
45
|
else
|
46
|
-
XapianDb
|
46
|
+
XapianDb.unindex(self)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
# add the after destroy logic
|
51
51
|
after_destroy do
|
52
|
-
XapianDb
|
52
|
+
XapianDb.unindex(self)
|
53
53
|
end
|
54
54
|
|
55
55
|
# Add a method to reindex all models of this class
|
56
56
|
define_singleton_method(:rebuild_xapian_index) do |options={}|
|
57
57
|
options[:primary_key] = klass.primary_key
|
58
|
-
XapianDb
|
58
|
+
XapianDb.reindex_class(klass, options)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -40,21 +40,21 @@ module XapianDb
|
|
40
40
|
after :save do
|
41
41
|
blueprint = XapianDb::DocumentBlueprint.blueprint_for klass
|
42
42
|
if blueprint.should_index?(self)
|
43
|
-
XapianDb
|
43
|
+
XapianDb.index(self)
|
44
44
|
else
|
45
|
-
XapianDb
|
45
|
+
XapianDb.unindex(self)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
# add the after destroy logic
|
50
50
|
after :destroy do
|
51
|
-
XapianDb
|
51
|
+
XapianDb.unindex(self)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Add a method to reindex all models of this class
|
55
55
|
define_singleton_method(:rebuild_xapian_index) do |options={}|
|
56
56
|
options[:primary_key] = klass.serial.name
|
57
|
-
XapianDb
|
57
|
+
XapianDb.reindex_class(self, options)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
data/lib/xapian_db/config.rb
CHANGED
@@ -12,6 +12,8 @@ module XapianDb
|
|
12
12
|
# @author Gernot Kogler
|
13
13
|
class Config
|
14
14
|
|
15
|
+
include XapianDb::Utilities
|
16
|
+
|
15
17
|
# ---------------------------------------------------------------------------------
|
16
18
|
# Singleton methods
|
17
19
|
# ---------------------------------------------------------------------------------
|
@@ -48,7 +50,6 @@ module XapianDb
|
|
48
50
|
# DSL methods
|
49
51
|
# ---------------------------------------------------------------------------------
|
50
52
|
|
51
|
-
#
|
52
53
|
attr_reader :_database, :_adapter, :_writer, :_beanstalk_daemon, :_stemmer, :_stopper
|
53
54
|
|
54
55
|
# Set the global database to use
|
@@ -108,16 +109,9 @@ module XapianDb
|
|
108
109
|
# end
|
109
110
|
# see {LANGUAGE_MAP} for supported languages
|
110
111
|
def language(lang)
|
111
|
-
|
112
|
-
@_stemmer = XapianDb::Repositories::Stemmer.stemmer_for
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
private
|
117
|
-
|
118
|
-
# TODO: move this to a helper module
|
119
|
-
def camelize(string)
|
120
|
-
string.split(/[^a-z0-9]/i).map{|w| w.capitalize}.join
|
112
|
+
lang ||= :none
|
113
|
+
@_stemmer = XapianDb::Repositories::Stemmer.stemmer_for lang
|
114
|
+
@_stopper = lang == :none ? nil : XapianDb::Repositories::Stopper.stopper_for(lang)
|
121
115
|
end
|
122
116
|
|
123
117
|
end
|
@@ -19,6 +19,8 @@ module XapianDb
|
|
19
19
|
# @author Gernot Kogler
|
20
20
|
class DocumentBlueprint
|
21
21
|
|
22
|
+
include XapianDb::Utilities
|
23
|
+
|
22
24
|
# ---------------------------------------------------------------------------------
|
23
25
|
# Singleton methods
|
24
26
|
# ---------------------------------------------------------------------------------
|
@@ -295,13 +297,6 @@ module XapianDb
|
|
295
297
|
@reserved_method_names.include?(attr_name.to_sym)
|
296
298
|
end
|
297
299
|
|
298
|
-
private
|
299
|
-
|
300
|
-
# TODO: move this to a helper module
|
301
|
-
def camelize(string)
|
302
|
-
string.split(/[^a-z0-9]/i).map{|w| w.capitalize}.join
|
303
|
-
end
|
304
|
-
|
305
300
|
end
|
306
301
|
|
307
302
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This writer collects index change requests but does not submit them immediately to the database.
|
4
|
+
# The index changes are applied when the commit method is called.
|
5
|
+
# This writer is intended for internal use only. Do not use it in a xapian configuration!
|
6
|
+
# @author Gernot Kogler
|
7
|
+
|
8
|
+
module XapianDb
|
9
|
+
module IndexWriters
|
10
|
+
|
11
|
+
class TransactionalWriter
|
12
|
+
|
13
|
+
attr_reader :index_requests, :unindex_requests
|
14
|
+
|
15
|
+
# Constructor
|
16
|
+
def initialize
|
17
|
+
@index_requests = []
|
18
|
+
@unindex_requests = []
|
19
|
+
end
|
20
|
+
|
21
|
+
# Update an object in the index
|
22
|
+
# @param [Object] obj An instance of a class with a blueprint configuration
|
23
|
+
def index(obj)
|
24
|
+
@index_requests << obj
|
25
|
+
end
|
26
|
+
|
27
|
+
# Remove an object from the index
|
28
|
+
# @param [Object] obj An instance of a class with a blueprint configuration
|
29
|
+
def unindex(obj)
|
30
|
+
@unindex_requests << obj
|
31
|
+
end
|
32
|
+
|
33
|
+
# Reindex all objects of a given class
|
34
|
+
# @param [Class] klass The class to reindex
|
35
|
+
# @param [Hash] options Options for reindexing
|
36
|
+
# @option options [Boolean] :verbose (false) Should the reindexing give status informations?
|
37
|
+
def reindex_class(klass, options={})
|
38
|
+
raise "rebuild_xapian_index is not supported in transactions"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Commit all pending changes to the database
|
42
|
+
# @param [DirectWriter, BeanstalkWriter] writer The writer to use
|
43
|
+
def commit_using(writer)
|
44
|
+
@index_requests.each { |obj| writer.index obj }
|
45
|
+
@unindex_requests.each { |obj| writer.unindex obj }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/xapian_db/railtie.rb
CHANGED
@@ -34,10 +34,10 @@ module XapianDb
|
|
34
34
|
else
|
35
35
|
config.database File.expand_path @database_path
|
36
36
|
end
|
37
|
-
config.adapter @adapter.to_sym
|
38
|
-
config.writer @writer.to_sym
|
37
|
+
config.adapter @adapter.try(:to_sym)
|
38
|
+
config.writer @writer.try(:to_sym)
|
39
39
|
config.beanstalk_daemon_url @beanstalk_daemon
|
40
|
-
config.language @language
|
40
|
+
config.language @language.try(:to_sym)
|
41
41
|
end
|
42
42
|
|
43
43
|
end
|
@@ -66,7 +66,6 @@ module XapianDb
|
|
66
66
|
@adapter = :active_record
|
67
67
|
@writer = :direct
|
68
68
|
@beanstalk_daemon = nil
|
69
|
-
@language = :en
|
70
69
|
end
|
71
70
|
|
72
71
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Collection of utility methods
|
4
|
+
# @author Gernot Kogler
|
5
|
+
module XapianDb
|
6
|
+
module Utilities
|
7
|
+
|
8
|
+
# Convert a string to camel case
|
9
|
+
# @param [String] The string to camelize
|
10
|
+
# @return [String] The camelized string
|
11
|
+
def camelize(string)
|
12
|
+
string.split(/[^a-z0-9]/i).map{|w| w.capitalize}.join
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
data/lib/xapian_db.rb
CHANGED
@@ -34,6 +34,7 @@ module XapianDb
|
|
34
34
|
# for available options
|
35
35
|
def self.setup(&block)
|
36
36
|
XapianDb::Config.setup(&block)
|
37
|
+
@writer = XapianDb::Config.writer
|
37
38
|
end
|
38
39
|
|
39
40
|
# Create a database
|
@@ -84,6 +85,26 @@ module XapianDb
|
|
84
85
|
XapianDb::Config.database.facets(expression)
|
85
86
|
end
|
86
87
|
|
88
|
+
# Update an object in the index
|
89
|
+
# @param [Object] obj An instance of a class with a blueprint configuration
|
90
|
+
def self.index(obj)
|
91
|
+
@writer.index obj
|
92
|
+
end
|
93
|
+
|
94
|
+
# Remove an object from the index
|
95
|
+
# @param [Object] obj An instance of a class with a blueprint configuration
|
96
|
+
def self.unindex(obj)
|
97
|
+
@writer.unindex obj
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reindex all objects of a given class
|
101
|
+
# @param [Class] klass The class to reindex
|
102
|
+
# @param [Hash] options Options for reindexing
|
103
|
+
# @option options [Boolean] :verbose (false) Should the reindexing give status informations?
|
104
|
+
def self.reindex_class(klass, options={})
|
105
|
+
@writer.reindex_class klass, options
|
106
|
+
end
|
107
|
+
|
87
108
|
# Rebuild the xapian index for all configured blueprints
|
88
109
|
# @param [Hash] options Options for reindexing
|
89
110
|
# @option options [Boolean] :verbose (false) Should the reindexing give status informations?
|
@@ -97,11 +118,32 @@ module XapianDb
|
|
97
118
|
true
|
98
119
|
end
|
99
120
|
|
121
|
+
# Execute a block as a transaction
|
122
|
+
def self.transaction(&block)
|
123
|
+
# Temporarily use the transactional writer
|
124
|
+
@writer = XapianDb::IndexWriters::TransactionalWriter.new
|
125
|
+
begin
|
126
|
+
block.call
|
127
|
+
@writer.commit_using XapianDb::Config.writer
|
128
|
+
rescue Exception => ex
|
129
|
+
msg = "error in XapianDb transaction block: #{ex}, transaction aborted"
|
130
|
+
if defined?(Rails)
|
131
|
+
Rails.logger.error msg
|
132
|
+
else
|
133
|
+
puts msg
|
134
|
+
end
|
135
|
+
ensure
|
136
|
+
# switch back to the configured writer
|
137
|
+
@writer = XapianDb::Config.writer
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
100
141
|
end
|
101
142
|
|
102
|
-
do_not_require = %w(update_stopwords.rb railtie.rb base_adapter.rb beanstalk_writer.rb)
|
143
|
+
do_not_require = %w(update_stopwords.rb railtie.rb base_adapter.rb beanstalk_writer.rb utilities.rb)
|
103
144
|
files = Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").reject{|path| do_not_require.include?(File.basename(path))}
|
104
|
-
# Require
|
145
|
+
# Require these first
|
146
|
+
require "#{File.dirname(__FILE__)}/xapian_db/utilities"
|
105
147
|
require "#{File.dirname(__FILE__)}/xapian_db/adapters/base_adapter"
|
106
148
|
files.each {|file| require file}
|
107
149
|
|
metadata
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xapian_db
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
- 8
|
9
|
+
version: 0.5.8
|
6
10
|
platform: ruby
|
7
11
|
authors:
|
8
12
|
- Gernot Kogler
|
@@ -10,7 +14,7 @@ autorequire:
|
|
10
14
|
bindir: bin
|
11
15
|
cert_chain: []
|
12
16
|
|
13
|
-
date: 2011-03-
|
17
|
+
date: 2011-03-23 00:00:00 +01:00
|
14
18
|
default_executable:
|
15
19
|
dependencies:
|
16
20
|
- !ruby/object:Gem::Dependency
|
@@ -21,6 +25,10 @@ dependencies:
|
|
21
25
|
requirements:
|
22
26
|
- - ">="
|
23
27
|
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 3
|
31
|
+
- 1
|
24
32
|
version: 2.3.1
|
25
33
|
type: :development
|
26
34
|
version_requirements: *id001
|
@@ -32,6 +40,10 @@ dependencies:
|
|
32
40
|
requirements:
|
33
41
|
- - ">="
|
34
42
|
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
- 3
|
46
|
+
- 7
|
35
47
|
version: 0.3.7
|
36
48
|
type: :development
|
37
49
|
version_requirements: *id002
|
@@ -43,6 +55,10 @@ dependencies:
|
|
43
55
|
requirements:
|
44
56
|
- - ">="
|
45
57
|
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 1
|
61
|
+
- 0
|
46
62
|
version: 1.1.0
|
47
63
|
type: :development
|
48
64
|
version_requirements: *id003
|
@@ -65,6 +81,7 @@ files:
|
|
65
81
|
- lib/xapian_db/index_writers/beanstalk_worker.rb
|
66
82
|
- lib/xapian_db/index_writers/beanstalk_writer.rb
|
67
83
|
- lib/xapian_db/index_writers/direct_writer.rb
|
84
|
+
- lib/xapian_db/index_writers/transactional_writer.rb
|
68
85
|
- lib/xapian_db/indexer.rb
|
69
86
|
- lib/xapian_db/query_parser.rb
|
70
87
|
- lib/xapian_db/railtie.rb
|
@@ -86,6 +103,7 @@ files:
|
|
86
103
|
- lib/xapian_db/stopwords/ru.txt
|
87
104
|
- lib/xapian_db/stopwords/sv.txt
|
88
105
|
- lib/xapian_db/stopwords/update_stopwords.rb
|
106
|
+
- lib/xapian_db/utilities.rb
|
89
107
|
- lib/xapian_db.rb
|
90
108
|
- tasks/beanstalk_worker.rake
|
91
109
|
- xapian_source/xapian-bindings-1.2.4.tar.gz
|
@@ -113,17 +131,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
131
|
requirements:
|
114
132
|
- - ">="
|
115
133
|
- !ruby/object:Gem::Version
|
134
|
+
segments:
|
135
|
+
- 0
|
116
136
|
version: "0"
|
117
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
138
|
none: false
|
119
139
|
requirements:
|
120
140
|
- - ">="
|
121
141
|
- !ruby/object:Gem::Version
|
142
|
+
segments:
|
143
|
+
- 1
|
144
|
+
- 3
|
145
|
+
- 6
|
122
146
|
version: 1.3.6
|
123
147
|
requirements: []
|
124
148
|
|
125
149
|
rubyforge_project:
|
126
|
-
rubygems_version: 1.
|
150
|
+
rubygems_version: 1.3.7
|
127
151
|
signing_key:
|
128
152
|
specification_version: 3
|
129
153
|
summary: Ruby library to use a Xapian db as a key/value store with high performance fulltext search
|