dusen 0.5.1 → 0.5.2

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/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