scoped_search 2.4.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +9 -0
- data/Gemfile.activerecord4 +16 -0
- data/README.rdoc +1 -0
- data/lib/scoped_search.rb +2 -2
- data/lib/scoped_search/definition.rb +20 -11
- data/lib/scoped_search/query_builder.rb +15 -12
- data/lib/scoped_search/query_language/tokenizer.rb +4 -1
- data/scoped_search.gemspec +3 -3
- data/spec/integration/api_spec.rb +6 -1
- data/spec/integration/key_value_querying_spec.rb +34 -22
- data/spec/integration/ordinal_querying_spec.rb +13 -2
- data/spec/integration/string_querying_spec.rb +1 -4
- data/tasks/github-gem.rake +6 -2
- metadata +75 -70
data/.travis.yml
CHANGED
@@ -7,6 +7,7 @@ rvm:
|
|
7
7
|
- 1.8.7
|
8
8
|
- 1.9.2
|
9
9
|
- 1.9.3
|
10
|
+
- 2.0.0
|
10
11
|
- ruby-head
|
11
12
|
- ree
|
12
13
|
- jruby-18mode
|
@@ -16,6 +17,11 @@ gemfile:
|
|
16
17
|
- Gemfile.activerecord2
|
17
18
|
- Gemfile.activerecord3
|
18
19
|
matrix:
|
20
|
+
include:
|
21
|
+
- rvm: 1.9.3
|
22
|
+
gemfile: Gemfile.activerecord4
|
23
|
+
- rvm: 2.0.0
|
24
|
+
gemfile: Gemfile.activerecord4
|
19
25
|
allow_failures:
|
20
26
|
- rvm: ruby-head
|
21
27
|
- rvm: jruby-head
|
@@ -28,3 +34,6 @@ matrix:
|
|
28
34
|
gemfile: Gemfile.activerecord2
|
29
35
|
- rvm: jruby-head
|
30
36
|
gemfile: Gemfile.activerecord2
|
37
|
+
- rvm: jruby-head
|
38
|
+
gemfile: Gemfile.activerecord2
|
39
|
+
- rvm: ree
|
@@ -0,0 +1,16 @@
|
|
1
|
+
source :rubygems
|
2
|
+
gemspec
|
3
|
+
|
4
|
+
gem 'activerecord', '~> 4.0.0.beta1'
|
5
|
+
|
6
|
+
platforms :jruby do
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter'
|
8
|
+
gem 'activerecord-jdbcmysql-adapter'
|
9
|
+
gem 'activerecord-jdbcpostgresql-adapter'
|
10
|
+
end
|
11
|
+
|
12
|
+
platforms :ruby do
|
13
|
+
gem 'sqlite3'
|
14
|
+
gem 'mysql2', '~> 0.3.11'
|
15
|
+
gem 'pg'
|
16
|
+
end
|
data/README.rdoc
CHANGED
@@ -13,6 +13,7 @@ to create a clean web UI with sorting and an ajax auto-completer.
|
|
13
13
|
== Preview
|
14
14
|
A demo application using the scoped search can be found here: http://github.com/abenari/scoped_search_demo_app
|
15
15
|
A running version of the demo application can be found here: http://scope-search-demo.heroku.com
|
16
|
+
A Rails 3.2 demo with assets pipeline and twitter bootstrap theame https://github.com/abenari/search-demo2
|
16
17
|
|
17
18
|
== Installing
|
18
19
|
For a Rails 3 application add the following line in your Gemfile, and run <tt>bundle install</tt>:
|
data/lib/scoped_search.rb
CHANGED
@@ -14,7 +14,7 @@ module ScopedSearch
|
|
14
14
|
|
15
15
|
# The current scoped_search version. Do not change thisvalue by hand,
|
16
16
|
# because it will be updated automatically by the gem release script.
|
17
|
-
VERSION = "2.
|
17
|
+
VERSION = "2.5.0"
|
18
18
|
|
19
19
|
# The ClassMethods module will be included into the ActiveRecord::Base class
|
20
20
|
# to add the <tt>ActiveRecord::Base.scoped_search</tt> method and the
|
@@ -54,7 +54,7 @@ module ScopedSearch
|
|
54
54
|
|
55
55
|
fields.each do |field|
|
56
56
|
if relation = self.reflections.keys.detect { |relation| field.to_s =~ Regexp.new("^#{relation}_(\\w+)$") }
|
57
|
-
scoped_search(:in => relation, :on => $1.to_sym)
|
57
|
+
scoped_search(:in => relation.to_sym, :on => $1.to_sym)
|
58
58
|
else
|
59
59
|
scoped_search(:on => field)
|
60
60
|
end
|
@@ -153,10 +153,8 @@ module ScopedSearch
|
|
153
153
|
@profile_fields = {:default => {}}
|
154
154
|
@profile_unique_fields = {:default => []}
|
155
155
|
|
156
|
-
|
157
156
|
register_named_scope! unless klass.respond_to?(:search_for)
|
158
157
|
register_complete_for! unless klass.respond_to?(:complete_for)
|
159
|
-
|
160
158
|
end
|
161
159
|
|
162
160
|
attr_accessor :profile, :default_order
|
@@ -185,11 +183,11 @@ module ScopedSearch
|
|
185
183
|
def operator_by_field_name(name)
|
186
184
|
field = field_by_name(name)
|
187
185
|
return [] if field.nil?
|
188
|
-
return field.operators
|
189
|
-
return ['= ', '!= ']
|
190
|
-
return ['= ', '> ', '< ', '<= ', '>= ','!= ', '^ ', '!^ ']
|
191
|
-
return ['= ', '!= ', '~ ', '!~ ', '^ ', '!^ ']
|
192
|
-
return ['= ', '> ', '< ']
|
186
|
+
return field.operators if field.operators
|
187
|
+
return ['= ', '!= '] if field.set?
|
188
|
+
return ['= ', '> ', '< ', '<= ', '>= ','!= ', '^ ', '!^ '] if field.numerical?
|
189
|
+
return ['= ', '!= ', '~ ', '!~ ', '^ ', '!^ '] if field.textual?
|
190
|
+
return ['= ', '> ', '< '] if field.temporal?
|
193
191
|
raise ScopedSearch::QueryNotSupported, "could not verify '#{name}' type, this can be a result of a definition error"
|
194
192
|
end
|
195
193
|
|
@@ -200,10 +198,10 @@ module ScopedSearch
|
|
200
198
|
def default_fields_for(value, operator = nil)
|
201
199
|
|
202
200
|
column_types = []
|
203
|
-
column_types += [:string, :text]
|
204
|
-
column_types += [:double, :float, :decimal]
|
205
|
-
column_types += [:integer]
|
206
|
-
column_types += [:datetime, :date, :timestamp]
|
201
|
+
column_types += [:string, :text] if [nil, :like, :unlike, :ne, :eq].include?(operator)
|
202
|
+
column_types += [:double, :float, :decimal] if value =~ NUMERICAL_REGXP
|
203
|
+
column_types += [:integer] if value =~ INTEGER_REGXP
|
204
|
+
column_types += [:datetime, :date, :timestamp] if (parse_temporal(value))
|
207
205
|
|
208
206
|
default_fields.select { |field| column_types.include?(field.type) && !field.set? }
|
209
207
|
end
|
@@ -250,6 +248,17 @@ module ScopedSearch
|
|
250
248
|
search_scope = search_scope.reorder(find_options[:order]) if find_options[:order]
|
251
249
|
search_scope
|
252
250
|
})
|
251
|
+
when 4
|
252
|
+
@klass.scope(:search_for, lambda { |*args|
|
253
|
+
find_options = ScopedSearch::QueryBuilder.build_query(self, args[0], args[1])
|
254
|
+
search_scope = @klass.all
|
255
|
+
search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
|
256
|
+
search_scope = search_scope.includes(find_options[:include]) if find_options[:include]
|
257
|
+
search_scope = search_scope.references(find_options[:include]) if find_options[:include]
|
258
|
+
search_scope = search_scope.joins(find_options[:joins]) if find_options[:joins]
|
259
|
+
search_scope = search_scope.reorder(find_options[:order]) if find_options[:order]
|
260
|
+
search_scope
|
261
|
+
})
|
253
262
|
else
|
254
263
|
raise "This ActiveRecord version is currently not supported!"
|
255
264
|
end
|
@@ -140,7 +140,7 @@ module ScopedSearch
|
|
140
140
|
# more logical results.
|
141
141
|
if field.datetime?
|
142
142
|
span = 1.minute if(value =~ /\A\s*\d+\s+\bminutes?\b\s+\bago\b\s*\z/i)
|
143
|
-
span ||= (timestamp.day_fraction == 0) ? 1.day :
|
143
|
+
span ||= (timestamp.day_fraction == 0) ? 1.day : 1.hour
|
144
144
|
if [:eq, :ne].include?(operator)
|
145
145
|
# Instead of looking for an exact (non-)match, look for dates that
|
146
146
|
# fall inside/outside the range of timestamps of that day.
|
@@ -271,18 +271,16 @@ module ScopedSearch
|
|
271
271
|
join_sql = ""
|
272
272
|
connection = klass.connection
|
273
273
|
key = key_relation.to_s.singularize.to_sym
|
274
|
-
main = definition.klass.to_s.gsub(/.*::/,'').underscore.to_sym
|
275
274
|
|
276
275
|
key_table = klass.reflections[key].table_name
|
277
|
-
key_table_pk = klass.reflections[key].klass.primary_key
|
278
|
-
|
279
276
|
value_table = klass.table_name.to_s
|
280
|
-
value_table_fk_key = klass.reflections[key].association_foreign_key
|
281
277
|
|
282
|
-
|
278
|
+
key_table_pk, value_table_fk_key = reflection_keys(klass.reflections[key])
|
279
|
+
|
280
|
+
main_reflection = definition.klass.reflections[relation]
|
281
|
+
if main_reflection
|
283
282
|
main_table = definition.klass.table_name
|
284
|
-
main_table_pk = klass.reflections[
|
285
|
-
value_table_fk_main = klass.reflections[main].association_foreign_key
|
283
|
+
main_table_pk, value_table_fk_main = reflection_keys(definition.klass.reflections[relation])
|
286
284
|
|
287
285
|
join_sql = "\n INNER JOIN #{connection.quote_table_name(value_table)} #{value_table}_#{num} ON (#{main_table}.#{main_table_pk} = #{value_table}_#{num}.#{value_table_fk_main})"
|
288
286
|
value_table = " #{value_table}_#{num}"
|
@@ -303,18 +301,23 @@ module ScopedSearch
|
|
303
301
|
# on different keys in the same query.
|
304
302
|
def construct_simple_join_sql( num )
|
305
303
|
connection = klass.connection
|
306
|
-
main = definition.klass.to_s.gsub(/.*::/,'').underscore.to_sym
|
307
304
|
key_value_table = klass.table_name
|
308
305
|
|
309
306
|
main_table = definition.klass.table_name
|
310
|
-
main_table_pk = klass.reflections[
|
311
|
-
value_table_fk_main = klass.reflections[main].options[:foreign_key]
|
312
|
-
value_table_fk_main ||= klass.reflections[main].association_foreign_key
|
307
|
+
main_table_pk, value_table_fk_main = reflection_keys(definition.klass.reflections[relation])
|
313
308
|
|
314
309
|
join_sql = "\n INNER JOIN #{connection.quote_table_name(key_value_table)} #{key_value_table}_#{num} ON (#{connection.quote_table_name(main_table)}.#{main_table_pk} = #{key_value_table}_#{num}.#{value_table_fk_main})"
|
315
310
|
return join_sql
|
316
311
|
end
|
317
312
|
|
313
|
+
def reflection_keys reflection
|
314
|
+
pk = reflection.klass.primary_key
|
315
|
+
fk = reflection.options[:foreign_key]
|
316
|
+
# activerecord prior to 3.1 doesn't respond to foreign_key method and hold the key name in the reflection primary key
|
317
|
+
fk = fk || reflection.respond_to?(:foreign_key) ? reflection.foreign_key : reflection.primary_key_name
|
318
|
+
[pk, fk]
|
319
|
+
end
|
320
|
+
|
318
321
|
def to_ext_method_sql(key, operator, value, &block)
|
319
322
|
raise ScopedSearch::QueryNotSupported, "'#{definition.klass}' doesn't respond to '#{ext_method}'" unless definition.klass.respond_to?(ext_method)
|
320
323
|
conditions = definition.klass.send(ext_method.to_sym,key, operator, value) rescue {}
|
@@ -49,9 +49,12 @@ module ScopedSearch::QueryLanguage::Tokenizer
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Tokenizes an operator that occurs in the OPERATORS hash
|
52
|
+
# The .to_s on [peek|next]_char is to prevent a ruby bug when nil
|
53
|
+
# values are returned from strings which have forced encoding.
|
54
|
+
# https://github.com/wvanbergen/scoped_search/issues/33 for details
|
52
55
|
def tokenize_operator(&block)
|
53
56
|
operator = current_char
|
54
|
-
operator << next_char if OPERATORS.has_key?(operator + peek_char)
|
57
|
+
operator << next_char.to_s if OPERATORS.has_key?(operator + peek_char.to_s)
|
55
58
|
yield(OPERATORS[operator])
|
56
59
|
end
|
57
60
|
|
data/scoped_search.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not change the version and date fields by hand. This will be done
|
5
5
|
# automatically by the gem release script.
|
6
|
-
s.version = "2.
|
7
|
-
s.date = "2013-03-
|
6
|
+
s.version = "2.5.0"
|
7
|
+
s.date = "2013-03-29"
|
8
8
|
|
9
9
|
s.summary = "Easily search you ActiveRecord models with a simple query language using a named scope."
|
10
10
|
s.description = <<-EOS
|
@@ -33,6 +33,6 @@ Gem::Specification.new do |s|
|
|
33
33
|
|
34
34
|
# Do not change the files and test_files fields by hand. This will be done
|
35
35
|
# automatically by the gem release script.
|
36
|
-
s.files = %w(.gitignore .infinity_test .travis.yml Gemfile Gemfile.activerecord2 Gemfile.activerecord3 LICENSE README.rdoc Rakefile init.rb lib/scoped_search.rb lib/scoped_search/auto_complete_builder.rb lib/scoped_search/definition.rb lib/scoped_search/engine.rb lib/scoped_search/query_builder.rb lib/scoped_search/query_language.rb lib/scoped_search/query_language/ast.rb lib/scoped_search/query_language/parser.rb lib/scoped_search/query_language/tokenizer.rb lib/scoped_search/rails_helper.rb scoped_search.gemspec spec/database.jruby.yml spec/database.ruby.yml spec/integration/api_spec.rb spec/integration/auto_complete_spec.rb spec/integration/key_value_querying_spec.rb spec/integration/ordinal_querying_spec.rb spec/integration/profile_querying_spec.rb spec/integration/relation_querying_spec.rb spec/integration/set_query_spec.rb spec/integration/string_querying_spec.rb spec/lib/database.rb spec/lib/matchers.rb spec/lib/mocks.rb spec/spec_helper.rb spec/unit/ast_spec.rb spec/unit/auto_complete_builder_spec.rb spec/unit/definition_spec.rb spec/unit/parser_spec.rb spec/unit/query_builder_spec.rb spec/unit/tokenizer_spec.rb tasks/github-gem.rake vendor/assets/images/spinner.gif vendor/assets/javascripts/scoped_search.js vendor/assets/stylesheets/scoped_search.scss)
|
36
|
+
s.files = %w(.gitignore .infinity_test .travis.yml Gemfile Gemfile.activerecord2 Gemfile.activerecord3 Gemfile.activerecord4 LICENSE README.rdoc Rakefile init.rb lib/scoped_search.rb lib/scoped_search/auto_complete_builder.rb lib/scoped_search/definition.rb lib/scoped_search/engine.rb lib/scoped_search/query_builder.rb lib/scoped_search/query_language.rb lib/scoped_search/query_language/ast.rb lib/scoped_search/query_language/parser.rb lib/scoped_search/query_language/tokenizer.rb lib/scoped_search/rails_helper.rb scoped_search.gemspec spec/database.jruby.yml spec/database.ruby.yml spec/integration/api_spec.rb spec/integration/auto_complete_spec.rb spec/integration/key_value_querying_spec.rb spec/integration/ordinal_querying_spec.rb spec/integration/profile_querying_spec.rb spec/integration/relation_querying_spec.rb spec/integration/set_query_spec.rb spec/integration/string_querying_spec.rb spec/lib/database.rb spec/lib/matchers.rb spec/lib/mocks.rb spec/spec_helper.rb spec/unit/ast_spec.rb spec/unit/auto_complete_builder_spec.rb spec/unit/definition_spec.rb spec/unit/parser_spec.rb spec/unit/query_builder_spec.rb spec/unit/tokenizer_spec.rb tasks/github-gem.rake vendor/assets/images/spinner.gif vendor/assets/javascripts/scoped_search.js vendor/assets/stylesheets/scoped_search.scss)
|
37
37
|
s.test_files = %w(spec/integration/api_spec.rb spec/integration/auto_complete_spec.rb spec/integration/key_value_querying_spec.rb spec/integration/ordinal_querying_spec.rb spec/integration/profile_querying_spec.rb spec/integration/relation_querying_spec.rb spec/integration/set_query_spec.rb spec/integration/string_querying_spec.rb spec/unit/ast_spec.rb spec/unit/auto_complete_builder_spec.rb spec/unit/definition_spec.rb spec/unit/parser_spec.rb spec/unit/query_builder_spec.rb spec/unit/tokenizer_spec.rb)
|
38
38
|
end
|
@@ -56,6 +56,12 @@ describe ScopedSearch, "API" do
|
|
56
56
|
@class.search_for('query').class.should eql(ActiveRecord::Relation)
|
57
57
|
end
|
58
58
|
|
59
|
+
elsif ActiveRecord::VERSION::MAJOR == 4
|
60
|
+
|
61
|
+
it "should return a ActiveRecord::Relation instance" do
|
62
|
+
@class.search_for('query').class.superclass.should eql(ActiveRecord::Relation)
|
63
|
+
end
|
64
|
+
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
@@ -83,7 +89,6 @@ describe ScopedSearch, "API" do
|
|
83
89
|
it "should create a Field with a valid relation when using the underscore notation" do
|
84
90
|
ScopedSearch::Definition::Field.should_receive(:new).with(
|
85
91
|
instance_of(ScopedSearch::Definition), hash_including(:in => :bar, :on => :related_field))
|
86
|
-
|
87
92
|
Foo.searchable_on(:bar_related_field)
|
88
93
|
end
|
89
94
|
|
@@ -20,73 +20,85 @@ require "spec_helper"
|
|
20
20
|
ActiveRecord::Migration.create_table(:keys) { |t| t.string :name }
|
21
21
|
class ::Key < ActiveRecord::Base; has_many :facts; end
|
22
22
|
|
23
|
-
ActiveRecord::Migration.create_table(:facts) { |t| t.string :value; t.integer :key_id; t.integer :
|
24
|
-
class ::Fact < ActiveRecord::Base
|
23
|
+
ActiveRecord::Migration.create_table(:facts) { |t| t.string :value; t.integer :key_id; t.integer :item_id }
|
24
|
+
class ::Fact < ActiveRecord::Base
|
25
|
+
belongs_to :key
|
26
|
+
belongs_to :item, :class_name => "MyItem", :foreign_key => :item_id
|
27
|
+
end
|
25
28
|
|
26
29
|
# The class that will run the queries
|
27
|
-
ActiveRecord::Migration.create_table(:
|
28
|
-
class ::
|
30
|
+
ActiveRecord::Migration.create_table(:items) { |t| t.string :name }
|
31
|
+
class ::Item < ActiveRecord::Base
|
29
32
|
has_many :facts
|
30
33
|
has_many :keys, :through => :facts
|
31
34
|
|
32
35
|
scoped_search :in => :facts, :on => :value, :rename => :facts, :in_key => :keys, :on_key => :name, :complete_value => true
|
33
36
|
end
|
37
|
+
class ::MyItem < ::Item
|
38
|
+
end
|
34
39
|
|
35
40
|
@key1 = Key.create!(:name => 'color')
|
36
41
|
@key2 = Key.create!(:name => 'size')
|
37
42
|
|
38
|
-
@kv1 =
|
39
|
-
@kv2 =
|
43
|
+
@kv1 = MyItem.create!(:name => 'bar')
|
44
|
+
@kv2 = MyItem.create!(:name => 'barbary')
|
40
45
|
|
41
|
-
Fact.create!(:value => 'green', :key => @key1, :
|
42
|
-
Fact.create!(:value => 'gold' , :key => @key1, :
|
43
|
-
Fact.create!(:value => '5' , :key => @key2, :
|
46
|
+
Fact.create!(:value => 'green', :key => @key1, :item => @kv1)
|
47
|
+
Fact.create!(:value => 'gold' , :key => @key1, :item => @kv2)
|
48
|
+
Fact.create!(:value => '5' , :key => @key2, :item => @kv1)
|
44
49
|
|
45
50
|
end
|
46
51
|
|
47
52
|
after(:all) do
|
48
|
-
ScopedSearch::RSpec::Database.drop_model(
|
53
|
+
ScopedSearch::RSpec::Database.drop_model(Item)
|
49
54
|
ScopedSearch::RSpec::Database.drop_model(Fact)
|
50
55
|
ScopedSearch::RSpec::Database.drop_model(Key)
|
51
56
|
Object.send :remove_const, :Fact
|
52
57
|
Object.send :remove_const, :Key
|
53
|
-
Object.send :remove_const, :
|
58
|
+
Object.send :remove_const, :Item
|
59
|
+
Object.send :remove_const, :MyItem
|
54
60
|
end
|
55
61
|
|
56
62
|
it "should find all bars with a fact name color and fact value green" do
|
57
|
-
|
63
|
+
Item.search_for('facts.color = green').should have(1).items
|
58
64
|
end
|
59
65
|
|
60
|
-
|
61
|
-
|
66
|
+
it "should find all bars with a fact name color and fact value gold" do
|
67
|
+
Item.search_for('facts.color = gold').first.name.should eql('barbary')
|
62
68
|
end
|
63
69
|
|
64
70
|
it "should find all bars with a fact name size and fact value 5" do
|
65
|
-
|
71
|
+
Item.search_for('facts.size = 5').should have(1).items
|
66
72
|
end
|
67
73
|
|
68
74
|
it "should find all bars with a fact color green and fact size 5" do
|
69
|
-
|
75
|
+
Item.search_for('facts.color = green and facts.size = 5').should have(1).items
|
70
76
|
end
|
71
77
|
|
72
78
|
it "should find all bars with a fact color gold or green" do
|
73
|
-
|
79
|
+
Item.search_for('facts.color = gold or facts.color = green').should have(2).items
|
74
80
|
end
|
75
81
|
|
76
82
|
it "should find all bars that has size value" do
|
77
|
-
|
83
|
+
Item.search_for('has facts.size').should have(1).items
|
78
84
|
end
|
79
85
|
|
80
86
|
it "should find all bars that has color value" do
|
81
|
-
|
87
|
+
Item.search_for('has facts.color').should have(2).items
|
82
88
|
end
|
83
89
|
|
84
90
|
it "should complete facts names" do
|
85
|
-
|
91
|
+
Item.complete_for('facts.').should have(2).items
|
86
92
|
end
|
87
93
|
|
88
|
-
|
89
|
-
|
94
|
+
it "should complete values for fact name = color" do
|
95
|
+
Item.complete_for('facts.color = ').should have(2).items
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should find all bars with a fact name color and fact value gold of descendant class" do
|
99
|
+
if ActiveRecord::VERSION::MAJOR == 3
|
100
|
+
MyItem.search_for('facts.color = gold').first.name.should eql('barbary')
|
101
|
+
end
|
90
102
|
end
|
91
103
|
|
92
104
|
end
|
@@ -81,6 +81,16 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
81
81
|
lambda { @class.search_for('unindexed = 10') }.should raise_error(ScopedSearch::Exception)
|
82
82
|
end
|
83
83
|
|
84
|
+
# Before Ruby 2.0 if a string had forced encoding and a nil was extracted from it during
|
85
|
+
# any implicit type conversions to a string (+ or << operators) a TypeError would be raised.
|
86
|
+
# https://github.com/wvanbergen/scoped_search/issues/33 for more details
|
87
|
+
it "encoded string should not raise TypeError when querying non-indexed column without a value" do
|
88
|
+
if defined? Encoding
|
89
|
+
query = 'unindexed ='.force_encoding(Encoding::UTF_8).encode
|
90
|
+
lambda { @class.search_for(query) }.should_not raise_error(TypeError)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
84
94
|
it "should not return records for which the query matches unindex records" do
|
85
95
|
@class.search_for('= 10').should have(0).item
|
86
96
|
end
|
@@ -161,7 +171,8 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
161
171
|
end
|
162
172
|
|
163
173
|
end
|
164
|
-
|
174
|
+
|
175
|
+
context 'humanized date and time query' do
|
165
176
|
|
166
177
|
before(:all) do
|
167
178
|
@curent_record = @class.create!(:timestamp => Time.current, :date => Date.current)
|
@@ -213,7 +224,7 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
213
224
|
|
214
225
|
end
|
215
226
|
|
216
|
-
|
227
|
+
context 'querying bitwise fields' do
|
217
228
|
|
218
229
|
before(:all) do
|
219
230
|
@foo = ScopedSearch::RSpec::Database.create_model(:int => :integer) do |klass|
|
@@ -207,11 +207,8 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
207
207
|
end
|
208
208
|
|
209
209
|
it "resetting order when selecting distinct values" do
|
210
|
-
distinct_search =
|
210
|
+
distinct_search =
|
211
211
|
@class.search_for('', :order => '').all(:select => 'DISTINCT(explicit)')
|
212
|
-
else
|
213
|
-
@class.search_for('', :order => '').select(:explicit).uniq
|
214
|
-
end
|
215
212
|
|
216
213
|
Set.new(distinct_search.map(&:explicit)).should == Set['baz', nil]
|
217
214
|
end
|
data/tasks/github-gem.rake
CHANGED
@@ -122,8 +122,8 @@ module GithubGem
|
|
122
122
|
task(:check_not_diverged => :fetch_origin) { check_not_diverged_task }
|
123
123
|
|
124
124
|
checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
|
125
|
-
checks.unshift('spec:basic') if has_specs?
|
126
|
-
checks.unshift('test:basic') if has_tests?
|
125
|
+
checks.unshift('spec:basic') if has_specs? && !skip_tests?
|
126
|
+
checks.unshift('test:basic') if has_tests? && !skip_tests?
|
127
127
|
# checks.push << [:check_rubyforge] if gemspec.rubyforge_project
|
128
128
|
|
129
129
|
desc "Perform all checks that would occur before a release"
|
@@ -278,6 +278,10 @@ module GithubGem
|
|
278
278
|
|
279
279
|
private
|
280
280
|
|
281
|
+
def skip_tests?
|
282
|
+
!!ENV['SKIP_TESTS']
|
283
|
+
end
|
284
|
+
|
281
285
|
# Checks whether this project has any RSpec files
|
282
286
|
def has_specs?
|
283
287
|
FileList[spec_pattern].any?
|
metadata
CHANGED
@@ -1,87 +1,93 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: scoped_search
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.5.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 4
|
9
|
-
- 1
|
10
|
-
version: 2.4.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Amos Benari
|
14
9
|
- Willem van Bergen
|
15
10
|
- Wes Hays
|
16
11
|
autorequire:
|
17
12
|
bindir: bin
|
18
13
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Dependency
|
23
|
-
prerelease: false
|
14
|
+
date: 2013-03-29 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
24
17
|
name: activerecord
|
25
|
-
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
26
19
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 11
|
31
|
-
segments:
|
32
|
-
- 2
|
33
|
-
- 1
|
34
|
-
- 0
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
35
23
|
version: 2.1.0
|
36
|
-
requirement: *id001
|
37
24
|
type: :runtime
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
25
|
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ! '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 2.1.0
|
32
|
+
- !ruby/object:Gem::Dependency
|
40
33
|
name: rspec
|
41
|
-
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
42
35
|
none: false
|
43
|
-
requirements:
|
36
|
+
requirements:
|
44
37
|
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
segments:
|
48
|
-
- 2
|
49
|
-
- 0
|
50
|
-
version: "2.0"
|
51
|
-
requirement: *id002
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
52
40
|
type: :development
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
41
|
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
- !ruby/object:Gem::Dependency
|
55
49
|
name: rake
|
56
|
-
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
57
51
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
segments:
|
63
|
-
- 0
|
64
|
-
version: "0"
|
65
|
-
requirement: *id003
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
66
56
|
type: :development
|
67
|
-
|
68
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
description: ! " Scoped search makes it easy to search your ActiveRecord-based
|
65
|
+
models.\n \n It will create a named scope :search_for that can be called with
|
66
|
+
a query string. It will build an SQL query using\n the provided query string
|
67
|
+
and a definition that specifies on what fields to search. Because the functionality
|
68
|
+
is\n built on named_scope, the result of the search_for call can be used like
|
69
|
+
any other named_scope, so it can be\n chained with another scope or combined
|
70
|
+
with will_paginate.\n \n Because it uses standard SQL, it does not require
|
71
|
+
any setup, indexers or daemons. This makes scoped_search\n suitable to quickly
|
72
|
+
add basic search functionality to your application with little hassle. On the other
|
73
|
+
hand,\n it may not be the best choice if it is going to be used on very large
|
74
|
+
datasets or by a large user base.\n"
|
75
|
+
email:
|
69
76
|
- abenari@redhat.com
|
70
77
|
- willem@railsdoctors.com
|
71
78
|
- weshays@gbdev.com
|
72
79
|
executables: []
|
73
|
-
|
74
80
|
extensions: []
|
75
|
-
|
76
|
-
extra_rdoc_files:
|
81
|
+
extra_rdoc_files:
|
77
82
|
- README.rdoc
|
78
|
-
files:
|
83
|
+
files:
|
79
84
|
- .gitignore
|
80
85
|
- .infinity_test
|
81
86
|
- .travis.yml
|
82
87
|
- Gemfile
|
83
88
|
- Gemfile.activerecord2
|
84
89
|
- Gemfile.activerecord3
|
90
|
+
- Gemfile.activerecord4
|
85
91
|
- LICENSE
|
86
92
|
- README.rdoc
|
87
93
|
- Rakefile
|
@@ -123,43 +129,42 @@ files:
|
|
123
129
|
- vendor/assets/stylesheets/scoped_search.scss
|
124
130
|
homepage: http://github.com/wvanbergen/scoped_search/wiki
|
125
131
|
licenses: []
|
126
|
-
|
127
132
|
post_install_message:
|
128
|
-
rdoc_options:
|
133
|
+
rdoc_options:
|
129
134
|
- --title
|
130
135
|
- scoped_search
|
131
136
|
- --main
|
132
137
|
- README.rdoc
|
133
138
|
- --line-numbers
|
134
139
|
- --inline-source
|
135
|
-
require_paths:
|
140
|
+
require_paths:
|
136
141
|
- lib
|
137
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
143
|
none: false
|
139
|
-
requirements:
|
140
|
-
- -
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
|
143
|
-
segments:
|
144
|
+
requirements:
|
145
|
+
- - ! '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
segments:
|
144
149
|
- 0
|
145
|
-
|
146
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
hash: 3717190913219406659
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
152
|
none: false
|
148
|
-
requirements:
|
149
|
-
- -
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
|
152
|
-
segments:
|
153
|
+
requirements:
|
154
|
+
- - ! '>='
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
segments:
|
153
158
|
- 0
|
154
|
-
|
159
|
+
hash: 3717190913219406659
|
155
160
|
requirements: []
|
156
|
-
|
157
161
|
rubyforge_project:
|
158
162
|
rubygems_version: 1.8.24
|
159
163
|
signing_key:
|
160
164
|
specification_version: 3
|
161
|
-
summary: Easily search you ActiveRecord models with a simple query language using
|
162
|
-
|
165
|
+
summary: Easily search you ActiveRecord models with a simple query language using
|
166
|
+
a named scope.
|
167
|
+
test_files:
|
163
168
|
- spec/integration/api_spec.rb
|
164
169
|
- spec/integration/auto_complete_spec.rb
|
165
170
|
- spec/integration/key_value_querying_spec.rb
|