supernova 0.3.12 → 0.3.13
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/VERSION +1 -1
- data/bin/start_solr +3 -0
- data/lib/supernova.rb +13 -0
- data/lib/supernova/criteria.rb +19 -4
- data/lib/supernova/solr_criteria.rb +4 -13
- data/lib/supernova/solr_indexer.rb +34 -4
- data/lib/supernova/thinking_sphinx_criteria.rb +1 -1
- data/spec/integration/solr_spec.rb +64 -40
- data/spec/supernova/criteria_spec.rb +74 -10
- data/spec/supernova/solr_criteria_spec.rb +16 -18
- data/spec/supernova/solr_indexer_spec.rb +128 -12
- data/spec/supernova_spec.rb +41 -0
- data/supernova.gemspec +4 -2
- metadata +7 -6
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.13
|
data/bin/start_solr
ADDED
data/lib/supernova.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require "rsolr"
|
2
|
+
require "active_support/core_ext/object/blank"
|
3
|
+
require "active_support/core_ext/hash"
|
2
4
|
|
3
5
|
module Supernova
|
4
6
|
KM_TO_METER = 1000.0
|
@@ -21,6 +23,17 @@ module Supernova
|
|
21
23
|
self.defined_named_search_scopes << name
|
22
24
|
end
|
23
25
|
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def build_ar_like_record(clazz, attributes, original_search_doc = nil)
|
29
|
+
record = clazz.new
|
30
|
+
record.instance_variable_set("@attributes", attributes)
|
31
|
+
record.instance_variable_set("@readonly", true)
|
32
|
+
record.instance_variable_set("@new_record", false)
|
33
|
+
record.instance_variable_set("@original_search_doc", original_search_doc) if original_search_doc
|
34
|
+
record
|
35
|
+
end
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
39
|
require "supernova/numeric_extensions"
|
data/lib/supernova/criteria.rb
CHANGED
@@ -2,7 +2,7 @@ class Supernova::Criteria
|
|
2
2
|
DEFAULT_PER_PAGE = 25
|
3
3
|
FIRST_PAGE = 1
|
4
4
|
|
5
|
-
attr_accessor :filters, :search_options, :clazz
|
5
|
+
attr_accessor :filters, :search_options, :clazz, :results
|
6
6
|
|
7
7
|
class << self
|
8
8
|
def method_missing(*args)
|
@@ -138,8 +138,22 @@ class Supernova::Criteria
|
|
138
138
|
def to_parameters
|
139
139
|
implement_in_subclass
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
|
+
def populate
|
143
|
+
@results = execute if !populated?
|
144
|
+
self
|
145
|
+
end
|
146
|
+
|
142
147
|
def to_a
|
148
|
+
populate
|
149
|
+
results
|
150
|
+
end
|
151
|
+
|
152
|
+
def populated?
|
153
|
+
instance_variables.include?("@results")
|
154
|
+
end
|
155
|
+
|
156
|
+
def execute
|
143
157
|
implement_in_subclass
|
144
158
|
end
|
145
159
|
|
@@ -170,8 +184,9 @@ class Supernova::Criteria
|
|
170
184
|
end
|
171
185
|
|
172
186
|
def method_missing(*args, &block)
|
173
|
-
if
|
174
|
-
|
187
|
+
if Supernova::Collection.instance_methods.include?(args.first.to_s)
|
188
|
+
populate
|
189
|
+
@results.send(*args, &block)
|
175
190
|
elsif self.named_scope_defined?(args.first)
|
176
191
|
self.merge(self.search_options[:named_scope_class].send(*args)) # merge named scope and current criteria
|
177
192
|
else
|
@@ -87,20 +87,11 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def build_doc(hash)
|
90
|
-
|
91
|
-
|
92
|
-
doc.instance_variable_set("@solr_doc", hash)
|
93
|
-
atts = convert_doc_attributes(hash)
|
94
|
-
if doc.instance_variables.include?("@attributes")
|
95
|
-
doc.instance_variable_set("@attributes", atts.except("type"))
|
90
|
+
if hash["type"].respond_to?(:constantize)
|
91
|
+
Supernova.build_ar_like_record(hash["type"].constantize, convert_doc_attributes(hash), hash)
|
96
92
|
else
|
97
|
-
|
98
|
-
doc.send(:"#{key}=", value) if doc.respond_to?(:"#{key}=")
|
99
|
-
end
|
93
|
+
hash
|
100
94
|
end
|
101
|
-
doc.instance_variable_set("@readonly", true)
|
102
|
-
doc.instance_variable_set("@new_record", false)
|
103
|
-
doc
|
104
95
|
end
|
105
96
|
|
106
97
|
# called in build doc, all hashes have strings as keys!!!
|
@@ -137,7 +128,7 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
137
128
|
end
|
138
129
|
end
|
139
130
|
|
140
|
-
def
|
131
|
+
def execute
|
141
132
|
response = Supernova::Solr.connection.post("select", :data => to_params)
|
142
133
|
collection = Supernova::Collection.new(current_page, per_page, response["response"]["numFound"])
|
143
134
|
collection.replace(build_docs(response["response"]["docs"]))
|
@@ -72,14 +72,43 @@ class Supernova::SolrIndexer
|
|
72
72
|
|
73
73
|
def index!
|
74
74
|
index_query(query_to_index) do |row|
|
75
|
-
|
75
|
+
map_for_solr(row)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def map_for_solr(row)
|
80
|
+
map_hash_keys_to_solr(
|
81
|
+
if self.respond_to?(:extra_attributes_from_record) && self.class.clazz
|
82
|
+
row.merge(self.extra_attributes_from_record(Supernova.build_ar_like_record(self.class.clazz, row)).stringify_keys)
|
83
|
+
elsif self.respond_to?(:row_to_solr)
|
84
|
+
puts "DEPRECATION WARNING: use before_index instead of row_to_solr! in #{caller.first}"
|
85
|
+
self.row_to_solr(row)
|
86
|
+
else
|
87
|
+
self.before_index(row)
|
88
|
+
end
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def before_index(row)
|
80
93
|
row
|
81
94
|
end
|
82
95
|
|
96
|
+
def map_hash_keys_to_solr(hash)
|
97
|
+
hash["indexed_at_dt"] = Time.now.utc.iso8601
|
98
|
+
hash["id_s"] = [self.class.table_name, hash["id"]].compact.join("/") if hash["id"]
|
99
|
+
self.class.field_definitions.each do |field, options|
|
100
|
+
if value = hash.delete(field.to_s)
|
101
|
+
if options[:type] == :date
|
102
|
+
value = Time.utc(value.year, value.month, value.day) if value.is_a?(Date)
|
103
|
+
value = value.utc.iso8601
|
104
|
+
end
|
105
|
+
hash["#{field}_#{self.class.suffix_from_type(options[:type])}"] = value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
hash["type"] = self.class.clazz.to_s if self.class.clazz
|
109
|
+
hash
|
110
|
+
end
|
111
|
+
|
83
112
|
def table_name
|
84
113
|
self.class.table_name || (self.class.clazz && self.class.clazz.respond_to?(:table_name) ? self.class.clazz.table_name : nil)
|
85
114
|
end
|
@@ -99,7 +128,7 @@ class Supernova::SolrIndexer
|
|
99
128
|
|
100
129
|
def defined_fields
|
101
130
|
self.class.field_definitions.map do |field, options|
|
102
|
-
|
131
|
+
field.to_s if options[:virtual] != true
|
103
132
|
end.compact
|
104
133
|
end
|
105
134
|
|
@@ -219,7 +248,8 @@ class Supernova::SolrIndexer
|
|
219
248
|
%(cd #{File.dirname(index_file_path)} && curl -s '#{solr_url}/update/json?commit=true' --data-binary @#{File.basename(index_file_path)} -H 'Content-type:application/json')
|
220
249
|
end
|
221
250
|
out = Kernel.send(:`, cmd)
|
222
|
-
|
251
|
+
raise "unable to index #{index_file_path}: #{out}" if !out.to_s.include?(%(<int name=\"status\">0</int>))
|
252
|
+
FileUtils.rm_f(self.index_file_path)
|
223
253
|
out
|
224
254
|
end
|
225
255
|
end
|
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
describe "Solr" do
|
4
4
|
before(:each) do
|
5
5
|
Supernova::Solr.instance_variable_set("@connection", nil)
|
6
|
-
Supernova::Solr.url = "http://localhost:
|
6
|
+
Supernova::Solr.url = "http://localhost:8985/solr/"
|
7
7
|
Supernova::Solr.truncate!
|
8
8
|
Offer.criteria_class = Supernova::SolrCriteria
|
9
9
|
root = Geokit::LatLng.new(47, 11)
|
@@ -41,7 +41,7 @@ describe "Solr" do
|
|
41
41
|
has :user_id, :type => :integer
|
42
42
|
has :popularity, :type => :integer
|
43
43
|
|
44
|
-
def
|
44
|
+
def before_index(row)
|
45
45
|
row["indexed_at_dt"] = Time.now.utc.iso8601
|
46
46
|
row
|
47
47
|
end
|
@@ -54,9 +54,9 @@ describe "Solr" do
|
|
54
54
|
offer2 = Offer.create!(:user_id => 2, :popularity => 20)
|
55
55
|
indexer = OfferIndex.new(:db => ActiveRecord::Base.connection)
|
56
56
|
indexer.index!
|
57
|
-
OfferIndex.search_scope.
|
58
|
-
OfferIndex.search_scope.
|
59
|
-
OfferIndex.search_scope.order("user_id desc").
|
57
|
+
OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
|
58
|
+
OfferIndex.search_scope.total_entries.should == 2
|
59
|
+
OfferIndex.search_scope.order("user_id desc").populate.results.should == [offer2, offer1]
|
60
60
|
indexer.instance_variable_get("@index_file_path").should be_nil
|
61
61
|
end
|
62
62
|
|
@@ -66,9 +66,9 @@ describe "Solr" do
|
|
66
66
|
indexer = OfferIndex.new(:db => ActiveRecord::Base.connection, :max_rows_to_direct_index => 0)
|
67
67
|
indexer.index!
|
68
68
|
indexer.instance_variable_get("@index_file_path").should_not be_nil
|
69
|
-
OfferIndex.search_scope.
|
70
|
-
OfferIndex.search_scope.
|
71
|
-
OfferIndex.search_scope.order("user_id desc").
|
69
|
+
OfferIndex.search_scope.total_entries.should == 2
|
70
|
+
OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
|
71
|
+
OfferIndex.search_scope.order("user_id desc").populate.results.should == [offer2, offer1]
|
72
72
|
File.should_not be_exists(indexer.instance_variable_get("@index_file_path"))
|
73
73
|
end
|
74
74
|
|
@@ -78,39 +78,63 @@ describe "Solr" do
|
|
78
78
|
indexer = OfferIndex.new(:db => ActiveRecord::Base.connection, :max_rows_to_direct_index => 0, :local_solr => true)
|
79
79
|
indexer.index!
|
80
80
|
indexer.instance_variable_get("@index_file_path").should_not be_nil
|
81
|
-
OfferIndex.search_scope.
|
82
|
-
OfferIndex.search_scope.
|
83
|
-
OfferIndex.search_scope.order("user_id desc").
|
81
|
+
OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
|
82
|
+
OfferIndex.search_scope.total_entries.should == 2
|
83
|
+
OfferIndex.search_scope.order("user_id desc").populate.results.should == [offer2, offer1]
|
84
84
|
File.should_not be_exists(indexer.instance_variable_get("@index_file_path"))
|
85
85
|
end
|
86
|
+
|
87
|
+
describe "with extra_attributes_from_doc method defined" do
|
88
|
+
|
89
|
+
class OfferIndexWitheExtraSearchMethodFromDoc < Supernova::SolrIndexer
|
90
|
+
has :user_id, :type => :integer
|
91
|
+
has :popularity, :type => :integer
|
92
|
+
has :upcased_text, :type => :text, :virtual => true
|
93
|
+
has :text, :type => :text
|
94
|
+
|
95
|
+
clazz Offer
|
96
|
+
|
97
|
+
def extra_attributes_from_record(record)
|
98
|
+
{ :upcased_text => record.text.to_s.upcase.presence }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it "sets the capitalize_text attribute" do
|
103
|
+
Offer.create!(:user_id => 2, :popularity => 20, :text => "lower_text")
|
104
|
+
indexer = OfferIndexWitheExtraSearchMethodFromDoc.new(:db => ActiveRecord::Base.connection)
|
105
|
+
indexer.index!
|
106
|
+
offer = OfferIndexWitheExtraSearchMethodFromDoc.search_scope.first
|
107
|
+
offer.instance_variable_get("@original_search_doc")["upcased_text_t"].should == "LOWER_TEXT"
|
108
|
+
end
|
109
|
+
end
|
86
110
|
end
|
87
111
|
|
88
112
|
describe "searching" do
|
89
113
|
it "returns the correct current_page when nil" do
|
90
|
-
new_criteria.
|
114
|
+
new_criteria.current_page.should == 1
|
91
115
|
end
|
92
116
|
|
93
117
|
it "returns the correct page when set" do
|
94
|
-
new_criteria.paginate(:page => 10).
|
118
|
+
new_criteria.paginate(:page => 10).current_page.should == 10
|
95
119
|
end
|
96
120
|
|
97
121
|
it "the correct per_page when set" do
|
98
|
-
new_criteria.paginate(:per_page => 10).
|
122
|
+
new_criteria.paginate(:per_page => 10).per_page.should == 10
|
99
123
|
end
|
100
124
|
|
101
125
|
it "the correct per_page when not set" do
|
102
|
-
new_criteria.
|
126
|
+
new_criteria.per_page.should == 25
|
103
127
|
end
|
104
128
|
|
105
129
|
describe "plain text search" do
|
106
130
|
it "returns the correct entries for 1 term" do
|
107
|
-
new_criteria.search("text_t:Hans").
|
108
|
-
new_criteria.search("text_t:Hans").search("text_t:Meyer").
|
109
|
-
new_criteria.search("text_t:Marek").
|
131
|
+
new_criteria.search("text_t:Hans").map { |h| h["id"] }.should == [1]
|
132
|
+
new_criteria.search("text_t:Hans").search("text_t:Meyer").map { |h| h["id"] }.should == [1]
|
133
|
+
new_criteria.search("text_t:Marek").map { |h| h["id"] }.should == [2]
|
110
134
|
end
|
111
135
|
|
112
136
|
it "returns the correct options for a combined search" do
|
113
|
-
new_criteria.search("text_t:Hans", "text_t:Marek").
|
137
|
+
new_criteria.search("text_t:Hans", "text_t:Marek").populate.results.should == []
|
114
138
|
end
|
115
139
|
end
|
116
140
|
|
@@ -119,14 +143,14 @@ describe "Solr" do
|
|
119
143
|
"popularity_i" => 10, "location_p" => "47,11"
|
120
144
|
}.each do |key, value|
|
121
145
|
it "sets #{key} to #{value}" do
|
122
|
-
doc = new_criteria.search("text_t:Hans").
|
146
|
+
doc = new_criteria.search("text_t:Hans").first.instance_variable_get("@original_search_doc")[key].should == value
|
123
147
|
end
|
124
148
|
end
|
125
149
|
|
126
150
|
describe "nearby search" do
|
127
151
|
{ 49.kms => 1, 51.kms => 2 }.each do |distance, total_entries|
|
128
152
|
it "returns #{total_entries} for distance #{distance}" do
|
129
|
-
new_criteria.attribute_mapping(:location => { :type => :location }).near(47, 11).within(distance).
|
153
|
+
new_criteria.attribute_mapping(:location => { :type => :location }).near(47, 11).within(distance).total_entries.should == total_entries
|
130
154
|
end
|
131
155
|
end
|
132
156
|
end
|
@@ -145,25 +169,25 @@ describe "Solr" do
|
|
145
169
|
:type => "Offer"
|
146
170
|
)
|
147
171
|
Supernova::Solr.connection.commit
|
148
|
-
raise "There should be 3 docs" if new_criteria.
|
149
|
-
new_criteria.with(:user_id_i.not => nil).
|
172
|
+
raise "There should be 3 docs" if new_criteria.total_entries != 3
|
173
|
+
new_criteria.with(:user_id_i.not => nil).map { |h| h["id"] }.should == [1, 2]
|
150
174
|
end
|
151
175
|
|
152
176
|
it "finds the correct values for not specific value" do
|
153
|
-
new_criteria.with(:user_id_i.not => 1).
|
177
|
+
new_criteria.with(:user_id_i.not => 1).map { |h| h["id"] }.should == [2]
|
154
178
|
end
|
155
179
|
end
|
156
180
|
|
157
181
|
describe "gt and lt searches" do
|
158
182
|
{ :gt => [2], :gte => [1, 2], :lt => [], :lte => [1] }.each do |type, ids|
|
159
183
|
it "finds ids #{ids.inspect} for #{type}" do
|
160
|
-
new_criteria.with(:user_id_i.send(type) => 1).
|
184
|
+
new_criteria.with(:user_id_i.send(type) => 1).map { |row| row["id"] }.sort.should == ids
|
161
185
|
end
|
162
186
|
end
|
163
187
|
end
|
164
188
|
|
165
189
|
it "returns the correct objects" do
|
166
|
-
new_criteria.with(:user_id_i => 1).
|
190
|
+
new_criteria.with(:user_id_i => 1).first.should be_an_instance_of(Offer)
|
167
191
|
end
|
168
192
|
|
169
193
|
{ :id => 1, :user_id => 1, :enabled => false, :text => "Hans Meyer", :popularity => 10 }.each do |key, value|
|
@@ -173,45 +197,45 @@ describe "Solr" do
|
|
173
197
|
:enabled => { :type => :boolean },
|
174
198
|
:popularity => { :type => :integer },
|
175
199
|
:text => { :type => :text}
|
176
|
-
).with(:id => "offers/1").
|
200
|
+
).with(:id => "offers/1").first
|
177
201
|
doc.send(key).should == value
|
178
202
|
end
|
179
203
|
end
|
180
204
|
|
181
205
|
it "combines filters" do
|
182
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => false).
|
183
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => true).
|
206
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).total_entries.should == 1
|
207
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => true).total_entries.should == 0
|
184
208
|
end
|
185
209
|
|
186
210
|
it "uses without correctly" do
|
187
|
-
new_criteria.without(:user_id_i => 1).
|
188
|
-
new_criteria.without(:user_id_i => 2).
|
189
|
-
new_criteria.without(:user_id_i => 2).without(:user_id_i => 1).
|
211
|
+
new_criteria.without(:user_id_i => 1).map(&:id).should == [2]
|
212
|
+
new_criteria.without(:user_id_i => 2).map(&:id).should == [1]
|
213
|
+
new_criteria.without(:user_id_i => 2).without(:user_id_i => 1).map(&:id).should == []
|
190
214
|
end
|
191
215
|
|
192
216
|
it "uses the correct orders" do
|
193
|
-
new_criteria.order("id desc").
|
194
|
-
new_criteria.order("id asc").
|
217
|
+
new_criteria.order("id desc").map(&:id).should == [2, 1]
|
218
|
+
new_criteria.order("id asc").map(&:id).should == [1, 2]
|
195
219
|
end
|
196
220
|
|
197
221
|
it "uses the correct pagination attributes" do
|
198
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => false).
|
222
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).total_entries.should == 1
|
199
223
|
new_criteria.with(:user_id_i => 1, :enabled_b => false).length.should == 1
|
200
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).
|
224
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).total_entries.should == 1
|
201
225
|
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).length.should == 0
|
202
226
|
|
203
|
-
new_criteria.paginate(:per_page => 1, :page => 1).
|
204
|
-
new_criteria.paginate(:per_page => 1, :page => 2).
|
227
|
+
new_criteria.paginate(:per_page => 1, :page => 1).map(&:id).should == [1]
|
228
|
+
new_criteria.paginate(:per_page => 1, :page => 2).map(&:id).should == [2]
|
205
229
|
end
|
206
230
|
|
207
231
|
it "handels empty results correctly" do
|
208
|
-
results = new_criteria.with(:user_id_i => 1, :enabled_b => true)
|
232
|
+
results = new_criteria.with(:user_id_i => 1, :enabled_b => true)
|
209
233
|
results.total_entries.should == 0
|
210
234
|
results.current_page.should == 1
|
211
235
|
end
|
212
236
|
|
213
237
|
it "only sets specific attributes" do
|
214
|
-
results = new_criteria.select(:user_id_i).with(:user_id_i => 1)
|
238
|
+
results = new_criteria.select(:user_id_i).with(:user_id_i => 1)
|
215
239
|
results.length.should == 1
|
216
240
|
results.first.should == { "id" => "offers/1", "user_id_i" => 1 }
|
217
241
|
end
|
@@ -3,7 +3,9 @@ require "ostruct"
|
|
3
3
|
|
4
4
|
describe "Supernova::Criteria" do
|
5
5
|
let(:scope) { Supernova::Criteria.new }
|
6
|
-
|
6
|
+
before(:each) do
|
7
|
+
scope.stub!(:execute).and_return [].paginate(:page => 1)
|
8
|
+
end
|
7
9
|
|
8
10
|
describe "#initialize" do
|
9
11
|
it "can be initialized" do
|
@@ -110,11 +112,68 @@ describe "Supernova::Criteria" do
|
|
110
112
|
end
|
111
113
|
|
112
114
|
it "to_a raises an implement in subclass error" do
|
115
|
+
scope.unstub(:execute)
|
113
116
|
lambda {
|
114
|
-
scope.
|
117
|
+
scope.execute
|
115
118
|
}.should raise_error("implement in subclass")
|
116
119
|
end
|
117
120
|
|
121
|
+
describe "#to_a" do
|
122
|
+
it "calls populate" do
|
123
|
+
scope.should_receive(:populate)
|
124
|
+
scope.to_a
|
125
|
+
end
|
126
|
+
|
127
|
+
it "returns the results" do
|
128
|
+
res = double("results")
|
129
|
+
scope.instance_variable_set("@results", res)
|
130
|
+
scope.to_a.should == res
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#populate" do
|
135
|
+
it "returns self when" do
|
136
|
+
scope.stub!(:populated?).and_return true
|
137
|
+
scope.populate.should == scope
|
138
|
+
end
|
139
|
+
|
140
|
+
it "does not change @results when already populated" do
|
141
|
+
res = double("results")
|
142
|
+
scope.instance_variable_set("@results", res)
|
143
|
+
scope.stub!(:populated?).and_return true
|
144
|
+
scope.populate.should == scope
|
145
|
+
scope.instance_variable_get("@results").should == res
|
146
|
+
end
|
147
|
+
|
148
|
+
it "returns the scope when not populated yet" do
|
149
|
+
scope.populate.should == scope
|
150
|
+
end
|
151
|
+
|
152
|
+
it "calls execute" do
|
153
|
+
scope.should_receive(:execute).and_return []
|
154
|
+
scope.populate
|
155
|
+
end
|
156
|
+
|
157
|
+
it "assigns the result of populate" do
|
158
|
+
result = double("result")
|
159
|
+
scope.stub!(:execute).and_return result
|
160
|
+
scope.populate
|
161
|
+
scope.instance_variable_get("@results").should == result
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "#populated?" do
|
166
|
+
it "returns false when @results not set" do
|
167
|
+
scope.should_not be_populated
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns true when instance variable set" do
|
171
|
+
scope.stub!(:execute).and_return []
|
172
|
+
scope.populate
|
173
|
+
scope.should be_populated
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
118
177
|
describe "with to_a stubbed" do
|
119
178
|
let(:array_double) { double("array") }
|
120
179
|
|
@@ -122,17 +181,19 @@ describe "Supernova::Criteria" do
|
|
122
181
|
scope.stub!(:to_a).and_return array_double
|
123
182
|
end
|
124
183
|
|
125
|
-
[ :first, :each, :count, :last ].each do |method|
|
184
|
+
[ :first, :each, :count, :last, :total_entries ].each do |method|
|
126
185
|
it "forwards #{method} to array" do
|
127
|
-
|
128
|
-
|
186
|
+
results = double("ret")
|
187
|
+
scope.instance_variable_set("@results", results)
|
188
|
+
scope.should_receive(:populated?).and_return false
|
129
189
|
scope.send(method)
|
130
190
|
end
|
131
191
|
end
|
132
192
|
|
133
193
|
it "hands given blocks in" do
|
134
194
|
array = [1, 2, 3]
|
135
|
-
scope.
|
195
|
+
scope.instance_variable_set("@results", array)
|
196
|
+
scope.stub!(:populated?).and_return true
|
136
197
|
called = []
|
137
198
|
scope.each do |i|
|
138
199
|
called << i
|
@@ -155,6 +216,13 @@ describe "Supernova::Criteria" do
|
|
155
216
|
}.should raise_error(NoMethodError)
|
156
217
|
end
|
157
218
|
|
219
|
+
it "forwards all array methods to @results" do
|
220
|
+
results = double("results")
|
221
|
+
scope.instance_variable_set("@results", results)
|
222
|
+
results.should_receive(:index, "1")
|
223
|
+
scope.index("1")
|
224
|
+
end
|
225
|
+
|
158
226
|
it "calls named_scope_defined" do
|
159
227
|
scope.should_receive(:named_scope_defined?).with(:rgne).and_return false
|
160
228
|
scope.method_missing(:rgne) rescue nil
|
@@ -195,10 +263,6 @@ describe "Supernova::Criteria" do
|
|
195
263
|
end
|
196
264
|
end
|
197
265
|
|
198
|
-
describe "#with_scopes" do
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
266
|
describe "#merge" do
|
203
267
|
let(:criteria) { Supernova::Criteria.new.order("popularity asc").with(:a => 1).conditions(:b => 2).search("New Search") }
|
204
268
|
let(:new_crit) { Supernova::Criteria.new.order("popularity desc").with(:c => 8).conditions(:e => 9).search("Search") }
|
@@ -163,7 +163,7 @@ describe Supernova::SolrCriteria do
|
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
166
|
-
describe "#
|
166
|
+
describe "#execute" do
|
167
167
|
let(:params) { double("params") }
|
168
168
|
|
169
169
|
before(:each) do
|
@@ -173,45 +173,45 @@ describe Supernova::SolrCriteria do
|
|
173
173
|
|
174
174
|
it "calls to_params" do
|
175
175
|
criteria.should_receive(:to_params).and_return params
|
176
|
-
criteria.
|
176
|
+
criteria.execute
|
177
177
|
end
|
178
178
|
|
179
179
|
it "calls get with select and params" do
|
180
180
|
rsolr.should_receive(:post).with("select", :data => params).and_return solr_response
|
181
|
-
criteria.
|
181
|
+
criteria.execute
|
182
182
|
end
|
183
183
|
|
184
184
|
it "returns a Supernova::Collection" do
|
185
|
-
criteria.
|
185
|
+
criteria.execute.should be_an_instance_of(Supernova::Collection)
|
186
186
|
end
|
187
187
|
|
188
188
|
it "sets the correct page when page is nil" do
|
189
|
-
criteria.
|
189
|
+
criteria.execute.current_page.should == 1
|
190
190
|
end
|
191
191
|
|
192
192
|
it "sets the correct page when page is 1" do
|
193
|
-
criteria.paginate(:page => 1).
|
193
|
+
criteria.paginate(:page => 1).execute.current_page.should == 1
|
194
194
|
end
|
195
195
|
|
196
196
|
it "sets the correct page when page is 2" do
|
197
|
-
criteria.paginate(:page => 2).
|
197
|
+
criteria.paginate(:page => 2).execute.current_page.should == 2
|
198
198
|
end
|
199
199
|
|
200
200
|
it "sets the correct per_page when zero" do
|
201
|
-
criteria.paginate(:page => 2, :per_page => nil).
|
201
|
+
criteria.paginate(:page => 2, :per_page => nil).execute.per_page.should == 25
|
202
202
|
end
|
203
203
|
|
204
204
|
it "sets the custom per_page when given" do
|
205
|
-
criteria.paginate(:page => 2, :per_page => 10).
|
205
|
+
criteria.paginate(:page => 2, :per_page => 10).execute.per_page.should == 10
|
206
206
|
end
|
207
207
|
|
208
208
|
it "sets the correct total_entries" do
|
209
|
-
criteria.paginate(:page => 2, :per_page => 10).
|
209
|
+
criteria.paginate(:page => 2, :per_page => 10).execute.total_entries.should == 2
|
210
210
|
end
|
211
211
|
|
212
212
|
it "calls build_docs with returned docs" do
|
213
213
|
criteria.should_receive(:build_docs).with(docs).and_return []
|
214
|
-
criteria.
|
214
|
+
criteria.execute
|
215
215
|
end
|
216
216
|
|
217
217
|
it "calls replace on collection wit returned docs" do
|
@@ -220,7 +220,7 @@ describe Supernova::SolrCriteria do
|
|
220
220
|
built_docs = double("built docs")
|
221
221
|
criteria.stub!(:build_docs).and_return built_docs
|
222
222
|
col.should_receive(:replace).with(built_docs)
|
223
|
-
criteria.
|
223
|
+
criteria.execute
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
@@ -283,9 +283,7 @@ describe Supernova::SolrCriteria do
|
|
283
283
|
criteria.build_doc(row).should == row
|
284
284
|
end
|
285
285
|
|
286
|
-
it "assigns the attributes returned from convert_doc_attributes to attributes when
|
287
|
-
str = String.new
|
288
|
-
str.instance_variable_set("@attributes", {})
|
286
|
+
it "assigns the attributes returned from convert_doc_attributes to attributes when record responds to attributes=" do
|
289
287
|
atts = { :title => "Hello" }
|
290
288
|
row = { "type" => "Offer" }
|
291
289
|
criteria.should_receive(:convert_doc_attributes).with(row).and_return atts
|
@@ -293,9 +291,9 @@ describe Supernova::SolrCriteria do
|
|
293
291
|
doc.instance_variable_get("@attributes").should == atts
|
294
292
|
end
|
295
293
|
|
296
|
-
it "sets the original
|
297
|
-
|
298
|
-
criteria.build_doc(
|
294
|
+
it "sets the original original_search_doc" do
|
295
|
+
original_search_doc = { "type" => "Offer", "id" => "offers/id" }
|
296
|
+
criteria.build_doc(original_search_doc).instance_variable_get("@original_search_doc").should == original_search_doc
|
299
297
|
end
|
300
298
|
|
301
299
|
it "should be readonly" do
|
@@ -6,11 +6,13 @@ describe Supernova::SolrIndexer do
|
|
6
6
|
let(:to_index) { { :id => 1, :title => "Some Title"} }
|
7
7
|
let(:file_stub) { double("file").as_null_object }
|
8
8
|
let(:solr) { double("solr").as_null_object }
|
9
|
+
let(:solr_index_response) { %(<int name="status">0</int>) }
|
9
10
|
|
10
11
|
let(:indexer) do
|
11
12
|
indexer = Supernova::SolrIndexer.new
|
12
13
|
indexer.db = db
|
13
14
|
indexer.stub!(:system).and_return true
|
15
|
+
Kernel.stub!(:`).and_return solr_index_response
|
14
16
|
indexer
|
15
17
|
end
|
16
18
|
|
@@ -68,17 +70,81 @@ describe Supernova::SolrIndexer do
|
|
68
70
|
indexer.index!
|
69
71
|
end
|
70
72
|
|
71
|
-
it "calls
|
73
|
+
it "calls map_for_solr with all returned rows from sql" do
|
72
74
|
row1 = double("row1")
|
73
75
|
row2 = double("row2")
|
74
76
|
indexer.stub!(:query).and_return [row1, row2]
|
75
77
|
indexer.stub!(:query_to_index).and_return "some query"
|
76
|
-
indexer.should_receive(:
|
78
|
+
indexer.should_receive(:map_for_solr).with(row1)
|
77
79
|
indexer.stub!(:index_query).and_yield(row1)
|
78
80
|
indexer.index!
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
84
|
+
describe "#map_for_solr" do
|
85
|
+
let(:row) { { "a" => 1 } }
|
86
|
+
|
87
|
+
before(:each) do
|
88
|
+
indexer.stub!(:puts)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "calls row_to_solr" do
|
92
|
+
indexer.should_not_receive(:before_index)
|
93
|
+
indexer.should_receive(:row_to_solr).with(row).and_return row
|
94
|
+
indexer.map_for_solr(row)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "prints a deprecation warning when using row_to_solr" do
|
98
|
+
indexer.stub!(:row_to_solr).with(row).and_return row
|
99
|
+
indexer.should_receive(:puts).with(/DEPRECATION WARNING: use before_index instead of row_to_solr! in/)
|
100
|
+
indexer.map_for_solr(row)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "calls before_index when row_to_solr is not defined" do
|
104
|
+
row = { "a" => 1 }
|
105
|
+
indexer.should_receive(:before_index).with(row).and_return row
|
106
|
+
indexer.map_for_solr(row)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "calls map_hash_keys_to_solr with result of row_to_solr" do
|
110
|
+
dummy_row = double("dummy row")
|
111
|
+
indexer.stub!(:row_to_solr).and_return dummy_row
|
112
|
+
indexer.should_receive(:map_hash_keys_to_solr).with(dummy_row)
|
113
|
+
indexer.map_for_solr({ "a" => 1 })
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "with the index defining extra_attributes_from_record" do
|
117
|
+
let(:index) { SolrOfferIndex.new }
|
118
|
+
let(:offer_double) { double("Solr Offer", :id => 88).as_null_object }
|
119
|
+
|
120
|
+
class SolrOfferIndex < Supernova::SolrIndexer
|
121
|
+
clazz Offer
|
122
|
+
has :created_at, :type => :date
|
123
|
+
has :offer_id, :type => :integer
|
124
|
+
|
125
|
+
def extra_attributes_from_record(doc)
|
126
|
+
{ :offer_code => "OFFER_#{doc.id}" }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it "calls Supernova.build_ar_like_record with correct parameters" do
|
131
|
+
Supernova.should_receive(:build_ar_like_record).and_return offer_double
|
132
|
+
SolrOfferIndex.new("offer_id" => 77, "type" => "Offer").map_for_solr(row)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "includes the original attributes" do
|
136
|
+
index = SolrOfferIndex.new
|
137
|
+
index.map_for_solr({ "a" => 2 })["a"].should == 2
|
138
|
+
end
|
139
|
+
|
140
|
+
it "includes the attributes from extra_attributes_from_record" do
|
141
|
+
index = SolrOfferIndex.new
|
142
|
+
index.map_for_solr({ "a" => 2, "id" => "88" })["offer_code"].should == "OFFER_88"
|
143
|
+
hash = { :a => 1, "a" => 2 }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
82
148
|
describe "validate_lat" do
|
83
149
|
{ nil => nil, 10 => 10.0, 90.1 => nil, 90 => 90, -90.1 => nil, -90 => -90 }.each do |from, to|
|
84
150
|
it "converts #{from} to #{to}" do
|
@@ -118,9 +184,9 @@ describe Supernova::SolrIndexer do
|
|
118
184
|
end
|
119
185
|
end
|
120
186
|
|
121
|
-
describe "#
|
187
|
+
describe "#before_index" do
|
122
188
|
it "returns the db row by default" do
|
123
|
-
indexer.
|
189
|
+
indexer.before_index("id" => 1).should == { "id" => 1 }
|
124
190
|
end
|
125
191
|
end
|
126
192
|
|
@@ -138,6 +204,56 @@ describe Supernova::SolrIndexer do
|
|
138
204
|
end
|
139
205
|
end
|
140
206
|
|
207
|
+
describe "#map_hash_keys_to_solr" do
|
208
|
+
class CustomSolrIndex < Supernova::SolrIndexer
|
209
|
+
has :offer_id, :type => :integer
|
210
|
+
has :lat, :type => :float
|
211
|
+
has :lng, :type => :float
|
212
|
+
has :created_at, :type => :date
|
213
|
+
has :checkin_date, :type => :date
|
214
|
+
end
|
215
|
+
|
216
|
+
it "maps float fields" do
|
217
|
+
index = CustomSolrIndex.new
|
218
|
+
index.map_hash_keys_to_solr("lat" => 49.0)["lat_f"].should == 49.0
|
219
|
+
end
|
220
|
+
|
221
|
+
it "maps time fields to iso8601" do
|
222
|
+
index = CustomSolrIndex.new
|
223
|
+
time = Time.parse("2011-02-03 11:20:30")
|
224
|
+
index.map_hash_keys_to_solr("created_at" => time)["created_at_dt"].should == "2011-02-03T10:20:30Z"
|
225
|
+
end
|
226
|
+
|
227
|
+
it "maps date fields to iso8601" do
|
228
|
+
date = Date.new(2011, 1, 2)
|
229
|
+
CustomSolrIndex.new.map_hash_keys_to_solr("checkin_date" => date)["checkin_date_dt"].should == "2011-01-02T00:00:00Z"
|
230
|
+
end
|
231
|
+
|
232
|
+
it "sets the indexed_at time" do
|
233
|
+
Time.stub!(:now).and_return Time.parse("2011-02-03T11:20:30Z")
|
234
|
+
CustomSolrIndex.new.map_hash_keys_to_solr({})["indexed_at_dt"].should == "2011-02-03T11:20:30Z"
|
235
|
+
Time.unstub!(:now)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "adds the class as type when class set" do
|
239
|
+
clazz = Class.new(Supernova::SolrIndexer)
|
240
|
+
clazz.clazz Offer
|
241
|
+
clazz.new.map_hash_keys_to_solr({})["type"].should == "Offer"
|
242
|
+
end
|
243
|
+
|
244
|
+
it "uses the table_name as prefix for ids" do
|
245
|
+
clazz = Class.new(Supernova::SolrIndexer)
|
246
|
+
clazz.table_name :people
|
247
|
+
clazz.new.map_hash_keys_to_solr({ "id" => 88 })["id_s"].should == "people/88"
|
248
|
+
end
|
249
|
+
|
250
|
+
it "adds the sets the cla" do
|
251
|
+
clazz = Class.new(Supernova::SolrIndexer)
|
252
|
+
clazz.clazz Offer
|
253
|
+
clazz.new.map_hash_keys_to_solr({})["type"].should == "Offer"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
141
257
|
describe "#index_query" do
|
142
258
|
let(:query) { %(SELECT CONCAT("user_", id) AS id, title FROM people WHERE type = 'User') }
|
143
259
|
|
@@ -300,13 +416,13 @@ describe Supernova::SolrIndexer do
|
|
300
416
|
|
301
417
|
it "calls the correct curl command" do
|
302
418
|
indexer = Supernova::SolrIndexer.new(:index_file_path => "/tmp/some_path.json", :local_solr => true)
|
303
|
-
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return
|
419
|
+
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return solr_index_response
|
304
420
|
indexer.do_index_file(:local => true)
|
305
421
|
end
|
306
422
|
|
307
423
|
it "calls rm on file" do
|
308
424
|
indexer = Supernova::SolrIndexer.new(:index_file_path => "/tmp/some_path.json", :local_solr => true)
|
309
|
-
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return
|
425
|
+
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return solr_index_response
|
310
426
|
FileUtils.should_receive(:rm_f).with("/tmp/some_path.json")
|
311
427
|
indexer.do_index_file(:local => true)
|
312
428
|
end
|
@@ -315,13 +431,15 @@ describe Supernova::SolrIndexer do
|
|
315
431
|
indexer = Supernova::SolrIndexer.new(:index_file_path => "/tmp/some_path.json", :local_solr => true)
|
316
432
|
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return %(<int name="status">1</int>)
|
317
433
|
FileUtils.should_not_receive(:rm_f).with("/tmp/some_path.json")
|
318
|
-
|
434
|
+
lambda {
|
435
|
+
indexer.do_index_file(:local => true)
|
436
|
+
}.should raise_error
|
319
437
|
end
|
320
438
|
|
321
439
|
it "executes the correct curl call when not local" do
|
322
440
|
# curl 'http://localhost:8983/solr/update/json?commit=true' --data-binary @books.json -H 'Content-type:application/json'
|
323
441
|
indexer.index_file_path = "/tmp/some_path.json"
|
324
|
-
Kernel.should_receive(:`).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'")
|
442
|
+
Kernel.should_receive(:`).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'").and_return solr_index_response
|
325
443
|
indexer.do_index_file
|
326
444
|
end
|
327
445
|
end
|
@@ -394,9 +512,7 @@ describe Supernova::SolrIndexer do
|
|
394
512
|
custom_indexer.defined_fields
|
395
513
|
end
|
396
514
|
|
397
|
-
["title
|
398
|
-
%(IF(created_at IS NULL, NULL, CONCAT(REPLACE(created_at, " ", "T"), "Z")) AS created_at_dt)
|
399
|
-
].each do |field|
|
515
|
+
["title", "artist_id", "description", "created_at"].each do |field|
|
400
516
|
it "includes field #{field.inspect}" do
|
401
517
|
custom_indexer.defined_fields.should include(field)
|
402
518
|
end
|
@@ -406,7 +522,7 @@ describe Supernova::SolrIndexer do
|
|
406
522
|
clazz = Class.new(Supernova::SolrIndexer)
|
407
523
|
clazz.has :location, :type => :location, :virtual => true
|
408
524
|
clazz.has :title, :type => :string
|
409
|
-
clazz.new.defined_fields.should == ["title
|
525
|
+
clazz.new.defined_fields.should == ["title"]
|
410
526
|
end
|
411
527
|
end
|
412
528
|
|
data/spec/supernova_spec.rb
CHANGED
@@ -84,4 +84,45 @@ describe Supernova do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
87
|
+
|
88
|
+
describe "#build_ar_like_record" do
|
89
|
+
let(:offer_double) { double("offer").as_null_object }
|
90
|
+
|
91
|
+
before(:each) do
|
92
|
+
Offer.stub!(:new).and_return offer_double
|
93
|
+
end
|
94
|
+
|
95
|
+
it "is callable" do
|
96
|
+
Supernova.should respond_to(:build_ar_like_record)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "creates a new instance" do
|
100
|
+
Offer.should_receive(:new).and_return offer_double
|
101
|
+
Supernova.build_ar_like_record(Offer, {})
|
102
|
+
end
|
103
|
+
|
104
|
+
it "sets the attributes" do
|
105
|
+
atts = { :a => 1 }
|
106
|
+
offer_double.should_receive(:instance_variable_set).with("@attributes", atts)
|
107
|
+
Supernova.build_ar_like_record(Offer, atts)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns the record" do
|
111
|
+
Supernova.build_ar_like_record(Offer, {}).should == offer_double
|
112
|
+
end
|
113
|
+
|
114
|
+
it "sets readonly to true" do
|
115
|
+
Supernova.build_ar_like_record(Offer, {}).instance_variable_get("@readonly").should == true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "sets new_record to false" do
|
119
|
+
Supernova.build_ar_like_record(Offer, {}).instance_variable_get("@new_record").should == false
|
120
|
+
end
|
121
|
+
|
122
|
+
it "sets the original_search_doc hash when given" do
|
123
|
+
original_search_doc = double("original_search_doc")
|
124
|
+
doc = Supernova.build_ar_like_record(Offer, {}, original_search_doc)
|
125
|
+
doc.instance_variable_get("@original_search_doc").should == original_search_doc
|
126
|
+
end
|
127
|
+
end
|
87
128
|
end
|
data/supernova.gemspec
CHANGED
@@ -5,13 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{supernova}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Tobias Schwab"]
|
12
|
-
s.date = %q{2011-06-
|
12
|
+
s.date = %q{2011-06-29}
|
13
13
|
s.description = %q{Unified search scopes}
|
14
14
|
s.email = %q{tobias.schwab@dynport.de}
|
15
|
+
s.executables = ["start_solr"]
|
15
16
|
s.extra_rdoc_files = [
|
16
17
|
"LICENSE.txt",
|
17
18
|
"README.rdoc"
|
@@ -27,6 +28,7 @@ Gem::Specification.new do |s|
|
|
27
28
|
"Rakefile",
|
28
29
|
"VERSION",
|
29
30
|
"autotest/discover.rb",
|
31
|
+
"bin/start_solr",
|
30
32
|
"lib/supernova.rb",
|
31
33
|
"lib/supernova/collection.rb",
|
32
34
|
"lib/supernova/condition.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: supernova
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 13
|
10
|
+
version: 0.3.13
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tobias Schwab
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-29 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
@@ -211,8 +211,8 @@ dependencies:
|
|
211
211
|
type: :development
|
212
212
|
description: Unified search scopes
|
213
213
|
email: tobias.schwab@dynport.de
|
214
|
-
executables:
|
215
|
-
|
214
|
+
executables:
|
215
|
+
- start_solr
|
216
216
|
extensions: []
|
217
217
|
|
218
218
|
extra_rdoc_files:
|
@@ -229,6 +229,7 @@ files:
|
|
229
229
|
- Rakefile
|
230
230
|
- VERSION
|
231
231
|
- autotest/discover.rb
|
232
|
+
- bin/start_solr
|
232
233
|
- lib/supernova.rb
|
233
234
|
- lib/supernova/collection.rb
|
234
235
|
- lib/supernova/condition.rb
|