xapit 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGELOG +27 -0
  2. data/Manifest +16 -1
  3. data/README.rdoc +29 -15
  4. data/Rakefile +1 -1
  5. data/features/facets.feature +40 -1
  6. data/features/finding.feature +15 -59
  7. data/features/sorting.feature +29 -0
  8. data/features/step_definitions/xapit_steps.rb +11 -3
  9. data/features/suggestions.feature +17 -0
  10. data/features/support/xapit_helpers.rb +1 -1
  11. data/install.rb +7 -8
  12. data/lib/xapit.rb +34 -2
  13. data/lib/xapit/adapters/abstract_adapter.rb +46 -0
  14. data/lib/xapit/adapters/active_record_adapter.rb +20 -0
  15. data/lib/xapit/adapters/data_mapper_adapter.rb +10 -0
  16. data/lib/xapit/collection.rb +17 -5
  17. data/lib/xapit/config.rb +1 -9
  18. data/lib/xapit/facet.rb +11 -8
  19. data/lib/xapit/index_blueprint.rb +9 -3
  20. data/lib/xapit/indexers/abstract_indexer.rb +13 -2
  21. data/lib/xapit/indexers/classic_indexer.rb +5 -3
  22. data/lib/xapit/indexers/simple_indexer.rb +15 -8
  23. data/lib/xapit/membership.rb +19 -1
  24. data/lib/xapit/query.rb +40 -15
  25. data/lib/xapit/query_parsers/abstract_query_parser.rb +46 -24
  26. data/lib/xapit/rake_tasks.rb +13 -0
  27. data/rails_generators/xapit/USAGE +13 -0
  28. data/rails_generators/xapit/templates/setup_xapit.rb +1 -0
  29. data/rails_generators/xapit/templates/xapit.rake +4 -0
  30. data/rails_generators/xapit/xapit_generator.rb +20 -0
  31. data/spec/spec_helper.rb +2 -2
  32. data/spec/xapit/adapters/active_record_adapter_spec.rb +31 -0
  33. data/spec/xapit/adapters/data_mapper_adapter_spec.rb +10 -0
  34. data/spec/xapit/facet_option_spec.rb +2 -2
  35. data/spec/xapit/index_blueprint_spec.rb +11 -3
  36. data/spec/xapit/indexers/abstract_indexer_spec.rb +37 -0
  37. data/spec/xapit/indexers/classic_indexer_spec.rb +9 -0
  38. data/spec/xapit/indexers/simple_indexer_spec.rb +22 -6
  39. data/spec/xapit/membership_spec.rb +16 -0
  40. data/spec/xapit/query_parsers/abstract_query_parser_spec.rb +21 -3
  41. data/spec/xapit/query_spec.rb +21 -0
  42. data/spec/xapit_member.rb +13 -2
  43. data/tasks/xapit.rake +1 -9
  44. data/tmp/xapiandatabase/postlist.DB +0 -0
  45. data/tmp/xapiandatabase/postlist.baseB +0 -0
  46. data/tmp/xapiandatabase/record.DB +0 -0
  47. data/tmp/xapiandatabase/record.baseB +0 -0
  48. data/tmp/xapiandatabase/spelling.DB +0 -0
  49. data/tmp/xapiandatabase/spelling.baseB +0 -0
  50. data/tmp/xapiandatabase/termlist.DB +0 -0
  51. data/tmp/xapiandatabase/termlist.baseB +0 -0
  52. data/tmp/xapiandatabase/value.DB +0 -0
  53. data/tmp/xapiandatabase/value.baseA +0 -0
  54. data/tmp/xapiandb/spelling.DB +0 -0
  55. data/tmp/xapiandb/spelling.baseB +0 -0
  56. data/xapit.gemspec +4 -4
  57. metadata +23 -3
data/CHANGELOG ADDED
@@ -0,0 +1,27 @@
1
+ *0.2.0* (June 12th, 2009)
2
+
3
+ * sort numeric attributes properly
4
+
5
+ * adding xapit generator for use with gem install
6
+
7
+ * adding Xapit.setup/remove_database instead of through Xapit::Config
8
+
9
+ * adding foundation for adapters to support other ORMs
10
+
11
+ * facet options which do not narrow down results are ignored
12
+
13
+ * performance improvements when fetching records and displaying facets
14
+
15
+ * search conditions can take an array or range of values
16
+
17
+ :conditions => { :priority => [2, 5, 7] }
18
+ :conditions => { :priority => 2..7 }
19
+
20
+ * adding not_condition option in search method
21
+
22
+ * fixing spelling suggestions when used with stemming
23
+
24
+
25
+ *0.1.0* (May 28th, 2009)
26
+
27
+ * initial release
data/Manifest CHANGED
@@ -1,12 +1,18 @@
1
+ CHANGELOG
1
2
  features/facets.feature
2
3
  features/finding.feature
3
4
  features/indexing.feature
5
+ features/sorting.feature
4
6
  features/step_definitions/common_steps.rb
5
7
  features/step_definitions/xapit_steps.rb
8
+ features/suggestions.feature
6
9
  features/support/env.rb
7
10
  features/support/xapit_helpers.rb
8
11
  init.rb
9
12
  install.rb
13
+ lib/xapit/adapters/abstract_adapter.rb
14
+ lib/xapit/adapters/active_record_adapter.rb
15
+ lib/xapit/adapters/data_mapper_adapter.rb
10
16
  lib/xapit/collection.rb
11
17
  lib/xapit/config.rb
12
18
  lib/xapit/facet.rb
@@ -21,8 +27,14 @@ lib/xapit/query.rb
21
27
  lib/xapit/query_parsers/abstract_query_parser.rb
22
28
  lib/xapit/query_parsers/classic_query_parser.rb
23
29
  lib/xapit/query_parsers/simple_query_parser.rb
30
+ lib/xapit/rake_tasks.rb
24
31
  lib/xapit.rb
25
32
  LICENSE
33
+ Manifest
34
+ rails_generators/xapit/templates/setup_xapit.rb
35
+ rails_generators/xapit/templates/xapit.rake
36
+ rails_generators/xapit/USAGE
37
+ rails_generators/xapit/xapit_generator.rb
26
38
  Rakefile
27
39
  README.rdoc
28
40
  spec/spec_helper.rb
@@ -126,6 +138,8 @@ spec/tmp/xapiandbase/spelling.DB
126
138
  spec/tmp/xapiandbase/termlist.baseA
127
139
  spec/tmp/xapiandbase/termlist.baseB
128
140
  spec/tmp/xapiandbase/termlist.DB
141
+ spec/xapit/adapters/active_record_adapter_spec.rb
142
+ spec/xapit/adapters/data_mapper_adapter_spec.rb
129
143
  spec/xapit/collection_spec.rb
130
144
  spec/xapit/config_spec.rb
131
145
  spec/xapit/facet_blueprint_spec.rb
@@ -157,7 +171,9 @@ tmp/xapiandatabase/spelling.DB
157
171
  tmp/xapiandatabase/termlist.baseA
158
172
  tmp/xapiandatabase/termlist.baseB
159
173
  tmp/xapiandatabase/termlist.DB
174
+ tmp/xapiandatabase/value.baseA
160
175
  tmp/xapiandatabase/value.baseB
176
+ tmp/xapiandatabase/value.DB
161
177
  tmp/xapiandb/flintlock
162
178
  tmp/xapiandb/iamflint
163
179
  tmp/xapiandb/postlist.baseA
@@ -175,4 +191,3 @@ tmp/xapiandb/termlist.DB
175
191
  tmp/xapiandb/value.baseB
176
192
  TODO
177
193
  uninstall.rb
178
- Manifest
data/README.rdoc CHANGED
@@ -14,7 +14,16 @@ To install as a Rails plugin, run this command.
14
14
 
15
15
  script/plugin install git://github.com/ryanb/xapit.git
16
16
 
17
- Note: this will soon also be available as a Ruby gem, but not yet.
17
+ Or to install as a gem in Rails first add this to config/environment.rb.
18
+
19
+ config.gem 'xapit'
20
+
21
+ And then install the gem and run the generator.
22
+
23
+ sudo rake gems:install
24
+ script/generate xapit
25
+
26
+ Important: only run the generator script on a gem install, not for the plugin.
18
27
 
19
28
 
20
29
  == Setup
@@ -61,9 +70,16 @@ To perform the indexing, run the xapit:index rake task.
61
70
 
62
71
  It can also be triggered through Ruby code using this command.
63
72
 
64
- Xapit::Config.remove_database
73
+ Xapit.remove_database
65
74
  Xapit.index_all
66
75
 
76
+ You may want to trigger this via a cron job on a recurring schedule (i.e. every day) to update the Xapian database. However it will only take effect after the Rails application is restarted because the Xapian database is stored in memory.
77
+
78
+ There are two projects in development to help improve this reindexing.
79
+
80
+ http://github.com/ryanb/xapit-sync/tree/master
81
+ http://github.com/ryanb/xapit-server/tree/master
82
+
67
83
 
68
84
  == Search
69
85
 
@@ -78,6 +94,12 @@ You can then perform a search on the model.
78
94
  # search based on indexed fields
79
95
  @articles = Article.search("phone", :conditions => { :category_id => params[:category_id] })
80
96
 
97
+ # search for multiple negative conditions (doesn't match 3, 5, or 8)
98
+ @articles = Article.search(:not_conditions => { :category_id => [3, 5, 8] })
99
+
100
+ # search for range of conditions by number
101
+ @articles = Article.search(:conditions => { :released_at => 2.years.ago..Time.now })
102
+
81
103
  # manually sort based on any number of indexed fields, sort defaults to most relevant
82
104
  @articles = Article.search("phone", :order => [:category_id, :id], :descending => true)
83
105
 
@@ -140,11 +162,11 @@ You can also list the applied facets along with a remove link.
140
162
 
141
163
  When installing Xapit as a Rails plugin, an initializer file is automatically created to setup. It looks like this.
142
164
 
143
- Xapit::Config.setup(:database_path => "#{Rails.root}/db/xapiandb")
165
+ Xapit.setup(:database_path => "#{Rails.root}/db/xapiandb")
144
166
 
145
167
  There are many other options you can pass into here. This is a more advanced configuration setting which changes the stemming language, disables spelling, and changes the indexer and parser to a classic variation. The classic ones use Xapian's built-in term generator and query parser instead of the ones offered by Xapit.
146
168
 
147
- Xapit::Config.setup(
169
+ Xapit.setup(
148
170
  :database_path => "#{Rails.root}/db/external/xapiandb",
149
171
  :spelling => false,
150
172
  :stemming => "german",
@@ -153,24 +175,16 @@ There are many other options you can pass into here. This is a more advanced con
153
175
  )
154
176
 
155
177
 
156
- == Outside of Rails
157
-
158
- Xapit can be used outside of Rails too. You'll just need to include the membership module:
159
-
160
- class Product # not Active Record
161
- include Xapit::Membership
162
-
163
- xapit # ...
164
- end
178
+ == Adapters
165
179
 
166
- This class is expected to respond to "find_each" (Product.find_each) which is used to iterate through the records when indexing and "find" for fetching a record by "id".
180
+ Adapters are used to support multiple ORMs since not everyone uses ActiveRecord. The right adapter is detected automatically so you should not have to do anything for popular ORMs. However if your ORM is not supported then it is very easy to make your own adapter. See AbstractAdapter class for details.
167
181
 
168
182
 
169
183
  == Bug Reports
170
184
 
171
185
  If you have found a bug to report or a feature to request, please add it to the GitHub issue tracker if it is not there already.
172
186
 
173
- http://github.com/ryanb/xapit/issues/
187
+ http://github.com/ryanb/xapit/issues
174
188
 
175
189
 
176
190
  == Development
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('xapit', '0.1.0') do |p|
5
+ Echoe.new('xapit', '0.2.0') do |p|
6
6
  p.summary = "Ruby library for interacting with Xapian, a full text search engine."
7
7
  p.description = "Ruby library for interacting with Xapian, a full text search engine."
8
8
  p.url = "http://github.com/ryanb/xapit"
@@ -44,8 +44,47 @@ Scenario: List Multiple Facets Applied to One Record
44
44
  | name |
45
45
  | John, Jack |
46
46
  | John |
47
+ | Joe, Jack |
47
48
  When I query for ""
48
49
  Then I should have the following facets
49
50
  | facet | option | count |
50
- | Name | Jack | 1 |
51
+ | Name | Jack | 2 |
52
+ | Name | Joe | 1 |
51
53
  | Name | John | 2 |
54
+
55
+ Scenario: Ignore Facets That Do Not Narrow Down List
56
+ Given the following indexed records
57
+ | name |
58
+ | John, Jack |
59
+ | John |
60
+ When I query for ""
61
+ Then I should have the following facets
62
+ | facet | option | count |
63
+ | Name | Jack | 1 |
64
+
65
+ Scenario: Query for One Facet
66
+ Given the following indexed records
67
+ | name | age |
68
+ | John | 23 |
69
+ | Jane | 17 |
70
+ | Jack | 17 |
71
+ When I query facets "0c93ee1"
72
+ Then I should find records named "Jane, Jack"
73
+
74
+ Scenario: Query for Two Facets
75
+ Given the following indexed records
76
+ | name | age |
77
+ | John | 23 |
78
+ | Jane | 17 |
79
+ | Jack | 17 |
80
+ When I query facets "0c93ee1-078661c"
81
+ Then I should find records named "Jane"
82
+
83
+ Scenario: Query for Facets with Keywords
84
+ Given the following indexed records
85
+ | name | age |
86
+ | John | 23 |
87
+ | Jane | 17 |
88
+ | Jack | 17 |
89
+ When I query "Jane" with facets "0c93ee1"
90
+ Then I should find record named "Jane"
@@ -36,25 +36,6 @@ Scenario: Query for Page 2
36
36
  Then I should find 1 record
37
37
  And I should have 3 records total
38
38
 
39
- Scenario: Query for One Facet
40
- Given the following indexed records
41
- | name | age |
42
- | John | 23 |
43
- | Jane | 17 |
44
- | Jack | 17 |
45
- When I query facets "0c93ee1"
46
- Then I should find records named "Jane, Jack"
47
-
48
-
49
- Scenario: Query for Two Facets
50
- Given the following indexed records
51
- | name | age |
52
- | John | 23 |
53
- | Jane | 17 |
54
- | Jack | 17 |
55
- When I query facets "0c93ee1-078661c"
56
- Then I should find records named "Jane"
57
-
58
39
  Scenario: Query for All Records Class Agnostic
59
40
  Given indexed records named "John, Jane"
60
41
  When I query for "John" on Xapit
@@ -70,50 +51,25 @@ Scenario: Query Matching Not Query
70
51
  When I query for "John NOT Smith"
71
52
  Then I should find records named "John Johnson"
72
53
 
73
- Scenario: Query for Facets with Keywords
54
+ Scenario: Unicode characters in search
55
+ Given indexed records named "über cool, uber hot"
56
+ When I query for "über"
57
+ Then I should find records named "über cool"
58
+
59
+ Scenario: Query Field Not Matching
74
60
  Given the following indexed records
75
61
  | name | age |
76
62
  | John | 23 |
77
63
  | Jane | 17 |
78
64
  | Jack | 17 |
79
- When I query "Jane" with facets "0c93ee1"
80
- Then I should find record named "Jane"
81
-
82
- Scenario: Query for All Records Sorted by Name
83
- Given indexed records named "Zebra, Apple, Banana"
84
- When I query "" sorted by name
85
- Then I should find records named "Apple, Banana, Zebra"
65
+ When I query "age" not matching "17"
66
+ Then I should find records named "John"
86
67
 
87
- Scenario: Query for All Records Sorted by Age then Name
68
+ Scenario: Query Range of Integer
88
69
  Given the following indexed records
89
- | name | age |
90
- | Banana | 23 |
91
- | Zebra | 17 |
92
- | Apple | 17 |
93
- When I query "" sorted by age, name
94
- Then I should find records named "Apple, Zebra, Banana"
95
-
96
- Scenario: Query for All Records Sorted by Name Descending
97
- Given indexed records named "Zebra, Apple, Banana"
98
- When I query "" sorted by name descending
99
- Then I should find records named "Zebra, Banana, Apple"
100
-
101
- Scenario: Spelling suggestion
102
- Given indexed records named "Zebra, Apple, Bike"
103
- When I query for "zerba bike aple"
104
- Then I should have "zebra bike apple" as a spelling suggestion
105
-
106
- Scenario: Match similar words with stemming
107
- Given indexed records named "flies, fly, glider"
108
- When I query for "flying"
109
- Then I should find records named "flies, fly"
110
-
111
- Scenario: Find similar records
112
- Given indexed records named "Jason John Smith, John Doe, Jason Smith, Jacob Johnson"
113
- When I query for similar records for "Jason John Smith"
114
- Then I should find records named "Jason Smith, John Doe"
115
-
116
- Scenario: Unicode characters in search
117
- Given indexed records named "über cool, uber hot"
118
- When I query for "über"
119
- Then I should find records named "über cool"
70
+ | name | age |
71
+ | John | 8 |
72
+ | Jane | 13 |
73
+ | Jack | 24 |
74
+ When I query "age" between 8 and 15
75
+ Then I should find records named "John, Jane"
@@ -0,0 +1,29 @@
1
+ Background:
2
+ Given an empty database at "tmp/xapiandatabase"
3
+
4
+ Scenario: Query for All Records Sorted by Name
5
+ Given indexed records named "Zebra, Apple, Banana"
6
+ When I query "" sorted by name
7
+ Then I should find records named "Apple, Banana, Zebra"
8
+
9
+ Scenario: Query for All Records Sorted by Age then Name
10
+ Given the following indexed records
11
+ | name | age |
12
+ | Banana | 23 |
13
+ | Zebra | 17 |
14
+ | Apple | 17 |
15
+ When I query "" sorted by age, name
16
+ Then I should find records named "Apple, Zebra, Banana"
17
+
18
+ Scenario: Query for All Records Sorted by Name Descending
19
+ Given indexed records named "Zebra, Apple, Banana"
20
+ When I query "" sorted by name descending
21
+ Then I should find records named "Zebra, Banana, Apple"
22
+
23
+ Scenario: Query for Records Sorted Numerically
24
+ Given the following indexed records
25
+ | name | age |
26
+ | Banana | 9 |
27
+ | Zebra | 10 |
28
+ When I query "" sorted by age, name
29
+ Then I should find records named "Banana, Zebra"
@@ -1,10 +1,10 @@
1
1
  Given /^I configured the database to be saved at "([^\"]*)"$/ do |path|
2
- Xapit::Config.setup(:database_path => File.dirname(__FILE__) + "/../../#{path}")
2
+ Xapit.setup(:database_path => File.dirname(__FILE__) + "/../../#{path}")
3
3
  end
4
4
 
5
5
  Given /^an empty database at "([^\"]*)"$/ do |path|
6
- Xapit::Config.setup(:database_path => File.dirname(__FILE__) + "/../../#{path}")
7
- Xapit::Config.remove_database
6
+ Xapit.setup(:database_path => File.dirname(__FILE__) + "/../../#{path}")
7
+ Xapit.remove_database
8
8
  XapitMember.delete_all
9
9
  end
10
10
 
@@ -70,6 +70,14 @@ When /^I query "([^\"]*)" matching "([^\"]*)"$/ do |field, value|
70
70
  @records = XapitMember.search("", :conditions => { field.to_sym => value })
71
71
  end
72
72
 
73
+ When /^I query "([^\"]*)" not matching "([^\"]*)"$/ do |field, value|
74
+ @records = XapitMember.search("", :not_conditions => { field.to_sym => value })
75
+ end
76
+
77
+ When /^I query "([^\"]*)" between (\d+) and (\d+)$/ do |field, beginning, ending|
78
+ @records = XapitMember.search("", :conditions => { field.to_sym => beginning.to_i..ending.to_i })
79
+ end
80
+
73
81
  When /^I query page ([0-9]+) at ([0-9]+) per page$/ do |page, per_page|
74
82
  @records = XapitMember.search("", :page => page, :per_page => per_page.to_i)
75
83
  end
@@ -0,0 +1,17 @@
1
+ Background:
2
+ Given an empty database at "tmp/xapiandatabase"
3
+
4
+ Scenario: Spelling suggestion
5
+ Given indexed records named "Zebra, Apple, Bike"
6
+ When I query for "zerba bike aple"
7
+ Then I should have "zebra bike apple" as a spelling suggestion
8
+
9
+ Scenario: Match similar words with stemming
10
+ Given indexed records named "flies, fly, glider"
11
+ When I query for "flying"
12
+ Then I should find records named "flies, fly"
13
+
14
+ Scenario: Find similar records
15
+ Given indexed records named "Jason John Smith, John Doe, Jason Smith, Jacob Johnson"
16
+ When I query for similar records for "Jason John Smith"
17
+ Then I should find records named "Jason Smith, John Doe"
@@ -1,6 +1,6 @@
1
1
  module XapitHelpers
2
2
  def create_records(records, perform_index = true)
3
- Xapit::Config.remove_database
3
+ Xapit.remove_database
4
4
  XapitMember.delete_all
5
5
  XapitMember.xapit do |index|
6
6
  records.first.keys.each do |attribute|
data/install.rb CHANGED
@@ -1,9 +1,8 @@
1
- path = "#{Rails.root}/config/initializers/setup_xapit.rb"
2
- unless File.exist? path
3
- puts "Adding setup_xapit.rb initializer."
4
- File.open(path, "w") do |f|
5
- f.write <<-EOS
6
- Xapit::Config.setup(:database_path => "\#{Rails.root}/db/xapiandb")
7
- EOS
8
- end
1
+ require 'ftools'
2
+
3
+ source = File.join(File.dirname(__FILE__), '/rails_generators/xapit/templates/setup_xapit.rb')
4
+ destination = "#{Rails.root}/config/initializers/setup_xapit.rb"
5
+ unless File.exist? destination
6
+ puts "Adding config/initializers/setup_xapit.rb"
7
+ File.copy(source, destination)
9
8
  end
data/lib/xapit.rb CHANGED
@@ -4,9 +4,8 @@ require 'xapian'
4
4
 
5
5
  # Looking for more documentation? A good place to start is Xapit::Membership
6
6
  module Xapit
7
-
8
7
  # Index all membership classes with xapit defined. Delegates to Xapit::IndexBlueprint.
9
- # You will likely want to call Xapit::Config.remove_database before this.
8
+ # You will likely want to call Xapit.remove_database before this.
10
9
  def self.index_all(*args, &block)
11
10
  IndexBlueprint.index_all(*args, &block)
12
11
  end
@@ -21,6 +20,36 @@ module Xapit
21
20
  def self.search(*args)
22
21
  Collection.new(nil, *args)
23
22
  end
23
+
24
+ # Setup configuration options. The following options are supported.
25
+ #
26
+ # <tt>:database_path</tt>: Where the database is stored.
27
+ # <tt>:stemming</tt>: The language to use for stemming, defaults to "english".
28
+ # <tt>:spelling</tt>: True or false to enable/disable spelling, defaults to true.
29
+ # <tt>:indexer</tt>: Class to handle the indexing, defaults to SimpleIndexer.
30
+ # <tt>:query_parser</tt>: Class to handle the parsing, defaults to ClassicQueryParser.
31
+ # <tt>:breadcrumb_facets</tt>: Use breadcrumb mode for applied facets. See Collection#applied_facet_options for details.
32
+ #
33
+ def self.setup(*args)
34
+ Config.setup(*args)
35
+ end
36
+
37
+ # Removes the configured database file and clears the stored one in memory.
38
+ def self.remove_database
39
+ Config.remove_database
40
+ end
41
+
42
+ def self.serialize_value(value)
43
+ if value.kind_of?(Date)
44
+ Xapian.sortable_serialise(value.to_time.to_i)
45
+ elsif value.kind_of?(Time)
46
+ Xapian.sortable_serialise(value.to_i)
47
+ elsif value.kind_of?(Numeric) || value.to_s =~ /^[0-9]+$/
48
+ Xapian.sortable_serialise(value.to_f)
49
+ else
50
+ value.to_s.downcase
51
+ end
52
+ end
24
53
  end
25
54
 
26
55
  require File.dirname(__FILE__) + '/xapit/membership'
@@ -37,3 +66,6 @@ require File.dirname(__FILE__) + '/xapit/query_parsers/classic_query_parser'
37
66
  require File.dirname(__FILE__) + '/xapit/indexers/abstract_indexer'
38
67
  require File.dirname(__FILE__) + '/xapit/indexers/simple_indexer'
39
68
  require File.dirname(__FILE__) + '/xapit/indexers/classic_indexer'
69
+ require File.dirname(__FILE__) + '/xapit/adapters/abstract_adapter'
70
+ require File.dirname(__FILE__) + '/xapit/adapters/active_record_adapter'
71
+ require File.dirname(__FILE__) + '/xapit/adapters/data_mapper_adapter'