DBA Data[Home] [Help]

PACKAGE BODY: APPS.WF_CACHE

Source


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