1 package body WF_CACHE as
2 /* $Header: WFCACHEB.pls 120.2 2006/02/22 16:40:17 rwunderl ship $ */
3
4
5 /*======================================+
6 | |
7 | Global Private Cache Variables |
8 | |
9 +======================================+================================*/
10
11 HashBase NUMBER := 1;
12 HashSize NUMBER := 16777216; -- 2^24
13 HashCollision EXCEPTION;
14 CacheSessionID DATE;
15
16 TrustedTransaction BOOLEAN;
17
18 /*======================================+
19 | |
20 | Functions |
21 | |
22 +======================================+================================*/
23
24
25 /*===========================+
26 | SetHashRange |
27 +===========================+===================+
28 | IN: p_HashBase in NUMBER, |
29 | p_HashSize in NUMBER |
30 +===============================================*/
31
32 PROCEDURE SetHashRange ( p_HashBase in NUMBER,
33 p_HashSize in NUMBER ) is
34
35
36 BEGIN
37 WF_CACHE.Clear;
38 HashBase := p_HashBase;
39 HashSize := p_HashSize;
40
41 END;
42
43
44 /*===========================+
45 | HashKey |
46 +===========================+===================+
47 | IN: p_HashString in VARCHAR2 |
48 +-----------------------------------------------+
49 | RETURNS: number |
50 +-----------------------------------------------+
51 | NOTES: We use HashBase and HashSize to prevent|
52 | a caller from setting the hash base or |
53 | size after caching has begun. |
54 +===============================================*/
55
56 FUNCTION HashKey (p_HashString in varchar2) return number is
57
58 l_hashKey number;
59
60 BEGIN
61
62 return(dbms_utility.get_hash_value(p_HashString, HashBase,
63 HashSize));
64
65 END;
66
67
68
69 /*=====================================+
70 | |
71 | Maintenance Procedures |
72 | |
73 +=====================================+================================+
74 | Maintenance procedures perform administrative functions such as |
75 | clearing the cache, managing cache positions, and raising errors. |
76 | |
77 +======================================================================*/
78
79 --<rwunderl:2412940>
80 /*===========================+
81 | ClearSynch |
82 +===============================================*/
83
84 PROCEDURE ClearSynch is
85
86 BEGIN
87
88 /*===============================+
89 | Clear the cache tables that |
90 | are used for #SYNCH mode |
91 +================================*/
92 ItemAttrValues.DELETE;
93
94 END;
95
96 /*===========================+
97 | Clear |
98 +===============================================*/
99
100 PROCEDURE Clear is
101
102 BEGIN
103
104 /*================================+
105 |Clear the Cache Tables. |
106 +================================*/
107 Activities.DELETE;
108 ActivityAttributes.DELETE;
109 ActivityAttrValues.DELETE;
110 ActivityTransitions.DELETE;
111 ItemAttributes.DELETE;
112 ItemTypes.DELETE;
113 ProcessActivities.DELETE;
114 NLSParameters.DELETE;
115
116 END;
117
118
119 /*===========================+
120 | CacheManager |
121 +===========================+===================+
122 | IN: p_TableName (PLS_INTEGER) |
123 | |
124 +===============================================*/
125
126 PROCEDURE CacheManager (TableName in PLS_INTEGER,
127 NumRows in NUMBER) is
128
129 BEGIN
130 if (TableName = WF_CACHE.TAB_Activities) then
131 if (Activities.COUNT + NumRows >= MaxActivities) then
132 Activities.DELETE;
133
134 end if;
135
136
137 elsif (TableName = WF_CACHE.TAB_ActivityTransitions) then
138 if (ActivityTransitions.COUNT + NumRows >= MaxActivityTransitions) then
139 ActivityTransitions.DELETE;
140
141 end if;
142
143
144 elsif (TableName = WF_CACHE.TAB_ActivityAttributes) then
145 if (ActivityAttributes.COUNT + NumRows >= MaxActivityAttrs) then
146 ActivityAttributes.DELETE;
147
148 end if;
149
150 if (Activities.COUNT + NumRows = MaxActivities) then
151 Activities.DELETE;
152
153 end if;
154
155 if (ProcessActivities.COUNT + NumRows >= MaxProcessActivities) then
156 ProcessActivities.DELETE;
157
158 end if;
159
160 elsif (TableName = WF_CACHE.TAB_ActivityAttrValues) then
161 if (ActivityAttrValues.COUNT + NumRows >= MaxActivityAttrValues) then
162 ActivityAttrValues.DELETE;
163
164 end if;
165
166 elsif (TableName = WF_CACHE.TAB_ItemAttributes) then
167 if (ItemAttributes.COUNT + NumRows >= MaxItemAttributes) then
168 ItemAttributes.DELETE;
169
170 end if;
171
172 elsif (TableName = WF_CACHE.TAB_ItemTypes) then
173 if (ItemTypes.COUNT + NumRows >= MaxItemTypes) then
174 ItemTypes.DELETE;
175
176 end if;
177
178 elsif (TableName = WF_CACHE.TAB_ProcessActivities) then
179 if (ProcessActivities.COUNT + NumRows >= MaxProcessActivities) then
180 ProcessActivities.DELETE;
181
182 end if;
183 --<rwunderl:2412971>
184 elsif (TableName = WF_CACHE.TAB_ProcessStartActivities) then
185 if (ProcessStartActivities.COUNT + NumRows >=
186 MaxProcessStartActivities) then
187 ProcessStartActivities.DELETE;
188
189 end if;
190
191 --</rwunderl:2412971>
192 else
193 return;
194
195 end if;
196
197 END;
198
199
200
201 /*===========================+
202 | MetaRefeshed |
203 +===========================+===================+
204 | Returns |
205 | BOOLEAN |
206 +-----------------------------------------------+
207 | This api checks to see if the p_itemType |
208 | has been updated by wfload. |
209 +===============================================*/
210
211 FUNCTION MetaRefreshed return BOOLEAN is
212
213 l_UpdateTime DATE;
214
215 BEGIN
216
217 if( WF_CACHE.CacheSessionID is NOT NULL ) then
218
219 /*----------------------------------------+
220 | Checking to see when the itemType was |
221 | last updated. |
222 +----------------------------------------*/
223 begin
224 select to_date(text, WF_ENGINE.date_format) into l_UpdateTime
225 from WF_RESOURCES
226 where TYPE='WFTKN'
227 and NAME = 'WFCACHE_META_UPD'
228 and LANGUAGE = 'US';
229
230 exception
231 when NO_DATA_FOUND then
232 WF_CACHE.Reset;
233 return TRUE;
234
235 when others then
236 raise;
237
238 end;
239
240 if ( l_UpdateTime > CacheSessionID ) then
241
242 /*---------------------------------------+
243 | The itemType was updated. We will |
244 | Clear the cache and reset our |
245 | CacheSessionID for a new Caching |
246 | session |
247 +---------------------------------------*/
248 WF_CACHE.Clear;
249 WF_CACHE.CacheSessionID := sysdate;
250 return TRUE;
251
252 end if;
253
254 elsif (CacheSessionID is NULL) then
255
256 /*---------------------------------------+
257 | This is the first initialization of |
258 | the cache for this DB session. |
259 | Setting the CacheSessionID to sysdate |
260 | and Clearing the cache. |
261 +---------------------------------------*/
262 WF_CACHE.CacheSessionID := sysdate;
263 WF_CACHE.Clear;
264 return TRUE;
265
266 end if;
267
268 return FALSE;
269
270 END;
271
272
273
274 /*===========================+
275 | Reset |
276 +===========================+===================+
277 | This api will update the WFCACHE_META_UPD |
278 | resource token to the current sysdate to |
279 | cause any running caches to be cleared. This |
280 | code is called by WF_LOAD when an upload event|
281 | has taken place. |
282 +===============================================*/
283
284 PROCEDURE Reset IS
285
286 BEGIN
287 if ((NOT trustedTransaction) or (trustedTransaction is NULL)) then
288 -- We will update the token to the current sysdate.
289 update WF_RESOURCES set text = to_char(sysdate,
290 WF_ENGINE.date_format)
291 where name = 'WFCACHE_META_UPD';
292
293 if (sql%notfound) then
294 -- When WF_CACHE.Reset is called for the very first time on a system
295 -- we will jump into this code to insert the record.
296 begin
297 insert into WF_RESOURCES (TYPE, NAME, LANGUAGE,SOURCE_LANG, ID,
298 TEXT, PROTECT_LEVEL, CUSTOM_LEVEL)
299 values ('WFTKN', 'WFCACHE_META_UPD', 'US', 'US', 0,
300 to_char(sysdate, WF_ENGINE.date_format), 0, 0);
301 exception
302 when DUP_VAL_ON_INDEX then
303 -- there is a race condition where it can potentially
304 -- have several insert at once the first time this is called.
305 null;
306 end;
307 end if;
308 end if;
309 WF_CACHE.Clear;
310
311 END;
312
313
314
315
316 /*=====================================+
317 | |
318 | Accessor Procedures |
319 | |
320 +=====================================+================================+
321 | Accessor procedures are the apis that consumers use to access meta- |
322 | data from cache. Each api will require as parameters the necessary |
323 | information to locate the record in cache as well as a record index. |
324 | |
325 +======================================================================*/
326
327
328 /*===========================+
329 | GetActivity |
330 +===========================+===================+
331 | IN: itemType (VARCHAR2) |
332 | name (VARCHAR2) |
333 | actdate (DATE) |
334 +-----------------------------------------------+
335 | OUT: status (PLS_INTEGER) |
336 | waIND (NUMBER) |
337 +===============================================*/
338
339 PROCEDURE GetActivity ( itemType in VARCHAR2,
340 name in VARCHAR2,
341 actdate in DATE,
342 status out NOCOPY PLS_INTEGER,
343 waIND out NOCOPY NUMBER) is
344
345
346 iKey NUMBER;
347
348 BEGIN
349
350 iKey := HashKey(itemType || name);
351 waIND := iKey;
352
353 if (Activities.EXISTS(iKey)) then --We found an Activity Record.
354
355 /*========================================================+
356 | We will validate the actdate against the Activity |
357 | record begin and end date to make sure we have the |
358 | proper version of the Activity in cache. |
359 +========================================================*/
360
361 if ((actdate > Activities(iKey).begin_date) and
362 ((Activities(iKey).END_DATE is Null) or
363 (actdate < Activities(iKey).END_DATE))) then
364
365 /*========================================================+
366 | We have the proper version, now we will make sure we |
367 | have not encountered a hash collision. (A condition |
368 | where the same HashKey has been generated for two |
369 | different records). |
370 +========================================================*/
371
372 if ((itemType <> Activities(iKey).item_type) or
373 (name <> Activities(iKey).name)) then
374 raise WF_CACHE.HashCollision;
375
376 else
377
378 /*========================================================+
379 | We have a good record and are ready to deliver the |
380 | waIND to the caller. |
381 +========================================================*/
382
383
384 status := WF_CACHE.task_SUCCESS;
385
386
387
388 end if;
389
390 else -- Activity Record is not the proper version.
391
392 status := WF_CACHE.task_FAILED;
393 CacheManager(TAB_Activities);
394
395 end if;
396
397 else -- We did not find an Activity Record in cache.
398
399 status := WF_CACHE.task_FAILED;
400 CacheManager(TAB_Activities);
401
402 end if;
403
404 EXCEPTION
405 when NO_DATA_FOUND then
409 when HashCollision then
406 status := WF_CACHE.task_FAILED;
407 CacheManager(TAB_Activities);
408
410 if not (ErrorOnCollision) then
411 status := WF_CACHE.task_FAILED;
412
413 else
414 raise;
415
416 end if;
417
418 when OTHERS then
419 raise;
420
421 END;
422
423
424 /*===========================+
425 | GetActivityAttr |
426 +===========================+===================+
427 | IN: itemType (VARCHAR2) |
428 | name (VARCHAR2) |
429 | actid (NUMBER) |
430 | actdate (DATE) |
431 +-----------------------------------------------+
432 | OUT: status (PLS_INTEGER) |
433 | wa_index (NUMBER) |
434 | waa_index (NUMBER) |
435 +===============================================*/
436
437 PROCEDURE GetActivityAttr ( itemType in VARCHAR2,
438 name in VARCHAR2,
439 actid in NUMBER,
440 actdate in DATE,
441 status out NOCOPY PLS_INTEGER,
442 wa_index out NOCOPY NUMBER,
443 waa_index out NOCOPY NUMBER) is
444
445 l_endDate DATE;
446 l_WAindex NUMBER;
447 l_WAAindex NUMBER;
448
449 l_status PLS_INTEGER;
450
451
452 BEGIN
453 WF_CACHE.GetProcessActivity(actid, l_status);
454
455 -- First we will check to see if the ProcessActivity is in cache.
456 -- Then we will use the ACTIVITY_NAME to check the other cache records.
457
458 if (l_status <> WF_CACHE.task_SUCCESS) then
459 status := WF_CACHE.task_FAILED;
460 CacheManager(TAB_ActivityAttributes);
461 return;
462
463 end if;
464
465 l_WAAindex := HashKey(itemType || name ||
466 ProcessActivities(actid).ACTIVITY_NAME);
467
468
469 -- Now that we have validated the ProcessActivity and Activity, we
470 -- will check to see if the ActivityAttribute matches.
471 if (ActivityAttributes.EXISTS(l_WAAindex)) then
472
473 -- We will now check to see if we have an activity in cache that is the
474 -- proper version.
475
476 WF_CACHE.GetActivity( ProcessActivities(actid).ACTIVITY_ITEM_TYPE,
477 ProcessActivities(actid).ACTIVITY_NAME,
478 actdate, l_status, l_WAIndex );
479
480 if (l_status <> WF_CACHE.task_SUCCESS) then
481 status := WF_CACHE.task_FAILED;
482 CacheManager(TAB_ActivityAttributes);
483 return;
484
485 end if;
486
487
488 if ( (ActivityAttributes(l_WAAindex).ACTIVITY_ITEM_TYPE <>
489 Activities(l_WAindex).ITEM_TYPE)
490
491 or
492
493 (ActivityAttributes(l_WAAindex).ACTIVITY_NAME <>
494 Activities(l_WAindex).NAME)
495
496 or
497
498 (ActivityAttributes(l_WAAindex).ACTIVITY_VERSION <>
499 Activities(l_WAindex).VERSION) ) then
500
501 CacheManager(TAB_ActivityAttributes);
502 status := task_FAILED;
503 return;
504
505 else
506
507 wa_index := l_WAindex;
508 waa_index := l_WAAindex;
509 status := task_SUCCESS;
510
511 end if;
512
513 else
514
515 status := WF_CACHE.task_FAILED;
516 CacheManager(TAB_ActivityAttributes);
517
518 return;
519
520 end if;
521
522 EXCEPTION
523 when HashCollision then
524 if not (ErrorOnCollision) then
525 status := WF_CACHE.task_FAILED;
526 CacheManager(TAB_ActivityAttributes);
527
528 else
529 raise;
530
531 end if;
532
533 when OTHERS then
534 raise;
535
536 END;
537
538
539
540
541
542 /*===========================+
543 | GetActivityAttrValue |
544 +===========================+===================+
545 | IN: actID (NUMBER) |
546 | name (VARCHAR2) |
547 +-----------------------------------------------+
548 | OUT: status (PLS_INTEGER) |
549 | waavIND (NUMBER) |
550 +===============================================*/
551
552 PROCEDURE GetActivityAttrValue (
553 actid in NUMBER,
554 name in VARCHAR2,
555 status out NOCOPY PLS_INTEGER,
556 waavIND out NOCOPY NUMBER)
560
557 is
558
559 iKey NUMBER;
561 BEGIN
562
563 iKey := HashKey(actid || name);
564 waavIND := iKey;
565
566 if (ActivityAttrValues.EXISTS(iKey)) then
567
568 if ((actid <> ActivityAttrValues(iKey).process_activity_id) or
569 (name <> ActivityAttrValues(iKey).name)) then
570 raise HashCollision;
571
572 else
573 status := WF_CACHE.task_SUCCESS;
574
575 end if;
576
577 else
578 status := WF_CACHE.task_FAILED;
579 CacheManager(TAB_ActivityAttrValues);
580
581 end if;
582
583 EXCEPTION
584 when NO_DATA_FOUND then
585 status := WF_CACHE.task_FAILED;
586 CacheManager(TAB_ActivityAttrValues);
587
588 when HashCollision then
589 if not (ErrorOnCollision) then
590 status := WF_CACHE.task_FAILED;
591 CacheManager(TAB_ActivityAttrValues);
592
593 else
594 raise;
595
596 end if;
597
598 when OTHERS then
599 raise;
600
601 END;
602
603
604 /*===========================+
605 | GetActivityTransitions |
606 +===========================+===================+
607 | IN: FromActID (NUMBER) |
608 | result (VARCHAR2) |
609 +-----------------------------------------------+
610 | OUT: status (PLS_INTEGER) |
611 | watIND (NUMBER) |
612 +===============================================*/
613
614 PROCEDURE GetActivityTransitions (
615 FromActID in NUMBER,
616 result in VARCHAR2,
617 status out NOCOPY PLS_INTEGER,
618 watIND out NOCOPY NUMBER )
619 is
620 iKey NUMBER;
621
622 begin
623 iKey := WF_CACHE.HashKey(FromActID||':'|| result);
624 watIND := iKey;
625
626 if (WF_CACHE.ActivityTransitions.EXISTS(iKey)) then
627 if ((WF_CACHE.ActivityTransitions(iKey).FROM_PROCESS_ACTIVITY <> FromActID)
628 or (WF_CACHE.ActivityTransitions(iKey).RESULT_CODE not in
629 (result, WF_ENGINE.eng_trans_default, WF_ENGINE.eng_trans_any))) then
630 raise HashCollision;
631
632 else
633 status := WF_CACHE.task_SUCCESS;
634
635
636 end if;
637
638 else
639 status := WF_CACHE.task_FAILED;
640 CacheManager(TAB_ActivityTransitions);
641 end if;
642
643 exception
644 when HashCollision then
645 if not (ErrorOnCollision) then
646 status := WF_CACHE.task_FAILED;
647 --Normally we can just report a failure so the calling api will store
648 --a new record in the current slot and move on. However since
649 --activity transitions are interrelated, we have to clear the whole
650 --table to ensure consistency. This condition should not occur in
651 --normal processing and is just a safegard against the extreme.
652 WF_CACHE.ActivityTransitions.DELETE;
653
654 else
655 raise;
656
657 end if;
658
659 when OTHERS then
660 raise;
661
662 end;
663
664
665 /*===========================+
666 | GetItemAttribute |
667 +===========================+===================+
668 | IN: itemType (VARCHAR2) |
669 | name (VARCHAR2) |
670 +-----------------------------------------------+
671 | OUT: status (PLS_INTEGER) |
672 | wiaIND (NUMBER) |
673 +===============================================*/
674
675 PROCEDURE GetItemAttribute (itemType in VARCHAR2,
676 name in VARCHAR2,
677 status out NOCOPY PLS_INTEGER,
678 wiaIND out NOCOPY NUMBER) is
679
680 iKey NUMBER;
681
682 BEGIN
683
684 iKey := HashKey(itemType || name);
685 wiaIND := iKey;
686
687 if (ItemAttributes.EXISTS(iKey)) then
688
689 if ((itemType <> ItemAttributes(iKey).item_type) or
690 (name <> ItemAttributes(iKey).name)) then
691 raise HashCollision;
692
693 else
694 status := WF_CACHE.task_SUCCESS;
695
696 end if;
697
698 else
699 status := WF_CACHE.task_FAILED;
700 CacheManager(TAB_ItemAttributes);
701
702 end if;
703
704 EXCEPTION
705 when NO_DATA_FOUND then
706 status := WF_CACHE.task_FAILED;
707 CacheManager(TAB_ItemAttributes);
708
709 when HashCollision then
710 if not (ErrorOnCollision) then
711 status := WF_CACHE.task_FAILED;
712 CacheManager(TAB_ItemAttributes);
713
714 else
715 raise;
719 when OTHERS then
716
717 end if;
718
720 raise;
721
722 END;
723
724
725 /*===========================+
726 | GetItemAttrValue |
727 +===========================+===================+
728 | IN: itemType (VARCHAR2) |
729 | itemKey (VARCHAR2) |
730 | name (VARCHAR2) |
731 +-----------------------------------------------+
732 | OUT: status (PLS_INTEGER) |
733 | wiavIND (NUMBER) |
734 +-----------------------------------------------+
735 | NOTE: Use in #SYNCH mode only. |
736 +===============================================*/
737
738 PROCEDURE GetItemAttrValue (itemType in VARCHAR2,
739 itemKey in VARCHAR2,
740 name in VARCHAR2,
741 status out NOCOPY PLS_INTEGER,
742 wiavIND out NOCOPY NUMBER) is
743
744 ikey number;
745
746 begin
747 --ItemAttrValue cache is introduced in synch process only, so itemKey
748 --will always be #SYNCH. However, later when we introduce item locking
749 --we will be able to cache attributes for multiple items.
750 iKey := Hashkey(itemType||itemKey||name);
751 wiavIND := iKey;
752
753 if (ItemAttrValues.EXISTS(iKey)) then
754 if ((ItemAttrValues(iKey).ITEM_TYPE <> itemType) or
755 (ItemAttrValues(iKey).ITEM_KEY <> itemKey) or
756 (ItemAttrValues(iKey).NAME <> name)) then
757 raise hashcollision;
758
759 else
760 status := WF_CACHE.task_SUCCESS;
761
762 end if;
763
764 else
765 status := WF_CACHE.task_FAILED;
766
767 end if;
768
769 exception
770 when HashCollision then
771 if not (ErrorOnCollision) then
772 status := WF_CACHE.task_FAILED;
773
774 else
775 raise;
776
777 end if;
778
779 end;
780
781
782 /*===========================+
783 | GetItemType |
784 +===========================+===================+
785 | IN: itemType (VARCHAR2) |
786 +-----------------------------------------------+
787 | OUT: status (PLS_INTEGER) |
788 | witIND (NUMBER) |
789 +===============================================*/
790
791 PROCEDURE GetItemType (itemType in VARCHAR2,
792 status out NOCOPY PLS_INTEGER,
793 witIND out NOCOPY NUMBER) is
794
795 iKey NUMBER;
796
797 BEGIN
798
799 iKey := HashKey(itemType);
800 witIND := iKey;
801
802 if (ItemTypes.EXISTS(iKey)) then
803 if (itemType <> ItemTypes(iKey).name) then
804 raise HashCollision;
805
806 else
807
808 status := WF_CACHE.task_SUCCESS;
809
810 end if;
811
812 else
813 status := WF_CACHE.task_FAILED;
814 CacheManager(TAB_ItemTypes);
815
816 end if;
817
818 EXCEPTION
819 when NO_DATA_FOUND then
820 status := WF_CACHE.task_FAILED;
821 CacheManager(TAB_ItemTypes);
822
823 when HashCollision then
824 if not (ErrorOnCollision) then
825 status := WF_CACHE.task_FAILED;
826 CacheManager(TAB_ItemTypes);
827
828 else
829 raise;
830
831 end if;
832
833 when OTHERS then
834 raise;
835
836
837 END;
838
839
840 /*===========================+
841 | GetProcessActivity |
842 +===========================+===================+
843 | IN: actid (NUMBER) |
844 +-----------------------------------------------+
845 | OUT: status (PLS_INTEGER) |
846 +===============================================*/
847
848 PROCEDURE GetProcessActivity (actid in NUMBER,
849 status out NOCOPY PLS_INTEGER) is
850
851
852 BEGIN
853
854 if (ProcessActivities.EXISTS(actid)) then
855
856 status := WF_CACHE.task_SUCCESS;
857
858 else
859 status := WF_CACHE.task_FAILED;
860
861 end if;
862
863 EXCEPTION
864 when NO_DATA_FOUND then
865 status := WF_CACHE.task_FAILED;
866 CacheManager(TAB_ProcessActivities);
867
868 when OTHERS then
869 raise;
870
871 END;
872
873 /*===========================+
874 | GetProcessActivityInfo |
875 +===========================+===================+
876 | IN: actid (NUMBER) |
877 | actdate (DATE) |
878 +-----------------------------------------------+
882
879 | OUT: status (PLS_INTEGER) |
880 | waIND (NUMBER) |
881 +===============================================*/
883 PROCEDURE GetProcessActivityInfo (actid in NUMBER,
884 actdate in DATE,
885 status out NOCOPY PLS_INTEGER,
886 waIND out NOCOPY NUMBER) is
887
888 l_status PLS_INTEGER;
889 l_waIND NUMBER;
890
891 BEGIN
892
893 if (ProcessActivities.EXISTS(actid)) then
894
895 WF_CACHE.GetActivity(ProcessActivities(actid).ACTIVITY_ITEM_TYPE,
896 ProcessActivities(actid).ACTIVITY_NAME, actdate,
897 l_status, l_waIND);
898
899 waIND := l_waIND;
900
901 if ((l_status <> WF_CACHE.task_SUCCESS)
902
903 or
904
905 ((ProcessActivities(actid).ACTIVITY_ITEM_TYPE <>
906 Activities(l_waIND).ITEM_TYPE) or
907
908 (ProcessActivities(actid).ACTIVITY_NAME <>
909 Activities(l_waIND).NAME)) ) then
910
911 status := WF_CACHE.task_FAILED;
912 CacheManager(TAB_Activities);
913 CacheManager(TAB_ProcessActivities);
914 return;
915
916 else
917 status := WF_CACHE.task_SUCCESS;
918
919 end if;
920
921 else
922 status := WF_CACHE.task_FAILED;
923 CacheManager(TAB_Activities);
924 CacheManager(TAB_ProcessActivities);
925 return;
926
927 end if;
928
929 EXCEPTION
930 when NO_DATA_FOUND then
931 status := WF_CACHE.task_FAILED;
932 CacheManager(TAB_ProcessActivities);
933
934 when OTHERS then
935 raise;
936
937 END;
938
939 /*===========================+
940 | GetNLSParameter |
941 +===========================+===================+
942 | IN: Parameter (VARCHAR2) |
943 +-----------------------------------------------+
944 | OUT: status (PLS_INTEGER) |
945 | nlsIND (NUMBER) |
946 +===============================================*/
947
948 PROCEDURE GetNLSParameter (Parameter in VARCHAR2,
949 status out NOCOPY PLS_INTEGER,
950 nlsIND out NOCOPY NUMBER) is
951 iKey NUMBER;
952
953 BEGIN
954 iKey := HashKey(Parameter);
955 nlsIND := iKey;
956
957 if (NLSParameters.EXISTS(iKey)) then
958 if (Parameter <> NLSParameters(iKey).PARAMETER) then
959 raise HashCollision;
960
961 else
962 status := WF_CACHE.task_SUCCESS;
963
964 end if;
965
966 else
967 status := WF_CACHE.task_FAILED;
968 --We do not really need to cache manage NLS Parameters, the plsql table
969 --should remain small.
970
971 end if;
972
973 EXCEPTION
974 when NO_DATA_FOUND then
975 status := WF_CACHE.task_FAILED;
976
977 when HashCollision then
978 if not (ErrorOnCollision) then
979 status := WF_CACHE.task_FAILED;
980
981 else
982 raise;
983
984 end if;
985
986 when OTHERS then
987 raise;
988
989 END;
990 --</rwunderl:2750876>
991 --<rwunderl:2412971>
992 /*===========================+
993 | GetProcessStartActivities |
994 +===========================+===================+
995 | IN: ItemType (VARCHAR2) |
996 | Name (VARCHAR2) |
997 | Version (NUMBER) |
998 +-----------------------------------------------+
999 | OUT: status (PLS_INTEGER) |
1000 | spaIND (NUMBER) |
1001 +===============================================*/
1002
1003 PROCEDURE GetProcessStartActivities (ItemType in VARCHAR2,
1004 Name in VARCHAR2,
1005 Version in NUMBER,
1006 status out NOCOPY PLS_INTEGER,
1007 psaIND out NOCOPY NUMBER) is
1008
1009 iKey NUMBER;
1010
1011 BEGIN
1012 iKey := HashKey(ItemType||':'||Name||':'||Version);
1013 psaIND := iKey;
1014
1015 if (ProcessStartActivities.EXISTS(iKey)) then
1016 if ((ItemType <> ProcessStartActivities(iKey).PROCESS_ITEM_TYPE) or
1017 (Name <> ProcessStartActivities(iKey).PROCESS_NAME) or
1018 (Version <> ProcessStartActivities(iKey).PROCESS_VERSION)) then
1019 raise HashCollision;
1020
1021 else
1022 status := WF_CACHE.task_SUCCESS;
1023
1024 end if;
1025
1026 else
1027 status := WF_CACHE.task_FAILED;
1028 CacheManager(TAB_ProcessStartActivities);
1029 end if;
1030
1031 exception
1032 when HashCollision then
1033 if not (ErrorOnCollision) then
1034 status := WF_CACHE.task_FAILED;
1035 --Normally we can just report a failure so the calling api will store
1036 --a new record in the current slot and move on. However since
1037 --starting process activites are interrelated, we have to clear the
1038 --whole table to ensure consistency. This condition should not occur
1039 --in normal processing and is just a safegard against the extreme.
1040 WF_CACHE.ProcessStartActivities.DELETE;
1041
1042 else
1043 raise;
1044
1045 end if;
1046
1047 when OTHERS then
1048 raise;
1049 end;
1050 --</rwunderl:2412971>
1051
1052 --
1053 -- BeginTransaction
1054 -- (PRIVATE)
1055 -- Begins a trusted session where calls to Reset() will not have any effect.
1056 -- Caller has to call EndTransaction() immediately before issuing commit.
1057 -- Returns FALSE if transaction was already begun by a parent call.
1058 FUNCTION BeginTransaction return BOOLEAN
1059 is
1060 begin
1061 if ((NOT trustedTransaction) or (trustedTransaction is NULL)) then
1062 trustedTransaction := TRUE;
1063 return TRUE; --Signal SUCCESS
1064 else
1065 return FALSE; --Signal that Transaction was already begun.
1066 end if;
1067 end;
1068
1069 --
1070 -- EndTransaction
1071 -- (PRIVATE)
1072 -- Signals the end of a trusted session and calls Reset() to lock and update
1073 -- WFCACHE_META_UPD.
1074 --
1075 FUNCTION EndTransaction return BOOLEAN
1076 is
1077 begin
1078 if ((NOT trustedTransaction) or (trustedTransaction is NULL)) then
1079 Reset(); --We are going to call Reset() to clear any running caches.
1080 return FALSE; --Signal that there was no transaction to end.
1081 else
1082 trustedTransaction := FALSE;
1083 Reset();
1084 return TRUE;
1085 end if;
1086 end;
1087
1088 END WF_CACHE;
1089