is_msfte_searchable 3.2.0 → 3.3.0
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/is_msfte_searchable.rb +1 -0
- data/lib/is_msfte_searchable/active_record_extension.rb +29 -0
- data/lib/is_msfte_searchable/arel_mixin.rb +15 -6
- data/lib/is_msfte_searchable/no_full_text_index_error.rb +4 -0
- data/lib/is_msfte_searchable/version.rb +1 -1
- data/test/active_record_extension_test.rb +4 -0
- data/test/arel_mixin_test.rb +23 -28
- metadata +91 -105
data/lib/is_msfte_searchable.rb
CHANGED
|
@@ -3,6 +3,7 @@ require 'active_record'
|
|
|
3
3
|
require 'is_msfte_searchable/active_record_extension'
|
|
4
4
|
require 'is_msfte_searchable/active_record_mixin'
|
|
5
5
|
require 'is_msfte_searchable/arel_mixin'
|
|
6
|
+
require 'is_msfte_searchable/no_full_text_index_error'
|
|
6
7
|
require 'is_msfte_searchable/version'
|
|
7
8
|
|
|
8
9
|
ActiveRecord::Base.send :include, IsMsfteSearchable::ActiveRecordExtension
|
|
@@ -16,6 +16,35 @@ module IsMsfteSearchable
|
|
|
16
16
|
include IsMsfteSearchable::ActiveRecordMixin
|
|
17
17
|
include IsMsfteSearchable::ArelMixin
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
def msfte_column_indexed?(column)
|
|
21
|
+
# Any column in this table full-text indexed?
|
|
22
|
+
sql_statement =
|
|
23
|
+
<<-stmt
|
|
24
|
+
select count(*)
|
|
25
|
+
from sys.fulltext_index_columns fic
|
|
26
|
+
inner join sys.columns c
|
|
27
|
+
on c.[object_id] = fic.[object_id]
|
|
28
|
+
and c.[column_id] = fic.[column_id]
|
|
29
|
+
where OBJECT_ID('#{table_name}') = fic.[object_id]
|
|
30
|
+
stmt
|
|
31
|
+
|
|
32
|
+
# Search for an actual column name if given.
|
|
33
|
+
sql_statement << " and name = '#{column}'" unless column == '*'
|
|
34
|
+
|
|
35
|
+
value = connection.select_value(sql_statement)
|
|
36
|
+
value.to_i == 1
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Query the object properties of the current table.
|
|
40
|
+
# TableFulltextPendingChanges returns the number of pending changes.
|
|
41
|
+
# See: http://technet.microsoft.com/en-us/library/ms188390.aspx
|
|
42
|
+
def msfte_pending_changes?
|
|
43
|
+
sql_statement =
|
|
44
|
+
%|select cast(OBJECTPROPERTYEX(OBJECT_ID('#{table_name}'), 'TableFulltextPendingChanges') as varchar(10))|
|
|
45
|
+
value = connection.select_value(sql_statement)
|
|
46
|
+
value.to_i != 0
|
|
47
|
+
end
|
|
19
48
|
end
|
|
20
49
|
end
|
|
21
50
|
end
|
|
@@ -27,20 +27,17 @@ module IsMsfteSearchable
|
|
|
27
27
|
msfte_columns.each do |c|
|
|
28
28
|
scope "msfte_#{c}_with_any".to_sym, lambda { |query|
|
|
29
29
|
return {} if query.blank?
|
|
30
|
-
|
|
31
|
-
msfte_contains(msfte_search_string(query, 'OR'), :column => c)
|
|
30
|
+
msfte_try_contains(msfte_search_string(query, 'OR'), :column => c)
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
scope "msfte_#{c}_with_all".to_sym, lambda { |query|
|
|
35
34
|
return {} if query.blank?
|
|
36
|
-
|
|
37
|
-
msfte_contains(msfte_search_string(query, 'AND'), :column => c)
|
|
35
|
+
msfte_try_contains(msfte_search_string(query, 'AND'), :column => c)
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
scope "msfte_#{c}_with_booleans".to_sym, lambda { |query|
|
|
41
39
|
return {} if query.blank?
|
|
42
|
-
|
|
43
|
-
msfte_contains(query, :column => c, :quote => true)
|
|
40
|
+
msfte_try_contains(query, :column => c, :quote => true)
|
|
44
41
|
}
|
|
45
42
|
end
|
|
46
43
|
end
|
|
@@ -49,6 +46,18 @@ module IsMsfteSearchable
|
|
|
49
46
|
module ClassMethods
|
|
50
47
|
private
|
|
51
48
|
|
|
49
|
+
def msfte_try_contains(query, options={})
|
|
50
|
+
column = options.fetch(:column, '*')
|
|
51
|
+
if msfte_column_indexed?(column)
|
|
52
|
+
until !msfte_pending_changes? do
|
|
53
|
+
sleep 1
|
|
54
|
+
end
|
|
55
|
+
msfte_contains(query, options)
|
|
56
|
+
else
|
|
57
|
+
raise NoFullTextIndexError, "column '#{column}' is not full-text indexed"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
52
61
|
def msfte_like_bailout(column, query)
|
|
53
62
|
{ :conditions => "#{table_name}.#{column} LIKE '%#{msfte_quote(query)}%'" }
|
|
54
63
|
end
|
|
@@ -5,6 +5,10 @@ describe IsMsfteSearchable::ActiveRecordExtension do
|
|
|
5
5
|
ActiveRecord::Base.must_respond_to(:is_msfte_searchable)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
it "extends ActiveRecord::Base with an msfte_pending_changes? method" do
|
|
9
|
+
ActiveRecord::Base.must_respond_to(:msfte_pending_changes?)
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
class FakeActiveRecord
|
|
9
13
|
def self.table_name
|
|
10
14
|
'people'
|
data/test/arel_mixin_test.rb
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
require 'helper'
|
|
2
2
|
|
|
3
|
-
class Rails
|
|
4
|
-
class Env
|
|
5
|
-
def self.test?
|
|
6
|
-
false
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.env
|
|
11
|
-
Env
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
3
|
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
|
16
4
|
|
|
17
5
|
ActiveRecord::Base.class_eval do
|
|
@@ -24,6 +12,14 @@ end
|
|
|
24
12
|
|
|
25
13
|
class Person < ActiveRecord::Base
|
|
26
14
|
is_msfte_searchable(:columns => %w(name))
|
|
15
|
+
|
|
16
|
+
def self.msfte_column_indexed?(column)
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.msfte_pending_changes?
|
|
21
|
+
false
|
|
22
|
+
end
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
# The SQL generated is courtesy of the sqlite adapter, so the whitespace and
|
|
@@ -121,11 +117,11 @@ describe IsMsfteSearchable::ArelMixin do
|
|
|
121
117
|
)
|
|
122
118
|
end
|
|
123
119
|
|
|
124
|
-
it "
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
it "raises an exception if the searched column is not indexed" do
|
|
121
|
+
Person.stubs(:msfte_column_indexed?).returns(false)
|
|
122
|
+
Proc.new do
|
|
123
|
+
Person.msfte_name_with_any('foo bar')
|
|
124
|
+
end.must_raise IsMsfteSearchable::NoFullTextIndexError
|
|
129
125
|
end
|
|
130
126
|
end
|
|
131
127
|
|
|
@@ -146,11 +142,11 @@ describe IsMsfteSearchable::ArelMixin do
|
|
|
146
142
|
)
|
|
147
143
|
end
|
|
148
144
|
|
|
149
|
-
it "
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
145
|
+
it "raises an exception if the searched column is not indexed" do
|
|
146
|
+
Person.stubs(:msfte_column_indexed?).returns(false)
|
|
147
|
+
Proc.new do
|
|
148
|
+
Person.msfte_name_with_all('foo bar')
|
|
149
|
+
end.must_raise IsMsfteSearchable::NoFullTextIndexError
|
|
154
150
|
end
|
|
155
151
|
end
|
|
156
152
|
|
|
@@ -171,13 +167,12 @@ describe IsMsfteSearchable::ArelMixin do
|
|
|
171
167
|
)
|
|
172
168
|
end
|
|
173
169
|
|
|
174
|
-
it "
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
170
|
+
it "raises an exception if the searched column is not indexed" do
|
|
171
|
+
Person.stubs(:msfte_column_indexed?).returns(false)
|
|
172
|
+
Proc.new do
|
|
173
|
+
Person.msfte_name_with_any('foo bar')
|
|
174
|
+
end.must_raise IsMsfteSearchable::NoFullTextIndexError
|
|
179
175
|
end
|
|
180
176
|
end
|
|
181
177
|
end
|
|
182
|
-
|
|
183
178
|
end
|
metadata
CHANGED
|
@@ -1,129 +1,121 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: is_msfte_searchable
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
prerelease:
|
|
6
|
-
segments:
|
|
7
|
-
- 3
|
|
8
|
-
- 2
|
|
9
|
-
- 0
|
|
10
|
-
version: 3.2.0
|
|
11
6
|
platform: ruby
|
|
12
|
-
authors:
|
|
7
|
+
authors:
|
|
13
8
|
- Ken Collins
|
|
14
9
|
- Donald Ball
|
|
15
10
|
autorequire:
|
|
16
11
|
bindir: bin
|
|
17
12
|
cert_chain: []
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
+
date: 2012-09-18 00:00:00.000000000 Z
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
22
16
|
name: activerecord
|
|
23
|
-
|
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
|
25
18
|
none: false
|
|
26
|
-
requirements:
|
|
19
|
+
requirements:
|
|
27
20
|
- - ~>
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
hash: 15
|
|
30
|
-
segments:
|
|
31
|
-
- 3
|
|
32
|
-
- 2
|
|
33
|
-
- 0
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
34
22
|
version: 3.2.0
|
|
35
23
|
type: :runtime
|
|
36
|
-
version_requirements: *id001
|
|
37
|
-
- !ruby/object:Gem::Dependency
|
|
38
|
-
name: activesupport
|
|
39
24
|
prerelease: false
|
|
40
|
-
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
none: false
|
|
27
|
+
requirements:
|
|
28
|
+
- - ~>
|
|
29
|
+
- !ruby/object:Gem::Version
|
|
30
|
+
version: 3.2.0
|
|
31
|
+
- !ruby/object:Gem::Dependency
|
|
32
|
+
name: activesupport
|
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
|
41
34
|
none: false
|
|
42
|
-
requirements:
|
|
35
|
+
requirements:
|
|
43
36
|
- - ~>
|
|
44
|
-
- !ruby/object:Gem::Version
|
|
45
|
-
hash: 15
|
|
46
|
-
segments:
|
|
47
|
-
- 3
|
|
48
|
-
- 2
|
|
49
|
-
- 0
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
50
38
|
version: 3.2.0
|
|
51
39
|
type: :runtime
|
|
52
|
-
version_requirements: *id002
|
|
53
|
-
- !ruby/object:Gem::Dependency
|
|
54
|
-
name: rake
|
|
55
40
|
prerelease: false
|
|
56
|
-
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
42
|
none: false
|
|
58
|
-
requirements:
|
|
43
|
+
requirements:
|
|
59
44
|
- - ~>
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 3.2.0
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: rake
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
none: false
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
66
54
|
version: 0.9.2
|
|
67
55
|
type: :development
|
|
68
|
-
version_requirements: *id003
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: minitest
|
|
71
56
|
prerelease: false
|
|
72
|
-
|
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
58
|
none: false
|
|
74
|
-
requirements:
|
|
59
|
+
requirements:
|
|
75
60
|
- - ~>
|
|
76
|
-
- !ruby/object:Gem::Version
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: 0.9.2
|
|
63
|
+
- !ruby/object:Gem::Dependency
|
|
64
|
+
name: minitest
|
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
|
66
|
+
none: false
|
|
67
|
+
requirements:
|
|
68
|
+
- - ~>
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
82
70
|
version: 2.8.1
|
|
83
71
|
type: :development
|
|
84
|
-
version_requirements: *id004
|
|
85
|
-
- !ruby/object:Gem::Dependency
|
|
86
|
-
name: mocha
|
|
87
72
|
prerelease: false
|
|
88
|
-
|
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
74
|
none: false
|
|
90
|
-
requirements:
|
|
75
|
+
requirements:
|
|
91
76
|
- - ~>
|
|
92
|
-
- !ruby/object:Gem::Version
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: 2.8.1
|
|
79
|
+
- !ruby/object:Gem::Dependency
|
|
80
|
+
name: mocha
|
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
|
82
|
+
none: false
|
|
83
|
+
requirements:
|
|
84
|
+
- - ~>
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
98
86
|
version: 0.10.5
|
|
99
87
|
type: :development
|
|
100
|
-
version_requirements: *id005
|
|
101
|
-
- !ruby/object:Gem::Dependency
|
|
102
|
-
name: sqlite3
|
|
103
88
|
prerelease: false
|
|
104
|
-
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
90
|
none: false
|
|
106
|
-
requirements:
|
|
91
|
+
requirements:
|
|
107
92
|
- - ~>
|
|
108
|
-
- !ruby/object:Gem::Version
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: 0.10.5
|
|
95
|
+
- !ruby/object:Gem::Dependency
|
|
96
|
+
name: sqlite3
|
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
|
98
|
+
none: false
|
|
99
|
+
requirements:
|
|
100
|
+
- - ~>
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '1.3'
|
|
114
103
|
type: :development
|
|
115
|
-
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
none: false
|
|
107
|
+
requirements:
|
|
108
|
+
- - ~>
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.3'
|
|
116
111
|
description: ActiveRecord extensions for Microsoft SQL Server full-text index
|
|
117
|
-
email:
|
|
112
|
+
email:
|
|
118
113
|
- ken@metaskills.net
|
|
119
114
|
- donald.ball@gmail.com
|
|
120
115
|
executables: []
|
|
121
|
-
|
|
122
116
|
extensions: []
|
|
123
|
-
|
|
124
117
|
extra_rdoc_files: []
|
|
125
|
-
|
|
126
|
-
files:
|
|
118
|
+
files:
|
|
127
119
|
- .gitignore
|
|
128
120
|
- CHANGELOG.md
|
|
129
121
|
- Gemfile
|
|
@@ -134,6 +126,7 @@ files:
|
|
|
134
126
|
- lib/is_msfte_searchable/active_record_extension.rb
|
|
135
127
|
- lib/is_msfte_searchable/active_record_mixin.rb
|
|
136
128
|
- lib/is_msfte_searchable/arel_mixin.rb
|
|
129
|
+
- lib/is_msfte_searchable/no_full_text_index_error.rb
|
|
137
130
|
- lib/is_msfte_searchable/version.rb
|
|
138
131
|
- test/active_record_extension_test.rb
|
|
139
132
|
- test/active_record_mixin_test.rb
|
|
@@ -141,39 +134,32 @@ files:
|
|
|
141
134
|
- test/helper.rb
|
|
142
135
|
homepage: http://github.com/Decisiv/is_msfte_searchable/
|
|
143
136
|
licenses: []
|
|
144
|
-
|
|
145
137
|
post_install_message:
|
|
146
|
-
rdoc_options:
|
|
138
|
+
rdoc_options:
|
|
147
139
|
- --charset=UTF-8
|
|
148
|
-
require_paths:
|
|
140
|
+
require_paths:
|
|
149
141
|
- lib
|
|
150
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
143
|
none: false
|
|
152
|
-
requirements:
|
|
153
|
-
- -
|
|
154
|
-
- !ruby/object:Gem::Version
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
- 0
|
|
158
|
-
version: "0"
|
|
159
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
|
+
requirements:
|
|
145
|
+
- - ! '>='
|
|
146
|
+
- !ruby/object:Gem::Version
|
|
147
|
+
version: '0'
|
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
149
|
none: false
|
|
161
|
-
requirements:
|
|
162
|
-
- -
|
|
163
|
-
- !ruby/object:Gem::Version
|
|
164
|
-
|
|
165
|
-
segments:
|
|
166
|
-
- 0
|
|
167
|
-
version: "0"
|
|
150
|
+
requirements:
|
|
151
|
+
- - ! '>='
|
|
152
|
+
- !ruby/object:Gem::Version
|
|
153
|
+
version: '0'
|
|
168
154
|
requirements: []
|
|
169
|
-
|
|
170
155
|
rubyforge_project:
|
|
171
|
-
rubygems_version: 1.8.
|
|
156
|
+
rubygems_version: 1.8.24
|
|
172
157
|
signing_key:
|
|
173
158
|
specification_version: 3
|
|
174
159
|
summary: ActiveRecord extensions for Microsoft SQL Server full-text index
|
|
175
|
-
test_files:
|
|
160
|
+
test_files:
|
|
176
161
|
- test/active_record_extension_test.rb
|
|
177
162
|
- test/active_record_mixin_test.rb
|
|
178
163
|
- test/arel_mixin_test.rb
|
|
179
164
|
- test/helper.rb
|
|
165
|
+
has_rdoc:
|