pg_search 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,66 @@
1
+ = PgSearch
2
+
3
+ == 0.3.3
4
+
5
+ * Backport array_agg() aggregate function to PostgreSQL 8.3 and earlier.
6
+ This fixes :associated_against searches.
7
+
8
+ * Backport unnest() function to PostgreSQL 8.3 and earlier.
9
+ This fixes {:using => :dmetaphone} searches.
10
+
11
+ * Disable {:using => {:tsearch => {:prefix => true}}} in PostgreSQL 8.3 and earlier.
12
+
13
+ == 0.3.2
14
+
15
+ * Fix :prefix search in PostgreSQL 8.x
16
+
17
+ * Disable {:ignoring => :accents} in PostgreSQL 8.x
18
+
19
+ == 0.3.1
20
+
21
+ * Fix syntax error in generated dmetaphone migration. (Max De Marzi)
22
+
23
+ == 0.3
24
+
25
+ * Drop Active Record 2.0 support.
26
+
27
+ * Add PgSearch.multisearch for cross-model searching.
28
+
29
+ * Fix PostgreSQL warnings about truncated identifiers
30
+
31
+ * Support specifying a method of rank normalisation when using tsearch. (Arthur Gunn)
32
+
33
+ * Add :any_word option to :tsearch which uses OR between query terms instead of AND. (Fernando Espinosa)
34
+
35
+ == 0.2
36
+
37
+ * Set dictionary to :simple by default for :tsearch. Before it was unset,
38
+ which would fall back to PostgreSQL's default dictionary, usually
39
+ "english".
40
+
41
+ * Fix a bug with search strings containing a colon ":"
42
+
43
+ * Improve performance of :associated_against by only doing one INNER JOIN per
44
+ association
45
+
46
+ == 0.1.1
47
+
48
+ * Fix a bug with dmetaphone searches containing " w " (which dmetaphone maps
49
+ to an empty string)
50
+
51
+ == 0.1
52
+
53
+ * Change API to {:ignoring => :accents} from {:normalizing => :diacritics}
54
+
55
+ * Improve documentation
56
+
57
+ * Fix bug where :associated_against would not work without an :against
58
+ present
59
+
60
+ == 0.0.2
61
+
62
+ * Fix gem ownership.
63
+
64
+ == 0.0.1
65
+
66
+ * Initial release.
data/README.rdoc CHANGED
@@ -181,7 +181,15 @@ Important: The returned hash must include a :query key. Its value does not neces
181
181
 
182
182
  ==== Searching through associations
183
183
 
184
- You can pass a Hash into the :associated_against option to search columns on other models. The keys are the names of the associations and the value works just like an :against option for the other model.
184
+ It is possible to search columns on associated models. Note that if you do this, it will be impossible to speed up searches with database indexes. However, it is supported as a quick way to try out cross-model searching.
185
+
186
+ In PostgreSQL 8.3 and earlier, you must install a utility function into your database. To generate a migration for this, run:
187
+
188
+ $ rake pg_search:migration:associated_against
189
+
190
+ This migration is safe to run against newer versions of PostgreSQL as well. It will essentially do nothing.
191
+
192
+ You can pass a Hash into the :associated_against option to set up searching through associations. The keys are the names of the associations and the value works just like an :against option for the other model. Right now, searching deeper than one association away is not supported. You can work around this by setting up a series of :through associations to point all the way through.
185
193
 
186
194
  class Cracker < ActiveRecord::Base
187
195
  has_many :cheeses
@@ -267,7 +275,7 @@ You can also pass the weights in as an array of arrays, or any other structure t
267
275
  ]
268
276
  end
269
277
 
270
- ===== :prefix
278
+ ===== :prefix (PostgreSQL 8.4 and newer only)
271
279
 
272
280
  PostgreSQL's full text search matches on whole words by default. If you want to search for partial words, however, you can set :prefix to true. Since this is a :tsearch-specific option, you should pass it to :tsearch directly, as shown in the following example.
273
281
 
@@ -414,7 +422,7 @@ Trigram support is currently available as part of the {pg_trgm contrib package}[
414
422
 
415
423
  Website.kinda_spelled_like("Yahoo!") # => [yahooo, yohoo]
416
424
 
417
- === Ignoring accent marks (PostgreSQL 9.0 and above only)
425
+ === Ignoring accent marks (PostgreSQL 9.0 and newer only)
418
426
 
419
427
  Most of the time you will want to ignore accent marks when searching. This makes it possible to find words like "piñata" when searching with the query "pinata". If you set a pg_search_scope to ignore accents, it will ignore accents in both the searchable text and the query terms.
420
428
 
@@ -11,6 +11,12 @@ module PgSearch
11
11
  @model = model
12
12
  @columns = columns
13
13
  @normalizer = normalizer
14
+
15
+ if @options[:prefix] && @model.connection.send(:postgresql_version) < 80400
16
+ raise PgSearch::NotSupportedForPostgresqlVersion.new(<<-MESSAGE.gsub /^\s*/, '')
17
+ Sorry, {:using => {:tsearch => {:prefix => true}}} only works in PostgreSQL 8.4 and above.")
18
+ MESSAGE
19
+ end
14
20
  end
15
21
 
16
22
  def conditions
@@ -8,7 +8,7 @@ module PgSearch
8
8
  normalized_sql = original_sql
9
9
  if @config.ignore.include?(:accents)
10
10
  if @config.postgresql_version < 90000
11
- raise PgSearch::NotSupportedForPostgresqlVersion.new(<<-MESSAGE)
11
+ raise PgSearch::NotSupportedForPostgresqlVersion.new(<<-MESSAGE.gsub /^\s*/, '')
12
12
  Sorry, {:ignoring => :accents} only works in PostgreSQL 9.0 and above.
13
13
  #{@config.inspect}
14
14
  MESSAGE
@@ -48,11 +48,19 @@ end
48
48
  dmetaphone_sql = File.read(File.join(File.dirname(__FILE__), '..', '..', 'sql', 'dmetaphone.sql')).chomp
49
49
  uninstall_dmetaphone_sql = File.read(File.join(File.dirname(__FILE__), '..', '..', 'sql', 'uninstall_dmetaphone.sql')).chomp
50
50
 
51
+ unnest_sql = File.read(File.join(File.dirname(__FILE__), '..', '..', 'sql', 'unnest.sql')).chomp
52
+ uninstall_unnest_sql = File.read(File.join(File.dirname(__FILE__), '..', '..', 'sql', 'uninstall_unnest.sql')).chomp
53
+
51
54
  File.open(Rails.root + 'db' + 'migrate' + filename, 'wb') do |migration_file|
52
55
  migration_file.puts <<-RUBY
53
56
  class AddPgSearchDmetaphoneSupportFunctions < ActiveRecord::Migration
54
57
  def self.up
55
58
  say_with_time("Adding support functions for pg_search :dmetaphone") do
59
+ if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
60
+ ActiveRecord::Base.connection.execute(<<-SQL)
61
+ #{unnest_sql}
62
+ SQL
63
+ end
56
64
  ActiveRecord::Base.connection.execute(<<-SQL)
57
65
  #{dmetaphone_sql}
58
66
  SQL
@@ -64,6 +72,46 @@ class AddPgSearchDmetaphoneSupportFunctions < ActiveRecord::Migration
64
72
  ActiveRecord::Base.connection.execute(<<-SQL)
65
73
  #{uninstall_dmetaphone_sql}
66
74
  SQL
75
+ if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
76
+ ActiveRecord::Base.connection.execute(<<-SQL)
77
+ #{uninstall_unnest_sql}
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ RUBY
84
+ end
85
+ end
86
+
87
+ desc "Generate migration to add support functions for :associated_against in PostgreSQL 8.3 and earlier"
88
+ task :associated_against do
89
+ now = Time.now.utc
90
+ filename = "#{now.strftime('%Y%m%d%H%M%S')}_add_pg_search_associated_against_support_functions.rb"
91
+
92
+ array_agg_sql = File.read(File.join(File.dirname(__FILE__), '..', '..', 'sql', 'array_agg.sql')).chomp
93
+ uninstall_array_agg_sql = File.read(File.join(File.dirname(__FILE__), '..', '..', 'sql', 'uninstall_array_agg.sql')).chomp
94
+
95
+ File.open(Rails.root + 'db' + 'migrate' + filename, 'wb') do |migration_file|
96
+ migration_file.puts <<-RUBY
97
+ class AddPgSearchAssociatedAgainstSupportFunctions < ActiveRecord::Migration
98
+ def self.up
99
+ say_with_time("Adding support functions for pg_search :associated_against") do
100
+ if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
101
+ ActiveRecord::Base.connection.execute(<<-SQL)
102
+ #{array_agg_sql}
103
+ SQL
104
+ end
105
+ end
106
+ end
107
+
108
+ def self.down
109
+ say_with_time("Dropping support functions for pg_search :associated_against") do
110
+ if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
111
+ ActiveRecord::Base.connection.execute(<<-SQL)
112
+ #{uninstall_array_agg_sql}
113
+ SQL
114
+ end
67
115
  end
68
116
  end
69
117
  end
@@ -1,3 +1,3 @@
1
1
  module PgSearch
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
@@ -316,36 +316,44 @@ describe "an ActiveRecord model which includes PgSearch" do
316
316
  end
317
317
 
318
318
  context "using tsearch" do
319
- context "with :prefix => true" do
320
- before do
321
- ModelWithPgSearch.class_eval do
322
- pg_search_scope :search_title_with_prefixes,
323
- :against => :title,
324
- :using => {
325
- :tsearch => {:prefix => true}
326
- }
327
- end
319
+ before do
320
+ ModelWithPgSearch.class_eval do
321
+ pg_search_scope :search_title_with_prefixes,
322
+ :against => :title,
323
+ :using => {
324
+ :tsearch => {:prefix => true}
325
+ }
328
326
  end
327
+ end
329
328
 
330
- it "returns rows that match the query and that are prefixed by the query" do
331
- included = ModelWithPgSearch.create!(:title => 'prefix')
332
- excluded = ModelWithPgSearch.create!(:title => 'postfix')
333
-
334
- results = ModelWithPgSearch.search_title_with_prefixes("pre")
335
- results.should == [included]
336
- results.should_not include(excluded)
329
+ if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
330
+ it "is unsupported in PostgreSQL 8.3 and earlier" do
331
+ lambda do
332
+ ModelWithPgSearch.search_title_with_prefixes("abcd\303\251f")
333
+ end.should raise_exception(PgSearch::NotSupportedForPostgresqlVersion)
337
334
  end
335
+ else
336
+ context "with :prefix => true" do
337
+ it "returns rows that match the query and that are prefixed by the query" do
338
+ included = ModelWithPgSearch.create!(:title => 'prefix')
339
+ excluded = ModelWithPgSearch.create!(:title => 'postfix')
340
+
341
+ results = ModelWithPgSearch.search_title_with_prefixes("pre")
342
+ results.should == [included]
343
+ results.should_not include(excluded)
344
+ end
338
345
 
339
- it "returns rows that match the query when the query has a hyphen" do
340
- included = [
341
- ModelWithPgSearch.create!(:title => 'foo bar'),
342
- ModelWithPgSearch.create!(:title => 'foo-bar')
343
- ]
344
- excluded = ModelWithPgSearch.create!(:title => 'baz quux')
346
+ it "returns rows that match the query when the query has a hyphen" do
347
+ included = [
348
+ ModelWithPgSearch.create!(:title => 'foo bar'),
349
+ ModelWithPgSearch.create!(:title => 'foo-bar')
350
+ ]
351
+ excluded = ModelWithPgSearch.create!(:title => 'baz quux')
345
352
 
346
- results = ModelWithPgSearch.search_title_with_prefixes("foo-bar")
347
- results.should =~ included
348
- results.should_not include(excluded)
353
+ results = ModelWithPgSearch.search_title_with_prefixes("foo-bar")
354
+ results.should =~ included
355
+ results.should_not include(excluded)
356
+ end
349
357
  end
350
358
  end
351
359
 
@@ -536,7 +544,7 @@ describe "an ActiveRecord model which includes PgSearch" do
536
544
  pg_search_scope :with_tsearch,
537
545
  :against => :title,
538
546
  :using => [
539
- [:tsearch, {:prefix => true}]
547
+ [:tsearch, {:dictionary => 'english'}]
540
548
  ]
541
549
 
542
550
  pg_search_scope :with_trigram, :against => :title, :using => :trigram
@@ -544,7 +552,7 @@ describe "an ActiveRecord model which includes PgSearch" do
544
552
  pg_search_scope :with_tsearch_and_trigram_using_array,
545
553
  :against => :title,
546
554
  :using => [
547
- [:tsearch, {:prefix => true}],
555
+ [:tsearch, {:dictionary => 'english'}],
548
556
  :trigram
549
557
  ]
550
558
 
@@ -561,7 +569,7 @@ describe "an ActiveRecord model which includes PgSearch" do
561
569
  ModelWithPgSearch.with_tsearch_and_trigram_using_array(trigram_query).should == [record]
562
570
 
563
571
  # matches tsearch only
564
- tsearch_query = "til"
572
+ tsearch_query = "tiles"
565
573
  ModelWithPgSearch.with_tsearch(tsearch_query).should include(record)
566
574
  ModelWithPgSearch.with_trigram(tsearch_query).should_not include(record)
567
575
  ModelWithPgSearch.with_tsearch_and_trigram_using_array(tsearch_query).should == [record]
data/spec/spec_helper.rb CHANGED
@@ -40,7 +40,17 @@ unless connection.send(:postgresql_version) < 90000
40
40
  end
41
41
  install_contrib_module_if_missing("fuzzystrmatch", "SELECT dmetaphone('foo')", "f")
42
42
 
43
- ActiveRecord::Base.connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'dmetaphone.sql')))
43
+ ActiveRecord::Base.connection.tap do |connection|
44
+ if connection.send(:postgresql_version) < 80400
45
+ unless connection.select_value("SELECT 1 FROM pg_catalog.pg_aggregate WHERE aggfnoid = 'array_agg'::REGPROC") == "1"
46
+ connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'array_agg.sql')))
47
+ end
48
+ connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'unnest.sql')))
49
+ end
50
+ connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'dmetaphone.sql')))
51
+ end
52
+
53
+
44
54
 
45
55
  require "with_model"
46
56
 
data/sql/array_agg.sql ADDED
@@ -0,0 +1,5 @@
1
+ CREATE AGGREGATE array_agg(anyelement) (
2
+ SFUNC=array_append,
3
+ STYPE=anyarray,
4
+ INITCOND='{}'
5
+ )
@@ -0,0 +1 @@
1
+ DROP AGGREGATE array_agg(anyelement);
@@ -0,0 +1 @@
1
+ DROP FUNCTION unnest(anyarray);
data/sql/unnest.sql ADDED
@@ -0,0 +1,8 @@
1
+ CREATE OR REPLACE FUNCTION unnest(anyarray)
2
+ RETURNS SETOF anyelement AS
3
+ $BODY$
4
+ SELECT $1[i] FROM
5
+ generate_series(array_lower($1,1),
6
+ array_upper($1,1)) i;
7
+ $BODY$
8
+ LANGUAGE 'sql' IMMUTABLE
metadata CHANGED
@@ -1,66 +1,52 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pg_search
3
- version: !ruby/object:Gem::Version
4
- hash: 23
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 3
9
- - 2
10
- version: 0.3.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Case Commons, LLC
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-10-18 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-22 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: activerecord
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70192130541140 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 5
29
- segments:
30
- - 3
31
- version: "3"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3'
32
22
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: activesupport
36
23
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70192130541140
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70192130540020 !ruby/object:Gem::Requirement
38
28
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 5
43
- segments:
44
- - 3
45
- version: "3"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
46
33
  type: :runtime
47
- version_requirements: *id002
48
- description: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's full text search
49
- email:
34
+ prerelease: false
35
+ version_requirements: *70192130540020
36
+ description: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's
37
+ full text search
38
+ email:
50
39
  - casecommons-dev@googlegroups.com
51
40
  executables: []
52
-
53
41
  extensions: []
54
-
55
42
  extra_rdoc_files: []
56
-
57
- files:
43
+ files:
58
44
  - .autotest
59
45
  - .gitignore
60
46
  - .rspec
61
47
  - .rvmrc
62
48
  - .travis.yml
63
- - CHANGELOG
49
+ - CHANGELOG.rdoc
64
50
  - Gemfile
65
51
  - LICENSE
66
52
  - README.rdoc
@@ -90,42 +76,38 @@ files:
90
76
  - spec/pg_search/multisearchable_spec.rb
91
77
  - spec/pg_search_spec.rb
92
78
  - spec/spec_helper.rb
79
+ - sql/array_agg.sql
93
80
  - sql/dmetaphone.sql
81
+ - sql/uninstall_array_agg.sql
94
82
  - sql/uninstall_dmetaphone.sql
83
+ - sql/uninstall_unnest.sql
84
+ - sql/unnest.sql
95
85
  homepage: https://github.com/Casecommons/pg_search
96
86
  licenses: []
97
-
98
87
  post_install_message:
99
88
  rdoc_options: []
100
-
101
- require_paths:
89
+ require_paths:
102
90
  - lib
103
- required_ruby_version: !ruby/object:Gem::Requirement
91
+ required_ruby_version: !ruby/object:Gem::Requirement
104
92
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- hash: 3
109
- segments:
110
- - 0
111
- version: "0"
112
- required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
98
  none: false
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- hash: 3
118
- segments:
119
- - 0
120
- version: "0"
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
121
103
  requirements: []
122
-
123
104
  rubyforge_project:
124
- rubygems_version: 1.8.4
105
+ rubygems_version: 1.8.10
125
106
  signing_key:
126
107
  specification_version: 3
127
- summary: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's full text search
128
- test_files:
108
+ summary: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's
109
+ full text search
110
+ test_files:
129
111
  - spec/associations_spec.rb
130
112
  - spec/pg_search/document_spec.rb
131
113
  - spec/pg_search/multisearch_spec.rb
data/CHANGELOG DELETED
@@ -1,54 +0,0 @@
1
- ### 0.3.2
2
-
3
- * Fix :prefix search in PostgreSQL 8.x
4
-
5
- * Disable {:ignoring => :accents} in PostgreSQL 8.x
6
-
7
- ### 0.3.1
8
-
9
- * Fix syntax error in generated dmetaphone migration. (Max De Marzi)
10
-
11
- ### 0.3
12
-
13
- * Drop Active Record 2.0 support.
14
-
15
- * Add PgSearch.multisearch for cross-model searching.
16
-
17
- * Fix PostgreSQL warnings about truncated identifiers
18
-
19
- * Support specifying a method of rank normalisation when using tsearch. (Arthur Gunn)
20
-
21
- * Add :any_word option to :tsearch which uses OR between query terms instead of AND. (Fernando Espinosa)
22
-
23
- ### 0.2
24
-
25
- * Set dictionary to :simple by default for :tsearch. Before it was unset,
26
- which would fall back to PostgreSQL's default dictionary, usually
27
- "english".
28
-
29
- * Fix a bug with search strings containing a colon ":"
30
-
31
- * Improve performance of :associated_against by only doing one INNER JOIN per
32
- association
33
-
34
- ### 0.1.1
35
-
36
- * Fix a bug with dmetaphone searches containing " w " (which dmetaphone maps
37
- to an empty string)
38
-
39
- ### 0.1
40
-
41
- * Change API to {:ignoring => :accents} from {:normalizing => :diacritics}
42
-
43
- * Improve documentation
44
-
45
- * Fix bug where :associated_against would not work without an :against
46
- present
47
-
48
- ### 0.0.2
49
-
50
- * Fix gem ownership.
51
-
52
- ### 0.0.1
53
-
54
- * Initial release.