Skip to content

Commit

Permalink
Merge pull request #50 from kreba/delete_docs_of_descendant_classes
Browse files Browse the repository at this point in the history
XapianDb.database.delete_docs_of_class should delete docs of descendant classes, too
  • Loading branch information
gernotkogler committed Jan 12, 2016
2 parents d7dbe9a + 376f090 commit 55a4c8e
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
.idea
.rvmrc
.bundle
coverage/*
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,7 +1,14 @@
## [next]

Fixes:

- `XapianDb.database.delete_docs_of_class(klass)` now deletes docs of all descendants of `klass`, too (if tracked)

##1.3.6 (August 14th, 2015)

Changes:

- The required Ruby version is now 2.0.0 since we started using keyword parameters in method definitions
- Ability do define and handle dependencies between blueprints (see README)
- explicit order option for searches

Expand Down
4 changes: 2 additions & 2 deletions README.rdoc
Expand Up @@ -32,9 +32,9 @@ I tried hard but I couldn't find such a thing so I decided to write it, based on

== Requirements

* ruby 1.9.2 or newer
* ruby 2.0.0 or newer
* rails 3.0 or newer (if you want to use it with rails)
* xapian-core and xapian-ruby binaries installed
* xapian-core and xapian-ruby binaries 1.2.x installed

== Installing xapian binaries

Expand Down
3 changes: 3 additions & 0 deletions examples/basic.rb
Expand Up @@ -19,6 +19,9 @@
# 2: Define a class which should get indexed; we define a class that
# could be an ActiveRecord or Datamapper Domain class
class Person
# If you are using inheritance hierarchies among indexed classes outside of ActiveRecord,
# using DescendantsTracker helps with rebuilding the Xapian index for a given class and all its subclasses.
extend DescendantsTracker

attr_accessor :id, :name, :first_name, :date_of_birth

Expand Down
11 changes: 10 additions & 1 deletion lib/xapian_db/database.rb
Expand Up @@ -35,10 +35,19 @@ def delete_doc_with_unique_term(term)
true
end

# Delete all docs of a specific class
# Delete all docs of a specific class.
#
# If `klass` tracks its descendants, then docs of any subclasses will be deleted, too.
# (ActiveRecord does this by default; the gem 'descendants_tracker' offers an alternative.)
#
# @param [Class] klass A class that has a {XapianDb::DocumentBlueprint} configuration
def delete_docs_of_class(klass)
writer.delete_document("C#{klass}")
if klass.respond_to? :descendants
klass.descendants.each do |subclass|
writer.delete_document("C#{subclass}")
end
end
true
end

Expand Down
19 changes: 18 additions & 1 deletion spec/basic_mocks.rb
Expand Up @@ -9,7 +9,7 @@ def tableize
self # not really important what we return
end

def parameterize
def parameterize
self # not really important what we return
end

Expand All @@ -24,6 +24,23 @@ def initialize(id)
end
end

class IndexedObjectSubclass < IndexedObject
end

require 'descendants_tracker'
class IndexedObjectDT
extend DescendantsTracker

attr_reader :id

def initialize(id)
@id = id
end
end

class IndexedObjectTrackedSubclass < IndexedObjectDT
end

class OtherIndexedObject
attr_reader :id

Expand Down
46 changes: 42 additions & 4 deletions spec/xapian_db/database_spec.rb
Expand Up @@ -73,11 +73,15 @@
config.adapter :generic
config.database :memory
end
XapianDb::DocumentBlueprint.setup(:IndexedObject) do |blueprint|
blueprint.attribute :id
%i[ IndexedObject IndexedObjectSubclass IndexedObjectDT IndexedObjectTrackedSubclass ].each do |klass|
XapianDb::DocumentBlueprint.setup(klass) do |blueprint|
blueprint.attribute :id
end
end
@blueprint = XapianDb::DocumentBlueprint.blueprint_for(:IndexedObject)
@indexer = XapianDb::Indexer.new(XapianDb.database, @blueprint)
@blueprint = XapianDb::DocumentBlueprint.blueprint_for(:IndexedObject)
@blueprint_dt = XapianDb::DocumentBlueprint.blueprint_for(:IndexedObjectDT)
@indexer = XapianDb::Indexer.new(XapianDb.database, @blueprint)
@indexer_dt = XapianDb::Indexer.new(XapianDb.database, @blueprint_dt)
end

it "should delete all docs of the given class" do
Expand All @@ -99,6 +103,40 @@

end

it "should delete all docs of descendant classes, too, if they are tracked" do

# Create a doc for a tracked subclass
obj = IndexedObjectTrackedSubclass.new(1)
doc = @indexer_dt.build_document_for(obj)
expect(XapianDb.database.store_doc(doc)).to be_truthy

XapianDb.database.commit
expect(XapianDb.database.size).to eq(1)

# Now delete all docs of the object's superclass
XapianDb.database.delete_docs_of_class(IndexedObjectDT)
XapianDb.database.commit
expect(XapianDb.database.size).to eq(0)

end

it "ignore descendant classes where no descendants tracking mechanism is employed" do

# Create a doc for a non-tracked subclass
obj = IndexedObjectSubclass.new(1)
doc = @indexer.build_document_for(obj)
expect(XapianDb.database.store_doc(doc)).to be_truthy

XapianDb.database.commit
expect(XapianDb.database.size).to eq(1)

# Now delete all docs of the object's superclass
XapianDb.database.delete_docs_of_class(IndexedObject)
XapianDb.database.commit
expect(XapianDb.database.size).to eq(1)

end

it "must not delete docs of a different class that have a term like the name of <klass>" do

class LeaveMeAlone
Expand Down
3 changes: 3 additions & 0 deletions spec/xapian_db/document_blueprint_spec.rb
Expand Up @@ -226,9 +226,12 @@ class InheritedIndexedObject < IndexedObject; end
it "does replace the blueprint for a class if the class is reloaded" do
XapianDb::DocumentBlueprint.setup(:IndexedObject)
expect(XapianDb::DocumentBlueprint.configured_classes.size).to eq(1)

# reload IndexedObject
Object.send(:remove_const, :IndexedObject)
Object.send(:remove_const, :IndexedObjectSubclass)
load File.expand_path('../../basic_mocks.rb', __FILE__)

XapianDb::DocumentBlueprint.setup(:IndexedObject)
expect(XapianDb::DocumentBlueprint.configured_classes.size).to eq(1)
end
Expand Down
6 changes: 4 additions & 2 deletions xapian_db.gemspec
Expand Up @@ -14,7 +14,8 @@ Gem::Specification.new do |s|
s.homepage = %q{https://github.com/garaio/xapian_db}
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Xapian-DB", "--main", "README.rdoc"]

s.required_rubygems_version = ">=1.3.6"
s.required_ruby_version = ">= 2.0.0"
s.required_rubygems_version = ">= 1.3.6"

s.add_dependency "daemons", ">= 1.0.10"

Expand All @@ -26,8 +27,9 @@ Gem::Specification.new do |s|
s.add_development_dependency "ruby-progressbar"
s.add_development_dependency "resque", ">= 1.19.0"
s.add_development_dependency "sidekiq", ">= 2.13.0"
s.add_development_dependency "xapian-ruby", "= 1.2.21"
s.add_development_dependency "xapian-ruby", "= 1.2.22"
s.add_development_dependency "pry-rails"
s.add_development_dependency "descendants_tracker"

s.files = Dir.glob("lib/**/*") + Dir.glob("tasks/*") + Dir.glob("xapian_source/*") + %w(LICENSE README.rdoc CHANGELOG.md Rakefile)
s.require_path = "lib"
Expand Down

0 comments on commit 55a4c8e

Please sign in to comment.