dusen 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/dusen/parser.rb CHANGED
@@ -5,7 +5,7 @@ module Dusen
5
5
 
6
6
  WESTERNISH_WORD_CHARACTER = '\\w\\-\\.;@_ÄÖÜäöüß' # this is wrong on so many levels
7
7
  TEXT_QUERY = /(?:(\-)?"([^"]+)"|(\-)?([#{WESTERNISH_WORD_CHARACTER}]+))/
8
- FIELD_QUERY = /(\w+)\:#{TEXT_QUERY}/
8
+ FIELD_QUERY = /(\-)?(\w+)\:#{TEXT_QUERY}/
9
9
 
10
10
  def self.parse(query_string)
11
11
  query_string = query_string.dup # we are going to delete substrings in-place
@@ -26,9 +26,9 @@ module Dusen
26
26
 
27
27
  def self.extract_field_query_tokens(query_string, query)
28
28
  while query_string.sub!(FIELD_QUERY, '')
29
- field = $1
30
- value = "#{$3}#{$5}"
31
- exclude = "#{$2}#{$4}" == "-"
29
+ field = $2
30
+ value = "#{$4}#{$6}"
31
+ exclude = "#{$1}" == "-"
32
32
  options = { :field => field, :value => value, :exclude => exclude }
33
33
  query << Token.new(options)
34
34
  end
data/lib/dusen/syntax.rb CHANGED
@@ -64,20 +64,31 @@ module Dusen
64
64
  def build_exclude_scope(root_scope, exclude_query)
65
65
  root_scope_without_conditions = root_scope.except(:where)
66
66
  exclude_scope = find_parsed_query(root_scope_without_conditions, exclude_query)
67
- exclude_scope_conditions = exclude_scope.where_values.reduce(:and)
67
+ exclude_scope_conditions = concatenate_where_values(exclude_scope.where_values)
68
68
  if exclude_scope_conditions.present?
69
- # where_values.reduce(:and) returns a string if only one where_value given
70
- # and a Arel::Node for more than one where_value
71
- unless exclude_scope_conditions.is_a?(String)
72
- exclude_scope_conditions = exclude_scope_conditions.to_sql
73
- end
74
69
  inverted_sql = "NOT COALESCE (" + exclude_scope_conditions + ",0)"
75
70
  exclude_scope.except(:where).where(inverted_sql)
76
71
  else
77
- # we cannot build an inverted scope if no where-conditions are present
72
+ # we cannot build an inverted scope without where-conditions
78
73
  root_scope
79
74
  end
80
75
  end
81
76
 
77
+ def concatenate_where_values(where_values)
78
+ if where_values.any?
79
+ if where_values[0].is_a?(String)
80
+ first = where_values.shift
81
+ where = where_values.reduce(first) do |result, value|
82
+ result << " AND " << value
83
+ end
84
+ where
85
+ else
86
+ # where_values are AREL-Nodes
87
+ where = where_values.reduce(:and)
88
+ where.to_sql
89
+ end
90
+ end
91
+ end
92
+
82
93
  end
83
94
  end
data/lib/dusen/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Dusen
4
- VERSION = '0.5.1'
4
+ VERSION = '0.5.2'
5
5
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- dusen (0.5)
4
+ dusen (0.5.1)
5
5
  activerecord (>= 3.0)
6
6
  edge_rider (>= 0.2.5)
7
7
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- dusen (0.5)
4
+ dusen (0.5.1)
5
5
  activerecord (>= 3.0)
6
6
  edge_rider (>= 0.2.5)
7
7
 
@@ -23,6 +23,12 @@ module User
23
23
  scope.scoped(:conditions => { :role => role })
24
24
  end
25
25
 
26
+ search_by :name_and_city_regex do |scope, regex|
27
+ #Example for regexes that need to be and'ed together by syntax#build_exclude_scope
28
+ first = scope.where("users_with_fulltext.name REGEXP ?", regex)
29
+ second = scope.where("users_with_fulltext.city REGEXP ?", regex)
30
+ first.merge(second)
31
+ end
26
32
  end
27
33
 
28
34
  search_text do
@@ -27,6 +27,13 @@ module User
27
27
  scope.scoped(:conditions => { :role => role })
28
28
  end
29
29
 
30
+ search_by :name_and_city_regex do |scope, regex|
31
+ #Example for regexes that need to be and'ed together by syntax#build_exclude_scope
32
+ first = scope.where("users_without_fulltext.name REGEXP ?", regex)
33
+ second = scope.where("users_without_fulltext.city REGEXP ?", regex)
34
+ first.merge(second)
35
+ end
36
+
30
37
  end
31
38
 
32
39
  end
@@ -98,7 +98,7 @@ shared_examples_for 'model with search syntax' do
98
98
  match = subject.create!(:name => 'Abraham', :city => 'Foohausen')
99
99
  no_match = subject.create!(:name => 'Abraham', :city => 'Barhausen')
100
100
  no_match2 = subject.create!(:name => 'Absolutly no match')
101
- subject.search('Abraham city:-Barhausen').to_a.should == [match]
101
+ subject.search('Abraham -city:Barhausen').to_a.should == [match]
102
102
  end
103
103
 
104
104
  it 'should work if the query only contains excluded words' do
@@ -116,7 +116,7 @@ shared_examples_for 'model with search syntax' do
116
116
  it 'should work if the query only contains excluded qualified fields' do
117
117
  match = subject.create!(:name => 'Abraham', :city => 'Foohausen')
118
118
  no_match = subject.create!(:name => 'Abraham', :city => 'Barhausen')
119
- subject.search('city:-Barhausen').to_a.should == [match]
119
+ subject.search('-city:Barhausen').to_a.should == [match]
120
120
  end
121
121
 
122
122
  it 'respects an existing scope chain when there are only excluded tokens (bugfix)' do
@@ -132,12 +132,18 @@ shared_examples_for 'model with search syntax' do
132
132
  subject.search('Sunny -Power').to_a.should == [match]
133
133
  end
134
134
 
135
- it 'should work if search_by contains a join' do
135
+ it 'should work if search_by contains a join (bugfix)' do
136
136
  category1 = Recipe::Category.create!(:name => 'Rice')
137
- category2= Recipe::Category.create!(:name => 'Barbecue')
137
+ category2 = Recipe::Category.create!(:name => 'Barbecue')
138
138
  match = Recipe.create!(:name => 'Martini Chicken', :category => category1)
139
139
  no_match = Recipe.create!(:name => 'Barbecue Chicken', :category => category2)
140
- Recipe.search('category:-Barbecue').to_a.should == [match]
140
+ Recipe.search('Chicken -category:Barbecue').to_a.should == [match]
141
+ end
142
+
143
+ it 'should work when search_by uses SQL-Regexes which need to be "and"ed together by syntax#build_exclude_scope (bugfix)' do
144
+ match = subject.create!(:name => 'Sunny Flower', :city => "Flower")
145
+ no_match = subject.create!(:name => 'Sunny Power', :city => "Power")
146
+ subject.search('-name_and_city_regex:Power').to_a.should == [match]
141
147
  end
142
148
 
143
149
  end
@@ -166,7 +172,7 @@ shared_examples_for 'model with search syntax' do
166
172
  end
167
173
 
168
174
  it 'should be callable multiple times, appending additional syntax' do
169
- subject.search_syntax.fields.keys.should =~ ['text', 'email', 'city', 'role']
175
+ subject.search_syntax.fields.keys.should =~ ['text', 'email', 'city', 'role', 'name_and_city_regex']
170
176
  end
171
177
 
172
178
  end
metadata CHANGED
@@ -1,52 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: dusen
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 2
10
+ version: 0.5.2
5
11
  platform: ruby
6
- authors:
12
+ authors:
7
13
  - Henning Koch
8
14
  autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
- date: 2015-04-01 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2015-04-02 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
14
22
  name: activerecord
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '3.0'
20
- type: :runtime
21
23
  prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '3.0'
27
- - !ruby/object:Gem::Dependency
28
- name: edge_rider
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
31
27
  - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 0.2.5
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ version: "3.0"
34
34
  type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: edge_rider
35
38
  prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
38
42
  - - ">="
39
- - !ruby/object:Gem::Version
43
+ - !ruby/object:Gem::Version
44
+ hash: 29
45
+ segments:
46
+ - 0
47
+ - 2
48
+ - 5
40
49
  version: 0.2.5
50
+ type: :runtime
51
+ version_requirements: *id002
41
52
  description: Comprehensive full text search for ActiveRecord and MySQL
42
53
  email: henning.koch@makandra.de
43
54
  executables: []
55
+
44
56
  extensions: []
57
+
45
58
  extra_rdoc_files: []
46
- files:
47
- - ".gitignore"
48
- - ".ruby-version"
49
- - ".travis.yml"
59
+
60
+ files:
61
+ - .gitignore
62
+ - .ruby-version
63
+ - .travis.yml
50
64
  - LICENSE
51
65
  - README.md
52
66
  - Rakefile
@@ -124,28 +138,39 @@ files:
124
138
  - spec/shared/spec/dusen/parser_spec.rb
125
139
  - spec/shared/spec/dusen/query_spec.rb
126
140
  - spec/shared/spec/dusen/util_spec.rb
141
+ has_rdoc: true
127
142
  homepage: https://github.com/makandra/dusen
128
- licenses:
143
+ licenses:
129
144
  - MIT
130
- metadata: {}
131
145
  post_install_message:
132
146
  rdoc_options: []
133
- require_paths:
147
+
148
+ require_paths:
134
149
  - lib
135
- required_ruby_version: !ruby/object:Gem::Requirement
136
- requirements:
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
137
153
  - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
- required_rubygems_version: !ruby/object:Gem::Requirement
141
- requirements:
154
+ - !ruby/object:Gem::Version
155
+ hash: 3
156
+ segments:
157
+ - 0
158
+ version: "0"
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
142
162
  - - ">="
143
- - !ruby/object:Gem::Version
144
- version: '0'
163
+ - !ruby/object:Gem::Version
164
+ hash: 3
165
+ segments:
166
+ - 0
167
+ version: "0"
145
168
  requirements: []
169
+
146
170
  rubyforge_project:
147
- rubygems_version: 2.2.2
171
+ rubygems_version: 1.3.9.5
148
172
  signing_key:
149
- specification_version: 4
173
+ specification_version: 3
150
174
  summary: Comprehensive full text search for ActiveRecord and MySQL
151
175
  test_files: []
176
+
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 28383a66956bb8c3378bb0033387475fca743a53
4
- data.tar.gz: 4b5dc66350c2c31cd070307a54b60296f8ed8dee
5
- SHA512:
6
- metadata.gz: 76ead2fcf071262ae45ea9d710c51150a668d6639752fa6750c4fa7908a11cd562eddb166be657d11d72dfe21009dcb8bcb16740ea29d39c2662cc871efc9936
7
- data.tar.gz: a93bc1087afd7ddb94fc955dc0f0323d1fb8c581503c7659615b5738158fe70779eead5cf958ef3c5a7bea69b46f7e15a20278a3ff68652333c531d4683c12fd