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,464 @@
1
+ # one document, many links, many links, one source
2
+ class PG::FTS::Index::OMMO
3
+ attr_reader :table, :fields, :catalog,
4
+ :document, :link,
5
+ :key, :foreign_key, :fordocument_key,
6
+ :name
7
+ alias source table
8
+
9
+ include PG::FTS::Index
10
+ include PG::FTS::Naming
11
+ include PG::FTS::TSVector
12
+
13
+ # rubocop:disable Metrics/ParameterLists, Metrics/CyclomaticComplexity
14
+ def initialize(table, *fields,
15
+ document: nil, link: nil,
16
+ key: nil, foreign_key: nil, fordocument_key: nil,
17
+ catalog: nil,
18
+ as: nil)
19
+ @table = table
20
+ @fields = fields
21
+ @catalog = catalog || PG::FTS.catalog
22
+ @document = document || fail(ArgumentError, ':document required')
23
+ @link = link || fail(ArgumentError, ':link required')
24
+ @key = key || :id
25
+ @foreign_key = foreign_key || :"#{table}_id"
26
+ @fordocument_key = fordocument_key || :"#{document}_id"
27
+ @name = as
28
+ end
29
+ # rubocop:enable Metrics/ParameterLists, Metrics/CyclomaticComplexity
30
+
31
+ def build_query
32
+ <<-SQL.gsub(/^ {4}/, '')
33
+ INSERT INTO "#{PG::FTS.table}" (
34
+ "document_id",
35
+ "document_table",
36
+ "source_id",
37
+ "source_table",
38
+ "tsv")
39
+ SELECT "#{document}"."#{key}",
40
+ '#{document}',
41
+ "#{source}"."#{key}",
42
+ '#{source}',
43
+ #{ts_vector(source)}
44
+ FROM "#{document}", "#{source}", "#{link}"
45
+ WHERE "#{document}"."#{key}" = "#{link}"."#{fordocument_key}"
46
+ AND "#{link}"."#{foreign_key}" = "#{source}"."#{key}";
47
+ SQL
48
+ end
49
+
50
+ def on_source_insert_query
51
+ <<-SQL.gsub(/^ {4}/, '')
52
+ INSERT INTO "#{PG::FTS.table}" (
53
+ "document_id",
54
+ "document_table",
55
+ "source_id",
56
+ "source_table",
57
+ "tsv")
58
+ SELECT
59
+ "#{document}"."#{key}",
60
+ '#{document}',
61
+ NEW."#{key}",
62
+ '#{source}',
63
+ #{ts_vector}
64
+ FROM "#{document}", "#{link}"
65
+ WHERE "#{document}"."#{key}" = "#{link}"."#{fordocument_key}"
66
+ AND "#{link}"."#{foreign_key}" = NEW."#{key}";
67
+ SQL
68
+ end
69
+
70
+ def on_source_insert_procedure
71
+ <<-SQL.gsub(/^ {4}/, '')
72
+ CREATE FUNCTION "#{on_source_insert_procedure_name}"()
73
+ RETURNS TRIGGER AS $$
74
+ BEGIN
75
+ #{on_source_insert_query.gsub(/^/, ' ')}
76
+ RETURN NEW;
77
+ END;
78
+ $$ LANGUAGE plpgsql;
79
+ SQL
80
+ end
81
+
82
+ def on_source_update_query
83
+ <<-SQL.gsub(/^ {4}/, '')
84
+ UPDATE "#{PG::FTS.table}"
85
+ SET
86
+ "tsv" = (#{ts_vector}),
87
+ "document_table" = '#{document}',
88
+ "document_id" = "#{document}"."#{key}"
89
+ FROM "#{document}", "#{link}"
90
+ WHERE "#{document}"."#{key}" = "#{link}"."#{fordocument_key}"
91
+ AND "#{link}"."#{foreign_key}" = NEW."#{key}"
92
+ AND "#{PG::FTS.table}"."source_id" = OLD."#{key}"
93
+ AND "#{PG::FTS.table}"."source_table" = '#{source}'
94
+ AND "#{PG::FTS.table}"."document_id" = "#{document}"."#{key}"
95
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
96
+ SQL
97
+ end
98
+
99
+ def on_source_update_procedure
100
+ <<-SQL.gsub(/^ {4}/, '')
101
+ CREATE FUNCTION "#{on_source_update_procedure_name}"()
102
+ RETURNS TRIGGER AS $$
103
+ BEGIN
104
+ #{on_source_update_query.gsub(/^/, ' ')}
105
+ RETURN NEW;
106
+ END;
107
+ $$ LANGUAGE plpgsql;
108
+ SQL
109
+ end
110
+
111
+ def on_source_delete_query
112
+ <<-SQL.gsub(/^ {4}/, '')
113
+ DELETE FROM "#{PG::FTS.table}"
114
+ WHERE "#{PG::FTS.table}"."source_id" = OLD."#{key}"
115
+ AND "#{PG::FTS.table}"."source_table" = '#{source}'
116
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
117
+ SQL
118
+ end
119
+
120
+ def on_source_delete_procedure
121
+ <<-SQL.gsub(/^ {4}/, '')
122
+ CREATE FUNCTION "#{on_source_delete_procedure_name}"()
123
+ RETURNS TRIGGER AS $$
124
+ BEGIN
125
+ #{on_source_delete_query.gsub(/^/, ' ')}
126
+ RETURN OLD;
127
+ END;
128
+ $$ LANGUAGE plpgsql;
129
+ SQL
130
+ end
131
+
132
+ def on_source_truncate_query
133
+ <<-SQL.gsub(/^ {4}/, '')
134
+ DELETE FROM "#{PG::FTS.table}"
135
+ WHERE "#{PG::FTS.table}"."source_table" = '#{source}'
136
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
137
+ SQL
138
+ end
139
+
140
+ def on_source_truncate_procedure
141
+ <<-SQL.gsub(/^ {4}/, '')
142
+ CREATE FUNCTION "#{on_source_truncate_procedure_name}"()
143
+ RETURNS TRIGGER AS $$
144
+ BEGIN
145
+ #{on_source_truncate_query.gsub(/^/, ' ')}
146
+ RETURN NULL;
147
+ END;
148
+ $$ LANGUAGE plpgsql;
149
+ SQL
150
+ end
151
+
152
+ def on_source_insert_trigger
153
+ <<-SQL.gsub(/^ {4}/, '')
154
+ CREATE TRIGGER "#{on_source_insert_trigger_name}"
155
+ AFTER INSERT ON "#{source}"
156
+ FOR EACH ROW
157
+ EXECUTE PROCEDURE "#{on_source_insert_procedure_name}"();
158
+ SQL
159
+ end
160
+
161
+ def on_source_update_trigger
162
+ <<-SQL.gsub(/^ {4}/, '')
163
+ CREATE TRIGGER "#{on_source_update_trigger_name}"
164
+ AFTER UPDATE ON "#{source}"
165
+ FOR EACH ROW
166
+ EXECUTE PROCEDURE "#{on_source_update_procedure_name}"();
167
+ SQL
168
+ end
169
+
170
+ def on_source_delete_trigger
171
+ <<-SQL.gsub(/^ {4}/, '')
172
+ CREATE TRIGGER "#{on_source_delete_trigger_name}"
173
+ AFTER DELETE ON "#{source}"
174
+ FOR EACH ROW
175
+ EXECUTE PROCEDURE "#{on_source_delete_procedure_name}"();
176
+ SQL
177
+ end
178
+
179
+ def on_source_truncate_trigger
180
+ <<-SQL.gsub(/^ {4}/, '')
181
+ CREATE TRIGGER "#{on_source_truncate_trigger_name}"
182
+ AFTER TRUNCATE ON "#{source}"
183
+ FOR EACH STATEMENT
184
+ EXECUTE PROCEDURE "#{on_source_truncate_procedure_name}"();
185
+ SQL
186
+ end
187
+
188
+ def on_document_insert_query
189
+ <<-SQL.gsub(/^ {4}/, '')
190
+ INSERT INTO "#{PG::FTS.table}" (
191
+ "document_id",
192
+ "document_table",
193
+ "source_id",
194
+ "source_table",
195
+ "tsv")
196
+ SELECT
197
+ NEW."#{key}",
198
+ '#{document}',
199
+ "#{source}"."#{key}",
200
+ '#{source}',
201
+ #{ts_vector(source)}
202
+ FROM "#{source}", "#{link}"
203
+ WHERE "#{source}"."#{key}" = "#{link}"."#{foreign_key}"
204
+ AND "#{link}"."#{fordocument_key}" = NEW."#{key}";
205
+ SQL
206
+ end
207
+
208
+ def on_document_insert_procedure
209
+ <<-SQL.gsub(/^ {4}/, '')
210
+ CREATE FUNCTION "#{on_document_insert_procedure_name}"()
211
+ RETURNS TRIGGER AS $$
212
+ BEGIN
213
+ #{on_document_insert_query.gsub(/^/, ' ')}
214
+ RETURN NEW;
215
+ END;
216
+ $$ LANGUAGE plpgsql;
217
+ SQL
218
+ end
219
+
220
+ def on_document_update_query
221
+ <<-SQL.gsub(/^ {4}/, '')
222
+ SQL
223
+ end
224
+
225
+ def on_document_update_procedure
226
+ <<-SQL.gsub(/^ {4}/, '')
227
+ CREATE FUNCTION "#{on_document_update_procedure_name}"()
228
+ RETURNS TRIGGER AS $$
229
+ BEGIN
230
+ #{on_document_update_query.gsub(/^/, ' ')}
231
+ RETURN NEW;
232
+ END;
233
+ $$ LANGUAGE plpgsql;
234
+ SQL
235
+ end
236
+
237
+ def on_document_delete_query
238
+ <<-SQL.gsub(/^ {4}/, '')
239
+ DELETE FROM "#{PG::FTS.table}"
240
+ WHERE "#{PG::FTS.table}"."source_table" = '#{source}'
241
+ AND "#{PG::FTS.table}"."document_id" = OLD."#{key}"
242
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
243
+ SQL
244
+ end
245
+
246
+ def on_document_delete_procedure
247
+ <<-SQL.gsub(/^ {4}/, '')
248
+ CREATE FUNCTION "#{on_document_delete_procedure_name}"()
249
+ RETURNS TRIGGER AS $$
250
+ BEGIN
251
+ #{on_document_delete_query.gsub(/^/, ' ')}
252
+ RETURN OLD;
253
+ END;
254
+ $$ LANGUAGE plpgsql;
255
+ SQL
256
+ end
257
+
258
+ def on_document_truncate_query
259
+ <<-SQL.gsub(/^ {4}/, '')
260
+ DELETE FROM "#{PG::FTS.table}"
261
+ WHERE "#{PG::FTS.table}"."source_table" = '#{source}'
262
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
263
+ SQL
264
+ end
265
+
266
+ def on_document_truncate_procedure
267
+ <<-SQL.gsub(/^ {4}/, '')
268
+ CREATE FUNCTION "#{on_document_truncate_procedure_name}"()
269
+ RETURNS TRIGGER AS $$
270
+ BEGIN
271
+ #{on_document_truncate_query.gsub(/^/, ' ')}
272
+ RETURN NULL;
273
+ END;
274
+ $$ LANGUAGE plpgsql;
275
+ SQL
276
+ end
277
+
278
+ def on_document_insert_trigger
279
+ <<-SQL.gsub(/^ {4}/, '')
280
+ CREATE TRIGGER "#{on_document_insert_trigger_name}"
281
+ AFTER INSERT ON "#{document}"
282
+ FOR EACH ROW
283
+ EXECUTE PROCEDURE "#{on_document_insert_procedure_name}"();
284
+ SQL
285
+ end
286
+
287
+ def on_document_update_trigger
288
+ <<-SQL.gsub(/^ {4}/, '')
289
+ CREATE TRIGGER "#{on_document_update_trigger_name}"
290
+ AFTER UPDATE ON "#{document}"
291
+ FOR EACH ROW
292
+ EXECUTE PROCEDURE "#{on_document_update_procedure_name}"();
293
+ SQL
294
+ end
295
+
296
+ def on_document_delete_trigger
297
+ <<-SQL.gsub(/^ {4}/, '')
298
+ CREATE TRIGGER "#{on_document_delete_trigger_name}"
299
+ AFTER DELETE ON "#{document}"
300
+ FOR EACH ROW
301
+ EXECUTE PROCEDURE "#{on_document_delete_procedure_name}"();
302
+ SQL
303
+ end
304
+
305
+ def on_document_truncate_trigger
306
+ <<-SQL.gsub(/^ {4}/, '')
307
+ CREATE TRIGGER "#{on_document_truncate_trigger_name}"
308
+ AFTER TRUNCATE ON "#{document}"
309
+ FOR EACH STATEMENT
310
+ EXECUTE PROCEDURE "#{on_document_truncate_procedure_name}"();
311
+ SQL
312
+ end
313
+
314
+ def on_link_insert_query
315
+ <<-SQL.gsub(/^ {4}/, '')
316
+ INSERT INTO "#{PG::FTS.table}" (
317
+ "document_id",
318
+ "document_table",
319
+ "source_id",
320
+ "source_table",
321
+ "tsv")
322
+ SELECT
323
+ "#{document}"."#{key}",
324
+ '#{document}',
325
+ "#{source}"."#{key}",
326
+ '#{source}',
327
+ #{ts_vector(source)}
328
+ FROM "#{document}", "#{source}"
329
+ WHERE "#{document}"."#{key}" = NEW."#{fordocument_key}"
330
+ AND "#{source}"."#{key}" = NEW."#{foreign_key}";
331
+ SQL
332
+ end
333
+
334
+ def on_link_insert_procedure
335
+ <<-SQL.gsub(/^ {4}/, '')
336
+ CREATE FUNCTION "#{on_link_insert_procedure_name}"()
337
+ RETURNS TRIGGER AS $$
338
+ BEGIN
339
+ #{on_link_insert_query.gsub(/^/, ' ')}
340
+ RETURN NEW;
341
+ END;
342
+ $$ LANGUAGE plpgsql;
343
+ SQL
344
+ end
345
+
346
+ def on_link_update_query
347
+ <<-SQL.gsub(/^ {4}/, '')
348
+ UPDATE "#{PG::FTS.table}"
349
+ SET
350
+ "tsv" = (#{ts_vector(source)}),
351
+ "document_table" = '#{document}',
352
+ "document_id" = NEW."#{fordocument_key}",
353
+ "source_table" = '#{source}',
354
+ "source_id" = NEW."#{foreign_key}"
355
+ FROM "#{document}", "#{source}"
356
+ WHERE "#{document}"."#{key}" = NEW."#{fordocument_key}"
357
+ AND "#{source}"."#{key}" = NEW."#{foreign_key}"
358
+ AND "#{PG::FTS.table}"."source_id" = OLD."#{foreign_key}"
359
+ AND "#{PG::FTS.table}"."source_table" = '#{source}'
360
+ AND "#{PG::FTS.table}"."document_id" = OLD."#{fordocument_key}"
361
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
362
+ SQL
363
+ end
364
+
365
+ def on_link_update_procedure
366
+ <<-SQL.gsub(/^ {4}/, '')
367
+ CREATE FUNCTION "#{on_link_update_procedure_name}"()
368
+ RETURNS TRIGGER AS $$
369
+ BEGIN
370
+ #{on_link_update_query.gsub(/^/, ' ')}
371
+ IF NOT FOUND THEN
372
+ #{on_link_insert_query.gsub(/^/, ' ')}
373
+ IF NOT FOUND THEN
374
+ #{on_link_delete_query.gsub(/^/, ' ')}
375
+ END IF;
376
+ RETURN NEW;
377
+ END IF;
378
+ RETURN NEW;
379
+ END;
380
+ $$ LANGUAGE plpgsql;
381
+ SQL
382
+ end
383
+
384
+ def on_link_delete_query
385
+ <<-SQL.gsub(/^ {4}/, '')
386
+ DELETE FROM "#{PG::FTS.table}"
387
+ USING "#{link}", "#{document}", "#{source}"
388
+ WHERE OLD."#{fordocument_key}" = "#{document}"."#{key}"
389
+ AND OLD."#{foreign_key}" = "#{source}"."#{key}"
390
+ AND "#{PG::FTS.table}"."source_id" = "#{source}"."#{key}"
391
+ AND "#{PG::FTS.table}"."source_table" = '#{source}'
392
+ AND "#{PG::FTS.table}"."document_id" = "#{document}"."#{key}"
393
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
394
+ SQL
395
+ end
396
+
397
+ def on_link_delete_procedure
398
+ <<-SQL.gsub(/^ {4}/, '')
399
+ CREATE FUNCTION "#{on_link_delete_procedure_name}"()
400
+ RETURNS TRIGGER AS $$
401
+ BEGIN
402
+ #{on_link_delete_query.gsub(/^/, ' ')}
403
+ RETURN OLD;
404
+ END;
405
+ $$ LANGUAGE plpgsql;
406
+ SQL
407
+ end
408
+
409
+ def on_link_truncate_query
410
+ <<-SQL.gsub(/^ {4}/, '')
411
+ DELETE FROM "#{PG::FTS.table}"
412
+ WHERE "#{PG::FTS.table}"."source_table" = '#{source}'
413
+ AND "#{PG::FTS.table}"."document_table" = '#{document}';
414
+ SQL
415
+ end
416
+
417
+ def on_link_truncate_procedure
418
+ <<-SQL.gsub(/^ {4}/, '')
419
+ CREATE FUNCTION "#{on_link_truncate_procedure_name}"()
420
+ RETURNS TRIGGER AS $$
421
+ BEGIN
422
+ #{on_link_truncate_query.gsub(/^/, ' ')}
423
+ RETURN NULL;
424
+ END;
425
+ $$ LANGUAGE plpgsql;
426
+ SQL
427
+ end
428
+
429
+ def on_link_insert_trigger
430
+ <<-SQL.gsub(/^ {4}/, '')
431
+ CREATE TRIGGER "#{on_link_insert_trigger_name}"
432
+ AFTER INSERT ON "#{link}"
433
+ FOR EACH ROW
434
+ EXECUTE PROCEDURE "#{on_link_insert_procedure_name}"();
435
+ SQL
436
+ end
437
+
438
+ def on_link_update_trigger
439
+ <<-SQL.gsub(/^ {4}/, '')
440
+ CREATE TRIGGER "#{on_link_update_trigger_name}"
441
+ AFTER UPDATE ON "#{link}"
442
+ FOR EACH ROW
443
+ EXECUTE PROCEDURE "#{on_link_update_procedure_name}"();
444
+ SQL
445
+ end
446
+
447
+ def on_link_delete_trigger
448
+ <<-SQL.gsub(/^ {4}/, '')
449
+ CREATE TRIGGER "#{on_link_delete_trigger_name}"
450
+ AFTER DELETE ON "#{link}"
451
+ FOR EACH ROW
452
+ EXECUTE PROCEDURE "#{on_link_delete_procedure_name}"();
453
+ SQL
454
+ end
455
+
456
+ def on_link_truncate_trigger
457
+ <<-SQL.gsub(/^ {4}/, '')
458
+ CREATE TRIGGER "#{on_link_truncate_trigger_name}"
459
+ AFTER TRUNCATE ON "#{link}"
460
+ FOR EACH STATEMENT
461
+ EXECUTE PROCEDURE "#{on_link_truncate_procedure_name}"();
462
+ SQL
463
+ end
464
+ end