pg_search 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -1
- data/README.md +3 -3
- data/lib/pg_search.rb +11 -13
- data/lib/pg_search/compatibility.rb +9 -0
- data/lib/pg_search/configuration.rb +4 -3
- data/lib/pg_search/features.rb +6 -5
- data/lib/pg_search/features/feature.rb +2 -0
- data/lib/pg_search/features/tsearch.rb +15 -5
- data/lib/pg_search/multisearch.rb +2 -1
- data/lib/pg_search/multisearchable.rb +9 -10
- data/lib/pg_search/version.rb +1 -1
- data/spec/integration/pg_search_spec.rb +70 -3
- data/spec/lib/pg_search/configuration/association_spec.rb +76 -0
- data/spec/lib/pg_search/configuration/foreign_column_spec.rb +36 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 061b1d5b8c2b15a078a7e24519d6ce8431165a89
|
4
|
+
data.tar.gz: 5f8d8ad2b97af42fe20a8bcbcfe3b506b865d29a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8395420354b745b6f31b860637ab36b0d3ade94bbc3fb5745c0d888d5feb7e2ff86a7790cc0f53360b540acfe8c1314d404cd3c48fe118a9bf2771be8210251e
|
7
|
+
data.tar.gz: 3e3ee515686fada644a424e3372d6f1891faa3506a4c18993f899684de7450505e174d71abde33c16196e13a378e0673ba9d13727e58bbaa706cf6158aded71d
|
data/.travis.yml
CHANGED
@@ -3,22 +3,24 @@ language: ruby
|
|
3
3
|
rvm:
|
4
4
|
- 1.9.3
|
5
5
|
- 2.0.0
|
6
|
+
- 2.1.0
|
6
7
|
- jruby-19mode
|
7
|
-
- rbx-19mode
|
8
8
|
|
9
9
|
env:
|
10
10
|
- ACTIVE_RECORD_BRANCH="master"
|
11
11
|
- ACTIVE_RECORD_BRANCH="4-0-stable"
|
12
|
+
- ACTIVE_RECORD_VERSION="~> 4.1.0.beta1"
|
12
13
|
- ACTIVE_RECORD_VERSION="~> 4.0.0"
|
13
14
|
- ACTIVE_RECORD_VERSION="~> 3.2.0"
|
14
15
|
- ACTIVE_RECORD_VERSION="~> 3.1.0"
|
15
16
|
|
16
17
|
matrix:
|
17
18
|
allow_failures:
|
18
|
-
- rvm:
|
19
|
+
- rvm: 2.1.0
|
19
20
|
- rvm: jruby-19mode
|
20
21
|
- env: ACTIVE_RECORD_BRANCH="master"
|
21
22
|
- env: ACTIVE_RECORD_BRANCH="4-0-stable"
|
23
|
+
- env: ACTIVE_RECORD_VERSION="~> 4.1.0.beta1"
|
22
24
|
|
23
25
|
before_script:
|
24
26
|
- "psql -c 'create database pg_search_test;' -U postgres >/dev/null"
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -22,8 +22,8 @@ Read the blog post introducing PgSearch at http://pivotallabs.com/pg-search/
|
|
22
22
|
|
23
23
|
## REQUIREMENTS
|
24
24
|
|
25
|
-
* Ruby 1.9.2 or later
|
26
|
-
* Active Record 3.1 or later
|
25
|
+
* Ruby 1.9.2, 2.0, or later
|
26
|
+
* Active Record 3.1, 3.2, 4.0 or later
|
27
27
|
* PostgreSQL
|
28
28
|
* [PostgreSQL contrib packages for certain
|
29
29
|
features](https://github.com/Casecommons/pg_search/wiki/Installing-Postgres-Contrib-Modules)
|
@@ -33,7 +33,7 @@ Read the blog post introducing PgSearch at http://pivotallabs.com/pg-search/
|
|
33
33
|
|
34
34
|
gem install pg_search
|
35
35
|
|
36
|
-
### Rails 3.1 or later, Ruby 1.9.2 or later
|
36
|
+
### Rails 3.1, 3.2, 4.0 or later, Ruby 1.9.2, 2.0, or later
|
37
37
|
|
38
38
|
In Gemfile
|
39
39
|
|
data/lib/pg_search.rb
CHANGED
@@ -2,19 +2,20 @@ require "active_record"
|
|
2
2
|
require "active_support/concern"
|
3
3
|
require "active_support/core_ext/module/attribute_accessors"
|
4
4
|
require "active_support/core_ext/string/strip"
|
5
|
+
|
6
|
+
require "pg_search/compatibility"
|
7
|
+
require "pg_search/configuration"
|
5
8
|
require "pg_search/extensions/arel"
|
9
|
+
require "pg_search/features"
|
10
|
+
require "pg_search/multisearch"
|
11
|
+
require "pg_search/multisearchable"
|
12
|
+
require "pg_search/normalizer"
|
13
|
+
require "pg_search/scope_options"
|
14
|
+
require "pg_search/version"
|
6
15
|
|
7
16
|
module PgSearch
|
8
|
-
autoload :Configuration, "pg_search/configuration"
|
9
|
-
autoload :Document, "pg_search/document"
|
10
|
-
autoload :Features, "pg_search/features"
|
11
|
-
autoload :Multisearch, "pg_search/multisearch"
|
12
|
-
autoload :Multisearchable, "pg_search/multisearchable"
|
13
|
-
autoload :Normalizer, "pg_search/normalizer"
|
14
|
-
autoload :ScopeOptions, "pg_search/scope_options"
|
15
|
-
autoload :VERSION, "pg_search/version"
|
16
|
-
|
17
17
|
extend ActiveSupport::Concern
|
18
|
+
include Compatibility::ActiveRecord3 if ActiveRecord::VERSION::MAJOR == 3
|
18
19
|
|
19
20
|
mattr_accessor :multisearch_options
|
20
21
|
self.multisearch_options = {}
|
@@ -53,10 +54,6 @@ module PgSearch
|
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
def pg_search_rank
|
57
|
-
read_attribute(:pg_search_rank).to_f
|
58
|
-
end
|
59
|
-
|
60
57
|
class << self
|
61
58
|
def multisearch(*args)
|
62
59
|
PgSearch::Document.search(*args)
|
@@ -81,4 +78,5 @@ module PgSearch
|
|
81
78
|
class NotSupportedForPostgresqlVersion < StandardError; end
|
82
79
|
end
|
83
80
|
|
81
|
+
require "pg_search/document"
|
84
82
|
require "pg_search/railtie" if defined?(Rails)
|
@@ -1,8 +1,9 @@
|
|
1
|
+
require "pg_search/configuration/association"
|
2
|
+
require "pg_search/configuration/column"
|
3
|
+
require "pg_search/configuration/foreign_column"
|
4
|
+
|
1
5
|
module PgSearch
|
2
6
|
class Configuration
|
3
|
-
autoload :Association, "pg_search/configuration/association"
|
4
|
-
autoload :Column, "pg_search/configuration/column"
|
5
|
-
autoload :ForeignColumn, "pg_search/configuration/foreign_column"
|
6
7
|
|
7
8
|
attr_reader :model
|
8
9
|
|
data/lib/pg_search/features.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
require "pg_search/features/feature"
|
2
|
+
|
3
|
+
require "pg_search/features/dmetaphone"
|
4
|
+
require "pg_search/features/trigram"
|
5
|
+
require "pg_search/features/tsearch"
|
6
|
+
|
1
7
|
module PgSearch
|
2
8
|
module Features
|
3
|
-
autoload :Feature, "pg_search/features/feature"
|
4
|
-
|
5
|
-
autoload :DMetaphone, "pg_search/features/dmetaphone"
|
6
|
-
autoload :Trigram, "pg_search/features/trigram"
|
7
|
-
autoload :TSearch, "pg_search/features/tsearch"
|
8
9
|
end
|
9
10
|
end
|
@@ -54,11 +54,14 @@ module PgSearch
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def tsdocument
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
tsdocument_terms = []
|
58
|
+
|
59
|
+
columns_to_use = options[:tsvector_column] ?
|
60
|
+
columns.select { |c| c.is_a?(PgSearch::Configuration::ForeignColumn) } :
|
61
|
+
columns
|
62
|
+
|
63
|
+
if columns_to_use.present?
|
64
|
+
tsdocument_terms << columns_to_use.map do |search_column|
|
62
65
|
tsvector = Arel::Nodes::NamedFunction.new(
|
63
66
|
"to_tsvector",
|
64
67
|
[dictionary, Arel.sql(normalize(search_column.to_sql))]
|
@@ -71,6 +74,13 @@ module PgSearch
|
|
71
74
|
end
|
72
75
|
end.join(" || ")
|
73
76
|
end
|
77
|
+
|
78
|
+
if options[:tsvector_column]
|
79
|
+
column_name = connection.quote_column_name(options[:tsvector_column])
|
80
|
+
tsdocument_terms << "#{quoted_table_name}.#{column_name}"
|
81
|
+
end
|
82
|
+
|
83
|
+
tsdocument_terms.join(' || ')
|
74
84
|
end
|
75
85
|
|
76
86
|
# From http://www.postgresql.org/docs/8.3/static/textsearch-controls.html
|
@@ -1,18 +1,17 @@
|
|
1
|
-
require "active_support/concern"
|
2
1
|
require "active_support/core_ext/class/attribute"
|
3
2
|
|
4
3
|
module PgSearch
|
5
4
|
module Multisearchable
|
6
|
-
|
5
|
+
def self.included mod
|
6
|
+
mod.class_eval do
|
7
|
+
has_one :pg_search_document,
|
8
|
+
:as => :searchable,
|
9
|
+
:class_name => "PgSearch::Document",
|
10
|
+
:dependent => :delete
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
:class_name => "PgSearch::Document",
|
12
|
-
:dependent => :delete
|
13
|
-
|
14
|
-
after_save :update_pg_search_document,
|
15
|
-
:if => lambda { PgSearch.multisearch_enabled? }
|
12
|
+
after_save :update_pg_search_document,
|
13
|
+
:if => lambda { PgSearch.multisearch_enabled? }
|
14
|
+
end
|
16
15
|
end
|
17
16
|
|
18
17
|
def update_pg_search_document
|
data/lib/pg_search/version.rb
CHANGED
@@ -151,6 +151,14 @@ describe "an Active Record model which includes PgSearch" do
|
|
151
151
|
results.should_not include(excluded)
|
152
152
|
end
|
153
153
|
|
154
|
+
it "returns the correct count" do
|
155
|
+
ModelWithPgSearch.create!(:content => 'foo')
|
156
|
+
ModelWithPgSearch.create!(:content => 'bar')
|
157
|
+
|
158
|
+
results = ModelWithPgSearch.search_content('foo')
|
159
|
+
expect(results.count(:all)).to eq 1
|
160
|
+
end
|
161
|
+
|
154
162
|
it "returns rows where the column contains all the terms in the query in any order" do
|
155
163
|
included = [ModelWithPgSearch.create!(:content => 'foo bar'),
|
156
164
|
ModelWithPgSearch.create!(:content => 'bar foo')]
|
@@ -621,7 +629,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
621
629
|
ModelWithPgSearch.with_trigram(accent_query).should_not include(record)
|
622
630
|
ModelWithPgSearch.with_trigram_and_ignoring_accents(accent_query).should include(record)
|
623
631
|
ModelWithPgSearch.with_tsearch(accent_query).should_not include(record)
|
624
|
-
ModelWithPgSearch.with_tsearch_and_trigram(accent_query).should
|
632
|
+
ModelWithPgSearch.with_tsearch_and_trigram(accent_query).count(:all).should == 0
|
625
633
|
ModelWithPgSearch.complex_search(accent_query).should include(record)
|
626
634
|
|
627
635
|
# matches tsearch only
|
@@ -668,7 +676,66 @@ describe "an Active Record model which includes PgSearch" do
|
|
668
676
|
end
|
669
677
|
end
|
670
678
|
|
671
|
-
context "using a tsvector column" do
|
679
|
+
context "using a tsvector column and an association" do
|
680
|
+
with_model :Comment do
|
681
|
+
table do |t|
|
682
|
+
t.integer :post_id
|
683
|
+
t.string :body
|
684
|
+
end
|
685
|
+
|
686
|
+
model do
|
687
|
+
belongs_to :post
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
with_model :Post do
|
692
|
+
table do |t|
|
693
|
+
t.text 'content'
|
694
|
+
t.tsvector 'content_tsvector'
|
695
|
+
end
|
696
|
+
|
697
|
+
model do
|
698
|
+
include PgSearch
|
699
|
+
has_many :comments
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
let!(:expected) { Post.create!(content: 'phooey') }
|
704
|
+
let!(:unexpected) { Post.create!(content: 'longcat is looooooooong') }
|
705
|
+
|
706
|
+
before do
|
707
|
+
ActiveRecord::Base.connection.execute <<-SQL.strip_heredoc
|
708
|
+
UPDATE #{Post.quoted_table_name}
|
709
|
+
SET content_tsvector = to_tsvector('english'::regconfig, #{Post.quoted_table_name}."content")
|
710
|
+
SQL
|
711
|
+
|
712
|
+
expected.comments.create(body: 'commentone')
|
713
|
+
unexpected.comments.create(body: 'commentwo')
|
714
|
+
|
715
|
+
Post.pg_search_scope :search_by_content_with_tsvector,
|
716
|
+
:associated_against => { comments: [:body] },
|
717
|
+
:using => {
|
718
|
+
:tsearch => {
|
719
|
+
:tsvector_column => 'content_tsvector',
|
720
|
+
:dictionary => 'english'
|
721
|
+
}
|
722
|
+
}
|
723
|
+
end
|
724
|
+
|
725
|
+
it "should find by the tsvector column" do
|
726
|
+
Post.search_by_content_with_tsvector("phooey").map(&:id).should == [expected.id]
|
727
|
+
end
|
728
|
+
|
729
|
+
it "should find by the associated record" do
|
730
|
+
Post.search_by_content_with_tsvector("commentone").map(&:id).should == [expected.id]
|
731
|
+
end
|
732
|
+
|
733
|
+
it 'should find by a combination of the two' do
|
734
|
+
Post.search_by_content_with_tsvector("phooey commentone").map(&:id).should == [expected.id]
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
738
|
+
context "using a tsvector column with" do
|
672
739
|
with_model :ModelWithTsvector do
|
673
740
|
table do |t|
|
674
741
|
t.text 'content'
|
@@ -877,7 +944,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
877
944
|
end
|
878
945
|
end
|
879
946
|
|
880
|
-
it "
|
947
|
+
it "returns only results for that subclass" do
|
881
948
|
included = [
|
882
949
|
SubclassModel.create!(:content => "foo bar")
|
883
950
|
]
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe PgSearch::Configuration::Association do
|
4
|
+
with_model :AssociatedModel do
|
5
|
+
table do |t|
|
6
|
+
t.string "title"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
with_model :Model do
|
11
|
+
table do |t|
|
12
|
+
t.string "title"
|
13
|
+
t.belongs_to :another_model
|
14
|
+
end
|
15
|
+
|
16
|
+
model do
|
17
|
+
include PgSearch
|
18
|
+
belongs_to :another_model, :class_name => 'AssociatedModel'
|
19
|
+
|
20
|
+
pg_search_scope :with_another, :associated_against => {:another_model => :title}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:association) { described_class.new(Model, :another_model, :title) }
|
25
|
+
|
26
|
+
describe "#table_name" do
|
27
|
+
it "returns the table name for the associated model" do
|
28
|
+
expect(association.table_name).to eq AssociatedModel.table_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#join" do
|
33
|
+
let(:expected_sql) do
|
34
|
+
<<-EOS.gsub(/\s+/, ' ').strip
|
35
|
+
LEFT OUTER JOIN
|
36
|
+
(SELECT model_id AS id,
|
37
|
+
#{column_select} AS #{association.columns.first.alias}
|
38
|
+
FROM \"#{Model.table_name}\"
|
39
|
+
INNER JOIN \"#{association.table_name}\"
|
40
|
+
ON \"#{association.table_name}\".\"id\" = \"#{Model.table_name}\".\"another_model_id\"
|
41
|
+
GROUP BY model_id) #{association.subselect_alias}
|
42
|
+
ON #{association.subselect_alias}.id = model_id
|
43
|
+
EOS
|
44
|
+
end
|
45
|
+
|
46
|
+
context "given postgresql_version 0..90_000" do
|
47
|
+
let(:column_select) do
|
48
|
+
"array_to_string(array_agg(\"#{association.table_name}\".\"title\"::text), ' ')"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns the correct SQL join" do
|
52
|
+
allow(Model.connection).to receive(:postgresql_version).and_return(1)
|
53
|
+
expect(association.join("model_id")).to eq(expected_sql)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "given any other postgresql_version" do
|
58
|
+
let(:column_select) do
|
59
|
+
"string_agg(\"#{association.table_name}\".\"title\"::text, ' ')"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns the correct SQL join" do
|
63
|
+
allow(Model.connection).to receive(:postgresql_version).and_return(100_000)
|
64
|
+
expect(association.join("model_id")).to eq(expected_sql)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#subselect_alias" do
|
70
|
+
it "returns a consistent string" do
|
71
|
+
subselect_alias = association.subselect_alias
|
72
|
+
expect(subselect_alias).to be_a String
|
73
|
+
expect(association.subselect_alias).to eq subselect_alias
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe PgSearch::Configuration::ForeignColumn do
|
4
|
+
describe "#alias" do
|
5
|
+
with_model :AssociatedModel do
|
6
|
+
table do |t|
|
7
|
+
t.string "title"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
with_model :Model do
|
12
|
+
table do |t|
|
13
|
+
t.string "title"
|
14
|
+
t.belongs_to :another_model
|
15
|
+
end
|
16
|
+
|
17
|
+
model do
|
18
|
+
include PgSearch
|
19
|
+
belongs_to :another_model, :class_name => 'AssociatedModel'
|
20
|
+
|
21
|
+
pg_search_scope :with_another, :associated_against => {:another_model => :title}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns a consistent string" do
|
26
|
+
association = PgSearch::Configuration::Association.new(Model,
|
27
|
+
:another_model,
|
28
|
+
:title)
|
29
|
+
foreign_column = described_class.new("title", nil, Model, association)
|
30
|
+
|
31
|
+
column_alias = foreign_column.alias
|
32
|
+
expect(column_alias).to be_a String
|
33
|
+
expect(foreign_column.alias).to eq column_alias
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grant Hutchins
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -130,6 +130,7 @@ files:
|
|
130
130
|
- README.md
|
131
131
|
- Rakefile
|
132
132
|
- lib/pg_search.rb
|
133
|
+
- lib/pg_search/compatibility.rb
|
133
134
|
- lib/pg_search/configuration.rb
|
134
135
|
- lib/pg_search/configuration/association.rb
|
135
136
|
- lib/pg_search/configuration/column.rb
|
@@ -159,7 +160,9 @@ files:
|
|
159
160
|
- spec/integration/associations_spec.rb
|
160
161
|
- spec/integration/pagination_spec.rb
|
161
162
|
- spec/integration/pg_search_spec.rb
|
163
|
+
- spec/lib/pg_search/configuration/association_spec.rb
|
162
164
|
- spec/lib/pg_search/configuration/column_spec.rb
|
165
|
+
- spec/lib/pg_search/configuration/foreign_column_spec.rb
|
163
166
|
- spec/lib/pg_search/document_spec.rb
|
164
167
|
- spec/lib/pg_search/features/dmetaphone_spec.rb
|
165
168
|
- spec/lib/pg_search/features/trigram_spec.rb
|
@@ -195,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
198
|
version: '0'
|
196
199
|
requirements: []
|
197
200
|
rubyforge_project:
|
198
|
-
rubygems_version: 2.0.
|
201
|
+
rubygems_version: 2.0.14
|
199
202
|
signing_key:
|
200
203
|
specification_version: 4
|
201
204
|
summary: PgSearch builds Active Record named scopes that take advantage of PostgreSQL's
|
@@ -204,7 +207,9 @@ test_files:
|
|
204
207
|
- spec/integration/associations_spec.rb
|
205
208
|
- spec/integration/pagination_spec.rb
|
206
209
|
- spec/integration/pg_search_spec.rb
|
210
|
+
- spec/lib/pg_search/configuration/association_spec.rb
|
207
211
|
- spec/lib/pg_search/configuration/column_spec.rb
|
212
|
+
- spec/lib/pg_search/configuration/foreign_column_spec.rb
|
208
213
|
- spec/lib/pg_search/document_spec.rb
|
209
214
|
- spec/lib/pg_search/features/dmetaphone_spec.rb
|
210
215
|
- spec/lib/pg_search/features/trigram_spec.rb
|