1 PACKAGE BODY ad_patch_analysis_engine
2 /* $Header: adpaengb.pls 120.10.12010000.2 2008/12/05 11:37:34 mkumandu ship $ */
3 AS
4
5 ----------------------------------------------------------------------------
6 -- Declaration of the global variables.
7 ----------------------------------------------------------------------------
8
9 ghashLevel typeHashVarchar;
10 ghashIfUsed typeHashVarchar;
11 ghashIfLoad typeHashVarchar;
12
13 ghashLevelIntr typeHashVarchar;
14 ghashBaselineIntr typeHashVarchar;
15 ghashRequires typeHashVarchar;
16
17
18 ----------------------------------------------------------------------------
19 -- Procedure to print the usage of this package.
20 -- This intializes the following
21 -- * Caching of CodeLevels on customer instance
22 -- * Caching of Baselines on customer instance
23 -- * Caching of IfLoad on customer instance
24 -- * Caching of IfUsed on customer instance
25 ----------------------------------------------------------------------------
26
27 PROCEDURE usage
28 IS
29
30 BEGIN
31 debugPrint ('--------------------------------------------------');
32 debugPrint ('------------Compare 2 Codelevels------------------');
33 debugPrint ('--------------------------------------------------');
34 debugPrint (' ad_patch_analysis_engine.compareLevel(<codelevel1>,<codelevel2>);');
35 debugPrint ('--------------------------------------------------');
36 debugPrint ('------------ Run the Analysis Engine ------------------');
37 debugPrint ('--------------------------------------------------');
38 debugPrint (' ad_patch_analysis_engine.getPatchStatus( '
39 ||'<bug_number>,'
40 ||'<baseline>,'
41 ||'<release>,'
42 ||'<OUT error_message>'
43 ||');');
44 debugPrint ('RETURNS patch_status ');
45 debugPrint ('--------------------------------------------------');
46 debugPrint ('----- Run the Analysis Engine and Update database------');
47 debugPrint ('--------------------------------------------------');
48 debugPrint (' ad_patch_analysis_engine.getPatchStatus( '
49 ||'<bug_number>,'
50 ||'<baseline>,'
51 ||'<release>,'
52 ||'<OUT error_message>,'
53 ||'<analysis_run_id>,'
54 ||'<user_id>,'
55 ||'<overwrite_database>'
56 ||');');
57 debugPrint ('RETURNS patch_status ');
58
59 END;
60
61 ----------------------------------------------------------------------------
62 -- Function to print messages on console
63 ----------------------------------------------------------------------------
64 PROCEDURE debugPrint
65 ( p_message IN VARCHAR2
66 )
67 IS
68 BEGIN
69 NULL;
70 -- DBMS_OUTPUT.put_line (p_message);
71 END;
72
73
74
75 ----------------------------------------------------------------------------
76 -- Get the value from desired hash
77 ----------------------------------------------------------------------------
78 FUNCTION getValueFromHash
79 ( p_key IN VARCHAR2,
80 p_hash IN typeHashVarchar
81 )
82 RETURN VARCHAR2
83 IS
84 l_Value VARCHAR2(50);
85 BEGIN
86
87 l_Value := p_hash(p_key);
88
89 RETURN l_Value;
90
91 EXCEPTION
92
93 WHEN OTHERS THEN
94 RETURN NULL;
95
96 END;
97
98
99
100 ----------------------------------------------------------------------------
101 -- Procedure to initialize the global variables.
102 -- This intializes the following
103 -- * Caching of CodeLevels on customer instance
104 -- * Caching of Baselines on customer instance
105 -- * Caching of IfLoad on customer instance
106 -- * Caching of IfUsed on customer instance
107 ----------------------------------------------------------------------------
108
109 PROCEDURE initialize
110 IS
111
112 BEGIN
113 FOR rec IN
114 (SELECT
115 abbreviation abbr,
116 NVL(used_flag, 'Y') used_flag,
117 NVL(load_flag, 'N') load_flag,
118 codelevel te_level
119 FROM ad_trackable_entities)
120 LOOP
121 ghashLevel(rec.abbr) := rec.te_level;
122 ghashIfUsed(rec.abbr) := rec.used_flag;
123 ghashIfLoad(rec.abbr) := rec.load_flag;
124
125
126 END LOOP;
127 debugPrint ('ghashLevel: '|| ghashLevel.COUNT || ' rows defined.');
128 debugPrint ('ghashIfUsed: '|| ghashIfUsed.COUNT || ' rows defined.');
129 debugPrint ('ghashIfLoad: '|| ghashIfLoad.COUNT || ' rows defined.');
130
131 ghashLevelIntr.DELETE;
132 ghashBaselineIntr.DELETE;
133 ghashRequires.DELETE;
134
135 END;
136
137 ----------------------------------------------------------------------------
138 -- Function to compare the the 2 inputs codelevels.
139 -- Currently assuming the codelevels are numeric.
140 -- Return 1 if (input1 > input2),
141 -- 2 if (input1 < input2)
142 -- 0 if (input1 = input2)
143 -- -1 in case of Error
144 ----------------------------------------------------------------------------
145 FUNCTION compareLevel
146 ( p_level_1 IN VARCHAR2 DEFAULT '',
147 p_level_2 IN VARCHAR2 DEFAULT ''
148 )
149 RETURN NUMBER
150 IS
151 TYPE arrVar IS TABLE OF VARCHAR2(10);
152 l_n NUMBER := 0;
153 l_str VARCHAR2(100);
154 -- As specified in the doc max decimal places can be 10. So initializing the
155 -- table with 10 values of 0 each.
156 l_arrLevel_1 arrVar := arrVar('0','0','0','0','0','0','0','0','0','0');
157 l_arrLevel_2 arrVar := arrVar('0','0','0','0','0','0','0','0','0','0');
158 l_arrLevel_1_size NUMBER := 0;
159 l_arrLevel_2_size NUMBER := 0;
160 BEGIN
161
162 -- Compare if the two levels are same (string comparison)
163 IF (p_level_1 = p_level_2) THEN
164 RETURN 0;
165 END IF;
166
167 -- Storing all the decimal values for Level 1 in plsql table
168 -- Also calculate the real size of the table.
169 -- If input level is empty replace with 0.
170 CASE
171 WHEN length(p_level_1) = 0 THEN l_str := '0';
172 WHEN length(p_level_1) > 0 THEN l_str := LOWER(p_level_1);
173 ELSE l_str := '0';
174 END CASE;
175
176 LOOP
177 l_n := instr(l_str, '.' );
178 IF ( length(l_str) > 0 AND l_n = 0) THEN
179 l_arrLevel_1_size := l_arrLevel_1_size +1;
180 l_arrLevel_1(l_arrLevel_1_size) := l_str;
181 END IF;
182 EXIT WHEN (nvl(l_n,0) = 0);
183 l_arrLevel_1_size := l_arrLevel_1_size +1;
184 l_arrLevel_1(l_arrLevel_1_size) := substr(l_str, 1, l_n-1);
185 l_str := ltrim( substr( l_str, l_n+1 ) );
186 END LOOP;
187
188 -- Storing all the decimal values for Level 2 in plsql table
189 -- Also calculate the real size of the table.
190 -- If input level is empty replace with 0.
191 CASE
192 WHEN length(p_level_2) = 0 THEN l_str := '0';
193 WHEN length(p_level_2) > 0 THEN l_str := LOWER(p_level_2);
194 ELSE l_str := '0';
195 END CASE;
196
197 LOOP
198 l_n := instr(l_str, '.' );
199 IF ( length(l_str) > 0 AND l_n = 0) THEN
200 l_arrLevel_2_size := l_arrLevel_2_size +1;
201 l_arrLevel_2(l_arrLevel_2_size) := l_str;
202 END IF;
203 EXIT WHEN (nvl(l_n,0) = 0);
204 l_arrLevel_2_size := l_arrLevel_2_size +1;
205 l_arrLevel_2(l_arrLevel_2_size) := substr(l_str, 1, l_n-1);
206 l_str := ltrim( substr( l_str, l_n+1 ) );
207 END LOOP;
208
209 --debugPrint(' 1::::'|| l_arrLevel_1_size);
210 --debugPrint(' 2::::'|| l_arrLevel_2_size);
211
212
213 -- Compare the each decimal value of one codelevel with the corresponding
214 -- decimal level of other codelevel for the same place. If one is
215 DECLARE
216 l_tmpSize NUMBER := 0;
217 l_tmpFlg NUMBER := 0;
218 l_tmpVar VARCHAR2(10);
219 l_value_1 VARCHAR2(10);
220 l_value_2 VARCHAR2(10);
221
222 BEGIN
223 IF(l_arrLevel_1_size >= l_arrLevel_2_size) THEN
224 l_tmpSize := l_arrLevel_1_size;
225 ELSE
226 l_tmpSize := l_arrLevel_2_size;
227 END IF;
228
229 --debugPrint(' '|| l_tmpSize);
230
231 -- Loop for each of the decimal places
232 FOR i IN 1..l_tmpSize LOOP
233 BEGIN
234 l_value_1 := l_arrLevel_1(i);
235 l_value_2 := l_arrLevel_2(i);
236
237 -- remove the keyword 'delta' before processing
238 l_value_1 := REPLACE(l_value_1,'delta','');
239 l_value_2 := REPLACE(l_value_2,'delta','');
240
241 -- Check that the first segment for both the levels should match.
242 -- If not return error
243 -- ababkuma 26-JUN-2006 Bug#5357093 commented the code below
244 -- IF(i = 1 AND l_value_1 <> l_value_2) THEN
245 -- RETURN -1;
246 -- END IF;
247
248 -- debugPrint(l_value_1||' '||l_value_2);
249 -- In loop when the segments are same then no action.
250 -- if one is greater than then return the index of the higher level
251 -- The segments 2 onwards could be varchar as well as number.
252 CASE
253 WHEN (TO_NUMBER(l_value_1) = TO_NUMBER(l_value_2) ) THEN NULL;
254 WHEN (TO_NUMBER(l_value_1) > TO_NUMBER(l_value_2) ) THEN RETURN 1;
255 WHEN (TO_NUMBER(l_value_1) < TO_NUMBER(l_value_2) ) THEN RETURN 2;
256 END CASE;
257 EXCEPTION
258 WHEN VALUE_ERROR THEN
259 SELECT GREATEST(l_value_1, l_value_2) INTO l_tmpVar FROM DUAL;
260 CASE
261 WHEN ((l_tmpVar = l_value_2) AND (l_tmpVar = l_value_1)) THEN NULL;
262 WHEN (l_tmpVar = l_value_1) THEN RETURN 1;
263 WHEN (l_tmpVar = l_value_2) THEN RETURN 2;
264 END CASE;
265 END;
266 END LOOP;
267 END;
268
269 CASE
270 WHEN length(p_level_1) = 0 THEN RETURN 2;
271 WHEN length(p_level_1) IS NULL THEN RETURN 2;
272 WHEN length(p_level_2) = 0 THEN RETURN 1;
273 WHEN length(p_level_2) IS NULL THEN RETURN 1;
274 ELSE RETURN 0;
275 END CASE;
276 EXCEPTION
277 WHEN OTHERS THEN
278 RETURN -1;
279 END;
280
281 ----------------------------------------------------------------------------
282 -- Procedure to add the pre-req found to the global pre-req associative array.
283 -- This also validates if the pre-req is
284 -- * present on customer's instance
285 -- * present in the pre-req associative array
286 ----------------------------------------------------------------------------
287 PROCEDURE addPrereq
288 ( p_te_abbr IN VARCHAR2 ,
289 p_te_level IN VARCHAR2 ,
290 p_hashRequires IN OUT NOCOPY typeHashVarchar
291 )
292 IS
293 l_te_level VARCHAR2(50);
294 BEGIN
295
296 -- Check level in ghashLevel for TE_NAME
297 IF (ghashLevel.EXISTS(p_te_abbr)) THEN
298 -- check level from hashRequires for TE_NAME
299 IF (p_hashRequires.EXISTS(p_te_abbr)) THEN
300 IF (compareLevel(p_te_level, p_hashRequires(p_te_abbr)) = 1) THEN
301 -- add to hashPrereq TE_NAME, TE_LEVEL
302 p_hashRequires(p_te_abbr) := p_te_level;
303 -- debugPrint (p_te_abbr||' '||p_te_level );
304 END IF;
305 ELSE
306 IF (compareLevel(p_te_level, ghashLevel(p_te_abbr)) = 1 ) THEN
307 -- add to hashPrereq TE_NAME, TE_LEVEL
308 p_hashRequires(p_te_abbr) := p_te_level;
309 -- debugPrint (p_te_abbr||' '||p_te_level );
310 END IF;
311 END IF;
312 ELSE
313 -- get level from hashPrereq for TE_NAME
314 IF (p_hashRequires.EXISTS(p_te_abbr)) THEN
315 IF ( compareLevel(p_te_level, p_hashRequires(p_te_abbr)) = 1) THEN
316 p_hashRequires(p_te_abbr) := p_te_level;
317 -- debugPrint (p_te_abbr||' '||p_te_level );
318 END IF;
319 ELSE
320 p_hashRequires(p_te_abbr) := p_te_level;
321 -- debugPrint (p_te_abbr||' '||p_te_level );
322 END IF;
323 END IF;
324 END;
325
326
327 ----------------------------------------------------------------------------
328 -- Procedure to determine the status of the patch asked by user and also
329 -- determines the reasons for output status.
330 -- This procedure is exposed to user.
331 ----------------------------------------------------------------------------
332
333 FUNCTION getPatchStatus (
334 p_bug_number IN NUMBER,
335 p_baseline IN VARCHAR2,
336 p_release IN VARCHAR2,
337 p_err_message OUT NOCOPY VARCHAR2,
338 p_analysis_run_id IN NUMBER,
339 p_user_id IN NUMBER,
340 p_overwrite IN BOOLEAN DEFAULT FALSE
341 )
342 RETURN VARCHAR2 IS
343 l_analysis_run_bug_id NUMBER := 0;
344 l_tmpCnt NUMBER := 0;
345 l_tmpVar VARCHAR2(30);
346 l_patch_status VARCHAR2(100) := 'ERROR';
347 l_tmpLevel VARCHAR2(30) := NULL;
348 l_tmpBaseline VARCHAR2(30) := NULL;
349 BEGIN
350
351 debugPrint ('Start - Calling pre-req');
352 l_patch_status := getPatchStatus (p_bug_number, p_baseline, p_release, p_err_message);
353 debugPrint ('End - Pre-req is ');
354
355 -- Perform the insertion in the Patch Wizard tables if analysis_id is specified
356 IF (p_analysis_run_id > 0) THEN
357 SELECT analysis_run_bug_id INTO l_analysis_run_bug_id
358 FROM ad_pa_analysis_run_bugs
359 WHERE analysis_run_id = p_analysis_run_id
360 AND bug_number = p_bug_number
361 AND baseline = p_baseline;
362
366 WHERE analysis_run_id = p_analysis_run_id
363 IF (l_analysis_run_bug_id > 0) THEN
364 UPDATE ad_pa_analysis_run_bugs
365 SET analysis_status = l_patch_status
367 AND bug_number = p_bug_number
368 AND baseline = p_baseline;
369
370 -- Insert the pre-req data in ad_pa_anal_run_bug_prereqs
371 debugPrint ('PREREQ CNT:'|| ghashRequires.COUNT);
372
373 IF(ghashRequires.COUNT > 0) THEN
374 l_tmpVar := ghashRequires.FIRST; -- get subscript of first element
375 WHILE l_tmpVar IS NOT NULL LOOP
376 debugPrint ('Pre-req is '|| l_tmpVar ||' Level: '|| ghashRequires(l_tmpVar));
377
378 IF (p_overwrite) THEN
379 DELETE FROM ad_pa_anal_run_bug_prereqs
380 WHERE analysis_run_bug_id = l_analysis_run_bug_id
381 AND prereq_te_abbr = l_tmpVar;
382 END IF;
383
384 INSERT INTO ad_pa_anal_run_bug_prereqs
385 (analysis_run_bug_id, prereq_te_abbr, prereq_te_level,
386 created_by, creation_date, last_updated_by , last_update_date)
387 SELECT l_analysis_run_bug_id,
388 l_tmpVar ,
389 ghashRequires(l_tmpVar),
390 p_user_id,
391 sysdate,
392 p_user_id,
393 sysdate
394 FROM DUAL
395 WHERE NOT EXISTS
396 ( SELECT 'x' FROM ad_pa_anal_run_bug_prereqs
397 WHERE analysis_run_bug_id = l_analysis_run_bug_id
398 AND prereq_te_abbr = l_tmpVar
399 );
400
401 l_tmpVar := ghashRequires.NEXT(l_tmpVar);
402 END LOOP;
403 END IF;
404
405 -- Insert the introducing codelevel/baseline data in ad_pa_anal_run_bug_codelevels
406 IF (ghashLevelIntr.COUNT > 0) THEN
407 debugPrint ('Introducing :'|| ghashLevelIntr.COUNT );
408 l_tmpVar := ghashLevelIntr.FIRST; -- get subscript of first element
409
410 WHILE l_tmpVar IS NOT NULL LOOP
411 debugPrint ('Introducing for '|| l_tmpVar || ' Level: '|| getValueFromHash(l_tmpVar, ghashLevelIntr)||' Baseline:'||getValueFromHash(l_tmpVar, ghashBaselineIntr) );
412
413 IF (p_overwrite) THEN
414 DELETE FROM ad_pa_anal_run_bug_codelevels
415 WHERE analysis_run_bug_id = l_analysis_run_bug_id
416 AND intr_te_abbr = l_tmpVar;
417 END IF;
418
419 l_tmpLevel := getValueFromHash(l_tmpVar, ghashLevelIntr);
420 l_tmpBaseline := getValueFromHash(l_tmpVar, ghashBaselineIntr);
421
422 INSERT INTO ad_pa_anal_run_bug_codelevels
423 (analysis_run_bug_id, intr_te_abbr, intr_te_level,
424 intr_te_baseline, intr_te_type,
425 created_by, creation_date, last_updated_by , last_update_date)
426 SELECT l_analysis_run_bug_id,
427 l_tmpVar ,
428 l_tmpLevel,
429 l_tmpBaseline,
430 null,
431 p_user_id,
432 sysdate,
433 p_user_id,
434 sysdate
435 FROM DUAL
436 WHERE NOT EXISTS
437 ( SELECT 'x' FROM ad_pa_anal_run_bug_codelevels
438 WHERE analysis_run_bug_id = l_analysis_run_bug_id
439 AND intr_te_abbr = l_tmpVar
440 );
441
442 l_tmpVar := ghashLevelIntr.NEXT(l_tmpVar);
443 END LOOP;
444 END IF;
445
446 COMMIT;
447
448 END IF;
449 END IF;
450
451 RETURN l_patch_status;
452
453 EXCEPTION
454 WHEN OTHERS THEN
455 ROLLBACK;
456 raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
457 RETURN l_patch_status;
458
459 END;
460
461 ----------------------------------------------------------------------------
462 -- Procedure to determine the status of the patch asked by user and also
463 -- determines the reasons for output status.
464 -- This procedure is exposed to user.
465 ----------------------------------------------------------------------------
466
467 FUNCTION getPatchStatus (
468 p_bug_number IN NUMBER,
469 p_baseline IN VARCHAR2,
470 p_release IN VARCHAR2,
471 p_err_message OUT NOCOPY VARCHAR2
472 )
473 RETURN VARCHAR2 IS
474 l_patch_status VARCHAR2(100) := 'READY';
475 l_patch_type VARCHAR2(100) :='';
476 l_count NUMBER := 0;
477 l_patch_id NUMBER := 0;
478 l_te_abbr VARCHAR2(30) ;
479 l_te_baseline VARCHAR2(30) ;
480
481 BEGIN
482
483 debugPrint ('Calling Initiallize.... ');
484 initialize();
485 debugPrint ('End Calling Initiallize.... ');
486
487 -- Check for the existence of BUG_NUMBER, BASELINE in Snapshot tables for global snapshot.
488 -- If found then set output status as 'APPLIED'
489 -- msailoz bug#5505349
490 -- If baseline is not provided or patch is baseline independent only search
491 -- for the existence of bug_number in AD_BUGS
492
496 FROM ad_snapshot_bugfixes
493 IF ( length(trim(p_baseline)) = 0 OR p_baseline = 'R12') THEN
494
495 SELECT count(SNAPSHOT_BUG_ID) INTO l_count
497 WHERE bugfix_id in
498 (SELECT bug_id FROM AD_BUGS
499 WHERE bug_number = to_char(p_bug_number)
500 AND ARU_RELEASE_NAME = p_release)
501 AND snapshot_id =
502 (SELECT snapshot_id
503 FROM ad_snapshots
504 WHERE snapshot_name = 'GLOBAL_VIEW'
505 and snapshot_type = 'G');
506 ELSE
507
508 SELECT count(SNAPSHOT_BUG_ID) INTO l_count
509 FROM ad_snapshot_bugfixes
510 WHERE bugfix_id in
511 (SELECT bug_id FROM AD_BUGS
512 WHERE bug_number = to_char(p_bug_number)
513 AND baseline_name = p_baseline
514 AND ARU_RELEASE_NAME = p_release)
515 AND snapshot_id =
516 (SELECT snapshot_id
517 FROM ad_snapshots
518 WHERE snapshot_name = 'GLOBAL_VIEW'
519 and snapshot_type = 'G');
520 END IF;
521
522 debugPrint ('Count'|| l_count);
523
524 IF (l_count > 0) THEN
525 l_patch_status := 'APPLIED';
526 RETURN l_patch_status;
527 ELSE
528 debugPrint ('No records found in Snapshot');
529 NULL;
530 END IF;
531
532 -- Check whether this patch has been uploaded
533 debugPrint ('... Checking uploading of patch');
534 DECLARE
535 l_upload_id NUMBER := 0;
536 BEGIN
537
538 SELECT entity_abbr,
539 patch_id,
540 NVL(upload_run_id,-1),
541 NVL(patch_type,'')
542 INTO l_te_abbr,
543 l_patch_id,
544 l_upload_id,
545 l_patch_type
546 FROM ad_pm_patches
547 WHERE bug_number = p_bug_number
548 AND baseline = p_baseline;
549
550 --- 09-Aug-2006 ababkuma bug#5357552 handling obsoleted patch
551 IF (l_patch_id = 0 ) THEN
552 l_patch_status := 'ERROR';
553 p_err_message := 'PATCH NOT UPLOADED';
554 RETURN l_patch_status;
555 ELSIF (l_upload_id <= 0 ) THEN
556 l_patch_status := 'ERROR';
557 p_err_message := 'PATCH METADATA NOT UPLOADED';
558 RETURN l_patch_status;
559 ELSIF (l_patch_type = 'obsoleted' ) THEN
560 l_patch_status := 'OBSOLETED';
561 p_err_message := 'PATCH IS OBSOLETED';
562 RETURN l_patch_status;
563 END IF;
564
565 EXCEPTION
566 WHEN no_data_found THEN
567 l_patch_status := 'ERROR';
568 p_err_message := 'PATCH NOT UPLOADED';
569 RETURN l_patch_status;
570 END;
571
572 -- Compare the baseline of patch with that on customer instance
573 debugPrint ('... Checking uploading of patch');
574
575 -- if the patch is generic patch then no need of comparing with baseline on customer instance
576 IF (p_baseline <> 'R12' AND LENGTH(TRIM(p_baseline)) > 0) THEN
577 BEGIN
578
579 SELECT baseline
580 INTO l_te_baseline
581 FROM ad_trackable_entities
582 WHERE abbreviation = l_te_abbr;
583
584 -- if the patch is not generic and doesn't match with the baseline
585 -- on customer instance then error out
586 IF (compareLevel(l_te_baseline, p_baseline) <> 0 ) THEN
587 l_patch_status := 'ERROR';
588 p_err_message := 'PATCH BASELINE NOT MATCHING';
589 END IF;
590
591 EXCEPTION
592 WHEN no_data_found THEN
593 l_patch_status := 'READY';
594 END;
595 END IF;
596
597 -- Check all the baselines introduced are higher or equal to that on the customer instance.
598 -- Also mark the new CodeLevels introduced
599 DECLARE
600 l_tmpVar VARCHAR2(100) := NULL;
601 BEGIN
602 debugPrint ('... Checking levels of patch');
603 FOR rec IN
604 (SELECT appei.te_abbr,
605 nvl(ate.baseline,0) curr_baseline,
606 nvl(appei.baseline,0) intr_baseline,
607 nvl(ate.codelevel,0) curr_level,
608 nvl(appei.te_level,0) intr_level
609 FROM ad_pa_patch_entity_info appei,
610 ad_trackable_entities ate
611 WHERE appei.te_abbr = ate.abbreviation(+)
612 AND appei.patch_id = l_patch_id)
613 LOOP
614 debugPrint (rec.te_abbr ||' BASELINE (current,intr) ('|| rec.curr_baseline||', '||rec.intr_baseline
615 ||') CODELEVEL (current,intr) ('|| rec.curr_level||', '|| rec.intr_level||')');
616 IF( compareLevel(rec.intr_baseline, rec.curr_baseline) <> 2) THEN
617 IF( compareLevel(rec.intr_level, rec.curr_level) = 1 ) THEN
618 ghashLevelIntr(rec.te_abbr) := rec.intr_level;
619 END IF;
620 IF( compareLevel(rec.intr_baseline, rec.curr_baseline) = 1 ) THEN
621 ghashBaselineIntr(rec.te_abbr) := rec.intr_level;
622 END IF;
623 END IF;
624 END LOOP;
625
626 -- IF(l_tmpStatus != NULL) THEN
627 -- l_patch_status := 'ERROR';
628 -- p_err_message := 'Found higher '||l_tmpStatus||' baselines than in Patch';
629 -- RETURN l_patch_status;
630 --END IF;
631
635 l_tmpVar := ghashLevelIntr.FIRST;
632 -- Store the introducing levels in output string
633 IF ( ghashLevelIntr.COUNT > 0) THEN
634 p_err_message := p_err_message || 'INTRODUCES ';
636 WHILE l_tmpVar IS NOT NULL LOOP
637 p_err_message := p_err_message || l_tmpVar ||':'|| ghashLevelIntr(l_tmpVar) ||' ';
638 l_tmpVar := ghashLevelIntr.NEXT(l_tmpVar);
639 END LOOP;
640 END IF;
641 END;
642
643 debugPrint ('New Levels Introduced: '|| ghashLevelIntr.COUNT );
644 debugPrint ('New Baselines Introduced: '|| ghashBaselineIntr.COUNT );
645
646
647 -- Check all the requires and conditional requires (PRE_REQUISITES )specified in patch driver.
648 DECLARE
649 l_tmpVar VARCHAR2(100) := NULL;
650 BEGIN
651 debugPrint ('... Checking Requires of patch');
652 debugPrint ('PATCH ID: '|| l_patch_id);
653 FOR rec IN
654 ( SELECT appri.patch_requires_id,
655 appri.te_abbr,
656 appri.requires_te_abbr,
657 appri.requires_te_level ,
658 appcri.condition_type,
659 appcri.condition_te_abbr,
660 appcri.condition_te_level
661 FROM ad_pa_patch_requires_info appri,
662 ad_pa_patch_cond_requires_info appcri
663 WHERE appri.patch_id = l_patch_id
664 AND appri.patch_requires_id = appcri.patch_requires_id (+) )
665
666 LOOP
667 IF (rec.condition_type IS NULL) THEN
668 addPrereq(rec.requires_te_abbr, rec.requires_te_level, ghashRequires);
669 ELSIF( UPPER(rec.condition_type) = 'IFUSED') THEN
670 IF( ghashIfUsed.EXISTS(rec.condition_te_abbr)) THEN
671 IF(ghashIfUsed(rec.condition_te_abbr) = 'Y'
672 AND (compareLevel(rec.condition_te_level, ghashLevel(rec.condition_te_abbr)) = 1
673 OR compareLevel(rec.condition_te_level, ghashLevel(rec.condition_te_abbr)) = 0 )
674 ) THEN
675
676 addPrereq(rec.requires_te_abbr, rec.requires_te_level, ghashRequires);
677 END IF;
678 END IF;
679 ELSIF( UPPER(rec.condition_type) = 'IFLOAD') THEN
680 IF(ghashIfLoad.EXISTS(rec.condition_te_abbr)) THEN
681 IF(ghashIfLoad(rec.condition_te_abbr) = 'Y'
682 AND (compareLevel(rec.condition_te_level, ghashLevel(rec.condition_te_abbr)) = 1
683 OR compareLevel(rec.condition_te_level, ghashLevel(rec.condition_te_abbr)) = 0 )
684 ) THEN
685 addPrereq(rec.requires_te_abbr, rec.requires_te_level, ghashRequires);
686 END IF;
687 END IF;
688 END IF;
689 END LOOP;
690
691 debugPrint ('Total Requires: '|| ghashRequires.COUNT );
692 -- Store the requires in output string
693 IF ( ghashRequires.COUNT > 0) THEN
694 l_patch_status := 'MISSING';
695 p_err_message := p_err_message || 'REQUIRES ';
696 l_tmpVar := ghashRequires.FIRST;
697 WHILE l_tmpVar IS NOT NULL LOOP
698 p_err_message := p_err_message || UPPER(l_tmpVar) ||'.'|| ghashRequires(l_tmpVar) ||' ';
699
700 l_tmpVar := ghashRequires.NEXT(l_tmpVar);
701 END LOOP;
702
703 RETURN l_patch_status;
704 END IF;
705 END;
706
707 RETURN l_patch_status;
708
709 END;
710
711 -- var p varchar2(100)
712 -- var c varchar2(100)
713 --- exec :p := ad_patch_analysis_engine.getPatchStatus(9000002,'R12','R12', :c);
714 --- exec :p := ad_patch_analysis_engine.getPatchStatus(7000002,'AD.1.0','R12', :c, 4652175, 4);
715 --- exec :p := ad_patch_analysis_engine.getPatchStatus(8000004,'R12','R12', :c);
716 --- exec :p := ad_patch_analysis_engine.compareLevel('AD.1.2','AD.1')
717 -- select ad_patch_analysis_engine.compareLevel('120.22','33') from dual
718
719 END ad_patch_analysis_engine;