@nsshunt/stsdatamanagement 1.18.196 → 1.18.199
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.
- package/db-scripts/builddb-01.sql +386 -0
- package/db-scripts/builddb-02.sql +2176 -0
- package/db-scripts/builddb-stsrest01.sql +2176 -0
- package/db-scripts/builddb.sql +210 -36
- package/dist/databaseutils.js +13 -6
- package/dist/databaseutils.js.map +1 -1
- package/package.json +1 -1
- package/types/databaseutils.d.ts.map +1 -1
|
@@ -0,0 +1,2176 @@
|
|
|
1
|
+
-- =============================================================================
|
|
2
|
+
-- stsrest01 - Generic Resource / Entity Database Model
|
|
3
|
+
-- =============================================================================
|
|
4
|
+
--
|
|
5
|
+
-- PURPOSE
|
|
6
|
+
-- -------
|
|
7
|
+
-- This schema implements a deliberately generic, versioned resource/entity
|
|
8
|
+
-- model.
|
|
9
|
+
--
|
|
10
|
+
-- A RESOURCE is a logical/conceptual container identified by resname.
|
|
11
|
+
-- A RESOURCE version is represented by a new stsresource row and therefore a
|
|
12
|
+
-- new stsresource.oid.
|
|
13
|
+
--
|
|
14
|
+
-- An ENTITY belongs to the RESOURCE CONCEPT, not permanently to one historical
|
|
15
|
+
-- resource row. For that reason, whenever the current resource version changes,
|
|
16
|
+
-- all entity history is moved to the new current resource OID.
|
|
17
|
+
--
|
|
18
|
+
-- This is intentional and is important to the design:
|
|
19
|
+
--
|
|
20
|
+
-- resource v1 (oid 10)
|
|
21
|
+
-- entity history -> resourceoid 10
|
|
22
|
+
--
|
|
23
|
+
-- resource updated to v2 (oid 11)
|
|
24
|
+
-- entity history -> resourceoid 11
|
|
25
|
+
--
|
|
26
|
+
-- resource deleted as v3 (oid 12)
|
|
27
|
+
-- entity history -> resourceoid 12
|
|
28
|
+
--
|
|
29
|
+
-- resource recreated / reinstated as v4 (oid 13)
|
|
30
|
+
-- entity history -> resourceoid 13
|
|
31
|
+
--
|
|
32
|
+
-- A delete therefore does NOT terminate the logical resource concept.
|
|
33
|
+
-- Recreating a deleted resource continues the resource version sequence and
|
|
34
|
+
-- restores the same concept, including its entity history.
|
|
35
|
+
--
|
|
36
|
+
-- dbaction values
|
|
37
|
+
-- ---------------
|
|
38
|
+
-- 1 = create / recreate
|
|
39
|
+
-- 2 = update
|
|
40
|
+
-- 3 = logical delete
|
|
41
|
+
--
|
|
42
|
+
-- VERSIONING RULES
|
|
43
|
+
-- ----------------
|
|
44
|
+
-- * Historical rows have validto IS NOT NULL.
|
|
45
|
+
-- * Exactly one row per resource concept may have validto IS NULL.
|
|
46
|
+
-- * A deleted resource is still the current resource version; it has
|
|
47
|
+
-- validto IS NULL and dbaction = 3.
|
|
48
|
+
-- * Exactly one row per entity concept may have validto IS NULL.
|
|
49
|
+
-- * A deleted entity is likewise represented by a current tombstone row with
|
|
50
|
+
-- dbaction = 3.
|
|
51
|
+
-- * Recreating a deleted resource/entity closes the tombstone and creates the
|
|
52
|
+
-- next version. Version numbers never reset to 1.
|
|
53
|
+
--
|
|
54
|
+
-- CONCURRENCY RULES
|
|
55
|
+
-- -----------------
|
|
56
|
+
-- Mutating functions lock the current resource/entity rows with FOR UPDATE
|
|
57
|
+
-- before changing versions. Partial unique indexes provide a final database
|
|
58
|
+
-- invariant for concurrent creates where there is no existing row to lock.
|
|
59
|
+
--
|
|
60
|
+
-- JSON
|
|
61
|
+
-- ----
|
|
62
|
+
-- resdesc and entvalue retain the supplied JSON text.
|
|
63
|
+
-- resdesc_jsonb and entvalue_jsonb retain the parsed JSON representation for
|
|
64
|
+
-- indexing/searching without making the model resource-type-specific.
|
|
65
|
+
--
|
|
66
|
+
-- =============================================================================
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
-- =============================================================================
|
|
70
|
+
-- Sequences
|
|
71
|
+
-- =============================================================================
|
|
72
|
+
|
|
73
|
+
-- Generates immutable surrogate OIDs for stsresource rows.
|
|
74
|
+
--
|
|
75
|
+
-- An OID identifies one database row/version; it is NOT the permanent logical
|
|
76
|
+
-- identity of a resource. resname is the logical resource concept identifier.
|
|
77
|
+
CREATE SEQUENCE public.stsresource_oid_seq
|
|
78
|
+
AS bigint
|
|
79
|
+
INCREMENT 1
|
|
80
|
+
START 1
|
|
81
|
+
MINVALUE 1
|
|
82
|
+
CACHE 1;
|
|
83
|
+
|
|
84
|
+
ALTER SEQUENCE public.stsresource_oid_seq
|
|
85
|
+
OWNER TO postgres;
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
-- Generates immutable surrogate OIDs for stsentity rows.
|
|
89
|
+
--
|
|
90
|
+
-- An entity OID identifies one entity version row.
|
|
91
|
+
CREATE SEQUENCE public.stsentity_oid_seq
|
|
92
|
+
AS bigint
|
|
93
|
+
INCREMENT 1
|
|
94
|
+
START 1
|
|
95
|
+
MINVALUE 1
|
|
96
|
+
CACHE 1;
|
|
97
|
+
|
|
98
|
+
ALTER SEQUENCE public.stsentity_oid_seq
|
|
99
|
+
OWNER TO postgres;
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
-- =============================================================================
|
|
103
|
+
-- stsresource
|
|
104
|
+
-- =============================================================================
|
|
105
|
+
|
|
106
|
+
-- Stores the complete version history for every generic resource concept.
|
|
107
|
+
--
|
|
108
|
+
-- resname
|
|
109
|
+
-- Logical identifier of the resource concept.
|
|
110
|
+
--
|
|
111
|
+
-- resdesc
|
|
112
|
+
-- Original JSON text supplied by the caller.
|
|
113
|
+
--
|
|
114
|
+
-- resdesc_jsonb
|
|
115
|
+
-- Parsed JSON representation of resdesc. This permits generic JSONB
|
|
116
|
+
-- searching/indexing while preserving the original text.
|
|
117
|
+
--
|
|
118
|
+
-- vnum
|
|
119
|
+
-- Monotonically increasing version number within a resname.
|
|
120
|
+
--
|
|
121
|
+
-- validfrom / validto
|
|
122
|
+
-- Temporal validity interval for this version. The current version has
|
|
123
|
+
-- validto IS NULL.
|
|
124
|
+
--
|
|
125
|
+
-- dbaction
|
|
126
|
+
-- 1=create/recreate, 2=update, 3=logical delete.
|
|
127
|
+
--
|
|
128
|
+
-- dbactionuser
|
|
129
|
+
-- Application/user identity responsible for the database change.
|
|
130
|
+
CREATE TABLE public.stsresource
|
|
131
|
+
(
|
|
132
|
+
oid bigint NOT NULL
|
|
133
|
+
DEFAULT nextval('public.stsresource_oid_seq'::regclass),
|
|
134
|
+
|
|
135
|
+
resname character varying(128)
|
|
136
|
+
COLLATE pg_catalog."default"
|
|
137
|
+
NOT NULL,
|
|
138
|
+
|
|
139
|
+
resdesc character varying(32768)
|
|
140
|
+
COLLATE pg_catalog."default",
|
|
141
|
+
|
|
142
|
+
resdesc_jsonb jsonb,
|
|
143
|
+
|
|
144
|
+
vnum bigint NOT NULL,
|
|
145
|
+
|
|
146
|
+
validfrom timestamp with time zone NOT NULL,
|
|
147
|
+
validto timestamp with time zone,
|
|
148
|
+
|
|
149
|
+
dbaction smallint NOT NULL,
|
|
150
|
+
|
|
151
|
+
dbactionuser character varying(64)
|
|
152
|
+
COLLATE pg_catalog."default"
|
|
153
|
+
NOT NULL,
|
|
154
|
+
|
|
155
|
+
CONSTRAINT stsresource_pkey
|
|
156
|
+
PRIMARY KEY (oid),
|
|
157
|
+
|
|
158
|
+
CONSTRAINT stsresource_dbaction_check
|
|
159
|
+
CHECK (dbaction IN (1, 2, 3))
|
|
160
|
+
)
|
|
161
|
+
TABLESPACE pg_default;
|
|
162
|
+
|
|
163
|
+
ALTER TABLE public.stsresource
|
|
164
|
+
OWNER TO postgres;
|
|
165
|
+
|
|
166
|
+
-- Make the sequence lifecycle follow its dedicated table column.
|
|
167
|
+
ALTER SEQUENCE public.stsresource_oid_seq
|
|
168
|
+
OWNED BY public.stsresource.oid;
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
-- -----------------------------------------------------------------------------
|
|
172
|
+
-- stsresource indexes
|
|
173
|
+
-- -----------------------------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
-- A resource concept may have only one row for each version number.
|
|
176
|
+
CREATE UNIQUE INDEX stsresource_resname_vnum
|
|
177
|
+
ON public.stsresource USING btree
|
|
178
|
+
(
|
|
179
|
+
resname COLLATE pg_catalog."default" ASC NULLS LAST,
|
|
180
|
+
vnum ASC NULLS LAST
|
|
181
|
+
)
|
|
182
|
+
TABLESPACE pg_default;
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
-- Database invariant: exactly zero or one CURRENT row may exist for resname.
|
|
186
|
+
--
|
|
187
|
+
-- IMPORTANT:
|
|
188
|
+
-- Do NOT filter dbaction = 3 here.
|
|
189
|
+
--
|
|
190
|
+
-- A logically deleted resource is still the current resource version until it
|
|
191
|
+
-- is recreated. This index prevents a deleted tombstone and an active row from
|
|
192
|
+
-- both being current at the same time.
|
|
193
|
+
CREATE UNIQUE INDEX idx_stsresource_resname_one_current
|
|
194
|
+
ON public.stsresource (resname)
|
|
195
|
+
WHERE validto IS NULL;
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
-- Supports general resource history/current-version lookup.
|
|
199
|
+
--
|
|
200
|
+
-- This index intentionally includes deleted current records.
|
|
201
|
+
CREATE INDEX stsresource_resname_validto
|
|
202
|
+
ON public.stsresource USING btree
|
|
203
|
+
(
|
|
204
|
+
resname COLLATE pg_catalog."default" ASC NULLS LAST,
|
|
205
|
+
validto DESC NULLS LAST
|
|
206
|
+
)
|
|
207
|
+
TABLESPACE pg_default;
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
-- Supports normal application reads and keyset/cursor pagination over active
|
|
211
|
+
-- resources only.
|
|
212
|
+
--
|
|
213
|
+
-- oid is included after resname to provide a deterministic ordered key.
|
|
214
|
+
CREATE INDEX idx_stsresource_resname_current
|
|
215
|
+
ON public.stsresource (resname, oid)
|
|
216
|
+
WHERE validto IS NULL
|
|
217
|
+
AND dbaction != 3;
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
-- =============================================================================
|
|
221
|
+
-- stsentity
|
|
222
|
+
-- =============================================================================
|
|
223
|
+
|
|
224
|
+
-- Stores the complete version history for entities belonging to a resource
|
|
225
|
+
-- concept.
|
|
226
|
+
--
|
|
227
|
+
-- resourceoid
|
|
228
|
+
-- Points to the CURRENT stsresource row for the resource concept.
|
|
229
|
+
--
|
|
230
|
+
-- This value intentionally changes whenever the resource gets a new
|
|
231
|
+
-- version. All entity history is migrated to the new resource OID by the
|
|
232
|
+
-- resource update/delete/recreate functions.
|
|
233
|
+
--
|
|
234
|
+
-- entname
|
|
235
|
+
-- Logical identifier of the entity within its resource concept.
|
|
236
|
+
--
|
|
237
|
+
-- entvalue
|
|
238
|
+
-- Original JSON text supplied by the caller.
|
|
239
|
+
--
|
|
240
|
+
-- entvalue_jsonb
|
|
241
|
+
-- Parsed JSON representation of entvalue.
|
|
242
|
+
--
|
|
243
|
+
-- vnum
|
|
244
|
+
-- Monotonically increasing entity version number.
|
|
245
|
+
--
|
|
246
|
+
-- validfrom / validto
|
|
247
|
+
-- Temporal validity interval for this entity version. The current version
|
|
248
|
+
-- has validto IS NULL.
|
|
249
|
+
--
|
|
250
|
+
-- dbaction
|
|
251
|
+
-- 1=create/recreate, 2=update, 3=logical delete.
|
|
252
|
+
CREATE TABLE public.stsentity
|
|
253
|
+
(
|
|
254
|
+
oid bigint NOT NULL
|
|
255
|
+
DEFAULT nextval('public.stsentity_oid_seq'::regclass),
|
|
256
|
+
|
|
257
|
+
resourceoid bigint NOT NULL,
|
|
258
|
+
|
|
259
|
+
entname character varying(128)
|
|
260
|
+
COLLATE pg_catalog."default"
|
|
261
|
+
NOT NULL,
|
|
262
|
+
|
|
263
|
+
entvalue character varying(32768)
|
|
264
|
+
COLLATE pg_catalog."default",
|
|
265
|
+
|
|
266
|
+
entvalue_jsonb jsonb,
|
|
267
|
+
|
|
268
|
+
vnum bigint NOT NULL,
|
|
269
|
+
|
|
270
|
+
validfrom timestamp with time zone NOT NULL,
|
|
271
|
+
validto timestamp with time zone,
|
|
272
|
+
|
|
273
|
+
dbaction smallint NOT NULL,
|
|
274
|
+
|
|
275
|
+
dbactionuser character varying(64)
|
|
276
|
+
COLLATE pg_catalog."default"
|
|
277
|
+
NOT NULL,
|
|
278
|
+
|
|
279
|
+
CONSTRAINT stsentity_pkey
|
|
280
|
+
PRIMARY KEY (oid),
|
|
281
|
+
|
|
282
|
+
CONSTRAINT stsentity_dbaction_check
|
|
283
|
+
CHECK (dbaction IN (1, 2, 3)),
|
|
284
|
+
|
|
285
|
+
-- Physical DELETE is not used by the versioning functions; they perform
|
|
286
|
+
-- logical deletes. ON DELETE CASCADE applies only if a stsresource row is
|
|
287
|
+
-- physically removed, in which case entity rows currently attached to that
|
|
288
|
+
-- resource OID are also physically removed.
|
|
289
|
+
CONSTRAINT fk_stsresource
|
|
290
|
+
FOREIGN KEY (resourceoid)
|
|
291
|
+
REFERENCES public.stsresource (oid)
|
|
292
|
+
MATCH SIMPLE
|
|
293
|
+
ON UPDATE NO ACTION
|
|
294
|
+
ON DELETE CASCADE
|
|
295
|
+
)
|
|
296
|
+
TABLESPACE pg_default;
|
|
297
|
+
|
|
298
|
+
ALTER TABLE public.stsentity
|
|
299
|
+
OWNER TO postgres;
|
|
300
|
+
|
|
301
|
+
-- Make the sequence lifecycle follow its dedicated table column.
|
|
302
|
+
ALTER SEQUENCE public.stsentity_oid_seq
|
|
303
|
+
OWNED BY public.stsentity.oid;
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
-- -----------------------------------------------------------------------------
|
|
307
|
+
-- stsentity indexes
|
|
308
|
+
-- -----------------------------------------------------------------------------
|
|
309
|
+
|
|
310
|
+
-- Enforces entity version uniqueness within the current resource concept OID.
|
|
311
|
+
--
|
|
312
|
+
-- Because all entity rows are migrated whenever the resource OID changes, the
|
|
313
|
+
-- complete entity version history continues to share the same resourceoid.
|
|
314
|
+
CREATE UNIQUE INDEX stsentity_resourceoid_entname_vnum
|
|
315
|
+
ON public.stsentity USING btree
|
|
316
|
+
(
|
|
317
|
+
resourceoid ASC NULLS LAST,
|
|
318
|
+
entname COLLATE pg_catalog."default" ASC NULLS LAST,
|
|
319
|
+
vnum ASC NULLS LAST
|
|
320
|
+
)
|
|
321
|
+
TABLESPACE pg_default;
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
-- Supports general entity history/current-version lookup.
|
|
325
|
+
CREATE INDEX stsentity_resourceoid_entname_validto
|
|
326
|
+
ON public.stsentity USING btree
|
|
327
|
+
(
|
|
328
|
+
resourceoid ASC NULLS LAST,
|
|
329
|
+
entname COLLATE pg_catalog."default" ASC NULLS LAST,
|
|
330
|
+
validto DESC NULLS LAST
|
|
331
|
+
)
|
|
332
|
+
TABLESPACE pg_default;
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
-- Database invariant: exactly zero or one CURRENT entity row may exist for an
|
|
336
|
+
-- entity concept within a resource.
|
|
337
|
+
--
|
|
338
|
+
-- IMPORTANT:
|
|
339
|
+
-- Do NOT filter dbaction = 3.
|
|
340
|
+
--
|
|
341
|
+
-- A logically deleted entity is still the current tombstone and must be closed
|
|
342
|
+
-- before the entity can be recreated.
|
|
343
|
+
CREATE UNIQUE INDEX idx_stsentity_resourceoid_entname_current
|
|
344
|
+
ON public.stsentity (resourceoid, entname)
|
|
345
|
+
WHERE validto IS NULL;
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
-- =============================================================================
|
|
349
|
+
-- Resource functions
|
|
350
|
+
-- =============================================================================
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
-- =============================================================================
|
|
354
|
+
-- create_stsresource
|
|
355
|
+
-- =============================================================================
|
|
356
|
+
--
|
|
357
|
+
-- Creates a new resource concept or reinstates a logically deleted resource.
|
|
358
|
+
--
|
|
359
|
+
-- Behaviour:
|
|
360
|
+
--
|
|
361
|
+
-- 1. Parse/validate the supplied JSON.
|
|
362
|
+
-- 2. Look for the current resource row, INCLUDING a deleted tombstone.
|
|
363
|
+
-- 3. If the current row is active, CREATE is rejected as a duplicate.
|
|
364
|
+
-- 4. If the current row is deleted:
|
|
365
|
+
-- * close the deleted version;
|
|
366
|
+
-- * create the next active version;
|
|
367
|
+
-- * move ALL entity history to the new current resource OID.
|
|
368
|
+
-- 5. If no current row exists:
|
|
369
|
+
-- * inspect the historical resource chain;
|
|
370
|
+
-- * continue from MAX/latest vnum rather than resetting to version 1;
|
|
371
|
+
-- * if historical entity rows point at the latest old resource OID, move
|
|
372
|
+
-- them to the new resource OID.
|
|
373
|
+
--
|
|
374
|
+
-- The historical fallback in step 5 also provides safe recovery from an
|
|
375
|
+
-- abnormal database state where history exists but no current row exists.
|
|
376
|
+
CREATE OR REPLACE FUNCTION public.create_stsresource(
|
|
377
|
+
_dbactionuser character varying,
|
|
378
|
+
_resname character varying,
|
|
379
|
+
_resdesc character varying
|
|
380
|
+
)
|
|
381
|
+
RETURNS SETOF public.stsresource
|
|
382
|
+
LANGUAGE plpgsql
|
|
383
|
+
COST 100
|
|
384
|
+
VOLATILE
|
|
385
|
+
ROWS 1
|
|
386
|
+
|
|
387
|
+
AS $BODY$
|
|
388
|
+
DECLARE
|
|
389
|
+
__now timestamptz := now();
|
|
390
|
+
|
|
391
|
+
-- Current resource, when one exists.
|
|
392
|
+
__resoid bigint;
|
|
393
|
+
__vnum bigint;
|
|
394
|
+
__dbaction smallint;
|
|
395
|
+
|
|
396
|
+
-- Last historical resource when no current row exists.
|
|
397
|
+
__historical_oid bigint;
|
|
398
|
+
__historical_vnum bigint;
|
|
399
|
+
|
|
400
|
+
-- Version/OID of the new active row.
|
|
401
|
+
__newvnum bigint;
|
|
402
|
+
__inserted_oid bigint;
|
|
403
|
+
|
|
404
|
+
-- Parsed JSON.
|
|
405
|
+
__resdesc_jsonb jsonb;
|
|
406
|
+
BEGIN
|
|
407
|
+
|
|
408
|
+
-- -------------------------------------------------------------------------
|
|
409
|
+
-- Validate / parse resource JSON
|
|
410
|
+
-- -------------------------------------------------------------------------
|
|
411
|
+
|
|
412
|
+
BEGIN
|
|
413
|
+
__resdesc_jsonb := _resdesc::jsonb;
|
|
414
|
+
|
|
415
|
+
EXCEPTION
|
|
416
|
+
WHEN invalid_text_representation THEN
|
|
417
|
+
RAISE EXCEPTION
|
|
418
|
+
'Invalid JSON string: %',
|
|
419
|
+
_resdesc
|
|
420
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
421
|
+
END;
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
-- -------------------------------------------------------------------------
|
|
425
|
+
-- Resolve and lock the current resource, including deleted tombstones.
|
|
426
|
+
--
|
|
427
|
+
-- The lock serializes update/delete/recreate operations for an existing
|
|
428
|
+
-- resource concept.
|
|
429
|
+
-- -------------------------------------------------------------------------
|
|
430
|
+
|
|
431
|
+
BEGIN
|
|
432
|
+
SELECT
|
|
433
|
+
r.oid,
|
|
434
|
+
r.vnum,
|
|
435
|
+
r.dbaction
|
|
436
|
+
INTO STRICT
|
|
437
|
+
__resoid,
|
|
438
|
+
__vnum,
|
|
439
|
+
__dbaction
|
|
440
|
+
FROM public.stsresource r
|
|
441
|
+
WHERE r.resname = _resname
|
|
442
|
+
AND r.validto IS NULL
|
|
443
|
+
FOR UPDATE;
|
|
444
|
+
|
|
445
|
+
EXCEPTION
|
|
446
|
+
|
|
447
|
+
WHEN no_data_found THEN
|
|
448
|
+
__resoid := NULL;
|
|
449
|
+
__vnum := NULL;
|
|
450
|
+
__dbaction := NULL;
|
|
451
|
+
|
|
452
|
+
WHEN too_many_rows THEN
|
|
453
|
+
RAISE
|
|
454
|
+
'Too many current stsresource records for resource %',
|
|
455
|
+
_resname
|
|
456
|
+
USING ERRCODE = 'cardinality_violation';
|
|
457
|
+
|
|
458
|
+
END;
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
-- -------------------------------------------------------------------------
|
|
462
|
+
-- A current resource exists.
|
|
463
|
+
-- -------------------------------------------------------------------------
|
|
464
|
+
|
|
465
|
+
IF __resoid IS NOT NULL THEN
|
|
466
|
+
|
|
467
|
+
-- An active resource already exists, so CREATE is invalid.
|
|
468
|
+
IF __dbaction != 3 THEN
|
|
469
|
+
RAISE
|
|
470
|
+
'Duplicate resname within stsresource: %',
|
|
471
|
+
_resname
|
|
472
|
+
USING ERRCODE = 'unique_violation';
|
|
473
|
+
END IF;
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
-- ---------------------------------------------------------------------
|
|
477
|
+
-- Reinstating a deleted resource concept.
|
|
478
|
+
--
|
|
479
|
+
-- Close the delete tombstone and continue the resource version chain.
|
|
480
|
+
-- ---------------------------------------------------------------------
|
|
481
|
+
|
|
482
|
+
UPDATE public.stsresource
|
|
483
|
+
SET validto = __now
|
|
484
|
+
WHERE oid = __resoid;
|
|
485
|
+
|
|
486
|
+
__newvnum := __vnum + 1;
|
|
487
|
+
|
|
488
|
+
INSERT INTO public.stsresource(
|
|
489
|
+
resname,
|
|
490
|
+
resdesc,
|
|
491
|
+
resdesc_jsonb,
|
|
492
|
+
vnum,
|
|
493
|
+
dbaction,
|
|
494
|
+
dbactionuser,
|
|
495
|
+
validfrom
|
|
496
|
+
)
|
|
497
|
+
VALUES (
|
|
498
|
+
_resname,
|
|
499
|
+
_resdesc,
|
|
500
|
+
__resdesc_jsonb,
|
|
501
|
+
__newvnum,
|
|
502
|
+
1,
|
|
503
|
+
_dbactionuser,
|
|
504
|
+
__now
|
|
505
|
+
)
|
|
506
|
+
RETURNING oid
|
|
507
|
+
INTO __inserted_oid;
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
-- ---------------------------------------------------------------------
|
|
511
|
+
-- RESOURCE-CONCEPT SEMANTICS
|
|
512
|
+
--
|
|
513
|
+
-- The entities belong to the resource concept, not to the deleted
|
|
514
|
+
-- resource version row. Move the complete entity history to the newly
|
|
515
|
+
-- reinstated resource OID.
|
|
516
|
+
-- ---------------------------------------------------------------------
|
|
517
|
+
|
|
518
|
+
UPDATE public.stsentity
|
|
519
|
+
SET resourceoid = __inserted_oid
|
|
520
|
+
WHERE resourceoid = __resoid;
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
ELSE
|
|
524
|
+
|
|
525
|
+
-- ---------------------------------------------------------------------
|
|
526
|
+
-- No current row exists.
|
|
527
|
+
--
|
|
528
|
+
-- Normally this is the first creation and there is no history.
|
|
529
|
+
--
|
|
530
|
+
-- If history exists without a current row, lock the latest historical
|
|
531
|
+
-- version and continue its version sequence instead of incorrectly
|
|
532
|
+
-- resetting to version 1.
|
|
533
|
+
-- ---------------------------------------------------------------------
|
|
534
|
+
|
|
535
|
+
SELECT
|
|
536
|
+
r.oid,
|
|
537
|
+
r.vnum
|
|
538
|
+
INTO
|
|
539
|
+
__historical_oid,
|
|
540
|
+
__historical_vnum
|
|
541
|
+
FROM public.stsresource r
|
|
542
|
+
WHERE r.resname = _resname
|
|
543
|
+
ORDER BY r.vnum DESC
|
|
544
|
+
LIMIT 1
|
|
545
|
+
FOR UPDATE;
|
|
546
|
+
|
|
547
|
+
__newvnum := COALESCE(__historical_vnum, 0) + 1;
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
-- Create the new active resource version.
|
|
551
|
+
INSERT INTO public.stsresource(
|
|
552
|
+
resname,
|
|
553
|
+
resdesc,
|
|
554
|
+
resdesc_jsonb,
|
|
555
|
+
vnum,
|
|
556
|
+
dbaction,
|
|
557
|
+
dbactionuser,
|
|
558
|
+
validfrom
|
|
559
|
+
)
|
|
560
|
+
VALUES (
|
|
561
|
+
_resname,
|
|
562
|
+
_resdesc,
|
|
563
|
+
__resdesc_jsonb,
|
|
564
|
+
__newvnum,
|
|
565
|
+
1,
|
|
566
|
+
_dbactionuser,
|
|
567
|
+
__now
|
|
568
|
+
)
|
|
569
|
+
RETURNING oid
|
|
570
|
+
INTO __inserted_oid;
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
-- If this was recovery from historical data with no current row,
|
|
574
|
+
-- preserve the resource-concept ownership of any entity history.
|
|
575
|
+
IF __historical_oid IS NOT NULL THEN
|
|
576
|
+
UPDATE public.stsentity
|
|
577
|
+
SET resourceoid = __inserted_oid
|
|
578
|
+
WHERE resourceoid = __historical_oid;
|
|
579
|
+
END IF;
|
|
580
|
+
|
|
581
|
+
END IF;
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
-- -------------------------------------------------------------------------
|
|
585
|
+
-- Return the newly created/reinstated resource version.
|
|
586
|
+
-- -------------------------------------------------------------------------
|
|
587
|
+
|
|
588
|
+
RETURN QUERY
|
|
589
|
+
SELECT *
|
|
590
|
+
FROM public.stsresource
|
|
591
|
+
WHERE oid = __inserted_oid;
|
|
592
|
+
|
|
593
|
+
END;
|
|
594
|
+
$BODY$;
|
|
595
|
+
|
|
596
|
+
ALTER FUNCTION public.create_stsresource(
|
|
597
|
+
character varying,
|
|
598
|
+
character varying,
|
|
599
|
+
character varying
|
|
600
|
+
)
|
|
601
|
+
OWNER TO postgres;
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
-- =============================================================================
|
|
605
|
+
-- update_stsresource
|
|
606
|
+
-- =============================================================================
|
|
607
|
+
--
|
|
608
|
+
-- Updates a caller-specified current resource version.
|
|
609
|
+
--
|
|
610
|
+
-- The supplied version acts as an optimistic-concurrency requirement:
|
|
611
|
+
-- the resource must still be current, active, and exactly _resvnum.
|
|
612
|
+
--
|
|
613
|
+
-- Creating the next resource version changes the current resource OID, so all
|
|
614
|
+
-- entity history is moved to the new OID to preserve resource-concept
|
|
615
|
+
-- ownership.
|
|
616
|
+
CREATE OR REPLACE FUNCTION public.update_stsresource(
|
|
617
|
+
_dbactionuser character varying,
|
|
618
|
+
_resname character varying,
|
|
619
|
+
_resvnum bigint,
|
|
620
|
+
_resdesc character varying
|
|
621
|
+
)
|
|
622
|
+
RETURNS SETOF public.stsresource
|
|
623
|
+
LANGUAGE plpgsql
|
|
624
|
+
COST 100
|
|
625
|
+
VOLATILE
|
|
626
|
+
ROWS 1
|
|
627
|
+
|
|
628
|
+
AS $BODY$
|
|
629
|
+
DECLARE
|
|
630
|
+
__now timestamptz := now();
|
|
631
|
+
__resoid bigint;
|
|
632
|
+
__newresoid bigint;
|
|
633
|
+
__resdesc_jsonb jsonb;
|
|
634
|
+
BEGIN
|
|
635
|
+
|
|
636
|
+
-- Validate / parse resource JSON.
|
|
637
|
+
BEGIN
|
|
638
|
+
__resdesc_jsonb := _resdesc::jsonb;
|
|
639
|
+
|
|
640
|
+
EXCEPTION
|
|
641
|
+
WHEN invalid_text_representation THEN
|
|
642
|
+
RAISE EXCEPTION
|
|
643
|
+
'Invalid JSON string: %',
|
|
644
|
+
_resdesc
|
|
645
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
646
|
+
END;
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
-- Resolve and lock the requested current, non-deleted resource version.
|
|
650
|
+
BEGIN
|
|
651
|
+
SELECT
|
|
652
|
+
r.oid
|
|
653
|
+
INTO STRICT
|
|
654
|
+
__resoid
|
|
655
|
+
FROM public.stsresource r
|
|
656
|
+
WHERE r.resname = _resname
|
|
657
|
+
AND r.vnum = _resvnum
|
|
658
|
+
AND r.validto IS NULL
|
|
659
|
+
AND r.dbaction != 3
|
|
660
|
+
FOR UPDATE;
|
|
661
|
+
|
|
662
|
+
EXCEPTION
|
|
663
|
+
|
|
664
|
+
WHEN no_data_found THEN
|
|
665
|
+
RAISE
|
|
666
|
+
'Resource % version % not found, not current, or deleted',
|
|
667
|
+
_resname,
|
|
668
|
+
_resvnum
|
|
669
|
+
USING ERRCODE = 'no_data_found';
|
|
670
|
+
|
|
671
|
+
WHEN too_many_rows THEN
|
|
672
|
+
RAISE
|
|
673
|
+
'Too many current stsresource records for resource % version %',
|
|
674
|
+
_resname,
|
|
675
|
+
_resvnum
|
|
676
|
+
USING ERRCODE = 'cardinality_violation';
|
|
677
|
+
|
|
678
|
+
END;
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
-- Close the previous active resource version.
|
|
682
|
+
UPDATE public.stsresource
|
|
683
|
+
SET validto = __now
|
|
684
|
+
WHERE oid = __resoid;
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
-- Create the next active resource version.
|
|
688
|
+
INSERT INTO public.stsresource(
|
|
689
|
+
resname,
|
|
690
|
+
resdesc,
|
|
691
|
+
resdesc_jsonb,
|
|
692
|
+
vnum,
|
|
693
|
+
dbaction,
|
|
694
|
+
dbactionuser,
|
|
695
|
+
validfrom
|
|
696
|
+
)
|
|
697
|
+
VALUES (
|
|
698
|
+
_resname,
|
|
699
|
+
_resdesc,
|
|
700
|
+
__resdesc_jsonb,
|
|
701
|
+
_resvnum + 1,
|
|
702
|
+
2,
|
|
703
|
+
_dbactionuser,
|
|
704
|
+
__now
|
|
705
|
+
)
|
|
706
|
+
RETURNING oid
|
|
707
|
+
INTO __newresoid;
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
-- Move all entity history to the new current resource OID.
|
|
711
|
+
UPDATE public.stsentity
|
|
712
|
+
SET resourceoid = __newresoid
|
|
713
|
+
WHERE resourceoid = __resoid;
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
-- Return the new resource version.
|
|
717
|
+
RETURN QUERY
|
|
718
|
+
SELECT *
|
|
719
|
+
FROM public.stsresource
|
|
720
|
+
WHERE oid = __newresoid;
|
|
721
|
+
|
|
722
|
+
END;
|
|
723
|
+
$BODY$;
|
|
724
|
+
|
|
725
|
+
ALTER FUNCTION public.update_stsresource(
|
|
726
|
+
character varying,
|
|
727
|
+
character varying,
|
|
728
|
+
bigint,
|
|
729
|
+
character varying
|
|
730
|
+
)
|
|
731
|
+
OWNER TO postgres;
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
-- =============================================================================
|
|
735
|
+
-- update_stsresource_latest
|
|
736
|
+
-- =============================================================================
|
|
737
|
+
--
|
|
738
|
+
-- Updates the current active resource without requiring the caller to supply
|
|
739
|
+
-- its version number.
|
|
740
|
+
--
|
|
741
|
+
-- oid and vnum are resolved in one locked query to avoid the duplicate lookups
|
|
742
|
+
-- used by the original implementation.
|
|
743
|
+
CREATE OR REPLACE FUNCTION public.update_stsresource_latest(
|
|
744
|
+
_dbactionuser character varying,
|
|
745
|
+
_resname character varying,
|
|
746
|
+
_resdesc character varying
|
|
747
|
+
)
|
|
748
|
+
RETURNS SETOF public.stsresource
|
|
749
|
+
LANGUAGE plpgsql
|
|
750
|
+
COST 100
|
|
751
|
+
VOLATILE
|
|
752
|
+
ROWS 1
|
|
753
|
+
|
|
754
|
+
AS $BODY$
|
|
755
|
+
DECLARE
|
|
756
|
+
__now timestamptz := now();
|
|
757
|
+
__resoid bigint;
|
|
758
|
+
__resvnum bigint;
|
|
759
|
+
__newresoid bigint;
|
|
760
|
+
__resdesc_jsonb jsonb;
|
|
761
|
+
BEGIN
|
|
762
|
+
|
|
763
|
+
-- Validate / parse resource JSON.
|
|
764
|
+
BEGIN
|
|
765
|
+
__resdesc_jsonb := _resdesc::jsonb;
|
|
766
|
+
|
|
767
|
+
EXCEPTION
|
|
768
|
+
WHEN invalid_text_representation THEN
|
|
769
|
+
RAISE EXCEPTION
|
|
770
|
+
'Invalid JSON string: %',
|
|
771
|
+
_resdesc
|
|
772
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
773
|
+
END;
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
-- Resolve and lock the current active resource in one operation.
|
|
777
|
+
BEGIN
|
|
778
|
+
SELECT
|
|
779
|
+
r.oid,
|
|
780
|
+
r.vnum
|
|
781
|
+
INTO STRICT
|
|
782
|
+
__resoid,
|
|
783
|
+
__resvnum
|
|
784
|
+
FROM public.stsresource r
|
|
785
|
+
WHERE r.resname = _resname
|
|
786
|
+
AND r.validto IS NULL
|
|
787
|
+
AND r.dbaction != 3
|
|
788
|
+
FOR UPDATE;
|
|
789
|
+
|
|
790
|
+
EXCEPTION
|
|
791
|
+
|
|
792
|
+
WHEN no_data_found THEN
|
|
793
|
+
RAISE
|
|
794
|
+
'Resource % not found, not current, or deleted',
|
|
795
|
+
_resname
|
|
796
|
+
USING ERRCODE = 'no_data_found';
|
|
797
|
+
|
|
798
|
+
WHEN too_many_rows THEN
|
|
799
|
+
RAISE
|
|
800
|
+
'Too many current stsresource records for resource %',
|
|
801
|
+
_resname
|
|
802
|
+
USING ERRCODE = 'cardinality_violation';
|
|
803
|
+
|
|
804
|
+
END;
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
-- Close the previous active resource version.
|
|
808
|
+
UPDATE public.stsresource
|
|
809
|
+
SET validto = __now
|
|
810
|
+
WHERE oid = __resoid;
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
-- Create the next active resource version.
|
|
814
|
+
INSERT INTO public.stsresource(
|
|
815
|
+
resname,
|
|
816
|
+
resdesc,
|
|
817
|
+
resdesc_jsonb,
|
|
818
|
+
vnum,
|
|
819
|
+
dbaction,
|
|
820
|
+
dbactionuser,
|
|
821
|
+
validfrom
|
|
822
|
+
)
|
|
823
|
+
VALUES (
|
|
824
|
+
_resname,
|
|
825
|
+
_resdesc,
|
|
826
|
+
__resdesc_jsonb,
|
|
827
|
+
__resvnum + 1,
|
|
828
|
+
2,
|
|
829
|
+
_dbactionuser,
|
|
830
|
+
__now
|
|
831
|
+
)
|
|
832
|
+
RETURNING oid
|
|
833
|
+
INTO __newresoid;
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
-- Preserve resource-concept ownership for all entity history.
|
|
837
|
+
UPDATE public.stsentity
|
|
838
|
+
SET resourceoid = __newresoid
|
|
839
|
+
WHERE resourceoid = __resoid;
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
-- Return the new resource version.
|
|
843
|
+
RETURN QUERY
|
|
844
|
+
SELECT *
|
|
845
|
+
FROM public.stsresource
|
|
846
|
+
WHERE oid = __newresoid;
|
|
847
|
+
|
|
848
|
+
END;
|
|
849
|
+
$BODY$;
|
|
850
|
+
|
|
851
|
+
ALTER FUNCTION public.update_stsresource_latest(
|
|
852
|
+
character varying,
|
|
853
|
+
character varying,
|
|
854
|
+
character varying
|
|
855
|
+
)
|
|
856
|
+
OWNER TO postgres;
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
-- =============================================================================
|
|
860
|
+
-- delete_stsresource
|
|
861
|
+
-- =============================================================================
|
|
862
|
+
--
|
|
863
|
+
-- Logically deletes a caller-specified current resource version.
|
|
864
|
+
--
|
|
865
|
+
-- Delete is versioned: the active row is closed and a new dbaction=3 tombstone
|
|
866
|
+
-- becomes the current resource version.
|
|
867
|
+
--
|
|
868
|
+
-- Entity rows are NOT individually deleted. Their complete history is moved to
|
|
869
|
+
-- the new resource tombstone OID. If the resource is later recreated, those
|
|
870
|
+
-- same rows are moved again to the reinstated active resource OID.
|
|
871
|
+
CREATE OR REPLACE FUNCTION public.delete_stsresource(
|
|
872
|
+
_dbactionuser character varying,
|
|
873
|
+
_resname character varying,
|
|
874
|
+
_resvnum bigint
|
|
875
|
+
)
|
|
876
|
+
RETURNS SETOF public.stsresource
|
|
877
|
+
LANGUAGE plpgsql
|
|
878
|
+
COST 100
|
|
879
|
+
VOLATILE
|
|
880
|
+
ROWS 1
|
|
881
|
+
|
|
882
|
+
AS $BODY$
|
|
883
|
+
DECLARE
|
|
884
|
+
__now timestamptz := now();
|
|
885
|
+
__resoid bigint;
|
|
886
|
+
__newresoid bigint;
|
|
887
|
+
BEGIN
|
|
888
|
+
|
|
889
|
+
-- Resolve and lock the requested current active resource version.
|
|
890
|
+
BEGIN
|
|
891
|
+
SELECT
|
|
892
|
+
r.oid
|
|
893
|
+
INTO STRICT
|
|
894
|
+
__resoid
|
|
895
|
+
FROM public.stsresource r
|
|
896
|
+
WHERE r.resname = _resname
|
|
897
|
+
AND r.vnum = _resvnum
|
|
898
|
+
AND r.validto IS NULL
|
|
899
|
+
AND r.dbaction != 3
|
|
900
|
+
FOR UPDATE;
|
|
901
|
+
|
|
902
|
+
EXCEPTION
|
|
903
|
+
|
|
904
|
+
WHEN no_data_found THEN
|
|
905
|
+
RAISE
|
|
906
|
+
'Resource % version % not found, not current, or deleted',
|
|
907
|
+
_resname,
|
|
908
|
+
_resvnum
|
|
909
|
+
USING ERRCODE = 'no_data_found';
|
|
910
|
+
|
|
911
|
+
WHEN too_many_rows THEN
|
|
912
|
+
RAISE
|
|
913
|
+
'Too many current stsresource records for resource % version %',
|
|
914
|
+
_resname,
|
|
915
|
+
_resvnum
|
|
916
|
+
USING ERRCODE = 'cardinality_violation';
|
|
917
|
+
|
|
918
|
+
END;
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
-- Close the current active resource version.
|
|
922
|
+
UPDATE public.stsresource
|
|
923
|
+
SET validto = __now
|
|
924
|
+
WHERE oid = __resoid;
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
-- Create the delete tombstone.
|
|
928
|
+
--
|
|
929
|
+
-- Copy resdesc_jsonb directly rather than reparsing resdesc text.
|
|
930
|
+
INSERT INTO public.stsresource(
|
|
931
|
+
resname,
|
|
932
|
+
resdesc,
|
|
933
|
+
resdesc_jsonb,
|
|
934
|
+
vnum,
|
|
935
|
+
dbaction,
|
|
936
|
+
dbactionuser,
|
|
937
|
+
validfrom
|
|
938
|
+
)
|
|
939
|
+
SELECT
|
|
940
|
+
r.resname,
|
|
941
|
+
r.resdesc,
|
|
942
|
+
r.resdesc_jsonb,
|
|
943
|
+
_resvnum + 1,
|
|
944
|
+
3,
|
|
945
|
+
_dbactionuser,
|
|
946
|
+
__now
|
|
947
|
+
FROM public.stsresource r
|
|
948
|
+
WHERE r.oid = __resoid
|
|
949
|
+
RETURNING oid
|
|
950
|
+
INTO __newresoid;
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
-- Preserve the entity history under the current resource tombstone OID.
|
|
954
|
+
UPDATE public.stsentity
|
|
955
|
+
SET resourceoid = __newresoid
|
|
956
|
+
WHERE resourceoid = __resoid;
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
-- Return the delete tombstone.
|
|
960
|
+
RETURN QUERY
|
|
961
|
+
SELECT *
|
|
962
|
+
FROM public.stsresource
|
|
963
|
+
WHERE oid = __newresoid;
|
|
964
|
+
|
|
965
|
+
END;
|
|
966
|
+
$BODY$;
|
|
967
|
+
|
|
968
|
+
ALTER FUNCTION public.delete_stsresource(
|
|
969
|
+
character varying,
|
|
970
|
+
character varying,
|
|
971
|
+
bigint
|
|
972
|
+
)
|
|
973
|
+
OWNER TO postgres;
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
-- =============================================================================
|
|
977
|
+
-- delete_stsresource_latest
|
|
978
|
+
-- =============================================================================
|
|
979
|
+
--
|
|
980
|
+
-- Logically deletes the current active resource without requiring the caller to
|
|
981
|
+
-- provide its version number.
|
|
982
|
+
--
|
|
983
|
+
-- The current OID and version are resolved together and locked in one query.
|
|
984
|
+
CREATE OR REPLACE FUNCTION public.delete_stsresource_latest(
|
|
985
|
+
_dbactionuser character varying,
|
|
986
|
+
_resname character varying
|
|
987
|
+
)
|
|
988
|
+
RETURNS SETOF public.stsresource
|
|
989
|
+
LANGUAGE plpgsql
|
|
990
|
+
COST 100
|
|
991
|
+
VOLATILE
|
|
992
|
+
ROWS 1
|
|
993
|
+
|
|
994
|
+
AS $BODY$
|
|
995
|
+
DECLARE
|
|
996
|
+
__now timestamptz := now();
|
|
997
|
+
__resoid bigint;
|
|
998
|
+
__resvnum bigint;
|
|
999
|
+
__newresoid bigint;
|
|
1000
|
+
BEGIN
|
|
1001
|
+
|
|
1002
|
+
-- Resolve and lock the current active resource.
|
|
1003
|
+
BEGIN
|
|
1004
|
+
SELECT
|
|
1005
|
+
r.oid,
|
|
1006
|
+
r.vnum
|
|
1007
|
+
INTO STRICT
|
|
1008
|
+
__resoid,
|
|
1009
|
+
__resvnum
|
|
1010
|
+
FROM public.stsresource r
|
|
1011
|
+
WHERE r.resname = _resname
|
|
1012
|
+
AND r.validto IS NULL
|
|
1013
|
+
AND r.dbaction != 3
|
|
1014
|
+
FOR UPDATE;
|
|
1015
|
+
|
|
1016
|
+
EXCEPTION
|
|
1017
|
+
|
|
1018
|
+
WHEN no_data_found THEN
|
|
1019
|
+
RAISE
|
|
1020
|
+
'Resource % not found, not current, or deleted',
|
|
1021
|
+
_resname
|
|
1022
|
+
USING ERRCODE = 'no_data_found';
|
|
1023
|
+
|
|
1024
|
+
WHEN too_many_rows THEN
|
|
1025
|
+
RAISE
|
|
1026
|
+
'Too many current stsresource records for resource %',
|
|
1027
|
+
_resname
|
|
1028
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1029
|
+
|
|
1030
|
+
END;
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
-- Close the current active resource version.
|
|
1034
|
+
UPDATE public.stsresource
|
|
1035
|
+
SET validto = __now
|
|
1036
|
+
WHERE oid = __resoid;
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
-- Create the delete tombstone.
|
|
1040
|
+
--
|
|
1041
|
+
-- The original implementation accidentally omitted resdesc_jsonb from the
|
|
1042
|
+
-- SELECT even though it was present in the INSERT column list. This version
|
|
1043
|
+
-- copies the already parsed JSONB value correctly.
|
|
1044
|
+
INSERT INTO public.stsresource(
|
|
1045
|
+
resname,
|
|
1046
|
+
resdesc,
|
|
1047
|
+
resdesc_jsonb,
|
|
1048
|
+
vnum,
|
|
1049
|
+
dbaction,
|
|
1050
|
+
dbactionuser,
|
|
1051
|
+
validfrom
|
|
1052
|
+
)
|
|
1053
|
+
SELECT
|
|
1054
|
+
r.resname,
|
|
1055
|
+
r.resdesc,
|
|
1056
|
+
r.resdesc_jsonb,
|
|
1057
|
+
__resvnum + 1,
|
|
1058
|
+
3,
|
|
1059
|
+
_dbactionuser,
|
|
1060
|
+
__now
|
|
1061
|
+
FROM public.stsresource r
|
|
1062
|
+
WHERE r.oid = __resoid
|
|
1063
|
+
RETURNING oid
|
|
1064
|
+
INTO __newresoid;
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
-- Preserve the entity history under the current resource tombstone OID.
|
|
1068
|
+
UPDATE public.stsentity
|
|
1069
|
+
SET resourceoid = __newresoid
|
|
1070
|
+
WHERE resourceoid = __resoid;
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
-- Return the delete tombstone.
|
|
1074
|
+
RETURN QUERY
|
|
1075
|
+
SELECT *
|
|
1076
|
+
FROM public.stsresource
|
|
1077
|
+
WHERE oid = __newresoid;
|
|
1078
|
+
|
|
1079
|
+
END;
|
|
1080
|
+
$BODY$;
|
|
1081
|
+
|
|
1082
|
+
ALTER FUNCTION public.delete_stsresource_latest(
|
|
1083
|
+
character varying,
|
|
1084
|
+
character varying
|
|
1085
|
+
)
|
|
1086
|
+
OWNER TO postgres;
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
-- =============================================================================
|
|
1090
|
+
-- Entity functions
|
|
1091
|
+
-- =============================================================================
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
-- =============================================================================
|
|
1095
|
+
-- create_stsentity
|
|
1096
|
+
-- =============================================================================
|
|
1097
|
+
--
|
|
1098
|
+
-- Creates an entity against a caller-specified current resource version.
|
|
1099
|
+
--
|
|
1100
|
+
-- A deleted entity is still the current entity tombstone. CREATE against a
|
|
1101
|
+
-- deleted entity closes that tombstone and continues the entity version chain.
|
|
1102
|
+
--
|
|
1103
|
+
-- The current resource row is locked first. This prevents the resource from
|
|
1104
|
+
-- changing OID while the entity operation is in progress.
|
|
1105
|
+
CREATE OR REPLACE FUNCTION public.create_stsentity(
|
|
1106
|
+
_dbactionuser character varying,
|
|
1107
|
+
_resname character varying,
|
|
1108
|
+
_resvnum bigint,
|
|
1109
|
+
_entname character varying,
|
|
1110
|
+
_entvalue character varying
|
|
1111
|
+
)
|
|
1112
|
+
RETURNS SETOF public.stsentity
|
|
1113
|
+
LANGUAGE plpgsql
|
|
1114
|
+
COST 100
|
|
1115
|
+
VOLATILE
|
|
1116
|
+
ROWS 1
|
|
1117
|
+
|
|
1118
|
+
AS $BODY$
|
|
1119
|
+
DECLARE
|
|
1120
|
+
__now timestamptz := now();
|
|
1121
|
+
|
|
1122
|
+
-- Current resource.
|
|
1123
|
+
__resoid bigint;
|
|
1124
|
+
|
|
1125
|
+
-- Current entity, if one exists.
|
|
1126
|
+
__entoid bigint;
|
|
1127
|
+
__entvnum bigint;
|
|
1128
|
+
__entdbaction smallint;
|
|
1129
|
+
|
|
1130
|
+
-- Version/OID for the new active entity.
|
|
1131
|
+
__newvnum bigint;
|
|
1132
|
+
__inserted_oid bigint;
|
|
1133
|
+
|
|
1134
|
+
-- Parsed JSON.
|
|
1135
|
+
__entvalue_jsonb jsonb;
|
|
1136
|
+
BEGIN
|
|
1137
|
+
|
|
1138
|
+
-- -------------------------------------------------------------------------
|
|
1139
|
+
-- Validate / parse entity JSON.
|
|
1140
|
+
-- -------------------------------------------------------------------------
|
|
1141
|
+
|
|
1142
|
+
BEGIN
|
|
1143
|
+
__entvalue_jsonb := _entvalue::jsonb;
|
|
1144
|
+
|
|
1145
|
+
EXCEPTION
|
|
1146
|
+
WHEN invalid_text_representation THEN
|
|
1147
|
+
RAISE EXCEPTION
|
|
1148
|
+
'Invalid JSON string: %',
|
|
1149
|
+
_entvalue
|
|
1150
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
1151
|
+
END;
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
-- -------------------------------------------------------------------------
|
|
1155
|
+
-- Resolve and lock the requested current, non-deleted resource version.
|
|
1156
|
+
--
|
|
1157
|
+
-- Locking the resource prevents a concurrent resource update/delete from
|
|
1158
|
+
-- changing resourceoid while this entity transaction is operating.
|
|
1159
|
+
-- -------------------------------------------------------------------------
|
|
1160
|
+
|
|
1161
|
+
BEGIN
|
|
1162
|
+
SELECT
|
|
1163
|
+
r.oid
|
|
1164
|
+
INTO STRICT
|
|
1165
|
+
__resoid
|
|
1166
|
+
FROM public.stsresource r
|
|
1167
|
+
WHERE r.resname = _resname
|
|
1168
|
+
AND r.vnum = _resvnum
|
|
1169
|
+
AND r.validto IS NULL
|
|
1170
|
+
AND r.dbaction != 3
|
|
1171
|
+
FOR UPDATE;
|
|
1172
|
+
|
|
1173
|
+
EXCEPTION
|
|
1174
|
+
|
|
1175
|
+
WHEN no_data_found THEN
|
|
1176
|
+
RAISE
|
|
1177
|
+
'Resource % version % not found, not current, or deleted',
|
|
1178
|
+
_resname,
|
|
1179
|
+
_resvnum
|
|
1180
|
+
USING ERRCODE = 'no_data_found';
|
|
1181
|
+
|
|
1182
|
+
WHEN too_many_rows THEN
|
|
1183
|
+
RAISE
|
|
1184
|
+
'Too many current stsresource records for resource % version %',
|
|
1185
|
+
_resname,
|
|
1186
|
+
_resvnum
|
|
1187
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1188
|
+
|
|
1189
|
+
END;
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
-- -------------------------------------------------------------------------
|
|
1193
|
+
-- Find and lock the current entity.
|
|
1194
|
+
--
|
|
1195
|
+
-- IMPORTANT:
|
|
1196
|
+
-- Do NOT exclude dbaction = 3.
|
|
1197
|
+
--
|
|
1198
|
+
-- A logically deleted entity remains the current entity version and must be
|
|
1199
|
+
-- closed before it can be recreated.
|
|
1200
|
+
-- -------------------------------------------------------------------------
|
|
1201
|
+
|
|
1202
|
+
BEGIN
|
|
1203
|
+
SELECT
|
|
1204
|
+
e.oid,
|
|
1205
|
+
e.vnum,
|
|
1206
|
+
e.dbaction
|
|
1207
|
+
INTO STRICT
|
|
1208
|
+
__entoid,
|
|
1209
|
+
__entvnum,
|
|
1210
|
+
__entdbaction
|
|
1211
|
+
FROM public.stsentity e
|
|
1212
|
+
WHERE e.resourceoid = __resoid
|
|
1213
|
+
AND e.entname = _entname
|
|
1214
|
+
AND e.validto IS NULL
|
|
1215
|
+
FOR UPDATE;
|
|
1216
|
+
|
|
1217
|
+
EXCEPTION
|
|
1218
|
+
|
|
1219
|
+
WHEN no_data_found THEN
|
|
1220
|
+
__entoid := NULL;
|
|
1221
|
+
__entvnum := NULL;
|
|
1222
|
+
__entdbaction := NULL;
|
|
1223
|
+
|
|
1224
|
+
WHEN too_many_rows THEN
|
|
1225
|
+
RAISE
|
|
1226
|
+
'Too many current stsentity records for entity % within resource %',
|
|
1227
|
+
_entname,
|
|
1228
|
+
_resname
|
|
1229
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1230
|
+
|
|
1231
|
+
END;
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
-- -------------------------------------------------------------------------
|
|
1235
|
+
-- A current entity exists.
|
|
1236
|
+
-- -------------------------------------------------------------------------
|
|
1237
|
+
|
|
1238
|
+
IF __entoid IS NOT NULL THEN
|
|
1239
|
+
|
|
1240
|
+
-- Active current entity: CREATE is a duplicate.
|
|
1241
|
+
IF __entdbaction != 3 THEN
|
|
1242
|
+
RAISE
|
|
1243
|
+
'Duplicate entname % within stsresource %',
|
|
1244
|
+
_entname,
|
|
1245
|
+
_resname
|
|
1246
|
+
USING ERRCODE = 'unique_violation';
|
|
1247
|
+
END IF;
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
-- Deleted current entity: close the tombstone and continue versioning.
|
|
1251
|
+
UPDATE public.stsentity
|
|
1252
|
+
SET validto = __now
|
|
1253
|
+
WHERE oid = __entoid;
|
|
1254
|
+
|
|
1255
|
+
__newvnum := __entvnum + 1;
|
|
1256
|
+
|
|
1257
|
+
ELSE
|
|
1258
|
+
|
|
1259
|
+
-- ---------------------------------------------------------------------
|
|
1260
|
+
-- No current entity exists.
|
|
1261
|
+
--
|
|
1262
|
+
-- Normally this is the first creation, producing version 1.
|
|
1263
|
+
--
|
|
1264
|
+
-- MAX(vnum) also protects against an abnormal history in which previous
|
|
1265
|
+
-- versions exist but no entity row currently has validto IS NULL.
|
|
1266
|
+
-- ---------------------------------------------------------------------
|
|
1267
|
+
|
|
1268
|
+
SELECT
|
|
1269
|
+
COALESCE(MAX(e.vnum), 0) + 1
|
|
1270
|
+
INTO
|
|
1271
|
+
__newvnum
|
|
1272
|
+
FROM public.stsentity e
|
|
1273
|
+
WHERE e.resourceoid = __resoid
|
|
1274
|
+
AND e.entname = _entname;
|
|
1275
|
+
|
|
1276
|
+
END IF;
|
|
1277
|
+
|
|
1278
|
+
|
|
1279
|
+
-- Create the new active entity version.
|
|
1280
|
+
INSERT INTO public.stsentity(
|
|
1281
|
+
resourceoid,
|
|
1282
|
+
entname,
|
|
1283
|
+
entvalue,
|
|
1284
|
+
entvalue_jsonb,
|
|
1285
|
+
vnum,
|
|
1286
|
+
dbaction,
|
|
1287
|
+
dbactionuser,
|
|
1288
|
+
validfrom
|
|
1289
|
+
)
|
|
1290
|
+
VALUES (
|
|
1291
|
+
__resoid,
|
|
1292
|
+
_entname,
|
|
1293
|
+
_entvalue,
|
|
1294
|
+
__entvalue_jsonb,
|
|
1295
|
+
__newvnum,
|
|
1296
|
+
1,
|
|
1297
|
+
_dbactionuser,
|
|
1298
|
+
__now
|
|
1299
|
+
)
|
|
1300
|
+
RETURNING oid
|
|
1301
|
+
INTO __inserted_oid;
|
|
1302
|
+
|
|
1303
|
+
|
|
1304
|
+
-- Return the newly created/recreated entity.
|
|
1305
|
+
RETURN QUERY
|
|
1306
|
+
SELECT *
|
|
1307
|
+
FROM public.stsentity
|
|
1308
|
+
WHERE oid = __inserted_oid;
|
|
1309
|
+
|
|
1310
|
+
END;
|
|
1311
|
+
$BODY$;
|
|
1312
|
+
|
|
1313
|
+
ALTER FUNCTION public.create_stsentity(
|
|
1314
|
+
character varying,
|
|
1315
|
+
character varying,
|
|
1316
|
+
bigint,
|
|
1317
|
+
character varying,
|
|
1318
|
+
character varying
|
|
1319
|
+
)
|
|
1320
|
+
OWNER TO postgres;
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
-- =============================================================================
|
|
1324
|
+
-- create_stsentity_latest
|
|
1325
|
+
-- =============================================================================
|
|
1326
|
+
--
|
|
1327
|
+
-- Creates an entity against the latest/current active resource version.
|
|
1328
|
+
--
|
|
1329
|
+
-- This is identical in entity semantics to create_stsentity, except the caller
|
|
1330
|
+
-- does not supply the resource version.
|
|
1331
|
+
CREATE OR REPLACE FUNCTION public.create_stsentity_latest(
|
|
1332
|
+
_dbactionuser character varying,
|
|
1333
|
+
_resname character varying,
|
|
1334
|
+
_entname character varying,
|
|
1335
|
+
_entvalue character varying
|
|
1336
|
+
)
|
|
1337
|
+
RETURNS SETOF public.stsentity
|
|
1338
|
+
LANGUAGE plpgsql
|
|
1339
|
+
COST 100
|
|
1340
|
+
VOLATILE
|
|
1341
|
+
ROWS 1
|
|
1342
|
+
|
|
1343
|
+
AS $BODY$
|
|
1344
|
+
DECLARE
|
|
1345
|
+
__now timestamptz := now();
|
|
1346
|
+
|
|
1347
|
+
__resoid bigint;
|
|
1348
|
+
|
|
1349
|
+
__entoid bigint;
|
|
1350
|
+
__entvnum bigint;
|
|
1351
|
+
__entdbaction smallint;
|
|
1352
|
+
|
|
1353
|
+
__newvnum bigint;
|
|
1354
|
+
__inserted_oid bigint;
|
|
1355
|
+
|
|
1356
|
+
__entvalue_jsonb jsonb;
|
|
1357
|
+
BEGIN
|
|
1358
|
+
|
|
1359
|
+
-- Validate / parse entity JSON.
|
|
1360
|
+
BEGIN
|
|
1361
|
+
__entvalue_jsonb := _entvalue::jsonb;
|
|
1362
|
+
|
|
1363
|
+
EXCEPTION
|
|
1364
|
+
WHEN invalid_text_representation THEN
|
|
1365
|
+
RAISE EXCEPTION
|
|
1366
|
+
'Invalid JSON string: %',
|
|
1367
|
+
_entvalue
|
|
1368
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
1369
|
+
END;
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
-- Resolve and lock the current active resource.
|
|
1373
|
+
BEGIN
|
|
1374
|
+
SELECT
|
|
1375
|
+
r.oid
|
|
1376
|
+
INTO STRICT
|
|
1377
|
+
__resoid
|
|
1378
|
+
FROM public.stsresource r
|
|
1379
|
+
WHERE r.resname = _resname
|
|
1380
|
+
AND r.validto IS NULL
|
|
1381
|
+
AND r.dbaction != 3
|
|
1382
|
+
FOR UPDATE;
|
|
1383
|
+
|
|
1384
|
+
EXCEPTION
|
|
1385
|
+
|
|
1386
|
+
WHEN no_data_found THEN
|
|
1387
|
+
RAISE
|
|
1388
|
+
'Resource % not found, not current, or deleted',
|
|
1389
|
+
_resname
|
|
1390
|
+
USING ERRCODE = 'no_data_found';
|
|
1391
|
+
|
|
1392
|
+
WHEN too_many_rows THEN
|
|
1393
|
+
RAISE
|
|
1394
|
+
'Too many current stsresource records for resource %',
|
|
1395
|
+
_resname
|
|
1396
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1397
|
+
|
|
1398
|
+
END;
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
-- Resolve and lock the current entity, including a deleted tombstone.
|
|
1402
|
+
BEGIN
|
|
1403
|
+
SELECT
|
|
1404
|
+
e.oid,
|
|
1405
|
+
e.vnum,
|
|
1406
|
+
e.dbaction
|
|
1407
|
+
INTO STRICT
|
|
1408
|
+
__entoid,
|
|
1409
|
+
__entvnum,
|
|
1410
|
+
__entdbaction
|
|
1411
|
+
FROM public.stsentity e
|
|
1412
|
+
WHERE e.resourceoid = __resoid
|
|
1413
|
+
AND e.entname = _entname
|
|
1414
|
+
AND e.validto IS NULL
|
|
1415
|
+
FOR UPDATE;
|
|
1416
|
+
|
|
1417
|
+
EXCEPTION
|
|
1418
|
+
|
|
1419
|
+
WHEN no_data_found THEN
|
|
1420
|
+
__entoid := NULL;
|
|
1421
|
+
__entvnum := NULL;
|
|
1422
|
+
__entdbaction := NULL;
|
|
1423
|
+
|
|
1424
|
+
WHEN too_many_rows THEN
|
|
1425
|
+
RAISE
|
|
1426
|
+
'Too many current stsentity records for entity % within resource %',
|
|
1427
|
+
_entname,
|
|
1428
|
+
_resname
|
|
1429
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1430
|
+
|
|
1431
|
+
END;
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
-- Current entity exists.
|
|
1435
|
+
IF __entoid IS NOT NULL THEN
|
|
1436
|
+
|
|
1437
|
+
-- Active entity already exists.
|
|
1438
|
+
IF __entdbaction != 3 THEN
|
|
1439
|
+
RAISE
|
|
1440
|
+
'Duplicate entname % within stsresource %',
|
|
1441
|
+
_entname,
|
|
1442
|
+
_resname
|
|
1443
|
+
USING ERRCODE = 'unique_violation';
|
|
1444
|
+
END IF;
|
|
1445
|
+
|
|
1446
|
+
-- Recreate the deleted entity by closing its tombstone.
|
|
1447
|
+
UPDATE public.stsentity
|
|
1448
|
+
SET validto = __now
|
|
1449
|
+
WHERE oid = __entoid;
|
|
1450
|
+
|
|
1451
|
+
__newvnum := __entvnum + 1;
|
|
1452
|
+
|
|
1453
|
+
ELSE
|
|
1454
|
+
|
|
1455
|
+
-- First creation, or recovery from history with no current row.
|
|
1456
|
+
SELECT
|
|
1457
|
+
COALESCE(MAX(e.vnum), 0) + 1
|
|
1458
|
+
INTO
|
|
1459
|
+
__newvnum
|
|
1460
|
+
FROM public.stsentity e
|
|
1461
|
+
WHERE e.resourceoid = __resoid
|
|
1462
|
+
AND e.entname = _entname;
|
|
1463
|
+
|
|
1464
|
+
END IF;
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
-- Create the new active entity version.
|
|
1468
|
+
INSERT INTO public.stsentity(
|
|
1469
|
+
resourceoid,
|
|
1470
|
+
entname,
|
|
1471
|
+
entvalue,
|
|
1472
|
+
entvalue_jsonb,
|
|
1473
|
+
vnum,
|
|
1474
|
+
dbaction,
|
|
1475
|
+
dbactionuser,
|
|
1476
|
+
validfrom
|
|
1477
|
+
)
|
|
1478
|
+
VALUES (
|
|
1479
|
+
__resoid,
|
|
1480
|
+
_entname,
|
|
1481
|
+
_entvalue,
|
|
1482
|
+
__entvalue_jsonb,
|
|
1483
|
+
__newvnum,
|
|
1484
|
+
1,
|
|
1485
|
+
_dbactionuser,
|
|
1486
|
+
__now
|
|
1487
|
+
)
|
|
1488
|
+
RETURNING oid
|
|
1489
|
+
INTO __inserted_oid;
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
-- Return the new entity version.
|
|
1493
|
+
RETURN QUERY
|
|
1494
|
+
SELECT *
|
|
1495
|
+
FROM public.stsentity
|
|
1496
|
+
WHERE oid = __inserted_oid;
|
|
1497
|
+
|
|
1498
|
+
END;
|
|
1499
|
+
$BODY$;
|
|
1500
|
+
|
|
1501
|
+
ALTER FUNCTION public.create_stsentity_latest(
|
|
1502
|
+
character varying,
|
|
1503
|
+
character varying,
|
|
1504
|
+
character varying,
|
|
1505
|
+
character varying
|
|
1506
|
+
)
|
|
1507
|
+
OWNER TO postgres;
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
-- =============================================================================
|
|
1511
|
+
-- update_stsentity
|
|
1512
|
+
-- =============================================================================
|
|
1513
|
+
--
|
|
1514
|
+
-- Updates a caller-specified current entity version under a caller-specified
|
|
1515
|
+
-- current resource version.
|
|
1516
|
+
--
|
|
1517
|
+
-- Both version arguments therefore act as optimistic-concurrency requirements.
|
|
1518
|
+
CREATE OR REPLACE FUNCTION public.update_stsentity(
|
|
1519
|
+
_dbactionuser character varying,
|
|
1520
|
+
_resname character varying,
|
|
1521
|
+
_resvnum bigint,
|
|
1522
|
+
_entname character varying,
|
|
1523
|
+
_entvnum bigint,
|
|
1524
|
+
_entvalue character varying
|
|
1525
|
+
)
|
|
1526
|
+
RETURNS SETOF public.stsentity
|
|
1527
|
+
LANGUAGE plpgsql
|
|
1528
|
+
COST 100
|
|
1529
|
+
VOLATILE
|
|
1530
|
+
ROWS 1
|
|
1531
|
+
|
|
1532
|
+
AS $BODY$
|
|
1533
|
+
DECLARE
|
|
1534
|
+
__now timestamptz := now();
|
|
1535
|
+
__resoid bigint;
|
|
1536
|
+
__entoid bigint;
|
|
1537
|
+
__inserted_oid bigint;
|
|
1538
|
+
__entvalue_jsonb jsonb;
|
|
1539
|
+
BEGIN
|
|
1540
|
+
|
|
1541
|
+
-- Validate / parse entity JSON.
|
|
1542
|
+
BEGIN
|
|
1543
|
+
__entvalue_jsonb := _entvalue::jsonb;
|
|
1544
|
+
|
|
1545
|
+
EXCEPTION
|
|
1546
|
+
WHEN invalid_text_representation THEN
|
|
1547
|
+
RAISE EXCEPTION
|
|
1548
|
+
'Invalid JSON string: %',
|
|
1549
|
+
_entvalue
|
|
1550
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
1551
|
+
END;
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
-- Resolve and lock the requested current active resource version.
|
|
1555
|
+
BEGIN
|
|
1556
|
+
SELECT
|
|
1557
|
+
r.oid
|
|
1558
|
+
INTO STRICT
|
|
1559
|
+
__resoid
|
|
1560
|
+
FROM public.stsresource r
|
|
1561
|
+
WHERE r.resname = _resname
|
|
1562
|
+
AND r.vnum = _resvnum
|
|
1563
|
+
AND r.validto IS NULL
|
|
1564
|
+
AND r.dbaction != 3
|
|
1565
|
+
FOR UPDATE;
|
|
1566
|
+
|
|
1567
|
+
EXCEPTION
|
|
1568
|
+
|
|
1569
|
+
WHEN no_data_found THEN
|
|
1570
|
+
RAISE
|
|
1571
|
+
'Resource % version % not found, not current, or deleted',
|
|
1572
|
+
_resname,
|
|
1573
|
+
_resvnum
|
|
1574
|
+
USING ERRCODE = 'no_data_found';
|
|
1575
|
+
|
|
1576
|
+
WHEN too_many_rows THEN
|
|
1577
|
+
RAISE
|
|
1578
|
+
'Too many current stsresource records for resource % version %',
|
|
1579
|
+
_resname,
|
|
1580
|
+
_resvnum
|
|
1581
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1582
|
+
|
|
1583
|
+
END;
|
|
1584
|
+
|
|
1585
|
+
|
|
1586
|
+
-- Resolve and lock the requested current active entity version.
|
|
1587
|
+
BEGIN
|
|
1588
|
+
SELECT
|
|
1589
|
+
e.oid
|
|
1590
|
+
INTO STRICT
|
|
1591
|
+
__entoid
|
|
1592
|
+
FROM public.stsentity e
|
|
1593
|
+
WHERE e.resourceoid = __resoid
|
|
1594
|
+
AND e.entname = _entname
|
|
1595
|
+
AND e.vnum = _entvnum
|
|
1596
|
+
AND e.validto IS NULL
|
|
1597
|
+
AND e.dbaction != 3
|
|
1598
|
+
FOR UPDATE;
|
|
1599
|
+
|
|
1600
|
+
EXCEPTION
|
|
1601
|
+
|
|
1602
|
+
WHEN no_data_found THEN
|
|
1603
|
+
RAISE
|
|
1604
|
+
'Entity % version % not found, not current, or deleted within resource %',
|
|
1605
|
+
_entname,
|
|
1606
|
+
_entvnum,
|
|
1607
|
+
_resname
|
|
1608
|
+
USING ERRCODE = 'no_data_found';
|
|
1609
|
+
|
|
1610
|
+
WHEN too_many_rows THEN
|
|
1611
|
+
RAISE
|
|
1612
|
+
'Too many current stsentity records for entity % version % within resource %',
|
|
1613
|
+
_entname,
|
|
1614
|
+
_entvnum,
|
|
1615
|
+
_resname
|
|
1616
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1617
|
+
|
|
1618
|
+
END;
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
-- Close the previous entity version.
|
|
1622
|
+
UPDATE public.stsentity
|
|
1623
|
+
SET validto = __now
|
|
1624
|
+
WHERE oid = __entoid;
|
|
1625
|
+
|
|
1626
|
+
|
|
1627
|
+
-- Create the next active entity version.
|
|
1628
|
+
INSERT INTO public.stsentity(
|
|
1629
|
+
resourceoid,
|
|
1630
|
+
entname,
|
|
1631
|
+
entvalue,
|
|
1632
|
+
entvalue_jsonb,
|
|
1633
|
+
vnum,
|
|
1634
|
+
dbaction,
|
|
1635
|
+
dbactionuser,
|
|
1636
|
+
validfrom
|
|
1637
|
+
)
|
|
1638
|
+
VALUES (
|
|
1639
|
+
__resoid,
|
|
1640
|
+
_entname,
|
|
1641
|
+
_entvalue,
|
|
1642
|
+
__entvalue_jsonb,
|
|
1643
|
+
_entvnum + 1,
|
|
1644
|
+
2,
|
|
1645
|
+
_dbactionuser,
|
|
1646
|
+
__now
|
|
1647
|
+
)
|
|
1648
|
+
RETURNING oid
|
|
1649
|
+
INTO __inserted_oid;
|
|
1650
|
+
|
|
1651
|
+
|
|
1652
|
+
-- Return the new entity version.
|
|
1653
|
+
RETURN QUERY
|
|
1654
|
+
SELECT *
|
|
1655
|
+
FROM public.stsentity
|
|
1656
|
+
WHERE oid = __inserted_oid;
|
|
1657
|
+
|
|
1658
|
+
END;
|
|
1659
|
+
$BODY$;
|
|
1660
|
+
|
|
1661
|
+
ALTER FUNCTION public.update_stsentity(
|
|
1662
|
+
character varying,
|
|
1663
|
+
character varying,
|
|
1664
|
+
bigint,
|
|
1665
|
+
character varying,
|
|
1666
|
+
bigint,
|
|
1667
|
+
character varying
|
|
1668
|
+
)
|
|
1669
|
+
OWNER TO postgres;
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
-- =============================================================================
|
|
1673
|
+
-- update_stsentity_latest
|
|
1674
|
+
-- =============================================================================
|
|
1675
|
+
--
|
|
1676
|
+
-- Updates the current active entity under the current active resource.
|
|
1677
|
+
--
|
|
1678
|
+
-- The current entity OID and version are resolved together in one locked query.
|
|
1679
|
+
CREATE OR REPLACE FUNCTION public.update_stsentity_latest(
|
|
1680
|
+
_dbactionuser character varying,
|
|
1681
|
+
_resname character varying,
|
|
1682
|
+
_entname character varying,
|
|
1683
|
+
_entvalue character varying
|
|
1684
|
+
)
|
|
1685
|
+
RETURNS SETOF public.stsentity
|
|
1686
|
+
LANGUAGE plpgsql
|
|
1687
|
+
COST 100
|
|
1688
|
+
VOLATILE
|
|
1689
|
+
ROWS 1
|
|
1690
|
+
|
|
1691
|
+
AS $BODY$
|
|
1692
|
+
DECLARE
|
|
1693
|
+
__now timestamptz := now();
|
|
1694
|
+
__resoid bigint;
|
|
1695
|
+
__entoid bigint;
|
|
1696
|
+
__entvnum bigint;
|
|
1697
|
+
__inserted_oid bigint;
|
|
1698
|
+
__entvalue_jsonb jsonb;
|
|
1699
|
+
BEGIN
|
|
1700
|
+
|
|
1701
|
+
-- Validate / parse entity JSON.
|
|
1702
|
+
BEGIN
|
|
1703
|
+
__entvalue_jsonb := _entvalue::jsonb;
|
|
1704
|
+
|
|
1705
|
+
EXCEPTION
|
|
1706
|
+
WHEN invalid_text_representation THEN
|
|
1707
|
+
RAISE EXCEPTION
|
|
1708
|
+
'Invalid JSON string: %',
|
|
1709
|
+
_entvalue
|
|
1710
|
+
USING ERRCODE = 'invalid_text_representation';
|
|
1711
|
+
END;
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
-- Resolve and lock the current active resource.
|
|
1715
|
+
BEGIN
|
|
1716
|
+
SELECT
|
|
1717
|
+
r.oid
|
|
1718
|
+
INTO STRICT
|
|
1719
|
+
__resoid
|
|
1720
|
+
FROM public.stsresource r
|
|
1721
|
+
WHERE r.resname = _resname
|
|
1722
|
+
AND r.validto IS NULL
|
|
1723
|
+
AND r.dbaction != 3
|
|
1724
|
+
FOR UPDATE;
|
|
1725
|
+
|
|
1726
|
+
EXCEPTION
|
|
1727
|
+
|
|
1728
|
+
WHEN no_data_found THEN
|
|
1729
|
+
RAISE
|
|
1730
|
+
'Resource % not found, not current, or deleted',
|
|
1731
|
+
_resname
|
|
1732
|
+
USING ERRCODE = 'no_data_found';
|
|
1733
|
+
|
|
1734
|
+
WHEN too_many_rows THEN
|
|
1735
|
+
RAISE
|
|
1736
|
+
'Too many current stsresource records for resource %',
|
|
1737
|
+
_resname
|
|
1738
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1739
|
+
|
|
1740
|
+
END;
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
-- Resolve and lock the current active entity and its version.
|
|
1744
|
+
BEGIN
|
|
1745
|
+
SELECT
|
|
1746
|
+
e.oid,
|
|
1747
|
+
e.vnum
|
|
1748
|
+
INTO STRICT
|
|
1749
|
+
__entoid,
|
|
1750
|
+
__entvnum
|
|
1751
|
+
FROM public.stsentity e
|
|
1752
|
+
WHERE e.resourceoid = __resoid
|
|
1753
|
+
AND e.entname = _entname
|
|
1754
|
+
AND e.validto IS NULL
|
|
1755
|
+
AND e.dbaction != 3
|
|
1756
|
+
FOR UPDATE;
|
|
1757
|
+
|
|
1758
|
+
EXCEPTION
|
|
1759
|
+
|
|
1760
|
+
WHEN no_data_found THEN
|
|
1761
|
+
RAISE
|
|
1762
|
+
'Entity % not found, not current, or deleted within resource %',
|
|
1763
|
+
_entname,
|
|
1764
|
+
_resname
|
|
1765
|
+
USING ERRCODE = 'no_data_found';
|
|
1766
|
+
|
|
1767
|
+
WHEN too_many_rows THEN
|
|
1768
|
+
RAISE
|
|
1769
|
+
'Too many current stsentity records for entity % within resource %',
|
|
1770
|
+
_entname,
|
|
1771
|
+
_resname
|
|
1772
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1773
|
+
|
|
1774
|
+
END;
|
|
1775
|
+
|
|
1776
|
+
|
|
1777
|
+
-- Close the previous entity version.
|
|
1778
|
+
UPDATE public.stsentity
|
|
1779
|
+
SET validto = __now
|
|
1780
|
+
WHERE oid = __entoid;
|
|
1781
|
+
|
|
1782
|
+
|
|
1783
|
+
-- Create the next active entity version.
|
|
1784
|
+
INSERT INTO public.stsentity(
|
|
1785
|
+
resourceoid,
|
|
1786
|
+
entname,
|
|
1787
|
+
entvalue,
|
|
1788
|
+
entvalue_jsonb,
|
|
1789
|
+
vnum,
|
|
1790
|
+
dbaction,
|
|
1791
|
+
dbactionuser,
|
|
1792
|
+
validfrom
|
|
1793
|
+
)
|
|
1794
|
+
VALUES (
|
|
1795
|
+
__resoid,
|
|
1796
|
+
_entname,
|
|
1797
|
+
_entvalue,
|
|
1798
|
+
__entvalue_jsonb,
|
|
1799
|
+
__entvnum + 1,
|
|
1800
|
+
2,
|
|
1801
|
+
_dbactionuser,
|
|
1802
|
+
__now
|
|
1803
|
+
)
|
|
1804
|
+
RETURNING oid
|
|
1805
|
+
INTO __inserted_oid;
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
-- Return the new entity version.
|
|
1809
|
+
RETURN QUERY
|
|
1810
|
+
SELECT *
|
|
1811
|
+
FROM public.stsentity
|
|
1812
|
+
WHERE oid = __inserted_oid;
|
|
1813
|
+
|
|
1814
|
+
END;
|
|
1815
|
+
$BODY$;
|
|
1816
|
+
|
|
1817
|
+
ALTER FUNCTION public.update_stsentity_latest(
|
|
1818
|
+
character varying,
|
|
1819
|
+
character varying,
|
|
1820
|
+
character varying,
|
|
1821
|
+
character varying
|
|
1822
|
+
)
|
|
1823
|
+
OWNER TO postgres;
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
-- =============================================================================
|
|
1827
|
+
-- delete_stsentity
|
|
1828
|
+
-- =============================================================================
|
|
1829
|
+
--
|
|
1830
|
+
-- Logically deletes a caller-specified current active entity version.
|
|
1831
|
+
--
|
|
1832
|
+
-- Delete closes the active entity version and creates a dbaction=3 tombstone
|
|
1833
|
+
-- as the next/current version.
|
|
1834
|
+
CREATE OR REPLACE FUNCTION public.delete_stsentity(
|
|
1835
|
+
_dbactionuser character varying,
|
|
1836
|
+
_resname character varying,
|
|
1837
|
+
_resvnum bigint,
|
|
1838
|
+
_entname character varying,
|
|
1839
|
+
_entvnum bigint
|
|
1840
|
+
)
|
|
1841
|
+
RETURNS SETOF public.stsentity
|
|
1842
|
+
LANGUAGE plpgsql
|
|
1843
|
+
COST 100
|
|
1844
|
+
VOLATILE
|
|
1845
|
+
ROWS 1
|
|
1846
|
+
|
|
1847
|
+
AS $BODY$
|
|
1848
|
+
DECLARE
|
|
1849
|
+
__now timestamptz := now();
|
|
1850
|
+
__resoid bigint;
|
|
1851
|
+
__entoid bigint;
|
|
1852
|
+
__inserted_oid bigint;
|
|
1853
|
+
BEGIN
|
|
1854
|
+
|
|
1855
|
+
-- Resolve and lock the requested current active resource version.
|
|
1856
|
+
BEGIN
|
|
1857
|
+
SELECT
|
|
1858
|
+
r.oid
|
|
1859
|
+
INTO STRICT
|
|
1860
|
+
__resoid
|
|
1861
|
+
FROM public.stsresource r
|
|
1862
|
+
WHERE r.resname = _resname
|
|
1863
|
+
AND r.vnum = _resvnum
|
|
1864
|
+
AND r.validto IS NULL
|
|
1865
|
+
AND r.dbaction != 3
|
|
1866
|
+
FOR UPDATE;
|
|
1867
|
+
|
|
1868
|
+
EXCEPTION
|
|
1869
|
+
|
|
1870
|
+
WHEN no_data_found THEN
|
|
1871
|
+
RAISE
|
|
1872
|
+
'Resource % version % not found, not current, or deleted',
|
|
1873
|
+
_resname,
|
|
1874
|
+
_resvnum
|
|
1875
|
+
USING ERRCODE = 'no_data_found';
|
|
1876
|
+
|
|
1877
|
+
WHEN too_many_rows THEN
|
|
1878
|
+
RAISE
|
|
1879
|
+
'Too many current stsresource records for resource % version %',
|
|
1880
|
+
_resname,
|
|
1881
|
+
_resvnum
|
|
1882
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1883
|
+
|
|
1884
|
+
END;
|
|
1885
|
+
|
|
1886
|
+
|
|
1887
|
+
-- Resolve and lock the requested current active entity version.
|
|
1888
|
+
BEGIN
|
|
1889
|
+
SELECT
|
|
1890
|
+
e.oid
|
|
1891
|
+
INTO STRICT
|
|
1892
|
+
__entoid
|
|
1893
|
+
FROM public.stsentity e
|
|
1894
|
+
WHERE e.resourceoid = __resoid
|
|
1895
|
+
AND e.entname = _entname
|
|
1896
|
+
AND e.vnum = _entvnum
|
|
1897
|
+
AND e.validto IS NULL
|
|
1898
|
+
AND e.dbaction != 3
|
|
1899
|
+
FOR UPDATE;
|
|
1900
|
+
|
|
1901
|
+
EXCEPTION
|
|
1902
|
+
|
|
1903
|
+
WHEN no_data_found THEN
|
|
1904
|
+
RAISE
|
|
1905
|
+
'Entity % version % not found, not current, or deleted within resource %',
|
|
1906
|
+
_entname,
|
|
1907
|
+
_entvnum,
|
|
1908
|
+
_resname
|
|
1909
|
+
USING ERRCODE = 'no_data_found';
|
|
1910
|
+
|
|
1911
|
+
WHEN too_many_rows THEN
|
|
1912
|
+
RAISE
|
|
1913
|
+
'Too many current stsentity records for entity % version % within resource %',
|
|
1914
|
+
_entname,
|
|
1915
|
+
_entvnum,
|
|
1916
|
+
_resname
|
|
1917
|
+
USING ERRCODE = 'cardinality_violation';
|
|
1918
|
+
|
|
1919
|
+
END;
|
|
1920
|
+
|
|
1921
|
+
|
|
1922
|
+
-- Close the previous active entity version.
|
|
1923
|
+
UPDATE public.stsentity
|
|
1924
|
+
SET validto = __now
|
|
1925
|
+
WHERE oid = __entoid;
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
-- Create the delete tombstone.
|
|
1929
|
+
--
|
|
1930
|
+
-- Copy entvalue_jsonb directly rather than reparsing entvalue text.
|
|
1931
|
+
INSERT INTO public.stsentity(
|
|
1932
|
+
resourceoid,
|
|
1933
|
+
entname,
|
|
1934
|
+
entvalue,
|
|
1935
|
+
entvalue_jsonb,
|
|
1936
|
+
vnum,
|
|
1937
|
+
dbaction,
|
|
1938
|
+
dbactionuser,
|
|
1939
|
+
validfrom
|
|
1940
|
+
)
|
|
1941
|
+
SELECT
|
|
1942
|
+
__resoid,
|
|
1943
|
+
e.entname,
|
|
1944
|
+
e.entvalue,
|
|
1945
|
+
e.entvalue_jsonb,
|
|
1946
|
+
_entvnum + 1,
|
|
1947
|
+
3,
|
|
1948
|
+
_dbactionuser,
|
|
1949
|
+
__now
|
|
1950
|
+
FROM public.stsentity e
|
|
1951
|
+
WHERE e.oid = __entoid
|
|
1952
|
+
RETURNING oid
|
|
1953
|
+
INTO __inserted_oid;
|
|
1954
|
+
|
|
1955
|
+
|
|
1956
|
+
-- Return the delete tombstone.
|
|
1957
|
+
RETURN QUERY
|
|
1958
|
+
SELECT *
|
|
1959
|
+
FROM public.stsentity
|
|
1960
|
+
WHERE oid = __inserted_oid;
|
|
1961
|
+
|
|
1962
|
+
END;
|
|
1963
|
+
$BODY$;
|
|
1964
|
+
|
|
1965
|
+
ALTER FUNCTION public.delete_stsentity(
|
|
1966
|
+
character varying,
|
|
1967
|
+
character varying,
|
|
1968
|
+
bigint,
|
|
1969
|
+
character varying,
|
|
1970
|
+
bigint
|
|
1971
|
+
)
|
|
1972
|
+
OWNER TO postgres;
|
|
1973
|
+
|
|
1974
|
+
|
|
1975
|
+
-- =============================================================================
|
|
1976
|
+
-- delete_stsentity_latest
|
|
1977
|
+
-- =============================================================================
|
|
1978
|
+
--
|
|
1979
|
+
-- Logically deletes the current active entity under the current active resource
|
|
1980
|
+
-- without requiring the caller to provide either version number.
|
|
1981
|
+
CREATE OR REPLACE FUNCTION public.delete_stsentity_latest(
|
|
1982
|
+
_dbactionuser character varying,
|
|
1983
|
+
_resname character varying,
|
|
1984
|
+
_entname character varying
|
|
1985
|
+
)
|
|
1986
|
+
RETURNS SETOF public.stsentity
|
|
1987
|
+
LANGUAGE plpgsql
|
|
1988
|
+
COST 100
|
|
1989
|
+
VOLATILE
|
|
1990
|
+
ROWS 1
|
|
1991
|
+
|
|
1992
|
+
AS $BODY$
|
|
1993
|
+
DECLARE
|
|
1994
|
+
__now timestamptz := now();
|
|
1995
|
+
__resoid bigint;
|
|
1996
|
+
__entoid bigint;
|
|
1997
|
+
__entvnum bigint;
|
|
1998
|
+
__inserted_oid bigint;
|
|
1999
|
+
BEGIN
|
|
2000
|
+
|
|
2001
|
+
-- Resolve and lock the current active resource.
|
|
2002
|
+
BEGIN
|
|
2003
|
+
SELECT
|
|
2004
|
+
r.oid
|
|
2005
|
+
INTO STRICT
|
|
2006
|
+
__resoid
|
|
2007
|
+
FROM public.stsresource r
|
|
2008
|
+
WHERE r.resname = _resname
|
|
2009
|
+
AND r.validto IS NULL
|
|
2010
|
+
AND r.dbaction != 3
|
|
2011
|
+
FOR UPDATE;
|
|
2012
|
+
|
|
2013
|
+
EXCEPTION
|
|
2014
|
+
|
|
2015
|
+
WHEN no_data_found THEN
|
|
2016
|
+
RAISE
|
|
2017
|
+
'Resource % not found, not current, or deleted',
|
|
2018
|
+
_resname
|
|
2019
|
+
USING ERRCODE = 'no_data_found';
|
|
2020
|
+
|
|
2021
|
+
WHEN too_many_rows THEN
|
|
2022
|
+
RAISE
|
|
2023
|
+
'Too many current stsresource records for resource %',
|
|
2024
|
+
_resname
|
|
2025
|
+
USING ERRCODE = 'cardinality_violation';
|
|
2026
|
+
|
|
2027
|
+
END;
|
|
2028
|
+
|
|
2029
|
+
|
|
2030
|
+
-- Resolve and lock the current active entity and its version.
|
|
2031
|
+
BEGIN
|
|
2032
|
+
SELECT
|
|
2033
|
+
e.oid,
|
|
2034
|
+
e.vnum
|
|
2035
|
+
INTO STRICT
|
|
2036
|
+
__entoid,
|
|
2037
|
+
__entvnum
|
|
2038
|
+
FROM public.stsentity e
|
|
2039
|
+
WHERE e.resourceoid = __resoid
|
|
2040
|
+
AND e.entname = _entname
|
|
2041
|
+
AND e.validto IS NULL
|
|
2042
|
+
AND e.dbaction != 3
|
|
2043
|
+
FOR UPDATE;
|
|
2044
|
+
|
|
2045
|
+
EXCEPTION
|
|
2046
|
+
|
|
2047
|
+
WHEN no_data_found THEN
|
|
2048
|
+
RAISE
|
|
2049
|
+
'Entity % not found, not current, or deleted within resource %',
|
|
2050
|
+
_entname,
|
|
2051
|
+
_resname
|
|
2052
|
+
USING ERRCODE = 'no_data_found';
|
|
2053
|
+
|
|
2054
|
+
WHEN too_many_rows THEN
|
|
2055
|
+
RAISE
|
|
2056
|
+
'Too many current stsentity records for entity % within resource %',
|
|
2057
|
+
_entname,
|
|
2058
|
+
_resname
|
|
2059
|
+
USING ERRCODE = 'cardinality_violation';
|
|
2060
|
+
|
|
2061
|
+
END;
|
|
2062
|
+
|
|
2063
|
+
|
|
2064
|
+
-- Close the previous active entity version.
|
|
2065
|
+
UPDATE public.stsentity
|
|
2066
|
+
SET validto = __now
|
|
2067
|
+
WHERE oid = __entoid;
|
|
2068
|
+
|
|
2069
|
+
|
|
2070
|
+
-- Create the delete tombstone.
|
|
2071
|
+
INSERT INTO public.stsentity(
|
|
2072
|
+
resourceoid,
|
|
2073
|
+
entname,
|
|
2074
|
+
entvalue,
|
|
2075
|
+
entvalue_jsonb,
|
|
2076
|
+
vnum,
|
|
2077
|
+
dbaction,
|
|
2078
|
+
dbactionuser,
|
|
2079
|
+
validfrom
|
|
2080
|
+
)
|
|
2081
|
+
SELECT
|
|
2082
|
+
__resoid,
|
|
2083
|
+
e.entname,
|
|
2084
|
+
e.entvalue,
|
|
2085
|
+
e.entvalue_jsonb,
|
|
2086
|
+
__entvnum + 1,
|
|
2087
|
+
3,
|
|
2088
|
+
_dbactionuser,
|
|
2089
|
+
__now
|
|
2090
|
+
FROM public.stsentity e
|
|
2091
|
+
WHERE e.oid = __entoid
|
|
2092
|
+
RETURNING oid
|
|
2093
|
+
INTO __inserted_oid;
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
-- Return the delete tombstone.
|
|
2097
|
+
RETURN QUERY
|
|
2098
|
+
SELECT *
|
|
2099
|
+
FROM public.stsentity
|
|
2100
|
+
WHERE oid = __inserted_oid;
|
|
2101
|
+
|
|
2102
|
+
END;
|
|
2103
|
+
$BODY$;
|
|
2104
|
+
|
|
2105
|
+
ALTER FUNCTION public.delete_stsentity_latest(
|
|
2106
|
+
character varying,
|
|
2107
|
+
character varying,
|
|
2108
|
+
character varying
|
|
2109
|
+
)
|
|
2110
|
+
OWNER TO postgres;
|
|
2111
|
+
|
|
2112
|
+
|
|
2113
|
+
-- =============================================================================
|
|
2114
|
+
-- Count functions
|
|
2115
|
+
-- =============================================================================
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
-- =============================================================================
|
|
2119
|
+
-- count_stsresource
|
|
2120
|
+
-- =============================================================================
|
|
2121
|
+
--
|
|
2122
|
+
-- Counts stsresource rows.
|
|
2123
|
+
--
|
|
2124
|
+
-- _valid_records = false
|
|
2125
|
+
-- Count every physical stsresource row, including all historical versions
|
|
2126
|
+
-- and delete tombstones.
|
|
2127
|
+
--
|
|
2128
|
+
-- _valid_records = true
|
|
2129
|
+
-- Count only current ACTIVE resource concepts.
|
|
2130
|
+
--
|
|
2131
|
+
-- A delete tombstone has validto IS NULL but dbaction = 3, so both
|
|
2132
|
+
-- predicates are required. Testing validto alone would incorrectly count
|
|
2133
|
+
-- logically deleted resources as valid.
|
|
2134
|
+
--
|
|
2135
|
+
-- This function performs no writes and is therefore STABLE rather than
|
|
2136
|
+
-- VOLATILE.
|
|
2137
|
+
CREATE OR REPLACE FUNCTION public.count_stsresource(
|
|
2138
|
+
_valid_records boolean DEFAULT false
|
|
2139
|
+
)
|
|
2140
|
+
RETURNS TABLE (count bigint)
|
|
2141
|
+
LANGUAGE plpgsql
|
|
2142
|
+
COST 100
|
|
2143
|
+
STABLE
|
|
2144
|
+
ROWS 1
|
|
2145
|
+
|
|
2146
|
+
AS $BODY$
|
|
2147
|
+
BEGIN
|
|
2148
|
+
|
|
2149
|
+
IF _valid_records THEN
|
|
2150
|
+
|
|
2151
|
+
RETURN QUERY
|
|
2152
|
+
SELECT
|
|
2153
|
+
COUNT(*)::bigint
|
|
2154
|
+
FROM public.stsresource r
|
|
2155
|
+
WHERE r.validto IS NULL
|
|
2156
|
+
AND r.dbaction != 3;
|
|
2157
|
+
|
|
2158
|
+
ELSE
|
|
2159
|
+
|
|
2160
|
+
RETURN QUERY
|
|
2161
|
+
SELECT
|
|
2162
|
+
COUNT(*)::bigint
|
|
2163
|
+
FROM public.stsresource r;
|
|
2164
|
+
|
|
2165
|
+
END IF;
|
|
2166
|
+
|
|
2167
|
+
END;
|
|
2168
|
+
$BODY$;
|
|
2169
|
+
|
|
2170
|
+
ALTER FUNCTION public.count_stsresource(boolean)
|
|
2171
|
+
OWNER TO postgres;
|
|
2172
|
+
|
|
2173
|
+
|
|
2174
|
+
-- =============================================================================
|
|
2175
|
+
-- End of stsrest01 generic resource/entity schema
|
|
2176
|
+
-- =============================================================================
|