pg_fts 0.0.0 → 0.2.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.
@@ -0,0 +1,247 @@
1
+ require 'digest/sha1'
2
+
3
+ # rubocop:disable Metrics/ModuleLength
4
+ module PG::FTS::Naming
5
+ private
6
+
7
+ # prefixes
8
+
9
+ def on_source_name
10
+ name ? name : "#{source}_to_#{document}"
11
+ end
12
+
13
+ def on_document_name
14
+ name ? name : "#{document}_from_#{source}"
15
+ end
16
+
17
+ def on_link_name
18
+ name ? name : "#{link}_to_#{document}_from_#{source}"
19
+ end
20
+
21
+ def on_source_prefix_unhashed
22
+ name ? suffix(name, :source) : on_source_name
23
+ end
24
+
25
+ def on_document_prefix_unhashed
26
+ name ? suffix(name, :document) : on_document_name
27
+ end
28
+
29
+ def on_link_prefix_unhashed
30
+ name ? suffix(name, :link) : on_link_name
31
+ end
32
+
33
+ def hash_name?
34
+ PG::FTS::Naming.hash_names?
35
+ end
36
+
37
+ def hashed(name)
38
+ 'sha1_' << (Digest::SHA1.new.tap { |sha| sha << name }).hexdigest
39
+ end
40
+
41
+ # rubocop:disable Metrics/CyclomaticComplexity
42
+ def suffix(str, *types)
43
+ str = str.dup
44
+
45
+ types.each do |type|
46
+ case type
47
+ when :source then str << '_src'
48
+ when :link then str << '_lnk'
49
+ when :document then str << '_doc'
50
+ when :insert then str << '_ins'
51
+ when :update then str << '_upd'
52
+ when :delete then str << '_del'
53
+ when :truncate then str << '_trn'
54
+ when :tsv then str << '_tsv'
55
+ end
56
+ end
57
+
58
+ str
59
+ end
60
+ # rubocop:enable Metrics/CyclomaticComplexity
61
+
62
+ def on_source_prefix
63
+ if hash_name?
64
+ suffix(hashed(on_source_name), :source)
65
+ else
66
+ on_source_prefix_unhashed
67
+ end
68
+ end
69
+
70
+ def on_document_prefix
71
+ if hash_name?
72
+ suffix(hashed(on_document_name), :document)
73
+ else
74
+ on_document_prefix_unhashed
75
+ end
76
+ end
77
+
78
+ def on_link_prefix
79
+ if hash_name?
80
+ suffix(hashed(on_link_name), :link)
81
+ else
82
+ on_link_prefix_unhashed
83
+ end
84
+ end
85
+
86
+ # names
87
+
88
+ def on_source_insert_name
89
+ suffix(on_source_prefix, :insert, :tsv)
90
+ end
91
+
92
+ def on_source_update_name
93
+ suffix(on_source_prefix, :update, :tsv)
94
+ end
95
+
96
+ def on_source_delete_name
97
+ suffix(on_source_prefix, :delete, :tsv)
98
+ end
99
+
100
+ def on_source_truncate_name
101
+ suffix(on_source_prefix, :truncate, :tsv)
102
+ end
103
+
104
+ def on_document_insert_name
105
+ suffix(on_document_prefix, :insert, :tsv)
106
+ end
107
+
108
+ def on_document_update_name
109
+ suffix(on_document_prefix, :update, :tsv)
110
+ end
111
+
112
+ def on_document_delete_name
113
+ suffix(on_document_prefix, :delete, :tsv)
114
+ end
115
+
116
+ def on_document_truncate_name
117
+ suffix(on_document_prefix, :truncate, :tsv)
118
+ end
119
+
120
+ def on_link_insert_name
121
+ suffix(on_link_prefix, :insert, :tsv)
122
+ end
123
+
124
+ def on_link_update_name
125
+ suffix(on_link_prefix, :update, :tsv)
126
+ end
127
+
128
+ def on_link_delete_name
129
+ suffix(on_link_prefix, :delete, :tsv)
130
+ end
131
+
132
+ def on_link_truncate_name
133
+ suffix(on_link_prefix, :truncate, :tsv)
134
+ end
135
+
136
+ # procedure names
137
+
138
+ def on_source_insert_procedure_name
139
+ on_source_insert_name
140
+ end
141
+
142
+ def on_source_update_procedure_name
143
+ on_source_update_name
144
+ end
145
+
146
+ def on_source_delete_procedure_name
147
+ on_source_delete_name
148
+ end
149
+
150
+ def on_source_truncate_procedure_name
151
+ on_source_truncate_name
152
+ end
153
+
154
+ def on_document_insert_procedure_name
155
+ on_document_insert_name
156
+ end
157
+
158
+ def on_document_update_procedure_name
159
+ on_document_update_name
160
+ end
161
+
162
+ def on_document_delete_procedure_name
163
+ on_document_delete_name
164
+ end
165
+
166
+ def on_document_truncate_procedure_name
167
+ on_document_truncate_name
168
+ end
169
+
170
+ def on_link_insert_procedure_name
171
+ on_link_insert_name
172
+ end
173
+
174
+ def on_link_update_procedure_name
175
+ on_link_update_name
176
+ end
177
+
178
+ def on_link_delete_procedure_name
179
+ on_link_delete_name
180
+ end
181
+
182
+ def on_link_truncate_procedure_name
183
+ on_link_truncate_name
184
+ end
185
+
186
+ # trigger names
187
+
188
+ def on_source_insert_trigger_name
189
+ on_source_insert_procedure_name
190
+ end
191
+
192
+ def on_source_update_trigger_name
193
+ on_source_update_procedure_name
194
+ end
195
+
196
+ def on_source_delete_trigger_name
197
+ on_source_delete_procedure_name
198
+ end
199
+
200
+ def on_source_truncate_trigger_name
201
+ on_source_truncate_procedure_name
202
+ end
203
+
204
+ def on_document_insert_trigger_name
205
+ on_document_insert_procedure_name
206
+ end
207
+
208
+ def on_document_update_trigger_name
209
+ on_document_update_procedure_name
210
+ end
211
+
212
+ def on_document_delete_trigger_name
213
+ on_document_delete_procedure_name
214
+ end
215
+
216
+ def on_document_truncate_trigger_name
217
+ on_document_truncate_procedure_name
218
+ end
219
+
220
+ def on_link_insert_trigger_name
221
+ on_link_insert_procedure_name
222
+ end
223
+
224
+ def on_link_update_trigger_name
225
+ on_link_update_procedure_name
226
+ end
227
+
228
+ def on_link_delete_trigger_name
229
+ on_link_delete_procedure_name
230
+ end
231
+
232
+ def on_link_truncate_trigger_name
233
+ on_link_truncate_procedure_name
234
+ end
235
+
236
+ module_function
237
+
238
+ @hash_names = false
239
+
240
+ def hash_names?
241
+ @hash_names
242
+ end
243
+
244
+ def hash_names!
245
+ @hash_names = true
246
+ end
247
+ end
@@ -0,0 +1,9 @@
1
+ module PG::FTS::TSVector
2
+ def ts_vector(record = 'NEW')
3
+ record = %("#{record}") unless %w(NEW OLD).include?(record)
4
+
5
+ fields.map do |field|
6
+ %(to_tsvector('#{catalog}', COALESCE(#{record}."#{field}", '')))
7
+ end.join(' || ')
8
+ end
9
+ end
data/lib/pg/fts.rb ADDED
@@ -0,0 +1,70 @@
1
+ module PG::FTS
2
+ module_function
3
+
4
+ def table
5
+ 'fts'
6
+ end
7
+
8
+ def catalog
9
+ 'pg_catalog.simple'
10
+ end
11
+
12
+ def create_table_query
13
+ <<-SQL.gsub(/^ {4}/, '')
14
+ CREATE TABLE "#{PG::FTS.table}" (
15
+ "id" SERIAL,
16
+ "document_table" VARCHAR(255),
17
+ "document_id" INT,
18
+ "source_table" VARCHAR(255),
19
+ "source_id" INT,
20
+ "tsv" TSVECTOR);
21
+ SQL
22
+ end
23
+
24
+ def create_key_index_query
25
+ <<-SQL.gsub(/^ {4}/, '')
26
+ CREATE UNIQUE INDEX "#{PG::FTS.table}_idx"
27
+ ON "#{PG::FTS.table}" (
28
+ "document_table",
29
+ "document_id",
30
+ "source_table",
31
+ "source_id");
32
+ SQL
33
+ end
34
+
35
+ def create_tsv_index_query
36
+ <<-SQL.gsub(/^ {4}/, '')
37
+ CREATE INDEX "#{PG::FTS.table}_tsv_idx"
38
+ ON "#{PG::FTS.table}"
39
+ USING GIN ("tsv");
40
+ SQL
41
+ end
42
+
43
+ def drop_table_query
44
+ <<-SQL.gsub(/^ {4}/, '')
45
+ DROP TABLE "#{PG::FTS.table}"
46
+ SQL
47
+ end
48
+
49
+ def truncate_table_query
50
+ <<-SQL.gsub(/^ {4}/, '')
51
+ TRUNCATE "#{PG::FTS.table}";
52
+ SQL
53
+ end
54
+
55
+ def create
56
+ yield(create_table_query)
57
+ yield(create_key_index_query)
58
+ yield(create_tsv_index_query)
59
+ end
60
+
61
+ def drop
62
+ yield(drop_table_query)
63
+ end
64
+
65
+ def clear
66
+ yield(truncate_table_query)
67
+ end
68
+ end
69
+
70
+ require 'pg/fts/index'
data/lib/pg_fts.rb CHANGED
@@ -1,3 +1,2 @@
1
- module PG
2
- module FTS; end
3
- end
1
+ require 'pg'
2
+ require 'pg/fts'
metadata CHANGED
@@ -1,28 +1,91 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_fts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - ADHOC-GTI
7
+ - Loic Nageleisen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-02 00:00:00.000000000 Z
12
- dependencies: []
13
- description: |2
14
- Relation-aware synchronous full text search index for PostgreSQL using
15
- PL/pgSQL triggers described in and generated via ORM-agnostic Ruby.
16
- email: foss@adhoc-gti.com
11
+ date: 2018-06-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pg
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.18'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.8.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.8.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.36.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.36.0
69
+ description: " Relation-aware synchronous full text search index for PostgreSQL using
70
+ PL/pgSQL triggers described in and generated via ORM-agnostic Ruby.\n"
71
+ email: l.nageleisen@adhoc-gti.com
17
72
  executables: []
18
73
  extensions: []
19
74
  extra_rdoc_files: []
20
75
  files:
21
- - LICENSE
76
+ - lib/pg/fts.rb
77
+ - lib/pg/fts/index.rb
78
+ - lib/pg/fts/index/many_to_one.rb
79
+ - lib/pg/fts/index/momo.rb
80
+ - lib/pg/fts/index/ommo.rb
81
+ - lib/pg/fts/index/one_to_many.rb
82
+ - lib/pg/fts/index/self.rb
83
+ - lib/pg/fts/naming.rb
84
+ - lib/pg/fts/ts_vector.rb
22
85
  - lib/pg_fts.rb
23
- homepage: https://github.com/adhoc-gti/pg_fts
86
+ homepage: https://gitlab.adhoc-gti.com/lnageleisen/pg-fts
24
87
  licenses:
25
- - BSD-3-Clause
88
+ - MIT
26
89
  metadata: {}
27
90
  post_install_message:
28
91
  rdoc_options: []
@@ -43,5 +106,5 @@ rubyforge_project:
43
106
  rubygems_version: 2.6.14
44
107
  signing_key:
45
108
  specification_version: 4
46
- summary: Synchronous full-text search index
109
+ summary: Postgres real-time full text search engine
47
110
  test_files: []
data/LICENSE DELETED
@@ -1,24 +0,0 @@
1
- Copyright (c) 2015, ADHOC-GTI
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are met:
6
- * Redistributions of source code must retain the above copyright
7
- notice, this list of conditions and the following disclaimer.
8
- * Redistributions in binary form must reproduce the above copyright
9
- notice, this list of conditions and the following disclaimer in the
10
- documentation and/or other materials provided with the distribution.
11
- * Neither the name of the copyright holders nor the
12
- names of its contributors may be used to endorse or promote products
13
- derived from this software without specific prior written permission.
14
-
15
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
19
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.