lunr 1.0.1 → 2.0.0

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/Isolate CHANGED
@@ -1,8 +1,13 @@
1
- gem "configlet", "~> 1.3"
2
- gem "rsolr", "~> 0.12"
1
+ options :system => false
2
+
3
+ gem "sunspot", "~> 1.1.0"
3
4
 
4
5
  env :development do
5
- gem "fakeweb", "~> 1.3"
6
- gem "minitest", "~> 1.7"
7
- gem "will_paginate", "~> 3.0.pre2"
6
+ gem "ZenTest", "4.4.0"
7
+ gem "fakeweb", "1.3.0"
8
+ gem "hoe", "2.6.2"
9
+ gem "hoe-doofus", "1.0.0"
10
+ gem "hoe-git", "1.3.0"
11
+ gem "minitest", "1.7.1"
12
+ gem "mocha", "0.9.8"
8
13
  end
data/Manifest.txt CHANGED
@@ -5,5 +5,10 @@ Manifest.txt
5
5
  README.rdoc
6
6
  Rakefile
7
7
  lib/lunr.rb
8
- lib/lunr/error.rb
8
+ lib/lunr/errors.rb
9
+ lib/lunr/model.rb
10
+ lib/lunr/search.rb
11
+ lib/lunr/sunspot.rb
9
12
  test/test_lunr.rb
13
+ test/test_lunr_model.rb
14
+ test/test_lunr_search.rb
data/README.rdoc CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  == Description
6
6
 
7
- A simple read-only interface to Solr, built on RSolr.
7
+ A simple read-only interface to Solr, built on Sunspot.
8
8
 
9
9
  Lunr makes it easy to query and create objects from a Solr index
10
10
  without requiring all the knowledge, code, and data that was used to
@@ -14,30 +14,38 @@ If you have complex indexes with a stored fields and need to search /
14
14
  access those fields without access to the original data store, Lunr
15
15
  might be what you're looking for.
16
16
 
17
- As seen in Sunspot and similar tools, if
18
- <code>WillPaginate::Collection</code> is available it'll be wrapped
19
- around the results of any search.
20
-
21
17
  == Examples
22
18
 
23
19
  require "lunr"
24
20
 
25
- # set ENV["LUNR_URL"], or...
26
- Lunr[:url] = "http://localhost:8983/solr"
21
+ class My::SimpleTrack
22
+ include Lunr::Model
27
23
 
28
- # simplest possible, returns a hash
29
- Lunr.search "foo"
24
+ searches "Track" do
25
+ property :album, :text
26
+ property :artist, :text
27
+ property :title, :text
30
28
 
31
- # returns the result of the block for each entry
32
- Lunr.search "foo" do |raw|
33
- MyReadOnlyModelClass.new raw
34
- end
29
+ time :accepted_at
30
+ boolean :hot
31
+ string :state
32
+ end
33
+
34
+ scope do |q|
35
+ q.order_by :hot, :desc
36
+ q.order_by :accepted_at, :desc
35
37
 
36
- # pagination is part of solr, select a page with :p
37
- Lunr.search "foo", :p => params[:page]
38
+ q.with :state, "accepted"
39
+ end
38
40
 
39
- # default per page is 25, but you can set ENV["LUNR_PP"] or...
40
- Lunr.search "foo", :p => params[:page], :pp => 500
41
+ scope :hot do
42
+ with :hot, true
43
+ end
44
+
45
+ scope :state do |q, state|
46
+ q.with :state, state
47
+ end
48
+ end
41
49
 
42
50
  == Installation
43
51
 
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
1
+ unless Gem.available? "isolate"
2
+ abort "Please `gem install isolate` and run rake again."
3
+ end
4
+
5
+ require "isolate/now"
1
6
  require "hoe"
2
7
 
3
8
  Hoe.plugins.delete :rubyforge
data/lib/lunr.rb CHANGED
@@ -1,57 +1,11 @@
1
- require "configlet"
2
- require "rsolr"
3
-
4
- require "lunr/error"
1
+ require "lunr/sunspot"
2
+ require "lunr/model"
3
+ require "lunr/search"
5
4
 
6
5
  module Lunr
7
- extend Configlet
8
-
9
- # Duh.
10
- VERSION = "1.0.1"
11
-
12
- config :lunr do
13
- default :pp => "25"
14
- default :url => "http://localhost:8983/solr"
15
- end
16
-
17
- def self.search query, options = {}, &block
18
- page = [1, Integer(options[:p] || 0)].max
19
- per = Integer options[:pp] || self[:pp]
20
-
21
- params = {
22
- :q => query,
23
- :rows => per,
24
- :start => per * (page - 1),
25
- }
26
-
27
- begin
28
- raw = solr.select params
29
- rescue Errno::ECONNREFUSED => e
30
- raise Lunr::Error, "Can't connect to #{self[:url]}: #{e}"
31
- end
32
-
33
- header = raw["responseHeader"]
34
- response = raw["response"]
35
6
 
36
- unless status = header["status"]
37
- raise Lunr::Error, "Bad (and cryptic) response status: #{status}"
38
- end
39
-
40
- docs = response.delete "docs"
41
- total = response.delete "numFound"
42
-
43
- docs = block_given? ? docs.map(&block) : docs
44
-
45
- if defined? WillPaginate::Collection
46
- old = docs
47
- docs = WillPaginate::Collection.new page, per, total
48
- docs.replace old
49
- end
50
-
51
- docs
52
- end
7
+ # Duh.
8
+ VERSION = "2.0.0"
53
9
 
54
- def self.solr
55
- @solr ||= RSolr.connect :url => self[:url]
56
- end
57
10
  end
11
+
@@ -0,0 +1,19 @@
1
+ module Lunr
2
+ class Error < StandardError
3
+ end
4
+
5
+ class AlreadyExecuted < Error
6
+ attr_reader :search
7
+
8
+ def initalize search
9
+ @search = search
10
+ super "Can't add more criteria, this search has already been executed!"
11
+ end
12
+ end
13
+
14
+ class BadModel < Error
15
+ def initialize klass
16
+ super "#{klass.name} doesn't include Lunr::Model!"
17
+ end
18
+ end
19
+ end
data/lib/lunr/model.rb ADDED
@@ -0,0 +1,47 @@
1
+ require "lunr/search"
2
+ require "lunr/sunspot"
3
+
4
+ module Lunr
5
+ module Model
6
+ def self.included klass
7
+ klass.extend Klass
8
+ end
9
+
10
+ attr_reader :id
11
+
12
+ module Klass
13
+ def properties
14
+ @properties ||= []
15
+ end
16
+
17
+ def scopes
18
+ @scopes ||= {}
19
+ end
20
+
21
+ def scope sym = :all, &block
22
+ scopes[sym] = block
23
+
24
+ unless sym == :all
25
+ class_eval <<-END, __FILE__, __LINE__ + 1
26
+ def self.#{sym}; search.#{sym} end
27
+ END
28
+ end
29
+ end
30
+
31
+ def search &block
32
+ Lunr::Search.new self, &block
33
+ end
34
+
35
+ alias_method :all, :search
36
+
37
+ def searches classname, &block
38
+ Sunspot::TypeField.alias self, classname
39
+ Sunspot.setup self, &block
40
+
41
+ properties.uniq.each do |prop|
42
+ attr_reader prop
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,116 @@
1
+ require "lunr/errors"
2
+ require "lunr/model"
3
+ require "lunr/sunspot"
4
+
5
+ module Lunr
6
+ class Search
7
+ include Enumerable
8
+
9
+ def each &block
10
+ execute && @results.each(&block)
11
+ end
12
+
13
+ def total
14
+ execute && @search.total
15
+ end
16
+
17
+ alias_method :size, :total
18
+
19
+ def empty?
20
+ 0 == total
21
+ end
22
+
23
+ # Acting like WillPaginate::Collection
24
+
25
+ def current_page
26
+ execute && @search.query.page
27
+ end
28
+
29
+ def per_page
30
+ execute && @search.query.per_page
31
+ end
32
+
33
+ def total_entries
34
+ total
35
+ end
36
+
37
+ def total_pages
38
+ total_entries / per_page +
39
+ (total_entries % per_page > 0 ? 1 : 0)
40
+ end
41
+
42
+ attr_reader :klass
43
+
44
+ def initialize klass, &block
45
+ raise Lunr::BadModel.new(klass) unless klass < Lunr::Model
46
+
47
+ @executed = false
48
+ @klass = klass
49
+ @search = Sunspot.new_search klass, &block
50
+
51
+ if all = @klass.scopes[:all]
52
+ scope &all
53
+ end
54
+ end
55
+
56
+ def scope &block
57
+ executable!
58
+ @search.build &block
59
+ end
60
+
61
+ def executable!
62
+ raise Lunr::AlreadyExecuted.new(self) if executed?
63
+ end
64
+
65
+ def executed?
66
+ @executed
67
+ end
68
+
69
+ # :nodoc:
70
+
71
+ def params
72
+ @search.query.to_params
73
+ end
74
+
75
+ def method_missing sym, *args
76
+ super unless scope = klass.scopes[sym]
77
+
78
+ executable!
79
+
80
+ dsl = @search.send :dsl
81
+
82
+ if args.empty?
83
+ dsl.instance_eval &scope
84
+ else
85
+ scope.call dsl, args
86
+ end
87
+
88
+ self
89
+ end
90
+
91
+ def respond_to sym, include_private = false
92
+ klass.scopes.key?(sym) || super
93
+ end
94
+
95
+ private
96
+
97
+ def execute
98
+ unless @executed
99
+ @executed = true
100
+ @search.execute
101
+
102
+ @results = @search.hits.map do |hit|
103
+ klass.new.tap do |model|
104
+ model.instance_variable_set :"@id", hit.primary_key
105
+
106
+ klass.properties.each do |prop|
107
+ model.instance_variable_set :"@#{prop}", hit.stored(prop)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ true
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,59 @@
1
+ require "sunspot"
2
+
3
+ module Sunspot
4
+ module DSL
5
+ class Fields
6
+ def property name, type, options = {}
7
+ @setup.clazz.properties << name
8
+ send type, name, options.merge(:stored => true)
9
+ end
10
+ end
11
+ end
12
+
13
+ class Field
14
+ def stored?
15
+ @stored
16
+ end
17
+ end
18
+
19
+ module Search
20
+ class Hit
21
+ alias_method :original_initialize, :initialize
22
+
23
+ def initialize *args
24
+ original_initialize *args
25
+
26
+ if clazz = Sunspot::TypeField.aliases_inverted[@class_name]
27
+ @class_name = clazz.name
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ class Setup
34
+ def lunr_properties
35
+ @lunr_properties ||= []
36
+ end
37
+ end
38
+
39
+ class TypeField
40
+ class << self
41
+ def alias(dest_class, source_class_name)
42
+ @@inverted = nil # invalidate cache
43
+ aliases[dest_class] = source_class_name
44
+ end
45
+
46
+ def aliases
47
+ @@aliases ||= {}
48
+ end
49
+
50
+ def aliases_inverted
51
+ @@inverted ||= aliases.invert
52
+ end
53
+ end
54
+
55
+ def to_indexed clazz
56
+ self.class.aliases[clazz] || clazz.name
57
+ end
58
+ end
59
+ end
data/test/test_lunr.rb CHANGED
@@ -8,18 +8,4 @@ class TestLunr < MiniTest::Unit::TestCase
8
8
  def setup
9
9
  FakeWeb.clean_registry
10
10
  end
11
-
12
- def test_self_search
13
- stub "foo"
14
- Lunr.search "foo"
15
- end
16
-
17
- def stub query, fixture = "simple"
18
- FakeWeb.register_uri :get, url(query),
19
- :body => File.read("test/fixtures/#{fixture}")
20
- end
21
-
22
- def url query
23
- "#{Lunr[:url]}/select?wt=ruby&start=0&q=#{query}&rows=25"
24
- end
25
11
  end
@@ -0,0 +1,4 @@
1
+ require "minitest/autorun"
2
+
3
+ class TestLunrModel < MiniTest::Unit::TestCase
4
+ end
@@ -0,0 +1,42 @@
1
+ require "minitest/autorun"
2
+ require "mocha"
3
+ require "lunr/search"
4
+
5
+ class TestLunrSearch < MiniTest::Unit::TestCase
6
+ include Lunr::Model
7
+
8
+ def setup
9
+ @search = Lunr::Search.new self.class
10
+ end
11
+
12
+ def test_initialize
13
+ s = Lunr::Search.new self.class do
14
+ with :foo, "bar"
15
+ end
16
+
17
+ assert_equal TestLunrSearch, s.klass
18
+ assert_equal "type:TestLunrSearch", s.params[:fq].first
19
+ assert s.params[:fq].include?("foo_s:bar")
20
+ end
21
+
22
+ def test_scope
23
+ @search.scope { with :foo, "blergh" }
24
+ @search.scope { with :bar, "corge" }
25
+
26
+ assert @search.params[:fq].include?("foo_s:blergh")
27
+ assert @search.params[:fq].include?("bar_s:corge")
28
+ end
29
+
30
+ def test_scope_bad
31
+ @search.stubs(:executed?).returns true
32
+
33
+ assert_raises Lunr::AlreadyExecuted do
34
+ @search.scope { with :foo, "hello" }
35
+ end
36
+ end
37
+ end
38
+
39
+ Sunspot.setup TestLunrSearch do
40
+ string :bar
41
+ string :foo
42
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lunr
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
- - 1
7
+ - 2
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 0
10
+ version: 2.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Barnette
@@ -15,38 +15,40 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-25 00:00:00 -07:00
18
+ date: 2010-09-01 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: configlet
22
+ name: sunspot
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 9
29
+ hash: 19
30
30
  segments:
31
31
  - 1
32
- - 3
33
- version: "1.3"
32
+ - 1
33
+ - 0
34
+ version: 1.1.0
34
35
  type: :runtime
35
36
  version_requirements: *id001
36
37
  - !ruby/object:Gem::Dependency
37
- name: rsolr
38
+ name: ZenTest
38
39
  prerelease: false
39
40
  requirement: &id002 !ruby/object:Gem::Requirement
40
41
  none: false
41
42
  requirements:
42
- - - ~>
43
+ - - "="
43
44
  - !ruby/object:Gem::Version
44
- hash: 19
45
+ hash: 47
45
46
  segments:
47
+ - 4
48
+ - 4
46
49
  - 0
47
- - 12
48
- version: "0.12"
49
- type: :runtime
50
+ version: 4.4.0
51
+ type: :development
50
52
  version_requirements: *id002
51
53
  - !ruby/object:Gem::Dependency
52
54
  name: fakeweb
@@ -54,64 +56,114 @@ dependencies:
54
56
  requirement: &id003 !ruby/object:Gem::Requirement
55
57
  none: false
56
58
  requirements:
57
- - - ~>
59
+ - - "="
58
60
  - !ruby/object:Gem::Version
59
- hash: 9
61
+ hash: 27
60
62
  segments:
61
63
  - 1
62
64
  - 3
63
- version: "1.3"
65
+ - 0
66
+ version: 1.3.0
64
67
  type: :development
65
68
  version_requirements: *id003
66
69
  - !ruby/object:Gem::Dependency
67
- name: minitest
70
+ name: hoe
68
71
  prerelease: false
69
72
  requirement: &id004 !ruby/object:Gem::Requirement
70
73
  none: false
71
74
  requirements:
72
- - - ~>
75
+ - - "="
73
76
  - !ruby/object:Gem::Version
74
- hash: 1
77
+ hash: 19
75
78
  segments:
76
- - 1
77
- - 7
78
- version: "1.7"
79
+ - 2
80
+ - 6
81
+ - 2
82
+ version: 2.6.2
79
83
  type: :development
80
84
  version_requirements: *id004
81
85
  - !ruby/object:Gem::Dependency
82
- name: will_paginate
86
+ name: hoe-doofus
83
87
  prerelease: false
84
88
  requirement: &id005 !ruby/object:Gem::Requirement
85
89
  none: false
86
90
  requirements:
87
- - - ~>
91
+ - - "="
88
92
  - !ruby/object:Gem::Version
89
- hash: -1876988247
93
+ hash: 23
90
94
  segments:
91
- - 3
95
+ - 1
96
+ - 0
92
97
  - 0
93
- - pre2
94
- version: 3.0.pre2
98
+ version: 1.0.0
95
99
  type: :development
96
100
  version_requirements: *id005
97
101
  - !ruby/object:Gem::Dependency
98
- name: hoe
102
+ name: hoe-git
99
103
  prerelease: false
100
104
  requirement: &id006 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - "="
108
+ - !ruby/object:Gem::Version
109
+ hash: 27
110
+ segments:
111
+ - 1
112
+ - 3
113
+ - 0
114
+ version: 1.3.0
115
+ type: :development
116
+ version_requirements: *id006
117
+ - !ruby/object:Gem::Dependency
118
+ name: minitest
119
+ prerelease: false
120
+ requirement: &id007 !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - "="
124
+ - !ruby/object:Gem::Version
125
+ hash: 9
126
+ segments:
127
+ - 1
128
+ - 7
129
+ - 1
130
+ version: 1.7.1
131
+ type: :development
132
+ version_requirements: *id007
133
+ - !ruby/object:Gem::Dependency
134
+ name: mocha
135
+ prerelease: false
136
+ requirement: &id008 !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - "="
140
+ - !ruby/object:Gem::Version
141
+ hash: 43
142
+ segments:
143
+ - 0
144
+ - 9
145
+ - 8
146
+ version: 0.9.8
147
+ type: :development
148
+ version_requirements: *id008
149
+ - !ruby/object:Gem::Dependency
150
+ name: hoe
151
+ prerelease: false
152
+ requirement: &id009 !ruby/object:Gem::Requirement
101
153
  none: false
102
154
  requirements:
103
155
  - - ">="
104
156
  - !ruby/object:Gem::Version
105
- hash: 21
157
+ hash: 19
106
158
  segments:
107
159
  - 2
108
160
  - 6
109
- - 1
110
- version: 2.6.1
161
+ - 2
162
+ version: 2.6.2
111
163
  type: :development
112
- version_requirements: *id006
164
+ version_requirements: *id009
113
165
  description: |-
114
- A simple read-only interface to Solr, built on RSolr.
166
+ A simple read-only interface to Solr, built on Sunspot.
115
167
 
116
168
  Lunr makes it easy to query and create objects from a Solr index
117
169
  without requiring all the knowledge, code, and data that was used to
@@ -120,10 +172,6 @@ description: |-
120
172
  If you have complex indexes with a stored fields and need to search /
121
173
  access those fields without access to the original data store, Lunr
122
174
  might be what you're looking for.
123
-
124
- As seen in Sunspot and similar tools, if
125
- <code>WillPaginate::Collection</code> is available it'll be wrapped
126
- around the results of any search.
127
175
  email:
128
176
  - code@jbarnette.com
129
177
  executables: []
@@ -142,8 +190,13 @@ files:
142
190
  - README.rdoc
143
191
  - Rakefile
144
192
  - lib/lunr.rb
145
- - lib/lunr/error.rb
193
+ - lib/lunr/errors.rb
194
+ - lib/lunr/model.rb
195
+ - lib/lunr/search.rb
196
+ - lib/lunr/sunspot.rb
146
197
  - test/test_lunr.rb
198
+ - test/test_lunr_model.rb
199
+ - test/test_lunr_search.rb
147
200
  has_rdoc: true
148
201
  homepage: http://github.com/jbarnette/lunr
149
202
  licenses: []
@@ -178,6 +231,8 @@ rubyforge_project: lunr
178
231
  rubygems_version: 1.3.7
179
232
  signing_key:
180
233
  specification_version: 3
181
- summary: A simple read-only interface to Solr, built on RSolr
234
+ summary: A simple read-only interface to Solr, built on Sunspot
182
235
  test_files:
183
236
  - test/test_lunr.rb
237
+ - test/test_lunr_model.rb
238
+ - test/test_lunr_search.rb
data/lib/lunr/error.rb DELETED
@@ -1,4 +0,0 @@
1
- module Lunr
2
- class Error < StandardError
3
- end
4
- end