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 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 save block to an indexed class to update the index
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
- after_save do
41
+ after_commit do
42
42
  blueprint = XapianDb::DocumentBlueprint.blueprint_for klass
43
43
  if blueprint.should_index?(self)
44
- XapianDb::Config.writer.index(self)
44
+ XapianDb.index(self)
45
45
  else
46
- XapianDb::Config.writer.unindex(self)
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::Config.writer.unindex(self)
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::Config.writer.reindex_class(klass, options)
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::Config.writer.index(self)
43
+ XapianDb.index(self)
44
44
  else
45
- XapianDb::Config.writer.unindex(self)
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::Config.writer.unindex(self)
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::Config.writer.reindex_class(self, options)
57
+ XapianDb.reindex_class(self, options)
58
58
  end
59
59
  end
60
60
 
@@ -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
- key = lang.to_sym
112
- @_stemmer = XapianDb::Repositories::Stemmer.stemmer_for key
113
- key == :none ? @_stopper = nil : @_stopper = XapianDb::Repositories::Stopper.stopper_for(key)
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
@@ -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 the base adapter first
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
- version: 0.5.7
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-07 00:00:00 +01:00
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.5.0
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