redis-textsearch 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -62,20 +62,26 @@ class Redis
62
62
  # how to retrieve records. You can override it by explicitly defining a
63
63
  # +text_search_find+ class method that takes an array of IDs as an argument.
64
64
  def guess_text_search_find
65
- if defined?(ActiveRecord::Base) and is_a?(ActiveRecord::Base)
65
+ if defined?(ActiveRecord::Base) and ancestors.include?(ActiveRecord::Base)
66
66
  instance_eval <<-EndMethod
67
67
  def text_search_find(ids, options)
68
+ puts "IDS=\#{ids.inspect}"
68
69
  all(options.merge(:conditions => {:#{primary_key} => ids}))
69
70
  end
70
71
  EndMethod
71
- elsif defined?(MongoRecord::Base) and is_a?(MongoRecord::Base)
72
+ elsif defined?(MongoRecord::Base) and ancestors.include?(MongoRecord::Base)
72
73
  instance_eval <<-EndMethod
73
74
  def text_search_find(ids, options)
74
75
  all(options.merge(:conditions => {:#{primary_key} => ids}))
75
76
  end
76
77
  EndMethod
77
- elsif respond_to?(:get)
78
- # DataMapper::Resource is an include, so is_a? won't work
78
+ elsif defined?(Sequel::Model) and ancestors.include?(Sequel::Model)
79
+ instance_eval <<-EndMethod
80
+ def text_search_find(ids, options)
81
+ all(options.merge(:conditions => {:#{primary_key} => ids}))
82
+ end
83
+ EndMethod
84
+ elsif defined?(DataMapper::Resource) and included_modules.include?(DataMapper::Resource)
79
85
  instance_eval <<-EndMethod
80
86
  def text_search_find(ids, options)
81
87
  get(ids, options)
@@ -41,9 +41,9 @@ TAGS = [
41
41
 
42
42
  describe Redis::TextSearch do
43
43
  before :all do
44
- @post = Post.new(:title => TITLES[0], :tags => TAGS[0], :id => 1)
44
+ @post = Post.new(:title => TITLES[0], :tags => TAGS[0] * ' ', :id => 1)
45
45
  @post2 = Post.new(:title => TITLES[1], :tags => TAGS[1], :id => 2)
46
- @post3 = Post.new(:title => TITLES[2], :tags => TAGS[2], :id => 3)
46
+ @post3 = Post.new(:title => TITLES[2], :tags => TAGS[2] * ' ', :id => 3)
47
47
 
48
48
  @post.delete_text_indexes
49
49
  @post2.delete_text_indexes
@@ -0,0 +1,214 @@
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
+
4
+ require 'active_record'
5
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'test.db')
6
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
7
+
8
+ def check_result_ids(results, ids, sort=true)
9
+ results.length.should == ids.length
10
+ if results.length > 0
11
+ results.first.should be_kind_of(ActiveRecord::Base)
12
+ end
13
+ if sort
14
+ results.collect{|m| m.id}.sort.should == ids.sort
15
+ else
16
+ results.collect{|m| m.id}.should == ids
17
+ end
18
+ end
19
+
20
+ class Post < ActiveRecord::Base
21
+ include Redis::TextSearch
22
+ include Marshal
23
+
24
+ text_index :title
25
+ text_index :tags, :exact => true
26
+ end
27
+
28
+ class CreatePosts < ActiveRecord::Migration
29
+ def self.up
30
+ create_table :posts do |t|
31
+ t.string :title
32
+ t.string :tags
33
+ t.timestamps
34
+ end
35
+ end
36
+
37
+ def self.down
38
+ drop_table :posts
39
+ end
40
+ end
41
+
42
+ TITLES = [
43
+ 'Some plain text',
44
+ 'More plain textstring comments',
45
+ 'Come get somebody personal comments',
46
+ '*Welcome to Nate\'s new BLOG!!',
47
+ ]
48
+
49
+ TAGS = [
50
+ ['personal', 'nontechnical'],
51
+ ['mysql', 'technical'],
52
+ ['gaming','technical']
53
+ ]
54
+
55
+
56
+ describe Redis::TextSearch do
57
+ before :all do
58
+ CreatePosts.up
59
+
60
+ @post = Post.new(:title => TITLES[0], :tags => TAGS[0] * ' ')
61
+ # @post.id = 1
62
+ @post.save!
63
+ # sleep 1 # sqlite timestamps
64
+ @post2 = Post.new(:title => TITLES[1], :tags => TAGS[1] * ' ')
65
+ # @post2.id = 2
66
+ @post2.save!
67
+ # sleep 1 # sqlite timestamps
68
+ @post3 = Post.new(:title => TITLES[2], :tags => TAGS[2] * ' ')
69
+ # @post3.id = 3
70
+ @post3.save!
71
+ # sleep 1 # sqlite timestamps
72
+
73
+ @post.delete_text_indexes
74
+ @post2.delete_text_indexes
75
+ Post.delete_text_indexes(3)
76
+ end
77
+
78
+ after :all do
79
+ CreatePosts.down
80
+ end
81
+
82
+ it "should define text indexes in the class" do
83
+ Post.text_indexes[:title][:key].should == 'post:text_index:title'
84
+ Post.text_indexes[:tags][:key].should == 'post:text_index:tags'
85
+ end
86
+
87
+ it "should update text indexes correctly" do
88
+ @post.update_text_indexes
89
+ @post2.update_text_indexes
90
+
91
+ Post.redis.set_members('post:text_index:title:so').should == ['1']
92
+ Post.redis.set_members('post:text_index:title:som').should == ['1']
93
+ Post.redis.set_members('post:text_index:title:some').should == ['1']
94
+ Post.redis.set_members('post:text_index:title:pl').sort.should == ['1','2']
95
+ Post.redis.set_members('post:text_index:title:pla').sort.should == ['1','2']
96
+ Post.redis.set_members('post:text_index:title:plai').sort.should == ['1','2']
97
+ Post.redis.set_members('post:text_index:title:plain').sort.should == ['1','2']
98
+ Post.redis.set_members('post:text_index:title:te').sort.should == ['1','2']
99
+ Post.redis.set_members('post:text_index:title:tex').sort.should == ['1','2']
100
+ Post.redis.set_members('post:text_index:title:text').sort.should == ['1','2']
101
+ Post.redis.set_members('post:text_index:title:texts').should == ['2']
102
+ Post.redis.set_members('post:text_index:title:textst').should == ['2']
103
+ Post.redis.set_members('post:text_index:title:textstr').should == ['2']
104
+ Post.redis.set_members('post:text_index:title:textstri').should == ['2']
105
+ Post.redis.set_members('post:text_index:title:textstrin').should == ['2']
106
+ Post.redis.set_members('post:text_index:title:textstring').should == ['2']
107
+ Post.redis.set_members('post:text_index:tags:pe').should == []
108
+ Post.redis.set_members('post:text_index:tags:per').should == []
109
+ Post.redis.set_members('post:text_index:tags:pers').should == []
110
+ Post.redis.set_members('post:text_index:tags:perso').should == []
111
+ Post.redis.set_members('post:text_index:tags:person').should == []
112
+ Post.redis.set_members('post:text_index:tags:persona').should == []
113
+ Post.redis.set_members('post:text_index:tags:personal').should == ['1']
114
+ Post.redis.set_members('post:text_index:tags:no').should == []
115
+ Post.redis.set_members('post:text_index:tags:non').should == []
116
+ Post.redis.set_members('post:text_index:tags:nont').should == []
117
+ Post.redis.set_members('post:text_index:tags:nonte').should == []
118
+ Post.redis.set_members('post:text_index:tags:nontec').should == []
119
+ Post.redis.set_members('post:text_index:tags:nontech').should == []
120
+ Post.redis.set_members('post:text_index:tags:nontechn').should == []
121
+ Post.redis.set_members('post:text_index:tags:nontechni').should == []
122
+ Post.redis.set_members('post:text_index:tags:nontechnic').should == []
123
+ Post.redis.set_members('post:text_index:tags:nontechnica').should == []
124
+ Post.redis.set_members('post:text_index:tags:nontechnical').should == ['1']
125
+ end
126
+
127
+ it "should search text indexes and return records" do
128
+ check_result_ids Post.text_search('some'), [1]
129
+ @post3.update_text_indexes
130
+ check_result_ids Post.text_search('some'), [1,3]
131
+
132
+ check_result_ids Post.text_search('plain'), [1,2]
133
+ check_result_ids Post.text_search('plain','text'), [1,2]
134
+ check_result_ids Post.text_search('plain','textstr'), [2]
135
+ check_result_ids Post.text_search('some','TExt'), [1]
136
+ check_result_ids Post.text_search('techNIcal'), [2,3]
137
+ check_result_ids Post.text_search('nontechnical'), [1]
138
+ check_result_ids Post.text_search('personal'), [1,3]
139
+ check_result_ids Post.text_search('personAL', :fields => :tags), [1]
140
+ check_result_ids Post.text_search('PERsonal', :fields => [:tags]), [1]
141
+ check_result_ids Post.text_search('nontechnical', :fields => [:title]), []
142
+ end
143
+
144
+ it "should pass options thru to find" do
145
+ check_result_ids Post.text_search('some', :order => 'id desc'), [3,1], false
146
+ res = Post.text_search('some', :select => 'id,title', :order => 'tags desc')
147
+ check_result_ids res, [1,3]
148
+ res.first.title.should == TITLES[0]
149
+ res.last.title.should == TITLES[2]
150
+
151
+ error = nil
152
+ begin
153
+ res.first.tags
154
+ rescue => error
155
+ end
156
+ error.should be_kind_of ActiveRecord::MissingAttributeError
157
+
158
+ error = nil
159
+ begin
160
+ res.first.updated_at
161
+ rescue => error
162
+ end
163
+ error.should be_kind_of ActiveRecord::MissingAttributeError
164
+
165
+ error = nil
166
+ begin
167
+ res.first.created_at
168
+ rescue => error
169
+ end
170
+ error.should be_kind_of ActiveRecord::MissingAttributeError
171
+ end
172
+
173
+ it "should handle pagination" do
174
+ res = Post.text_search('some', :page => 1, :per_page => 1, :order => 'id desc')
175
+ check_result_ids res, [3]
176
+ res.total_entries.should == 2
177
+ res.total_pages.should == 2
178
+ res.per_page.should == 1
179
+ res.current_page.should == 1
180
+
181
+ res = Post.text_search('some', :page => 2, :per_page => 1, :order => 'id desc')
182
+ check_result_ids res, [1]
183
+ res.total_entries.should == 2
184
+ res.total_pages.should == 2
185
+ res.per_page.should == 1
186
+ res.current_page.should == 2
187
+
188
+ res = Post.text_search('some', :page => 2, :per_page => 5)
189
+ check_result_ids res, []
190
+ res.total_entries.should == 2
191
+ res.total_pages.should == 1
192
+ res.per_page.should == 5
193
+ res.current_page.should == 2
194
+ end
195
+
196
+ it "should support a hash to the text_search method" do
197
+ check_result_ids Post.text_search(:tags => 'technical'), [2,3]
198
+ check_result_ids Post.text_search(:tags => 'nontechnical'), [1]
199
+ check_result_ids Post.text_search(:tags => 'technical', :title => 'plain'), [2]
200
+ check_result_ids Post.text_search(:tags => ['technical','MYsql'], :title => 'Mo'), [2]
201
+ check_result_ids Post.text_search(:tags => ['technical','MYsql'], :title => 'some'), []
202
+ check_result_ids Post.text_search(:tags => 'technical', :title => 'comments'), [2,3]
203
+ end
204
+
205
+ # MUST BE LAST!!!!!!
206
+ it "should delete text indexes" do
207
+ @post.delete_text_indexes
208
+ @post2.delete_text_indexes
209
+ Post.delete_text_indexes(3)
210
+ @post.text_indexes.should == []
211
+ @post2.text_indexes.should == []
212
+ @post3.text_indexes.should == []
213
+ end
214
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-textsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Wiger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-03 00:00:00 -08:00
12
+ date: 2009-12-04 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -34,6 +34,7 @@ files:
34
34
  - lib/redis/text_search/collection.rb
35
35
  - lib/redis/text_search.rb
36
36
  - spec/redis_text_search_core_spec.rb
37
+ - spec/redis_text_search_sqlite_spec.rb
37
38
  - spec/spec_helper.rb
38
39
  - README.rdoc
39
40
  has_rdoc: true