scoped_search 2.4.1 → 2.5.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/.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
|