pg_search 0.3.3 → 0.3.4

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/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,11 @@
1
1
  = PgSearch
2
2
 
3
+ == 0.3.4
4
+
5
+ * Fix issue with {:using => {:tsearch => {:prefix => true}}} and hyphens.
6
+
7
+ * Get tests running against PostgreSQL 9.1 by using CREATE EXTENSION
8
+
3
9
  == 0.3.3
4
10
 
5
11
  * Backport array_agg() aggregate function to PostgreSQL 8.3 and earlier.
data/README.rdoc CHANGED
@@ -75,7 +75,7 @@ Two associations are built automatically. On the original record, there is a has
75
75
 
76
76
  ==== Searching in the global search index
77
77
 
78
- To fetch the PgSearch::Document entries for all of the records that match a given query, use PgSearch.multisearch.
78
+ To fetch the PgSearch::Document entries for all of the records that match a given query, use PgSearch.multisearch.
79
79
 
80
80
  odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
81
81
  rose = Flower.create!(:color => "Red")
@@ -93,6 +93,15 @@ PgSearch.multisearch returns an ActiveRecord::Relation, just like scopes do, so
93
93
  puts document.searchable.updated_at
94
94
  end
95
95
 
96
+ ==== Configuring multi-search
97
+
98
+ PgSearch.multisearch can be configured using the same options as `pg_search_scope` (explained in more detail below). Just set the PgSearch.multisearchable_options in an initializer:
99
+
100
+ PgSearch.multisearchable_options = {
101
+ :using => [:tsearch, :trigram],
102
+ :ignoring => :accents
103
+ }
104
+
96
105
  ==== Rebuilding search documents for a given class
97
106
 
98
107
  If you change the :against option on a class, add multisearchable to a class that already has records in the database, or remove multisearchable from a class in order to remove it from the index, you will find that the pg_search_documents table could become out-of-sync with the actual records in your other tables.
data/lib/pg_search.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  require "active_record"
2
2
  require "active_support/concern"
3
+ require "active_support/core_ext/module/attribute_accessors"
3
4
 
4
5
  module PgSearch
5
6
  extend ActiveSupport::Concern
6
7
 
8
+ mattr_accessor :multisearch_options
9
+ self.multisearch_options = {}
10
+
7
11
  module ClassMethods
8
12
  def pg_search_scope(name, options)
9
13
  self.scope(
@@ -26,8 +30,8 @@ module PgSearch
26
30
  end
27
31
 
28
32
  class << self
29
- def multisearch(query)
30
- PgSearch::Document.search(query)
33
+ def multisearch(*args)
34
+ PgSearch::Document.search(*args)
31
35
  end
32
36
 
33
37
  def disable_multisearch
@@ -8,7 +8,14 @@ module PgSearch
8
8
 
9
9
  before_validation :update_content
10
10
 
11
- pg_search_scope :search, :against => :content
11
+ pg_search_scope :search, lambda { |*args|
12
+ if PgSearch.multisearch_options.respond_to?(:call)
13
+ options = PgSearch.multisearch_options.call(*args)
14
+ else
15
+ options = PgSearch.multisearch_options.reverse_merge(:query => args.first)
16
+ end
17
+ options.reverse_merge(:against => :content)
18
+ }
12
19
 
13
20
  private
14
21
 
@@ -37,7 +37,7 @@ module PgSearch
37
37
  @columns.map { |column| column.to_sql }.join(" || ' ' || ")
38
38
  end
39
39
 
40
- DISALLOWED_TSQUERY_CHARACTERS = /['?\-\\:]/
40
+ DISALLOWED_TSQUERY_CHARACTERS = /['?\\:]/
41
41
 
42
42
  def tsquery_for_term(term)
43
43
  sanitized_term = term.gsub(DISALLOWED_TSQUERY_CHARACTERS, " ")
@@ -1,3 +1,3 @@
1
1
  module PgSearch
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  end
@@ -344,14 +344,11 @@ describe "an ActiveRecord model which includes PgSearch" do
344
344
  end
345
345
 
346
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')
347
+ included = ModelWithPgSearch.create!(:title => 'foo-bar')
348
+ excluded = ModelWithPgSearch.create!(:title => 'foo bar')
352
349
 
353
350
  results = ModelWithPgSearch.search_title_with_prefixes("foo-bar")
354
- results.should =~ included
351
+ results.should include(included)
355
352
  results.should_not include(excluded)
356
353
  end
357
354
  end
@@ -703,14 +700,77 @@ describe "an ActiveRecord model which includes PgSearch" do
703
700
  end
704
701
 
705
702
  describe ".multisearch" do
706
- subject { PgSearch.multisearch(query) }
707
- let(:query) { double(:query) }
708
- let(:relation) { double(:relation) }
709
- before do
710
- PgSearch::Document.should_receive(:search).with(query).and_return(relation)
703
+ with_table "pg_search_documents", {}, &DOCUMENTS_SCHEMA
704
+
705
+ describe "delegation to PgSearch::Document.search" do
706
+ subject { PgSearch.multisearch(query) }
707
+
708
+ let(:query) { double(:query) }
709
+ let(:relation) { double(:relation) }
710
+ before do
711
+ PgSearch::Document.should_receive(:search).with(query).and_return(relation)
712
+ end
713
+
714
+ it { should == relation }
715
+ end
716
+
717
+ context "with PgSearch.multisearch_options set to a Hash" do
718
+ before { PgSearch.stub(:multisearch_options).and_return({:using => :dmetaphone}) }
719
+ subject { PgSearch.multisearch(query).map(&:searchable) }
720
+
721
+ with_model :MultisearchableModel do
722
+ table do |t|
723
+ t.string :title
724
+ end
725
+ model do
726
+ include PgSearch
727
+ multisearchable :against => :title
728
+ end
729
+ end
730
+
731
+ let!(:soundalike_record) { MultisearchableModel.create!(:title => 'foning') }
732
+ let(:query) { "Phoning" }
733
+ it { should include(soundalike_record) }
711
734
  end
712
735
 
713
- it { should == relation }
736
+ context "with PgSearch.multisearch_options set to a Proc" do
737
+ subject { PgSearch.multisearch(query, soundalike).map(&:searchable) }
738
+
739
+ before do
740
+ PgSearch.stub(:multisearch_options).and_return do
741
+ lambda do |query, soundalike|
742
+ if soundalike
743
+ {:using => :dmetaphone, :query => query}
744
+ else
745
+ {:query => query}
746
+ end
747
+ end
748
+ end
749
+ end
750
+
751
+ with_model :MultisearchableModel do
752
+ table do |t|
753
+ t.string :title
754
+ end
755
+ model do
756
+ include PgSearch
757
+ multisearchable :against => :title
758
+ end
759
+ end
760
+
761
+ let!(:soundalike_record) { MultisearchableModel.create!(:title => 'foning') }
762
+ let(:query) { "Phoning" }
763
+
764
+ context "with soundalike true" do
765
+ let(:soundalike) { true }
766
+ it { should include(soundalike_record) }
767
+ end
768
+
769
+ context "with soundalike false" do
770
+ let(:soundalike) { false }
771
+ it { should_not include(soundalike_record) }
772
+ end
773
+ end
714
774
  end
715
775
 
716
776
  describe ".disable_multisearch" do
data/spec/spec_helper.rb CHANGED
@@ -7,7 +7,9 @@ begin
7
7
  :username => ('postgres' if ENV["TRAVIS"]),
8
8
  :min_messages => 'warning')
9
9
  connection = ActiveRecord::Base.connection
10
+ postgresql_version = connection.send(:postgresql_version)
10
11
  connection.execute("SELECT 1")
12
+ puts "postgresql_version = #{postgresql_version}"
11
13
  rescue PGError => e
12
14
  puts "-" * 80
13
15
  puts "Unable to connect to database. Please run:"
@@ -17,40 +19,40 @@ rescue PGError => e
17
19
  raise e
18
20
  end
19
21
 
20
- def install_contrib_module_if_missing(name, query, expected_result)
22
+ def install_extension_if_missing(name, query, expected_result)
21
23
  connection = ActiveRecord::Base.connection
22
24
  result = connection.select_value(query)
23
25
  raise "Unexpected output for #{query}: #{result.inspect}" unless result.downcase == expected_result.downcase
24
26
  rescue => e
25
27
  begin
26
- share_path = `pg_config --sharedir`.strip
27
- ActiveRecord::Base.connection.execute File.read(File.join(share_path, 'contrib', "#{name}.sql"))
28
- puts $!.message
29
- rescue
28
+ if postgresql_version >= 90100
29
+ ActiveRecord::Base.connection.execute "CREATE EXTENSION #{name};"
30
+ else
31
+ share_path = `pg_config --sharedir`.strip
32
+ ActiveRecord::Base.connection.execute File.read(File.join(share_path, 'contrib', "#{name}.sql"))
33
+ puts $!.message
34
+ end
35
+ rescue => e2
30
36
  puts "-" * 80
31
37
  puts "Please install the #{name} contrib module"
32
38
  puts "-" * 80
33
- raise e
39
+ raise e2
34
40
  end
35
41
  end
36
42
 
37
- install_contrib_module_if_missing("pg_trgm", "SELECT 'abcdef' % 'cdef'", "t")
38
- unless connection.send(:postgresql_version) < 90000
39
- install_contrib_module_if_missing("unaccent", "SELECT unaccent('foo')", "foo")
43
+ install_extension_if_missing("pg_trgm", "SELECT 'abcdef' % 'cdef'", "t")
44
+ unless postgresql_version < 90000
45
+ install_extension_if_missing("unaccent", "SELECT unaccent('foo')", "foo")
40
46
  end
41
- install_contrib_module_if_missing("fuzzystrmatch", "SELECT dmetaphone('foo')", "f")
47
+ install_extension_if_missing("fuzzystrmatch", "SELECT dmetaphone('foo')", "f")
42
48
 
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
+ if postgresql_version < 80400
50
+ unless connection.select_value("SELECT 1 FROM pg_catalog.pg_aggregate WHERE aggfnoid = 'array_agg'::REGPROC") == "1"
51
+ connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'array_agg.sql')))
49
52
  end
50
- connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'dmetaphone.sql')))
53
+ connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'unnest.sql')))
51
54
  end
52
-
53
-
55
+ connection.execute(File.read(File.join(File.dirname(__FILE__), '..', 'sql', 'dmetaphone.sql')))
54
56
 
55
57
  require "with_model"
56
58
 
metadata CHANGED
@@ -1,46 +1,60 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pg_search
3
- version: !ruby/object:Gem::Version
4
- version: 0.3.3
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 4
10
+ version: 0.3.4
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Case Commons, LLC
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2011-10-22 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2011-11-25 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: activerecord
16
- requirement: &70192130541140 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '3'
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 5
29
+ segments:
30
+ - 3
31
+ version: "3"
22
32
  type: :runtime
23
- prerelease: false
24
- version_requirements: *70192130541140
25
- - !ruby/object:Gem::Dependency
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
26
35
  name: activesupport
27
- requirement: &70192130540020 !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
28
38
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '3'
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 5
43
+ segments:
44
+ - 3
45
+ version: "3"
33
46
  type: :runtime
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:
47
+ version_requirements: *id002
48
+ description: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's full text search
49
+ email:
39
50
  - casecommons-dev@googlegroups.com
40
51
  executables: []
52
+
41
53
  extensions: []
54
+
42
55
  extra_rdoc_files: []
43
- files:
56
+
57
+ files:
44
58
  - .autotest
45
59
  - .gitignore
46
60
  - .rspec
@@ -69,7 +83,6 @@ files:
69
83
  - lib/pg_search/tasks.rb
70
84
  - lib/pg_search/version.rb
71
85
  - pg_search.gemspec
72
- - script/setup-contrib
73
86
  - spec/associations_spec.rb
74
87
  - spec/pg_search/document_spec.rb
75
88
  - spec/pg_search/multisearch_spec.rb
@@ -84,30 +97,38 @@ files:
84
97
  - sql/unnest.sql
85
98
  homepage: https://github.com/Casecommons/pg_search
86
99
  licenses: []
100
+
87
101
  post_install_message:
88
102
  rdoc_options: []
89
- require_paths:
103
+
104
+ require_paths:
90
105
  - lib
91
- required_ruby_version: !ruby/object:Gem::Requirement
106
+ required_ruby_version: !ruby/object:Gem::Requirement
92
107
  none: false
93
- requirements:
94
- - - ! '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
116
  none: false
99
- requirements:
100
- - - ! '>='
101
- - !ruby/object:Gem::Version
102
- version: '0'
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
103
124
  requirements: []
125
+
104
126
  rubyforge_project:
105
127
  rubygems_version: 1.8.10
106
128
  signing_key:
107
129
  specification_version: 3
108
- summary: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's
109
- full text search
110
- test_files:
130
+ summary: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's full text search
131
+ test_files:
111
132
  - spec/associations_spec.rb
112
133
  - spec/pg_search/document_spec.rb
113
134
  - spec/pg_search/multisearch_spec.rb
data/script/setup-contrib DELETED
@@ -1,12 +0,0 @@
1
- #!/bin/sh
2
- POSTGRESQL_VERSION=`pg_config --version | awk '{print $2}'`
3
-
4
- cd /tmp
5
- test -e /tmp/postgresql-$POSTGRESQL_VERSION.tar.bz2 || wget http://ftp9.us.postgresql.org/pub/mirrors/postgresql/source/v$POSTGRESQL_VERSION/postgresql-$POSTGRESQL_VERSION.tar.bz2
6
- test -d /tmp/postgresql-$POSTGRESQL_VERSION || tar zxvf postgresql-$POSTGRESQL_VERSION.tar.bz2
7
- cd postgresql-$POSTGRESQL_VERSION && eval ./configure `pg_config --configure` && make
8
- cd contrib/unaccent && make && make install
9
- cd ..
10
- cd contrib/pg_trgm && make && make install
11
- cd ..
12
- cd contrib/fuzzystrmatch && make && make install