pg_search 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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